Round-seven fixes: swap name room for .tmp; input and notice details
- The shortened fallback swap name was capped at exactly NAME_MAX, so compaction's '<journal>.tmp' failed with ENAMETOOLONG on every checkpoint and the journal grew by a full copy of the buffer each time. Cap it at NAME_MAX - 4. - A lone UTF-8 lead byte (8-bit Meta terminals) waited a second for continuation bytes on every key; wait 250 ms. An invalid byte now ends a pending ESC/C-k prefix instead of leaving it for the next key. - Journal notices are shown after a deferred open's own status (which used to overwrite them), all pending ones at once, and the lock-out notice is not repeated after every save while the lock is still held. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015rcVQiiWyTzoNrsvLSaAfB
This commit is contained in:
@@ -489,25 +489,33 @@ Editor::ResolveRecoveryPrompt(const bool yes)
|
||||
bool
|
||||
Editor::ProcessPendingOpens()
|
||||
{
|
||||
// Opening can throw (bad_alloc on a huge file, filesystem errors). This
|
||||
// runs from every frontend's loop, outside command dispatch: report the
|
||||
// failure instead of letting it end the editor.
|
||||
bool opened = false;
|
||||
// Opening can throw (bad_alloc on a huge file, filesystem errors), and so
|
||||
// can the checkpoint snapshot below. This runs from every frontend's
|
||||
// loop, outside command dispatch: report the failure instead of letting
|
||||
// it end the editor.
|
||||
try {
|
||||
// Also the once-per-frame hook for the journal: retry the
|
||||
// checkpoint of a journal that lost a record.
|
||||
if (kte::SwapManager *sm = Swap()) {
|
||||
if (kte::SwapManager *sm = Swap())
|
||||
sm->RetryGapCheckpoints();
|
||||
if (std::string notice = sm->TakeUserNotice(); !notice.empty())
|
||||
SetStatus(notice);
|
||||
}
|
||||
return process_pending_opens_();
|
||||
opened = process_pending_opens_();
|
||||
} catch (const std::exception &e) {
|
||||
kte::ErrorHandler::Instance().Error("Editor", std::string("open failed: ") + e.what(), "");
|
||||
SetStatus(std::string("Open failed: ") + e.what());
|
||||
} catch (...) {
|
||||
SetStatus("Open failed");
|
||||
}
|
||||
return false;
|
||||
// Journal problems for the user, after the open's own status so it does
|
||||
// not hide them; all pending ones at once (one per frame flashed by).
|
||||
if (kte::SwapManager *sm = Swap()) {
|
||||
std::string notices;
|
||||
for (std::string n = sm->TakeUserNotice(); !n.empty(); n = sm->TakeUserNotice())
|
||||
notices += (notices.empty() ? "" : "; ") + n;
|
||||
if (!notices.empty())
|
||||
SetStatus(notices);
|
||||
}
|
||||
return opened;
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user