2

There are several commands in Emacs that work as prefixes to other commands, changing the behavior of the next command in some way.

  • The most well-known example is the commands that set up the "universal prefix argument": universal-argument, digit-argument, and so on.

  • Another example that's built into Emacs is the prefix commands that control which window the next command will use (if it pops a buffer): same-window-prefix, other-window-prefix (both implemented using display-buffer-override-next-command), and so on.

  • An example from a popular third-party library is Evil's evil-execute-in-emacs-state and evil-execute-in-normal-state.

The common pattern here is that each of these control an orthogonal aspect of behavior and if you invoke one of them after the other, you basically always want them to combine (for the latter to pass the effects of the former through to the next command, rather than using up the effect of the former).

But there doesn't seem to be any built-in facility or standard/convention for writing prefix commands such that they neatly combine with each other without basically coupling all their implementation details.

  • Commands can forward the universal argument with (setq prefix-arg current-prefix-arg).

  • Commands could, in principle, forward the display overriding... but it's hacky and requires non-trivial understanding of implementation details. Best I got is: (push (apply-partially (car display-buffer-overriding-action)) display-buffer-overriding-action) - basically we copy the current overriding action, but wrap it in a dummy partial application with no arguments so that it doesn't match when the post-command-hook added by display-buffer-override-next-command deletes it from display-buffer-overriding-action (of course we then need to do something to make sure our copy is deleted once used... simplest thing is probably do add our own post-command hook).

  • Evil's prefix commands also install a post-command-hook to clear themselves, and have some logic to combine properly with a few built-in prefix commands (notably, they missed the display-overriding stuff).

So, question:

Does anyone have a proper solution for this mess yet?

Is there something obscure already shipped with Emacs that makes wrangling this better?

If not, the ideal answer is a few functions (or the name of a package containing such functions, ideally in the default ELPA repos) which allow

  1. hitting prefix functions with advice which makes them transparent to other prefix commands (ideally out-of-the-box any prefix commands which ship with Emacs), and

  2. registering new state variables or custom state-preserving functions to add support for prefix commands not covered out-of-the-box.

Or at least, any experience/lessons from having written prefix commands in ways that make this problem less bad?

2

1 Answer 1

0

It appears that Emacs provides building blocks for exactly this!

  1. prefix-command-preserve-state is a function which is supposed to be called by every prefix command. If they do that, then:

  2. prefix-command-preserve-state-hook is a hook which can be used by any prefix command to run whatever logic it needs to run to pass its state from the current command to the next.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.