Commands: second-pass fixes from the follow-up review
- Motion and delete commands read rows through RowsView (on-demand, version-cached) instead of Buffer::Rows(), which rebuilt every line of the file after each edit. On a 500k-line buffer after an edit: backspace/delete/motions 80-90 ms -> ~0.1 ms; C-u 3000 C-d 273 s -> 0.25 s. Whole-buffer search scans keep Rows() (cached between edits). - While a prompt is open only prompt-aware and view-only commands run. Others edited the buffer behind the prompt (bypassing the read-only check) or switched/closed buffers under a pending confirmation, which then acted on the wrong buffer. The ':' command path now applies the read-only check too. - Pasting into a prompt (ImGui) flattens line breaks to spaces instead of emitting Newline, which accepted the prompt and sent the rest of the paste to the buffer (or ran replace-all). - The mark region clamps both ends; a stale mark past the end of the buffer is treated as end of buffer. This fixes kill-region deleting the wrong text and leaving the cursor past end-of-line. - Kill-line with a count stops at end of buffer instead of killing lines above the cursor (regression from the D3 change). - Undo groups nest, so SmartNewline in visual-line mode is one step. - Word motions and word deletion treat non-ASCII bytes as word characters and so never split a UTF-8 character. - The universal-argument count saturates at 1,000,000 instead of overflowing int. 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,12 @@
|
||||
#include "syntax/NullHighlighter.h"
|
||||
|
||||
|
||||
namespace {
|
||||
// Universal-argument repeat counts are capped here (well below INT_MAX).
|
||||
constexpr int kMaxUArgCount = 1000000;
|
||||
} // namespace
|
||||
|
||||
|
||||
namespace {
|
||||
static std::string
|
||||
buffer_bytes_via_views(const Buffer &b)
|
||||
@@ -594,7 +600,7 @@ Editor::UArgStart()
|
||||
if (ucount_ == 0) {
|
||||
ucount_ = 1;
|
||||
}
|
||||
ucount_ *= 4;
|
||||
ucount_ = std::min(ucount_ * 4, kMaxUArgCount); // no int overflow
|
||||
}
|
||||
uarg_ = 1;
|
||||
char buf[64];
|
||||
@@ -614,7 +620,7 @@ Editor::UArgDigit(int d)
|
||||
uarg_ = 1;
|
||||
ucount_ = 0;
|
||||
}
|
||||
ucount_ = ucount_ * 10 + d;
|
||||
ucount_ = (ucount_ > (kMaxUArgCount - d) / 10) ? kMaxUArgCount : ucount_ * 10 + d;
|
||||
char buf[64];
|
||||
std::snprintf(buf, sizeof(buf), "C-u %d", ucount_);
|
||||
SetStatus(buf);
|
||||
|
||||
Reference in New Issue
Block a user