Terminal loop, virtual buffers, yank bound
- kte refuses to start when stdin is not a terminal: piped bytes were executed as editor commands (C-k s plus a path writes a file), and after EOF the loop spun at full CPU with no way to quit. - The terminal frontend handles all pending input before drawing (a paste used to cost a frame and a full redraw per character) and redraws only after input, a resize or deferred opens, else once a second. The renderer caches, per row and buffer version, where the horizontally scrolled part of a line starts and the cursor's render column, instead of rescanning the line every frame. Idle CPU with the cursor at the end of a 20 MB line: one full core -> ~1%. - Buffers with a virtual name (+HELP+) are not journaled and saving one asks for a file name; it used to write ./+HELP+ and journal under that path. - Yank with a repeat count is capped at 256 MiB in total instead of reserving count x size bytes (C-u 1000000 C-y of a large kill). - Remove an overload clang reports as unused (-Werror on macOS). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015rcVQiiWyTzoNrsvLSaAfB
This commit is contained in:
@@ -9,6 +9,7 @@
|
||||
#include "ErrorRecovery.h"
|
||||
#include "PieceTable.h"
|
||||
#include "RegexGuard.h"
|
||||
#include "Swap.h"
|
||||
#include "UndoTree.h"
|
||||
#include "syntax/HighlighterEngine.h"
|
||||
#include "syntax/HighlighterRegistry.h"
|
||||
@@ -992,3 +993,36 @@ TEST(Audit_Save_KeepsSpecialModeBits)
|
||||
ASSERT_EQ(::stat(f.c_str(), &st), 0);
|
||||
ASSERT_EQ(st.st_mode & 07777, (mode_t) 06755);
|
||||
}
|
||||
|
||||
|
||||
// The help buffer's name is not a path: it is not journaled, and saving it
|
||||
// asks for a file name instead of writing ./+HELP+.
|
||||
TEST(Audit_HelpBuffer_NotJournaledOrSavedByName)
|
||||
{
|
||||
TestHarness h;
|
||||
Editor &ed = h.EditorRef();
|
||||
ASSERT_TRUE(h.Exec(CommandId::ShowHelp));
|
||||
Buffer *help = ed.CurrentBuffer();
|
||||
ASSERT_TRUE(help->IsVirtual());
|
||||
ASSERT_TRUE(h.Exec(CommandId::ToggleReadOnly));
|
||||
ASSERT_TRUE(h.Exec(CommandId::InsertText, "x"));
|
||||
ed.Swap()->Flush(help);
|
||||
ASSERT_TRUE(!std::filesystem::exists(kte::SwapManager::ComputeSwapPathForTests(*help)));
|
||||
ASSERT_TRUE(h.Exec(CommandId::Save));
|
||||
ASSERT_TRUE(ed.PromptActive());
|
||||
ASSERT_TRUE(ed.CurrentPromptKind() == Editor::PromptKind::SaveAs);
|
||||
ASSERT_TRUE(!std::filesystem::exists("+HELP+"));
|
||||
ASSERT_TRUE(h.Exec(CommandId::Refresh));
|
||||
}
|
||||
|
||||
|
||||
// A huge repeated yank is refused rather than allocating without bound.
|
||||
TEST(Audit_Yank_HugeRepeatRefused)
|
||||
{
|
||||
TestHarness h;
|
||||
Editor &ed = h.EditorRef();
|
||||
ed.KillRingPush(std::string(1 << 20, 'k'));
|
||||
ASSERT_TRUE(!h.Exec(CommandId::Yank, std::string(), 1000000));
|
||||
ASSERT_EQ(h.Buf().Nrows(), (std::size_t) 1);
|
||||
ASSERT_EQ(h.Line(0), std::string());
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user