Summary
TerminalScreen::linefeed() resets cursor.col = 0 in addition to advancing the row. Per VT100/ECMA-48 spec, LF (line feed, 0x0A) should only move the cursor down one row. Column reset is the responsibility of CR (carriage return, 0x0D).
Impact
Programs that rely on LF-only cursor movement (without CR) will have incorrect cursor positioning. This affects ncurses-based TUI applications that position the cursor then use LF to move down, and cmd.exe/PowerShell output that uses LF without CR in certain modes.
Most Unix shells pair CR+LF so this bug is masked for basic command output, but TUI programs may emit standalone LF.
Affected Code
crates/kestrel-tools/src/builtins/terminal/screen.rs:854-861:
fn linefeed(&mut self) {
self.cursor.col = 0; // BUG: should NOT reset column
if self.cursor.row == self.scroll_bottom {
self.scroll_up(1);
} else if self.cursor.row < self.active_buf().rows - 1 {
self.cursor.row += 1;
}
}
Fix
Remove self.cursor.col = 0; from linefeed(). Note: some terminals implement LNM (DECSET 20) for automatic newline mode, but this should be opt-in, not the default.
Summary
TerminalScreen::linefeed()resetscursor.col = 0in addition to advancing the row. Per VT100/ECMA-48 spec, LF (line feed, 0x0A) should only move the cursor down one row. Column reset is the responsibility of CR (carriage return, 0x0D).Impact
Programs that rely on LF-only cursor movement (without CR) will have incorrect cursor positioning. This affects ncurses-based TUI applications that position the cursor then use LF to move down, and cmd.exe/PowerShell output that uses LF without CR in certain modes.
Most Unix shells pair CR+LF so this bug is masked for basic command output, but TUI programs may emit standalone LF.
Affected Code
crates/kestrel-tools/src/builtins/terminal/screen.rs:854-861:Fix
Remove
self.cursor.col = 0;fromlinefeed(). Note: some terminals implement LNM (DECSET 20) for automatic newline mode, but this should be opt-in, not the default.