Notes: edit a text file of any size (#47)
CI / build (pull_request) Successful in 1m52s
Site / build (pull_request) Successful in 12s

The editor held the whole note in memory and stopped at 16 KB. It now keeps
a window of the file around the cursor, and the rest on the card as a list
of pieces (notes::NoteDocument). Memory with a note open is what it was.

Up to 64 KB a save rewrites the file, as before. Above, the five-second
save appends what changed to <note>.edit, and the file is rewritten on
leaving the note, with a progress bar. After a power cut, opening the note
picks the edit up where it was saved; a rewrite cut short is finished or
dropped, never half applied.

Also: Ctrl with Fn+Up/Down go to the start and end of the note; the
consoles' `key` command takes ctrl-, alt- and shift-; the Storage App's
`e` no longer refuses a big file.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EhqxQ49eCju4CzKYNjZzwT
This commit is contained in:
2026-10-07 15:39:45 +02:00
co-authored by Claude Opus 5.5
parent 10c5291e15
commit de8af6ed92
21 changed files with 1681 additions and 111 deletions
+17 -4
View File
@@ -16,11 +16,24 @@ NoteText::NoteText(int cols, int rows, std::string&& text) : cols_(std::max(1, c
text_.reserve(kMaxBytes);
}
void NoteText::dropCarriageReturns() {
size_t kept = 0;
for (size_t i = 0; i < text_.size(); i++)
if (!(text_[i] == '\r' && i + 1 < text_.size() && text_[i + 1] == '\n')) text_[kept++] = text_[i];
size_t NoteText::dropCarriageReturns(size_t* follow) {
size_t kept = 0, size = text_.size(), place = follow ? *follow : 0;
for (size_t i = 0; i < size; i++) {
if (follow && i == place) *follow = kept;
if (!(text_[i] == '\r' && i + 1 < size && text_[i + 1] == '\n')) text_[kept++] = text_[i];
}
if (follow && place >= size) *follow = kept;
text_.resize(kept);
return size - kept;
}
size_t NoteText::refilled(size_t cursor, int row) {
size_t dropped = dropCarriageReturns(&cursor);
cursor_ = std::min(cursor, text_.size());
while (cursor_ > 0 && cursor_ < text_.size() && continuation(text_[cursor_])) cursor_--;
top_ = lineOf(cursor_);
for (int i = 0; i < row && top_ > 0; i++) top_ = lineOf(top_ - 1);
return dropped;
}
bool NoteText::setText(const std::string& text) {