Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Conversation

@gdamore
Copy link
Owner

@gdamore gdamore commented Dec 8, 2025

Summary by CodeRabbit

  • Breaking Changes

    • Terminal initialization API simplified — no automatic term lookup; callers may need minor updates.
  • Refactor

    • Removed embedded terminal database and all predefined terminal profiles.
    • Switched to a VT-centric runtime capability detection and unified output path.
    • Improved color handling with truecolor/256/88-color support and legacy fallbacks.
  • Chores

    • Added an explicit device close API for deterministic tty resource management.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 8, 2025

Walkthrough

This PR removes the Termcap/terminfo system (types, database, generated terminfo modules and tests), replaces termcap-driven TtyScreen behavior with an internal VT-based implementation, updates parser tests/timing, and adds explicit tty lifecycle control via a new TtyImpl.close().

Changes

Cohort / File(s) Change Summary
Core termcap/database removal
source/dcell/database.d, source/dcell/termcap.d
Deleted the synchronized Database and the Termcap module (types, param engine, puts/opAssign, param evaluation engine, and unit tests). Removed public module/import declarations exposing termcap/database.
Generated terminfo modules removed
dcell.terminfo
source/dcell/terminfo/package.d, source/dcell/terminfo/... (aixterm.d, alacritty.d, ansi.d, dtterm.d, gnome.d, konsole.d, linux.d, rxvt.d, screen.d, vt100.d, vt102.d, vt220.d, vt320.d, vt420.d, xfce.d, xterm.d)
Deleted all generated terminfo modules, their static immutable Termcap entries, and static this() constructors that registered them via Database.put.
VT-based terminal handling
source/dcell/ttyscreen.d
Replaced Termcap/caps usage with an internal VT implementation (vt.numColors detection, VT sequences for colors/keys/ACS, OutBuffer-based output); removed Termcap parameter from TtyScreen constructor and updated newTtyScreen() signature.
Parser cleanup and tests updated
source/dcell/parser.d
Removed import dcell.termcap and termcap-dependent unittest setup; dropped pasteTime/pasteStart/pasteEnd fields; updated unittest sleeps to use p.seqTime-based timing.
Tty/term I/O interface changes
source/dcell/termio.d
Added void close() to TtyImpl and implemented PosixTty.close(); made PosixTty.start() idempotent and adjusted stop/close lifecycle semantics.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

  • Files needing extra attention:
    • source/dcell/ttyscreen.d — correctness of vt.numColors detection, startup/shutdown VT sequences, color fallbacks and legacy branching.
    • Call sites of TtyScreen / newTtyScreen() across the codebase to validate updated constructor/signature usage.
    • Removal of Database/Termcap — ensure no remaining references or public API regressions.
    • source/dcell/termio.d — lifecycle semantics of stop() vs close() and PosixTty resource handling.
    • Parser unittest timing changes for potential flakiness.

Possibly related PRs

Poem

🐰 I hopped through files at dawn,
Termcap burrows cleared and gone,
VT hums softly where echoes were loud,
Colors now whisper instead of proud,
A rabbit nods — the terminal's calm.

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title directly describes the main change: removing the terminfo database system in favor of built-in VT sequences, which is substantiated by deletions of database.d, termcap.d, all terminfo modules, and refactoring of ttyscreen.d to use VT-centric approach.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch gdamore/terminfo-bye

Comment @coderabbitai help to get the list of available commands and usage tips.

We will rely upon standard VT style sequences that are also
used by all other supported terminal emulators.  (Note that the
fallback to using alternate characters is *not* supported by dcell
at this time, but we plan to add it following the tcell model.)
(We don't use these yet, but we will. And when we do, we will use
the common VT mode 1 strings just like tcell.)
This initialization (terminal init) follows what tcell does.
This makes dcell work with nearly all modern terminals, and calculates
correct colors based on the values of $TERM, $COLORTERM, and $NO_COLOR.

This should greatly enhance functionality for many folks with unusual
or otherwise unknown terminals.
@gdamore gdamore force-pushed the gdamore/terminfo-bye branch from 4c99d50 to 8c9e273 Compare December 8, 2025 18:15
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
source/dcell/parser.d (1)

369-372: Remove unused member variables pasteTime, pasteStart, and pasteEnd.

These member variables have no usages in the implementation and should be cleaned up. Note that pasteBuf is actively used and should be retained.

     bool buttonDown; // true if buttons were down
     bool pasting;
-    MonoTime pasteTime;
     dstring pasteBuf;
-    string pasteStart;
-    string pasteEnd;
source/dcell/termio.d (1)

117-125: Missing file.close() in stop() may cause file descriptor leak.

The stop() method no longer closes the file descriptor. If stop() is called without destroying the object, or if start() is called again, the old file descriptor may remain open until garbage collection or until overwritten in a subsequent start().

Consider explicitly closing the file to ensure deterministic cleanup:

         if (file.isOpen())
         {
             ignoreResize(fd);
             flush();
             restore();
+            file.close();
         }
🧹 Nitpick comments (1)
source/dcell/ttyscreen.d (1)

139-143: NO_COLOR check may not fully comply with the specification.

The NO_COLOR spec states that the mere presence of the variable should disable colors, even if set to an empty string. The current check if (environment.get("NO_COLOR")) returns an empty string as falsy, so NO_COLOR="" would not disable colors.

Consider using a presence check instead:

-        if (environment.get("NO_COLOR"))
+        import std.process : environment;
+        string noColor;
+        try { noColor = environment["NO_COLOR"]; } catch (Exception) { noColor = null; }
+        if (noColor !is null)

Alternatively, if std.process.environment supports checking for presence, use that.

D lang std.process environment check if variable exists
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f1d5b57 and 4c99d50.

📒 Files selected for processing (27)
  • demos/colors/dub.json (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 (0 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/package.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 (1 hunks)
  • source/dcell/ttyscreen.d (18 hunks)
💤 Files with no reviewable changes (22)
  • mkinfo/terms.txt
  • source/dcell/terminfo/alacritty.d
  • source/dcell/terminfo/vt320.d
  • source/dcell/terminfo/vt420.d
  • source/dcell/terminfo/gnome.d
  • source/dcell/terminfo/vt102.d
  • source/dcell/terminfo/rxvt.d
  • source/dcell/terminfo/ansi.d
  • source/dcell/terminfo/vt220.d
  • source/dcell/terminfo/konsole.d
  • source/dcell/terminfo/dtterm.d
  • source/dcell/database.d
  • mkinfo/source/mkinfo.d
  • source/dcell/terminfo/xfce.d
  • mkinfo/dub.json
  • source/dcell/terminfo/aixterm.d
  • source/dcell/terminfo/linux.d
  • source/dcell/terminfo/xterm.d
  • source/dcell/terminfo/screen.d
  • source/dcell/terminfo/vt100.d
  • source/dcell/terminfo/package.d
  • source/dcell/termcap.d
🔇 Additional comments (11)
demos/colors/dub.json (1)

2-10: LGTM!

The copyright year update and minor formatting adjustments are consistent with repository-wide changes. No functional impact on the demo configuration.

dub.json (1)

2-10: LGTM!

The copyright year update, formatting adjustments, and removal of mkinfo from subPackages align with the PR's objective to eliminate the terminfo/termcap infrastructure and mkinfo tool. No remaining references to mkinfo were found in the codebase, confirming the removal is complete.

source/dcell/parser.d (2)

816-829: Paste handling logic looks correct.

The CSI sequence handling for paste start (200) and paste end (201) is correctly implemented. The explicit braces improve readability.


1241-1249: Unit tests confirm paste handling is still functional.

The tests verify that paste events are correctly parsed and emitted. This contradicts the AI-generated summary which claims paste-handling logic was "eliminated."

source/dcell/termio.d (1)

144-153: LGTM - VMIN/VTIME approach is appropriate for terminal blocking control.

Using VMIN/VTIME instead of O_NONBLOCK via fcntl is a valid approach for controlling blocking behavior on terminal devices in raw mode. Note that the block member variable (line 152) is assigned but doesn't appear to be read elsewhere in this file.

source/dcell/ttyscreen.d (6)

44-115: Well-structured VT escape sequence definitions.

The separation of immutable enum sequences from configurable instance fields (enterURL, numColors, etc.) is a clean design that allows runtime customization for legacy terminals while keeping the common sequences constant.


529-536: Consider 1-based adjustment for VT100 cursor positioning.

VT100 cursor positioning (CSI row;col H) uses 1-based coordinates, but pos appears to be 0-based. While most terminals treat 0 as 1, this is technically incorrect per ANSI/VT100 spec.

If coordinates are indeed 0-based internally:

-            puts(format!(Vt.setCursorPosition)(pos.y, pos.x));
+            puts(format!(Vt.setCursorPosition)(pos.y + 1, pos.x + 1));

Please verify whether the previous termcap-based implementation applied a +1 offset, or if coordinates were already adjusted elsewhere.


437-493: LGTM - Color handling logic is correct.

The RGB color optimization (combined format when both fg/bg are RGB) and the fallback to palette colors are well-implemented. Setting fg/bg to Color.invalid after RGB processing correctly prevents duplicate color output.


762-765: Breaking API change: newTtyScreen() no longer accepts a terminal type parameter.

The public factory function signature changed from Screen newTtyScreen(string term = "") to Screen newTtyScreen(). Callers that previously passed an explicit terminal type will need to update their code. The TtyScreen constructor still accepts a term parameter, so users needing explicit terminal type can instantiate directly:

auto screen = new TtyScreen(newDevTty(), "xterm-256color");

Consider documenting this breaking change in release notes.


679-698: LGTM - Mouse enable/disable follows XTerm conventions.

The implementation correctly disables all mouse modes before enabling specific ones, and enables SGR extended mode (1006) when any mouse tracking is active. The de-facto XTerm standard reliance is appropriately documented.


742-747: LGTM - Input loop termination sequence is correct.

The turnstile pattern for coordinating thread shutdown is properly implemented: checking stopping.get(), then signaling completion via stopping.set(false) before returning.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4c99d50 and 8c9e273.

📒 Files selected for processing (21)
  • source/dcell/database.d (0 hunks)
  • source/dcell/parser.d (0 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/package.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/ttyscreen.d (12 hunks)
💤 Files with no reviewable changes (20)
  • source/dcell/terminfo/vt102.d
  • source/dcell/terminfo/aixterm.d
  • source/dcell/terminfo/gnome.d
  • source/dcell/terminfo/dtterm.d
  • source/dcell/parser.d
  • source/dcell/termcap.d
  • source/dcell/terminfo/alacritty.d
  • source/dcell/terminfo/vt420.d
  • source/dcell/terminfo/vt320.d
  • source/dcell/terminfo/konsole.d
  • source/dcell/terminfo/vt220.d
  • source/dcell/terminfo/rxvt.d
  • source/dcell/terminfo/xterm.d
  • source/dcell/terminfo/vt100.d
  • source/dcell/terminfo/linux.d
  • source/dcell/terminfo/ansi.d
  • source/dcell/database.d
  • source/dcell/terminfo/screen.d
  • source/dcell/terminfo/package.d
  • source/dcell/terminfo/xfce.d
🔇 Additional comments (10)
source/dcell/ttyscreen.d (10)

22-22: LGTM!

The std.process import is correctly added to support the new environment variable handling for terminal capability detection.


44-115: LGTM! Well-structured VT sequence definitions.

The Vt struct provides a comprehensive set of standard VT escape sequences. The design correctly separates immutable sequences (enum strings) from mutable ones (enterURL, exitURL, etc.) that need to be disabled for legacy terminals. The numColors field with a default of 256 is appropriate for modern terminals.


204-209: LGTM! Proper terminal initialization sequence.

The additions of enterKeypad and enableAltChars ensure proper handling of function keys and line-drawing characters during terminal initialization.


234-240: LGTM! Proper terminal cleanup sequence.

The additions of resetFgBg and exitKeypad ensure proper terminal state restoration when stopping, correctly reversing the initialization done in start().


323-326: LGTM!

Correctly returns the color count from the VT configuration.


354-363: LGTM!

Correctly uses the VT-based window size sequence with appropriate legacy terminal handling.


424-427: LGTM!

The puts() method correctly writes to the output buffer.


437-493: LGTM! Well-structured color handling with RGB and palette support.

The sendColors method correctly handles the following scenarios:

  1. Monochrome terminals (early return)
  2. Color reset requests
  3. Truecolor (>256 colors) with optimized combined RGB sequence
  4. Fallback to palette colors for non-RGB or when terminal doesn't support truecolor
  5. 8-color and 256-color palette sequences

The logic of setting colors to Color.invalid after sending RGB (lines 464, 470) prevents them from being sent again in palette form, which is correct.


596-603: LGTM! Clever monochrome simulation.

The monochrome handling correctly simulates different brightness levels by toggling the reverse attribute when the foreground is darker than the background.


127-180: The color detection logic is sound. VT terminals that support color are properly detected through their TERM names (e.g., "vt220-color" matches the term.endsWith("color") check at line 168). The fallback at line 164 that treats generic vt-named terminals as monochrome is appropriate, as the original VT100/102/220 terminals were monochrome. Users with color-capable VT variants can override this by setting appropriate TERM names or the COLORTERM environment variable.

Copy link
Contributor

@coderabbitai coderabbitai bot left a 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

♻️ Duplicate comments (2)
source/dcell/ttyscreen.d (2)

139-179: Verify color detection logic and NO_COLOR handling.

The color detection heuristics are comprehensive, but the NO_COLOR check at line 140 may have an issue flagged in a previous review. According to the NO_COLOR standard, any presence of the variable (even if empty, like NO_COLOR=) should disable colors.

In D, environment.get("NO_COLOR") returns null if the variable doesn't exist, or the value (which could be an empty string) if it does. The current check should work correctly because:

  • If NO_COLOR is not set: environment.get("NO_COLOR") returns null, which is falsy
  • If NO_COLOR is set (even to empty): it returns a non-null string (even if empty), which is truthy

However, for clarity and explicit compliance with the NO_COLOR spec, consider this alternative:

-        if (environment.get("NO_COLOR"))
+        if (environment.get("NO_COLOR") !is null)
         {
             vt.numColors = 0;
         }

Also verify that the TERM-based color detection fallback logic handles edge cases correctly (e.g., unknown TERM values).

Run the following script to test the NO_COLOR behavior:

#!/bin/bash
# Test NO_COLOR environment variable handling

# Test 1: NO_COLOR not set
echo "Test 1: NO_COLOR not set"
unset NO_COLOR
./your_program 2>&1 | head -5 || echo "Program requires compilation"

# Test 2: NO_COLOR set to empty string
echo "Test 2: NO_COLOR set to empty"
NO_COLOR= ./your_program 2>&1 | head -5 || echo "Program requires compilation"

# Test 3: NO_COLOR set to a value
echo "Test 3: NO_COLOR=1"
NO_COLOR=1 ./your_program 2>&1 | head -5 || echo "Program requires compilation"

763-766: API change removes custom terminal type parameter.

As noted in a previous review, the factory function no longer accepts a term parameter, eliminating the ability to override the TERM environment variable through the factory. Users who need custom terminal types must now construct TtyScreen directly: new TtyScreen(newDevTty(), "custom-term").

If this is intentional to enforce environment-based configuration (consistent with the PR's shift to VT-based behavior), this is acceptable. Otherwise, consider restoring the parameter.

Please confirm whether removing the term parameter from the factory function is intentional. If not, the signature can be restored:

-Screen newTtyScreen()
+Screen newTtyScreen(string term = "")
 {
-    return new TtyScreen(newDevTty());
+    return new TtyScreen(newDevTty(), term);
 }
🧹 Nitpick comments (1)
source/dcell/ttyscreen.d (1)

438-494: Color rendering logic is comprehensive but complex.

The refactored sendColors() correctly handles multiple color depths (monochrome, 8-color, 256-color, and RGB) using VT escape sequences. The optimization to combine FG+BG RGB colors in a single sequence (line 458) is efficient.

However, the method is quite dense. Consider adding inline comments to clarify the logic flow, especially around the RGB vs palette color decision points.

Example refactor to improve readability:

     void sendColors(Style style)
     {
         auto fg = style.fg;
         auto bg = style.bg;
 
         if (vt.numColors == 0 || (fg == Color.invalid && bg == Color.invalid))
         {
             return;
         }
         if (fg == Color.reset || bg == Color.reset)
         {
             puts(vt.resetFgBg);
         }
+        // For true color terminals (>256 colors), use RGB sequences
         if (vt.numColors > 256)
         {
+            // Optimization: combine FG+BG RGB in one escape sequence
             if (isRGB(fg) && isRGB(bg))
             {
                 auto rgb1 = decompose(fg);
                 auto rgb2 = decompose(bg);
                 puts(format!(vt.setFgBgRGB)(rgb1[0], rgb1[1], rgb1[2], rgb2[0], rgb2[1], rgb2[2]));
                 return;
             }
+            // Handle individual RGB colors
             if (isRGB(fg))
             {
                 auto rgb = decompose(fg);
                 puts(format!(vt.setFgRGB)(rgb[0], rgb[1], rgb[2]));
                 fg = Color.invalid;
             }
             if (isRGB(bg))
             {
                 auto rgb = decompose(bg);
                 puts(format!(vt.setBgRGB)(rgb[0], rgb[1], rgb[2]));
                 bg = Color.invalid;
             }
         }
 
+        // Convert remaining colors to palette indices
         fg = toPalette(fg, vt.numColors);
         bg = toPalette(bg, vt.numColors);
 
+        // Emit palette colors using appropriate sequence
         if (fg < 8)
         {
             puts(format!(vt.setFg8)(fg));
         }
         else if (fg < 256)
         {
             puts(format!(vt.setFg256)(fg));
         }
         if (bg < 8)
         {
             puts(format!(vt.setBg8)(bg));
         }
         else if (bg < 256)
         {
             puts(format!(vt.setBg256)(bg));
         }
     }
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8c9e273 and e8f70f0.

📒 Files selected for processing (3)
  • source/dcell/parser.d (2 hunks)
  • source/dcell/termio.d (3 hunks)
  • source/dcell/ttyscreen.d (13 hunks)
🔇 Additional comments (13)
source/dcell/parser.d (1)

1218-1218: LGTM! Test timing improvements enhance maintainability.

The changes replace hardcoded sleep durations with p.seqTime * 2, making the timeout tests consistent with the Parser's configured seqTime (50ms). The 2x multiplier provides an adequate buffer to ensure timeout conditions are met during testing.

Also applies to: 1230-1230

source/dcell/termio.d (3)

77-79: LGTM: Comment clarifies lifecycle semantics.

The updated comment clarifies that stop() stops input scanning but doesn't close the device, which aligns well with the new explicit close() method.


116-120: LGTM: Start is now idempotent.

The guard prevents re-opening an already-open device, making start() safe to call multiple times.


135-141: LGTM: Clean resource cleanup.

The implementation correctly guards against closing an already-closed file and provides explicit device closure.

source/dcell/ttyscreen.d (9)

22-22: LGTM: Import needed for environment access.

The std.process import is required for the environment.get() calls used in color and TERM detection.


75-87: LGTM: Standard VT escape sequences.

The keypad, alternate character set, and color sequences follow standard VT100/ANSI conventions and will work across modern terminal emulators.


97-105: LGTM: Well-documented color capability field.

The numColors field is clearly documented with typical values and reasonable defaults. The 256-color default aligns with modern terminal capabilities.


127-130: LGTM: TERM environment variable fallback.

The logic correctly defaults to the TERM environment variable when no explicit term parameter is provided.


192-196: LGTM: Explicit device closure in destructor.

The destructor correctly stops input scanning first, then explicitly closes the device using the new close() method. This ensures proper resource cleanup.


205-209: LGTM: Complete terminal initialization sequence.

The startup sequence properly initializes keypad mode and alternate character sets alongside cursor hiding and margin control. The order of operations is appropriate.


235-241: LGTM: Symmetric cleanup sequence.

The stop sequence properly resets colors, attributes, and exits keypad mode, providing a clean symmetric teardown that mirrors the start sequence.


326-327: LGTM: Returns VT-based color count.

The method correctly returns the detected color capability from the VT configuration.


425-428: LGTM: Buffered output improves performance.

Writing to an OutBuffer reduces system calls by batching terminal output, which is flushed explicitly via flush().

@gdamore gdamore changed the title Gdamore/terminfo bye Remove the terminfo database (use builtins instead) Dec 8, 2025
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

♻️ Duplicate comments (1)
source/dcell/ttyscreen.d (1)

763-766: API change removes ability to specify custom terminal type.

The factory function signature changed from newTtyScreen(string term = "") to newTtyScreen(), eliminating the ability to specify a custom terminal type through the factory. This was previously flagged in past reviews.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e8f70f0 and 5c86915.

📒 Files selected for processing (1)
  • source/dcell/ttyscreen.d (13 hunks)
🔇 Additional comments (6)
source/dcell/ttyscreen.d (6)

22-22: LGTM!

The std.process import is correctly added to support environment variable handling used throughout the refactored code.


75-105: LGTM!

The VT escape sequences for alternate character sets, keypad modes, and color handling are correct and follow standard terminal conventions. The numColors field is well-documented.


140-143: LGTM - Past review concern addressed.

The NO_COLOR environment variable handling correctly uses the in operator to check for the variable's presence. This properly disables colors when NO_COLOR is set to any value, including empty strings, as per the NO_COLOR standard. The idiomatic D approach addresses the concern raised in the previous review.


192-196: LGTM!

The destructor correctly calls ti.stop() followed by ti.close() to ensure proper resource cleanup and explicit tty resource management.


205-209: LGTM!

The startup sequence correctly applies VT escape sequences in the proper order: hiding cursor, configuring keypad mode, enabling alternate character sets, and clearing the screen.


235-241: LGTM!

The shutdown sequence correctly uses VT-based sequences to reset colors, attributes, cursor state, and exit keypad mode.

Copy link
Contributor

@coderabbitai coderabbitai bot left a 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

🧹 Nitpick comments (2)
source/dcell/termio.d (2)

81-84: Clarify close() expectations relative to stop() in the interface

The new close() method is clear, but the doc doesn’t say whether it restores termios / stops resize handling, or whether callers must always invoke stop() before close().

Consider expanding the comment to state the intended lifecycle (e.g., “Call stop() to restore terminal state before close(), which only releases the underlying device handle.”). That will make misuse less likely across non-Posix implementations too.


116-120: Idempotent open in start() looks good

Guarding the open with if (!file.isOpen) makes start() safe to call multiple times without leaking or re-opening the device, while still re-running save() and watchResize(fd) each time.

If you care about precision, you might tweak the start() doc comment to say it “will open the device if not already open”, but that’s optional.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 5c86915 and fceeddc.

📒 Files selected for processing (1)
  • source/dcell/termio.d (3 hunks)
🧰 Additional context used
🧠 Learnings (1)
📓 Common learnings
Learnt from: gdamore
Repo: gdamore/dcell PR: 27
File: source/dcell/ttyscreen.d:763-766
Timestamp: 2025-12-08T19:10:45.974Z
Learning: In source/dcell/ttyscreen.d, the newTtyScreen() factory function intentionally does not accept a term parameter because the TtyScreen constructor handles environment variable resolution internally with an optional term parameter. Users needing to override the terminal type should call the constructor directly: new TtyScreen(newDevTty(), "custom-term").
🔇 Additional comments (1)
source/dcell/termio.d (1)

77-79: stop() doc now matches its behavior

The shorter description (“Stop input scanning.”) aligns with the actual stop() implementation, which restores settings and disables resize handling without closing the device.

@gdamore gdamore force-pushed the gdamore/terminfo-bye branch from fceeddc to 2b5a0d3 Compare December 8, 2025 19:20
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

♻️ Duplicate comments (1)
source/dcell/termio.d (1)

81-84: Fix typo in close documentation comment.

The doc comment still says “ttye device”; please correct to “tty device” for clarity.

-    /**
-     * Close the ttye device.
-     */
+    /**
+     * Close the tty device.
+     */
🧹 Nitpick comments (1)
source/dcell/ttyscreen.d (1)

117-190: Environment‑driven TERM/COLORTERM/NO_COLOR handling looks sound; consider optional case‑folding.

The ctor correctly:

  • Starts the tty and sizes the cell buffer.
  • Derives term from TERM when empty.
  • Marks legacy terms (vt*, ansi, linux, sun*) and disables OSC‑style features for them.
  • Gives NO_COLOR highest precedence, then COLORTERM truecolor hints, then TERM/COLORTERM 256/88/16/8, with a safe 256‑color default.

Given TERM/COLORTERM values are usually lowercase, this should behave well in practice; if you want extra robustness against odd uppercase values, you could optionally normalize term/cterm with .toLower() before the tests.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between fceeddc and 2b5a0d3.

📒 Files selected for processing (2)
  • source/dcell/termio.d (3 hunks)
  • source/dcell/ttyscreen.d (13 hunks)
🧰 Additional context used
🧠 Learnings (4)
📓 Common learnings
Learnt from: gdamore
Repo: gdamore/dcell PR: 27
File: source/dcell/ttyscreen.d:763-766
Timestamp: 2025-12-08T19:10:45.974Z
Learning: In source/dcell/ttyscreen.d, the newTtyScreen() factory function intentionally does not accept a term parameter because the TtyScreen constructor handles environment variable resolution internally with an optional term parameter. Users needing to override the terminal type should call the constructor directly: new TtyScreen(newDevTty(), "custom-term").
📚 Learning: 2025-12-08T19:10:45.974Z
Learnt from: gdamore
Repo: gdamore/dcell PR: 27
File: source/dcell/ttyscreen.d:763-766
Timestamp: 2025-12-08T19:10:45.974Z
Learning: In source/dcell/ttyscreen.d, the newTtyScreen() factory function intentionally does not accept a term parameter because the TtyScreen constructor handles environment variable resolution internally with an optional term parameter. Users needing to override the terminal type should call the constructor directly: new TtyScreen(newDevTty(), "custom-term").

Applied to files:

  • source/dcell/ttyscreen.d
  • source/dcell/termio.d
📚 Learning: 2025-12-08T19:17:33.657Z
Learnt from: gdamore
Repo: gdamore/dcell PR: 27
File: source/dcell/ttyscreen.d:448-494
Timestamp: 2025-12-08T19:17:33.657Z
Learning: In source/dcell/ttyscreen.d, Color.reset is defined as a value above the range of valid colors. In the sendColors() function, after emitting the reset sequence (vt.resetFgBg), Color.reset values naturally skip all subsequent color-setting logic (isRGB checks and palette range checks < 8, < 256) because they are out of range, which is the correct behavior by design.

Applied to files:

  • source/dcell/ttyscreen.d
📚 Learning: 2025-12-08T19:16:26.974Z
Learnt from: gdamore
Repo: gdamore/dcell PR: 27
File: source/dcell/ttyscreen.d:164-171
Timestamp: 2025-12-08T19:16:26.974Z
Learning: VT series terminals (vt100, vt102, vt220, vt320, vt420) are strictly monochrome. There are no color terminals with names like "vt220-color" in the VT series. The vt525 is mythical and would use "ansi" for $TERM if needed. Therefore, checking term.startsWith("vt") for monochrome classification is correct.

Applied to files:

  • source/dcell/ttyscreen.d
🔇 Additional comments (7)
source/dcell/termio.d (2)

114-123: Idempotent start() opening looks correct.

Guarding the open with if (!file.isOpen) avoids reopening the tty on repeated start() calls while still re-running save() and watchResize(fd), which matches the intended lifecycle.


135-142: close() now safely restores terminal state and disables resize handling.

Having close() call stop() before file.close() ensures saved termios are restored and ignoreResize(fd) runs even when callers skip an explicit stop(), fixing the earlier risk of leaving the tty in raw mode or with SIGWINCH still registered.

source/dcell/ttyscreen.d (5)

75-87: VT escape table and numColors default are coherent.

The added VT sequences for alt chars, keypad, and color (8/256/RGB plus reset) are standard, and defaulting vt.numColors to 256 with later overrides is a sensible baseline for modern terminals.

Also applies to: 97-105


192-195: TtyScreen lifecycle now aligns with TtyImpl start/stop/close.

  • The destructor delegating to ti.close() relies on the new PosixTty.close() to restore termios and tear down resize handling even if callers forgot stop().
  • start() moves the tty into raw mode, hides the cursor, disables auto‑margin, enables keypad/alt chars, clears the screen, and spawns the input loop.
  • stop() symmetrically restores auto‑margin, colors/attrs, cursor visibility/shape, keypad/paste/focus/mouse, flushes, stops the input loop, and restores blocking and the saved tty state.

This gives a clear and consistent lifecycle for callers (start()stop() → GC/~this()).

Also applies to: 197-215, 228-252


323-326: Colors API, window sizing, and buffered output integration are consistent.

  • colors() exposing vt.numColors matches the new VT‑centric model.
  • setSize() using vt.setWindowSize with (rows=size.y, cols=size.x) and then dirtying and resizing the cell buffer is correct for CSI 8 ; rows ; cols t.
  • Routing all output through puts()OutBuffer and flushing via ti.write/ti.flush keeps terminal I/O centralized and should reduce syscalls.

Also applies to: 354-363, 424-435


438-493: Color and monochrome rendering paths look correct (including Color.reset behavior).

  • sendColors() respects vt.numColors == 0, early‑outs on fully invalid colors, and handles truecolor (numColors > 256) using combined FG/BG RGB when possible, falling back to per‑channel or palette cases otherwise.
  • When fg or bg is Color.reset, emitting vt.resetFgBg and then running through isRGB/toPalette is safe because Color.reset is defined outside the valid ranges, so all subsequent checks naturally skip it. Based on learnings, this is intentional.
  • The monochrome branch in drawCell() that toggles Attr.reverse based on darker(fg,bg) only when vt.numColors == 0 is a nice touch to preserve contrast without using color.

Also applies to: 596-603


762-765: newTtyScreen() factory simplification matches the new constructor semantics.

The factory now always constructs new TtyScreen(newDevTty()), relying on the term default to come from $TERM inside the constructor; callers that need a custom terminal type can still use new TtyScreen(newDevTty(), "custom-term") directly. This aligns with the intent captured in the previous discussion and learnings.

@gdamore gdamore merged commit c666836 into main Dec 8, 2025
3 checks passed
@gdamore gdamore deleted the gdamore/terminfo-bye branch December 8, 2025 19:50
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.

2 participants