Repository navigation
feat: draw right-to-left terminal text in reading order (terminal_bidi) - #838
Open
1Goltsman1 wants to merge 2 commits into
Open
1Goltsman1 wants to merge 2 commits into
1Goltsman1 wants to merge 2 commits into
Conversation
1Goltsman1
force-pushed
the
feat/terminal-bidi
branch
from
November 15, 2026 15:26
cbad608 to
eb94fd1
Compare
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Adds an opt-in
terminal_bidisetting (default off). With it on, terminal rows that hold right-to-left characters (Hebrew, Arabic, ...) are drawn with the Unicode Bidirectional Algorithm, each row a left-to-right paragraph (the terminal-wg "implicit" mode, as in iTerm2 and mlterm). Today such rows are drawn strictly left to right, so Hebrew typed into an agent's prompt, and Hebrew output, read reversed. Only the drawing changes: the grid, copy, search, links,hc readand selection stay in logical order. A mod can't change how panes draw, so this is app code.Rebased onto current master (
5216e6f).How
src/bidi.rs: a quick per-row scan for strong RTL characters (rows without them are untouched);unicode-bidi(already a transitive dependency) resolves levels; logical↔visual column maps; a wide character keeps head and tail adjacent.│ שם │ גודל │no longer swaps its columns (segmenting idea from feat: draw right-to-left text right to left with joined letters #945).links::spans)/and\count as left to right, so/Users/dan/פרויקטים/תיקייה/srckeeps its folders in order while each Hebrew name still reads right to left. A slash in prose (כן/לא) still reads right to left.row_opsplaces backgrounds, text runs, sprites, icons androw_decorationsat visual columns. Text runs keep logical text, so shaping (Arabic joining, mirrored brackets) still happens in the platform shaper, and runs break where visual adjacency breaks. Search and link highlights, the cursor and the IME box follow their cells; clicks map visual→logical.HERDR:patch toShapedLine::with_cell_positions: each cluster moves by one shift taken from its lowest-index glyph, so niqqud that CoreText emits before its base stays on its letter (fix from fix(macos): restore keyboard suggestions and add opt-in Hebrew BiDi #916). Left-to-right text gets the same result as before.terminal_bidiin settings.json, documented indefaults/AGENTS.md; the painted-row cache key includes it, so toggling applies live.Tests (
cargo test --lockedon macOS: 509 passed, 0 failed, 2 ignored)bidi::tests: pure Hebrew, mixed Hebrew/English, numbers (prices, dates, versions, phone numbers), commands and prompts, brackets, wide characters and emoji, niqqud cells, table borders, aligned columns, paths and URLs, cursor and click mapping. The border, column and path tests fail on the previous version of this PR.render_to_image, not part of the PR): each sample row drawn off and on; colors follow their letters, borders stay aligned, niqqud sits on its letters, and a path's folders were measured to keep their columns.Known limits (fine for an opt-in first step, happy to iterate)
CSI 8 l) opt-out yet for programs that do their own bidi; planned as a follow-up, watched app-side inVt::writelikewin32.watch, with no Ghostty patch.Part of #804 and #847 (RTL/BiDi). Builds on ideas from #916 and #945. Math formula rendering is out of scope.
🤖 Generated with Claude Code