-
Notifications
You must be signed in to change notification settings - Fork 3
Terminfo cleanups #26
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
WalkthroughThis PR removes the mkinfo tool and its data, simplifies the Termcap struct by removing many attribute/cursor/mouse/paste/URL fields, deletes parser paste/rune methods, updates many terminfo initializers, and adds a VT-based escape layer in TtyScreen; manifest years updated to 2025. Changes
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes
Files/areas to pay extra attention to:
Possibly related PRs
Poem
Pre-merge checks and finishing touches✅ Passed checks (3 passed)
✨ Finishing touches🧪 Generate unit tests (beta)
📜 Recent review detailsConfiguration used: CodeRabbit UI Review profile: CHILL Plan: Pro 📒 Files selected for processing (22)
💤 Files with no reviewable changes (17)
🚧 Files skipped from review as they are similar to previous changes (1)
🔇 Additional comments (10)
Comment |
This will eliminate more incremental changes going forward.
Setting O_NONBLOCK on the underlying file was causing a file in phobos when it tries to write out content, as it cannot cope with an incomplete write. We only care aobut the VMIN/VTIME behavior to control terminal *input*, and we presume that if VMIN and VTIME are both zero, read will still do a non-blocking read, regardless of the setting of O_NONBLOCK.
72e9d40 to
9bed71a
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
source/dcell/ttyscreen.d (1)
723-723: Missingtermparameter in TtyScreen constructor call.The
termvariable is available but not passed toTtyScreen, so legacy terminal detection (lines 120-124) will never trigger. Legacy terminals likevt100,ansi,linux, orsunwon't have OSC functions properly disabled.- return new TtyScreen(newDevTty(), caps); + return new TtyScreen(newDevTty(), caps, term);
🧹 Nitpick comments (1)
source/dcell/ttyscreen.d (1)
667-670: Consider preserving exception details in assertion.The
assert(false)loses the original exception message, making debugging harder. Additionally, in release builds with assertions disabled, this could lead to silent continuation.catch (Exception e) { - assert(false); + assert(false, e.msg); }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (26)
demos/colors/source/colors.d(1 hunks)dub.json(1 hunks)mkinfo/dub.json(0 hunks)mkinfo/source/mkinfo.d(0 hunks)mkinfo/terms.txt(0 hunks)source/dcell/database.d(1 hunks)source/dcell/parser.d(1 hunks)source/dcell/termcap.d(0 hunks)source/dcell/terminfo/aixterm.d(0 hunks)source/dcell/terminfo/alacritty.d(0 hunks)source/dcell/terminfo/ansi.d(0 hunks)source/dcell/terminfo/dtterm.d(0 hunks)source/dcell/terminfo/gnome.d(0 hunks)source/dcell/terminfo/konsole.d(0 hunks)source/dcell/terminfo/linux.d(0 hunks)source/dcell/terminfo/rxvt.d(0 hunks)source/dcell/terminfo/screen.d(0 hunks)source/dcell/terminfo/vt100.d(0 hunks)source/dcell/terminfo/vt102.d(0 hunks)source/dcell/terminfo/vt220.d(0 hunks)source/dcell/terminfo/vt320.d(0 hunks)source/dcell/terminfo/vt420.d(0 hunks)source/dcell/terminfo/xfce.d(0 hunks)source/dcell/terminfo/xterm.d(0 hunks)source/dcell/termio.d(0 hunks)source/dcell/ttyscreen.d(19 hunks)
💤 Files with no reviewable changes (21)
- mkinfo/terms.txt
- source/dcell/terminfo/vt100.d
- source/dcell/terminfo/vt320.d
- source/dcell/terminfo/ansi.d
- source/dcell/terminfo/xfce.d
- source/dcell/terminfo/linux.d
- source/dcell/terminfo/vt220.d
- source/dcell/terminfo/vt102.d
- source/dcell/terminfo/screen.d
- source/dcell/terminfo/gnome.d
- source/dcell/terminfo/xterm.d
- mkinfo/source/mkinfo.d
- source/dcell/terminfo/dtterm.d
- source/dcell/terminfo/konsole.d
- source/dcell/termio.d
- source/dcell/terminfo/vt420.d
- source/dcell/terminfo/aixterm.d
- source/dcell/terminfo/alacritty.d
- mkinfo/dub.json
- source/dcell/terminfo/rxvt.d
- source/dcell/termcap.d
🔇 Additional comments (6)
dub.json (1)
2-11: LGTM!The manifest changes are consistent with the PR's goal of removing the mkinfo build tool. Copyright year update and subPackages cleanup look correct.
demos/colors/source/colors.d (1)
135-183: LGTM! Improved error handling and event loop structure.The try/catch pattern ensures
s.stop()is called on exceptions, preventing terminal state from being left in raw mode. The timing output is a nice addition for performance insights.One note: the
assert(0, "error received")on line 170 will crash the demo if an error event occurs. This is acceptable for a demo but worth keeping in mind.source/dcell/database.d (1)
152-152: LGTM!Test data simplified to align with the Termcap structure changes in this PR.
source/dcell/parser.d (1)
817-830: LGTM!The reformatting with explicit braces improves readability while preserving the paste handling logic.
source/dcell/ttyscreen.d (2)
41-106: Good centralization of terminal escape sequences.The
Vtstruct provides a clean, organized location for terminal control sequences. The mix ofenumconstants for immutable sequences and regular fields for sequences that may need legacy overrides is a sensible design choice.
108-136: LGTM! Sensible legacy terminal handling.The legacy detection covers common legacy terminals (
vt*,ansi,linux,sun) and appropriately disables unsupported OSC/window management features for them.
9bed71a to
fdb710f
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
source/dcell/ttyscreen.d (1)
476-483: Add+ 1to convert 0-basedCoordto 1-based terminal coordinates ingoTo.The
goTofunction passes cursor coordinates directly to the VT100 escape sequencesetCursorPositionwithout adjustment:puts(format!(Vt.setCursorPosition)(pos.y, pos.x));However,
Coorduses 0-based indexing internally:
- Draw loops iterate from
Coord(0, 0):for (pos.y = 0; pos.y < size.y; ...)- Mouse coordinates from the terminal are converted to 0-based with
- 1inhandleMouse:auto x = p1 - 1; auto y = p2 - 1;The VT100 escape sequence
"\x1b[%d;%dH"requires 1-based coordinates. The fix is:puts(format!(Vt.setCursorPosition)(pos.y + 1, pos.x + 1));
🧹 Nitpick comments (3)
source/dcell/parser.d (1)
789-831: Bracketed paste handling via CSI 200/201 is consistent and covered by tests.The new
p0 == 200/p0 == 201handling correctly:
- Enters paste mode and clears
pasteBufon start.- Accumulates runes only while
pastingis true (viapostKey).- Emits a single
pasteevent with the collected buffer on end, matching the unit test that expectspaste.content == "A".Given the old termcap-driven paste sequences are gone, this VT-based approach is appropriate.
You now have some dead state (
pasteTime,pasteStart,pasteEnd) that’s no longer read anywhere; consider removing these fields in a follow-up to keepParserlean.source/dcell/ttyscreen.d (2)
143-193: Stop sequence is mostly sound but has minor redundancy and relies onblocking(true)behaving correctly.The new
stop()sequence:
- Restores auto-margin, colors, SGR state, cursor shape/visibility, and clears the screen using VT sequences.
- Disables paste, mouse, and focus reporting before flushing.
- Uses the
stoppingTurnstile to coordinate withinputLoop, then callsti.stop()and finallyti.restore().Two minor points:
vt.cursorResetis emitted twice back-to-back; you can drop one of them with no behavioral change.- For
PosixTty,ti.stop()already callsrestore(), andstop()then callsti.restore()again. This is harmless but redundant.Once
PosixTty.blocking(bool)is fixed to honor its argument again, theblocking(false)/blocking(true)calls here will correctly ensure the reader thread isn’t stuck in a blocking read while you shut it down.
253-263:hasMouse()now unconditionally returnstrue.This is a behavior change from termcap-driven capability checks to “assume XTerm-style mouse reporting is available everywhere”. Given the rest of the code hard-codes XTerm mouse enable/disable sequences, this is consistent, but it does mean callers can no longer distinguish terminals that truly don’t support mouse tracking.
If you ever need that distinction again, consider deriving the result from
term/legacyor a small allowlist instead of always returningtrue.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (22)
demos/colors/dub.json(1 hunks)source/dcell/database.d(1 hunks)source/dcell/parser.d(1 hunks)source/dcell/termcap.d(0 hunks)source/dcell/terminfo/aixterm.d(0 hunks)source/dcell/terminfo/alacritty.d(0 hunks)source/dcell/terminfo/ansi.d(0 hunks)source/dcell/terminfo/dtterm.d(0 hunks)source/dcell/terminfo/gnome.d(0 hunks)source/dcell/terminfo/konsole.d(0 hunks)source/dcell/terminfo/linux.d(0 hunks)source/dcell/terminfo/rxvt.d(0 hunks)source/dcell/terminfo/screen.d(0 hunks)source/dcell/terminfo/vt100.d(0 hunks)source/dcell/terminfo/vt102.d(0 hunks)source/dcell/terminfo/vt220.d(0 hunks)source/dcell/terminfo/vt320.d(0 hunks)source/dcell/terminfo/vt420.d(0 hunks)source/dcell/terminfo/xfce.d(0 hunks)source/dcell/terminfo/xterm.d(0 hunks)source/dcell/termio.d(2 hunks)source/dcell/ttyscreen.d(20 hunks)
💤 Files with no reviewable changes (17)
- source/dcell/terminfo/vt220.d
- source/dcell/terminfo/linux.d
- source/dcell/terminfo/vt102.d
- source/dcell/terminfo/vt320.d
- source/dcell/terminfo/vt100.d
- source/dcell/terminfo/aixterm.d
- source/dcell/terminfo/ansi.d
- source/dcell/terminfo/dtterm.d
- source/dcell/terminfo/vt420.d
- source/dcell/terminfo/xfce.d
- source/dcell/terminfo/screen.d
- source/dcell/terminfo/rxvt.d
- source/dcell/terminfo/xterm.d
- source/dcell/terminfo/gnome.d
- source/dcell/terminfo/alacritty.d
- source/dcell/termcap.d
- source/dcell/terminfo/konsole.d
✅ Files skipped from review due to trivial changes (1)
- demos/colors/dub.json
🔇 Additional comments (10)
source/dcell/termio.d (1)
117-125: Stop now correctly unregisters SIGWINCH before restoring termios.Calling
ignoreResize(fd)insidePosixTty.stop()pairs cleanly withwatchResize(fd)instart()and avoids leaving the SIGWINCH handler installed once the TTY is no longer in use. No issues from this change.source/dcell/database.d (1)
147-186: Simplifiedcaps2fixture still exercises the truecolor augmentation path correctly.Dropping the mouse-related field from
caps2while keepingcolors: 1 << 24matches the PR’s capability trimming and remains compatible with the unittest expectations for RGB/color sequences.source/dcell/ttyscreen.d (8)
41-136: VT escape struct and legacy gating look coherent.Encapsulating all the VT escape sequences in the nested
Vtstruct and then selectively blanking out URL/title/window-size OSC codes for obvious legacy terms (vt*,ansi,linux,sun*) gives you a clear separation between “modern VT-like” and “legacy” behavior without complicating the rest of the code. Using instancestringfields for the OSC sequences (so they can be set to""for legacy) andenum stringfor fixed SGR/DEC private modes is a sensible split.From a quick scan, all of the hard-coded SGR and DEC private mode values (bold/dim/italic/underline/blink/reverse/strikethrough, cursor show/hide, cursor shapes, alt-screen, paste, focus, auto‑margin) match the usual VT/xterm conventions.
295-305:setSizecorrectly guards on VT support for window-resize reports.Conditioning the
ESC[8;rows;cols tsequence onvt.setWindowSize != ""ensures you don’t send this on legacy terminals where you’ve deliberately disabled it. Marking all cells dirty and callingresize()afterward is the right thing to do whenever the terminal accepts a size change.
442-459: Attribute rendering via VT SGR codes is straightforward.Switching
sendAttrsto use the VT SGR constants (Vt.bold,Vt.underline, etc.) gets you out of the business of maintaining per-termcap attribute sequences. The mapping fromAttr.*bits to SGR 1/2/3/4/5/7/9 looks correct, and terminals that don’t support some of these will simply ignore them.
461-472: Screen clear path is consistent with the new VT abstraction.On a pending clear you:
- Reset SGR with
vt.sgr0and end any active URL withvt.exitURL.- Reapply the default colors and attributes.
- Use
Vt.clear(home + clear screen) and flush.This matches the VT-centric design and should leave both the terminal state and your internal style tracking in sync.
528-599: Draw path is consistent with VT usage and legacy URL disabling.The updated
draw()/drawCell()logic:
- Hides the cursor while drawing (
vt.hideCursor), then restores it viasendCursor().- Uses
goTofor cursor movement whenpos != pos_instead of relying on auto-margin.- For monochrome caps, still simulates light/dark via
Attr.reverse.- Clears
c.style.urlwhenevervt.enterURL == ""so you don’t emit OSC 8 on terminals you’ve marked legacy.- Resets attributes with
Vt.sgr0before sending colors/attrs for a new cell.All of this hangs together with the VT abstraction and your legacy gating.
626-645: Mouse enable/disable sequences hard-code the common XTerm variants.
sendMouseEnablenow:
- Always sends a full disable (
?1000l/?1002l/?1003l/?1006l) first.- Then enables button, drag, motion, and SGR mouse mode (
?1006h) based on theMouseEnableflags.That’s a reasonable, explicit strategy for the de facto XTerm mouse protocol, especially now that terminfo mouse capabilities have been removed. Just be aware it assumes SGR mouse (
1006) rather than older encodings; if you ever need to support those again, you’ll need additional toggles here.
647-651: Paste enable/disable correctly matches parser’s bracketed-paste handling.Using
Vt.enablePaste/Vt.disablePaste(CSI ? 2004 h/l) here lines up with the parser’s CSI 200/201 handling and the unit test that injects those sequences. That keeps the send/receive paths consistent without relying on termcap data.
653-705: Newstoppinghandshake givesinputLoopa clean shutdown path.The added block:
if (stopping.get()) { stopping.set(false); return; }combined with
TtyScreen.stop()callingstopping.set(true)and thenstopping.wait(false)provides a simple, explicit handshake to exit theinputLoopwithout resorting to out-of-band thread termination.Once
PosixTty.blocking(true/false)is fixed to behave as intended, the loop will again switch between blocking and non‑blocking reads based on parser state, and this stop signaling should remain reliable.
| void blocking(bool b) @trusted | ||
| { | ||
| termios tio; | ||
| b = false; | ||
| enforce(tcgetattr(fd, &tio) >= 0); | ||
| tio.c_cc[VMIN] = b ? 1 : 0; | ||
| tio.c_cc[VTIME] = 0; | ||
|
|
||
| enforce(tcsetattr(fd, TCSANOW, &tio) >= 0); | ||
| fcntl(fd, F_SETFL, b ? 0 : O_NONBLOCK); | ||
| block = b; | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
blocking(bool) now ignores its argument and can cause a busy‑spin input loop.
Overwriting the b parameter with false means:
- Callers can never request blocking behavior;
VMINis always set to 0 andblockis alwaysfalse. read()on the TTY will effectively be non‑blocking all the time.TtyScreen.inputLoop()still togglesblocking(true)/blocking(false)to control whether the read blocks, so with this change the loop will busy‑poll and can peg a CPU core when there’s no input.
You can keep the removal of the F_SETFL logic but should honor the requested mode again:
void blocking(bool b) @trusted
{
termios tio;
- b = false;
enforce(tcgetattr(fd, &tio) >= 0);
tio.c_cc[VMIN] = b ? 1 : 0;
tio.c_cc[VTIME] = 0;
enforce(tcsetattr(fd, TCSANOW, &tio) >= 0);
block = b;
}This restores the intended distinction between blocking and non‑blocking behavior using only termios.
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| void blocking(bool b) @trusted | |
| { | |
| termios tio; | |
| b = false; | |
| enforce(tcgetattr(fd, &tio) >= 0); | |
| tio.c_cc[VMIN] = b ? 1 : 0; | |
| tio.c_cc[VTIME] = 0; | |
| enforce(tcsetattr(fd, TCSANOW, &tio) >= 0); | |
| fcntl(fd, F_SETFL, b ? 0 : O_NONBLOCK); | |
| block = b; | |
| } | |
| void blocking(bool b) @trusted | |
| { | |
| termios tio; | |
| enforce(tcgetattr(fd, &tio) >= 0); | |
| tio.c_cc[VMIN] = b ? 1 : 0; | |
| tio.c_cc[VTIME] = 0; | |
| enforce(tcsetattr(fd, TCSANOW, &tio) >= 0); | |
| block = b; | |
| } |
🤖 Prompt for AI Agents
In source/dcell/termio.d around lines 144 to 154, the function blocking(bool b)
currently overwrites the parameter with "b = false" which ignores the caller's
intent and forces non‑blocking reads; remove the "b = false" assignment so the
passed argument is honored, keep the existing tcgetattr/tcsetattr calls, set
tio.c_cc[VMIN] = b ? 1 : 0 and tio.c_cc[VTIME] = 0 as written, and ensure block
= b remains so the object state reflects the requested mode; this restores
proper blocking vs non‑blocking TTY behavior using termios only.
We're moving to delete the terminfo database, and this is more work on that path. We have better support for standard escapes, as the terminals have common and compatible functionality (the terminfo DB had pointless, from our perspective, differences). This also eliminates the automargin bug hackery, as no supported terminals actually need it. The terminfo capabilities have shrunk considerably. We still need to sort out a few last bits, before delete this entirely. This also has some termio fixes.
fdb710f to
63a838d
Compare
Summary by CodeRabbit
New Features
Bug Fixes
Chores
✏️ Tip: You can customize this high-level summary in your review settings.