omp packages

pi-rtl0.1.1

Right-to-left rendering for Pi: Arabic/Persian shaping, Unicode bidi, RTL alignment, bold text and lam-alef ligatures for terminals that have no bidi or shaping, plus a one-command Persian font setup.

co-parsa Published 3 days ago MIT ~328 downloads/mo

Untested on omp

This is a pi package. No one has reported whether it works on omp yet. If you try it, add your result below.

Did it work for you?

Result

One report per person. A new report replaces your old one.

Reports 0

No reports yet.

Readme

pi-rtl

Right-to-left support for Pi's terminal UI — Persian, Arabic and Hebrew — for terminals that do no bidi and no Arabic shaping (Windows Terminal, conhost, Windows Terminal-family, xterm, alacritty, kitty, …).

Pi stores text in logical order; terminals paint cells left to right and most of them have no shaping engine, so Persian comes out reversed and with disconnected letters. This package fixes both, everywhere Pi draws.

before:  .ﺩﻮﺷﯽﻣ ﺖﺴﻳﺍ ﻪﻠﻤﺟ ﻦﻳﺍ
after:   این جمله است میشود

Install

pi install npm:pi-rtl

Then restart Pi (or run /reload). Verify with /rtl test and /rtl status.

To try it without touching settings:

pi -e npm:pi-rtl

Persian font (recommended)

Most terminal fonts have no Arabic glyphs, so the shaped letters are drawn by a fallback font and look uneven. Install the bundled Persian monospace font and point your terminals at it:

npx pi-rtl font           # install + configure console and Windows Terminal
npx pi-rtl font status    # what is installed / configured
npx pi-rtl font revert    # restore the previous terminal fonts
  • Windows — copies Vazir Code into %LOCALAPPDATA%\Microsoft\Windows\Fonts (per-user, no admin), registers it, sets HKCU\Console to it and sets profiles.defaults.font in Windows Terminal. Existing values are backed up to ~/.pi/agent/pi-rtl-font-backup.json and settings.json.bak-pi-rtl.
  • macOS / Linux — copies the font into your user font directory and runs fc-cache; select the font in your terminal manually.

Close and reopen the terminal window afterwards.

What it does

Every rendered line is converted to visual order right before it is written out, at the single point where the regular and the fullscreen renderer hand their lines over (TuiBase.resolveFakeCursors). Nothing is patched on disk.

  1. Shaping — Persian/Arabic letters are mapped to their contextual presentation forms (isolated / final / initial / medial), including lam-alef ligatures. ZWNJ (نیم‌فاصله) is honoured: the half-space blocks the join but letters keep their joined forms, the way Persian typography does it.
  2. Bidi — a full UAX #9 implementation (P2/P3, W1–W7, N0–N2, I1–I2, L1, L2) reorders each line, mirrors brackets and keeps Latin words, numbers, emoji and punctuation where they belong.
  3. Presentation — right-to-left paragraphs are right-aligned to a stable right edge, RTL runs are drawn bold, and ANSI colors, hyperlinks and the editor's cursor markers travel with the characters they belong to.

The transform is width preserving: one codepoint in, one out. Wrapping, truncation, padding, block backgrounds and the hardware cursor column are exactly as Pi computed them. Lines without right-to-left characters pass through byte-identical.

Commands

Command Effect
/rtl toggle on / off (also Ctrl+Alt+R)
/rtl on / /rtl off enable / disable
/rtl bidi reorder only, keep the disconnected letter shapes
/rtl bold / /rtl normal bold RTL runs (default: bold)
/rtl ligatures / /rtl no-ligatures lam-alef ligatures (default: on)
/rtl align right / /rtl align left alignment of RTL paragraphs (default: right)
/rtl auto | /rtl ltr | /rtl rtl paragraph direction for lines without strong text
/rtl status current settings
/rtl test print a Persian sample line

Settings live in ~/.pi/agent/pi-rtl.json:

{
  "mode": "on",
  "baseDirection": "auto",
  "align": "right",
  "bold": true,
  "ligatures": true
}

PI_RTL=on|bidi|off overrides the mode for one run.

Scrolling and the scrollbar

The fullscreen scrollbar is painted into the last column of every line. The transform removes that cell before deciding anything and puts it back afterwards, so a scrollbar appearing or fading never changes alignment: every RTL line ends on the same column whether you are scrolling or not.

Limitations

  • Copying text copies what is on screen — presentation forms in visual order. The session, the prompts sent to the model and the files stay logical.
  • Code blocks containing Persian are reordered too, because the transform works on rendered lines. Use /rtl off when reading code rather than text.
  • Terminals with native bidi (mlterm, konsole, GNOME Terminal) would apply bidi twice — keep the extension off there.
  • Lam-alef merges two cells into one; the freed cell is returned to the line's own padding so widths never change.

How it hooks in

index.ts patches TuiBase.resolveFakeCursors on the prototype chain of TuiMainScreen/TuiAltScreen once per process, through the module instance Pi maps for @earendil-works/pi-tui. No files on disk are modified, so updates of Pi cannot break the patch and a newer copy re-applies it on the next start.

Files

Path Purpose
extensions/index.ts hook, /rtl command, config
extensions/visualize.ts ANSI-aware logical → visual line transform
extensions/unicode-bidi.ts UAX #9 implementation + mirroring
extensions/shape.ts Arabic/Persian contextual shaping
bin/pi-rtl.mjs font installer / status / revert
fonts/ bundled Vazir Code font (see fonts/LICENSE-Vazir-Code.txt)
test/selftest.ts node test/selftest.ts

Related work

pi-bidi, pi-arabic-rtl, pi-persian-rtl, pi-persian-rtl-bundle and pi-hebrew-rtl all reorder lines, but none of them shape Arabic letters, and several patch a node_modules/@earendil-works/pi-tui copy that Pi's bundled build never loads. This package does shaping, bidi, styling and alignment in one runtime hook.

License

MIT. The bundled Vazir Code font is public domain / Bitstream Vera based; see fonts/LICENSE-Vazir-Code.txt.