Skip to content

fix: fold text that has no spaces instead of cutting it off at the pane - #24

Merged
hidekingerz merged 3 commits into
mainfrom
claude/cjk-wrap
Sep 4, 2026
Merged

fix: fold text that has no spaces instead of cutting it off at the pane#24
hidekingerz merged 3 commits into
mainfrom
claude/cjk-wrap

Conversation

@hidekingerz

@hidekingerz hidekingerz commented Sep 3, 2026

Copy link
Copy Markdown
Owner

Summary

A Japanese paragraph, or any run of text without spaces such as a long URL, was cut off at the right edge of the pane instead of being folded, and once folded, a run that followed a space was moved to the next row whole, leaving a nearly empty row before it. Word wrapping (reflow/wordwrap, used by glamour and by mado itself) breaks only at spaces and hyphens.

  • internal/ui/wrap.go: mado folds text itself. wrapText breaks a row at a space where one will do, between any two East Asian characters (Japanese has no spaces to offer), and inside a word only when the word alone is wider than the row. Wide characters count as two columns, escape sequences take none and stay whole, and closing marks such as stay with the character before them while stay with the one after (行頭・行末禁則, minimal).
  • hardWrapLines folds glamour's already laid-out output the same way, keeping a paragraph's margin on the rows it continues on; glamour now renders with word wrap off (WithWordWrap(0)), which also stops it padding rows to the width.
  • Tabs are expanded to the columns a terminal draws them at before folding; trailing spaces (glamour pads table cells) are kept only where they fit; an escape sequence inside a highlighted word stays in the word instead of becoming a break.
  • Used everywhere text is folded: reader view, source view, line numbers (continuation rows keep the blank gutter) and the search jump's row count.
  • New direct dependency on github.com/mattn/go-runewidth, already in the module graph; reflow is no longer used directly.

Test plan

  • gofmt -l ., go vet ./..., TMPDIR=/tmp go test -race ./... clean
  • New tests: reader and source view fold a spaceless sentence within the pane with no text lost; the row before a Japanese run is filled rather than left short; Latin words stay whole and an overlong word is split; escape sequences survive; no row starts with or ; line numbers number a folded line once; the search jump's row matches where the line is rendered; hardWrapLines keeps every line once and keeps an indent set behind escape sequences; mermaid diagrams still fit at the exact width and fall back one column narrower
  • Probed headings, quotes, nested and ordered lists, inline styling, links, tables, code blocks, emoji, full- and half-width forms, Hangul and Chinese, spaceless URLs and kinsoku marks: no row wider than the pane, no text lost, no row starting with a closing mark
  • tmux: README bullets, a paragraph starting with 「, mixed English/Japanese, a table, a rule and an English paragraph, in reader, source and numbered modes

🤖 Generated with Claude Code

https://claude.ai/code/session_01KUYF9hXeZFML1s8r3i2RVX

hidekingerz and others added 3 commits September 4, 2026 08:47
Word wrapping breaks only at spaces and hyphens, so a Japanese
sentence, or a long URL, stayed on one line and the pane cut it off.
Every place that folds text now hard-wraps what word wrapping could
not: source view, line numbers, the search jump's row count, and
glamour's output, where a folded paragraph keeps its margin on the
rows it continues on.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KUYF9hXeZFML1s8r3i2RVX
The first fix folded a spaceless run only once word wrapping had
given up on it, so a Japanese sentence that followed a space was moved
to the next row whole, leaving the row before it nearly empty, and a
closing mark could start a row. Folding is now done by mado itself:
rows break at spaces where one will do, between any two East Asian
characters, and inside a word only when the word alone is wider than
the row; 。」 and the like stay with the character before them, and
「( with the one after. Glamour renders without word wrap (which also
stops it padding rows) and its output is folded the same way.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KUYF9hXeZFML1s8r3i2RVX
…ws, keep styled words whole

Checked folding against headings, quotes, nested and ordered lists,
inline styling, links, tables, code blocks, emoji, full- and
half-width forms, Hangul and Chinese, spaceless URLs and the kinsoku
marks. Three things were still cut off or split badly: a tab counted
as one column though the terminal draws it to the next multiple of
eight; the spaces glamour pads table cells with pushed a row past the
pane; and an escape sequence inside a highlighted word was a place to
break. Tabs are now expanded before folding, trailing spaces are kept
only where they fit, and a sequence inside a word stays in the word.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KUYF9hXeZFML1s8r3i2RVX
@hidekingerz
hidekingerz merged commit 5f14a3f into main Sep 4, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant