When I am writing a shell script in sh-mode and decide to run it, I hit C-cC-x (executable-interpret). An *interpretation* buffer is displayed, showing the script's output.

Is there a robust way to automatically make this *interpretation* buffer current after it pops up, instead of having to type C-xo (other-window)?

  • @Drew Please review my edit.
    – John Goofy
    Mar 5 '18 at 16:12

Is there a robust way to automatically make this *interpretation* buffer current after it pops up, instead of having to type C-xo (other-window)?

There are several ways of varying degree of hackiness to achieve this, but here is my preferred method.

The *interpretation* buffer is created by the command executable-interpret, bound to C-cC-x by default in sh-mode, whose docstring reads:

executable-interpret is an interactive autoloaded compiled Lisp
function in ‘executable.el’.

(executable-interpret COMMAND)

Run script with user-specified args, and collect output in a buffer.
While script runs asynchronously, you can use the C-x `
command to find the next error.  The buffer is also in ‘comint-mode’ and
‘compilation-shell-minor-mode’, so that you can answer any prompts.

The key clue here is compilation-shell-minor-mode, which suggests we can hook into settings of the compile library. One such relevant setting is compilation-finish-functions:

compilation-finish-functions is a variable defined in ‘compile.el’.
Its value is nil

  This variable may be risky if used as a file-local variable.

Functions to call when a compilation process finishes.
Each function is called with two arguments: the compilation buffer,
and a string describing how the process finished.

This allows us to register a custom function which selects the *interpretation* buffer when the script is done jogging:

(defun my-pop-to-interpretation-buffer (buffer _why)
  "Pop to `*interpretation*' BUFFER.
Intended as an element of `compilation-finish-functions'."
  (when (string-match-p "\\`\\*interpretation\\*\\'" (buffer-name buffer))
    (pop-to-buffer buffer)))

(add-to-list 'compilation-finish-functions #'my-pop-to-interpretation-buffer)

You can, of course, modify my-pop-to-interpretation-buffer to your heart's content.

  • This sounds good. But my first attempt was just to copy&paste the last code snippet to my ~/.emacs.d/init.el doesn't work.
    – John Goofy
    Mar 13 '18 at 16:20
  • @JohnGoofy You'll have to update your question with a more precise description than "doesn't work" in order for anyone to be able to help you. Please try to provide a reproducible set of steps starting from emacs -Q leading to the unexpected behaviour.
    – Basil
    Mar 13 '18 at 16:47
  • Okay, storing this code snippet in my init.el doesn't work. Where do I need to store this code?
    – John Goofy
    Mar 13 '18 at 17:41
  • @JohnGoofy If you want it to take effect in every Emacs session, then you need to place it in your user-init-file. You can also just evaluate it once-off for the current session. Are you sure you are evaluating the code, i.e. adding it to your user-init-file and then restarting Emacs?
    – Basil
    Mar 13 '18 at 17:46
  • Sorry, but I saved this code-snippet via copy&paste into my ~/.emacs.d/init.el, sourced it and even restart my machine but it won't work, nothing happens.
    – John Goofy
    Mar 16 '18 at 15:53

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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