Command Loop

Function: start-command-loop ()
Start Neomacs command loop.
If a command loop is already running, ask and wait for it to quit before starting a new one. This is useful when you want changes to the function command-loop to take effect.

Command dispatch

Variable: *this-command*
Current command run by command loop.
The value is bound to nil outside command invocation made by command loop.
Variable: *this-command-keys*
List of keys that cause current command to run.
The value is bound to nil outside command invocation made by command loop.
Variable: *last-command*
Last command run by command loop.

Buffer transactions

Neomacs commands are processed in a transactional manner, following the 2PL (2-phase locking) model. During a command invocation, every with-current-buffer form obtains a lock for the buffer. All buffer locks are released at the end of command invocation. on-pre-command is run when the buffer lock is obtained for the first time and on-post-command is run when the buffer lock is released. When with-current-buffer runs outside any command invocation, it effectively starts a new command invocation for running its body and will run on-pre-command and on-post-command like normal command invocations. It's important to note the interaction between with-current-buffer and transactions.

Macro: with-current-buffer (buffer &body body)
Run BODY with BUFFER as the current buffer.
Progn generic function: on-pre-command (buffer)
Run before command invocation.
More specifically, this runs before entering the first with-current-buffer form for BUFFER during a command invocation.
Progn generic function: on-post-command (buffer)
Run after command invocation.
More specifically, this runs after a command invocation iff it has ever entered any with-current-buffer form for BUFFER during its execution.

Condition handling

Normally, Neomacs command loop handles any error conditions that reach it. It runs approriate hook, logs a message, then continue processing the next command.

Variable: *quit-hook*
Invoked when a quit condition reaches command loop.
user-errors are considered quits and also trigger this hook.
Variable: *error-hook*
Invoked when an error condition reaches command loop.
user-errors are considered quits and does not trigger this hook.

It is also possible to ask the command loop to invoke the debugger instead of handling error conditions.

Variable: *debug-on-error*
Command: toggle-debug-on-error ()
Class: user-error inherits (error)
A user generated error.
This is normally treated the same as a quit condition and does not drop into Neomacs debugger.
Function: user-error (control-string &rest format-arguments)
Signal a simple-user-error with messages formatted from CONTROL-STRING and FORMAT-ARGUMENT.
Macro: with-demoted-errors (prompt &body body)
Run BODY and demote any error to simple messages. Error messages are prepended with PROMPT.
If *debug-on-error* is t, run BODY without catching its errors.

Defining commands

Macro: define-command (name &rest args)
Define a command with NAME.
ARGS has the form {:option OPTION}* LAMBDA-LIST FORM*. This is like (defun LAMBDA-LIST FORM*) besides supporting extra options:
:mode MODE-OR-MODES: The command is made avaliable in MODE-OR-MODES. MODE-OR-MODES can either be a list or a single symbol. If this options is not provided, the command is avaliable globally.
:interactive INTERACTIVE: INTERACTIVE should evaluate to a function which takes zero arguments. When called, it should return a list of arguments which can be supplied to the command. The command loop and call-interactive call this function to compute arguments for the command.