Repository navigation
fix(emacs-core): log a routine command-loop signal at debug, not error - #343
Merged
eval-exec merged 5 commits intoSep 4, 2026
Merged
Conversation
eval-exec
self-requested a review
September 3, 2026 06:20
Pressing an arrow key at the end of a line under evil signals `end-of-line`
(evil-macros.el defines the error and pushes it onto
`debug-ignored-errors`). The echo area showed "End of line" exactly as GNU
does, and the log said
ERROR neovm_core::emacs_core::eval: Command loop error: End of line
[signal=(end-of-line nil)] condition=end-of-line
on every keystroke, and the same for every `C-g`.
GNU's command loop never logs: `cmd_error_internal`
(src/keyboard.c:1030-1047, emacs-31.0.90) hands the signal to
`command-error-function` and that is the whole handling. The log line is
this port's diagnostic, and it ranked every signal the same. GNU does rank
signals in one place, the debugger gate `skip_debugger`
(src/eval.c:2146-2180): a condition or message matched by
`debug-ignored-errors` (`beginning-of-line`, `end-of-line`, `end-of-buffer`,
`buffer-read-only`, `user-error`, ... by default, lisp/bindings.el:1038-1046,
plus whatever packages push there) must not interrupt the user, and a quit
is routine by construction (`signal_quit_p`, src/eval.c:2181-2190).
`Context::command_error_severity` applies that ranking through the existing
`skip_debugger` matcher and the crate's quit predicate, as the closed
`CommandErrorSeverity { Routine, Diagnostic }`; `command_loop_2` logs a
routine signal at debug and keeps the error level, with condition and
payload, for everything else, so a void function in a command still reaches
a bug report. Presentation is unchanged: `report_command_error` still runs
first, through Lisp's buffer-local `command-error-function`.
Two declared departures from GNU. GNU consults `skip_debugger` only when
the debugger is otherwise wanted (`maybe_call_debugger`,
src/eval.c:2206-2213); the log has no such gate, so the ignore list is
evaluated on every uncaught command signal. And the ranking runs inside
`command_loop_2`, GNU's sole recovery owner, where nothing may signal: a
string entry in `debug-ignored-errors` that is not a valid regexp makes the
matcher signal `invalid-regexp`, and an adversarial pre-push review found
the first version propagating that with `?` and unwinding the whole command
loop. The classification is infallible: a matcher failure ranks the
original error as a diagnostic.
Tests, red first: `command_error_severity_follows_gnus_debug_ignored_errors`
(evil's `end-of-line` is a diagnostic with an empty ignore list and routine
once listed; `user-error`, a condition inheriting from it, and a regexp
entry over the message are routine; `quit` and `minibuffer-quit` are
routine whatever the list says; `void-function` stays a diagnostic) and
`command_error_severity_never_signals_on_a_bad_ignore_list`.
Not run: Linux and Windows builds (the change is platform-neutral Rust in
neovm-core); clippy on neovm-core's tests stops on a pre-existing
`never_loop` error in the process tests, unrelated to this change.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0117NsCB7AbwgdEqduGF5Kww
eval-exec
force-pushed
the
fix/command-loop-signal-log-level
branch
from
September 4, 2026 07:19
014a9ef to
d010b67
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #342.
Pressing an arrow key at the end of a line under evil shows "End of line" in the echo area exactly as GNU does, and also logs
on every keystroke, and the same for every
C-g. Evil definesend-of-lineas an error and pushes it ontodebug-ignored-errors(evil-macros.el).GNU's command loop never logs:
cmd_error_internal(src/keyboard.c:1030-1047, emacs-31.0.90) hands the signal tocommand-error-functionand that is the whole handling. The log line is this port's diagnostic, and it ranked every signal the same. GNU ranks signals in one place, the debugger gateskip_debugger(src/eval.c:2146-2180) overdebug-ignored-errors(defaults in lisp/bindings.el:1038-1046:beginning-of-line,end-of-line,end-of-buffer,buffer-read-only,user-error, ...), and a quit is routine by construction (signal_quit_p, src/eval.c:2181-2190).Context::command_error_severityapplies that ranking through the existingskip_debuggermatcher and the crate's quit predicate, as a closedCommandErrorSeverity { Routine, Diagnostic }.command_loop_2logs a routine signal at debug and keeps the error level, with condition and payload, for everything else, so a void function in a command still reaches a bug report. Presentation is unchanged:report_command_errorstill runs first through Lisp's buffer-localcommand-error-function.Declared departures from GNU. GNU consults
skip_debuggeronly when the debugger is otherwise wanted (maybe_call_debugger, src/eval.c:2206-2213); the log has no such gate, so the list is evaluated on every uncaught command signal. And the ranking runs insidecommand_loop_2, GNU's sole recovery owner, where nothing may signal: a string entry indebug-ignored-errorsthat is not a valid regexp makes the matcher signalinvalid-regexp. The classification is therefore infallible and a matcher failure ranks the original error as a diagnostic; a test pins that.Tests, red first:
command_error_severity_follows_gnus_debug_ignored_errors(evil'send-of-lineis a diagnostic with an empty list and routine once listed;user-error, a condition inheriting from it, and a regexp entry over the message are routine;quitandminibuffer-quitare routine whatever the list says;void-functionstays a diagnostic) andcommand_error_severity_never_signals_on_a_bad_ignore_list.Verified on macOS: the two tests, rustfmt, and a GUI run of the release build feeding the real command loop a command that signals
end-of-lineand one that calls a void function: the first logs at debug only, the second keeps its ERROR line. Not run: Linux and Windows (platform-neutral Rust in neovm-core); clippy on neovm-core's tests stops on a pre-existingnever_looperror in the process tests.🤖 Generated with Claude Code
https://claude.ai/code/session_0117NsCB7AbwgdEqduGF5Kww