2

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)?

Basil
  • 12,019
  • 43
  • 69
John Goofy
  • 121
  • 2

1 Answers1

1

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.

Documentation:
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.

Basil
  • 12,019
  • 43
  • 69
  • 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
  • @JohnGoofy Like I said in my first comment: "it won't work" and "nothing happens" do not provide others with enough information to help you. Please update your question with a precise and reproducible set of steps leading to the undesired behaviour. This recipe should state your Emacs version and list all the commands/keys you invoke starting from `emacs -Q`. – Basil Mar 16 '18 at 15:57
  • @JohnGoofy Just to clarify - the code in my answer does not on its own do anything. It customises what happens when you type `C-c C-x` in a `sh-mode` buffer, as you describe in your question. I.e. you need to type `C-c C-x` in a `sh-mode` buffer to see the effects of my suggestion. – Basil Mar 16 '18 at 15:59
  • ... I know, I've already tried this in sh-mode, which is normally activated if I open a shell-script. What you do not understand, that your code-snippet do not has any effect if I save it in my init-file? I Still have to type `C-x` `o` to switch to the `*interpretation*`-buffer if I execute the script via `C-c` `C-x` – John Goofy Mar 16 '18 at 16:04
  • @JohnGoofy What I don't understand is **why** my suggestion doesn't work, not **that** it doesn't work. This is why a comment such as "it doesn't work" does not help anyone, and providing a reproducible recipe is crucial. Try starting Emacs with the `-Q` flag and then evaluating my suggested code before invoking `C-c C-x`. If it works, which it should, then some other setting or package you enable in your `user-init-file`, e.g. [`shackle`](https://github.com/wasamasa/shackle), is interfering with my suggested customisation. – Basil Mar 16 '18 at 16:17
  • @JohnGoofy See also this article about reporting Emacs bugs starting with `-Q`: https://swsnr.de/posts/reproduce-bugs-in-emacs-q. – Basil Mar 16 '18 at 16:21