Terminal: draw control characters as ^X; bound GUI config values
- C0 controls and DEL were passed to ncurses, which acted on them: a carriage return moved to column 0 and the line padding then erased the text, so every line of a CRLF file drew blank, and a backspace ate the previous character. They are now drawn in caret notation (^M, ^H, ^?) and counted as two cells. C1 controls (and stray bytes 0x80-0x9F, which decode to them; U+009B is CSI) are drawn as '?'. - The width rule lives in TermWidth.h and is shared by the renderer's drawing loop, its cursor placement and the command layer's horizontal scrolling and mouse mapping, which also disagreed on NUL and invalid bytes. - GUI config: columns/rows must be 1..1000 and the font size a finite 4..200 (TOML 'size = inf' and huge values were accepted, leading to UB in float-to-int conversion and int overflow downstream). Verified in tmux: a CRLF file now shows 'first line^M' where the baseline showed a blank line. Audit findings B9 (and the CR/BS case from the follow-up review). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015rcVQiiWyTzoNrsvLSaAfB
This commit is contained in:
@@ -818,3 +818,16 @@ TEST(Audit_SaveAs_ExistingFile_AsksFirst)
|
||||
ASSERT_TRUE(h.Exec(CommandId::Newline));
|
||||
ASSERT_EQ(slurp(d.path / "other.txt"), std::string("precious\n"));
|
||||
}
|
||||
|
||||
|
||||
// Control characters are drawn as ^X (two cells); horizontal scrolling must
|
||||
// count them the same way.
|
||||
TEST(Audit_HorizontalScroll_ControlCharsAreTwoCells)
|
||||
{
|
||||
TestHarness h;
|
||||
Buffer &b = h.Buf();
|
||||
b.insert_text(0, 0, std::string(50, '\r'));
|
||||
b.SetCursor(0, 0);
|
||||
ASSERT_TRUE(h.Exec(CommandId::MoveEnd));
|
||||
ASSERT_EQ(b.Coloffs(), (std::size_t) (100 - 80 + 1));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user