• Stars
    star
    112
  • Rank 312,240 (Top 7 %)
  • Language
    Emacs Lisp
  • License
    GNU General Publi...
  • Created over 3 years ago
  • Updated 10 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Shelldon: an enhanced shell interface

https://melpa.org/packages/shelldon-badge.svg

./shell.jpg

Introduction

This is what I use for my main shell/terminal. It is largely just an enhancement of async-shell-command that provides a more minibuffer-centric workflow, allowing you to store and navigate command outputs in separate buffers among other things.

./example.gif (I have lots of windowing and minibuffer enhancements from other packages, so yours probably won’t look exactly like this. See usage below for ideas…)

Installation

I just use straight+use-package like so:

  (use-package shelldon
    :straight (shelldon :type git
                        :host github
                        :repo "Overdr0ne/shelldon"
                        :branch "master"
                        :files ("shelldon.el"))
      ; below is the configuration I use, take what you want...
      ; tell bash this shell is interactive
      (setf shell-command-switch "-ic")
      ; recursive minibuffers for nested autocompletion from minibuffer commands,
      ; to e.g. interactively select from the kill-ring
      (setf enable-recursive-minibuffers t)
      ; comint output may contain SGR control sequences that may be translated into
      ; text properties if emacs has something equivalent. This requires special
      ; processing.
      (add-hook 'shelldon-mode-hook 'ansi-color-for-comint-mode-on)
      (add-to-list 'comint-output-filter-functions 'ansi-color-process-output)
      (autoload 'ansi-color-for-comint-mode-on "ansi-color" nil t)
      ; Tell Emacs how to display shelldon’s output buffers
      (add-to-list 'display-buffer-alist
                   '("*shelldon:"
                     (display-buffer-reuse-window display-buffer-in-previous-window display-buffer-in-side-window display-buffer-pop-up-window)
                     (side . right)
                     (slot . 0)
                     (window-width . 80)))
)

Usage

In a standard terminal, all command inputs and outputs are tangled together in one buffer. In Shelldon, each command is entered into the minibuffer individually with the shelldon command, much like an internal M-x command, and output is sent to a buffer derived from each command name. Here are the core commands.

commanddescription
shelldonenter shell command in the minibuffer
shelldon-loopenter a sequence of shell commands
shelldon-output-histgo too shelldon output buffer

Since Shelldon is largely just an enhancement of built-in shell interaction facilities, much of this is already documented within Emacs, but I’ve tried to present a unified workflow here.

minibuffer

  • You may of course search the minibuffer history for shelldon commands, as with any comint command, with comint-history-isearch-backward (M-r) and the like.
  • If you’d like to then use shelldon like an actual REPL, well, we’re just missing the loop part, so I’ve also provided a shelldon-loop command.
  • Customize the prompt by modifying the shelldon-prompt-str variable. You may also toggle the display of the current working directory with the shell-command-prompt-show-cwd, just like other shell commands.
  • By popular demand, you may also change the workdir without leaving shelldon-loop with the shelldon-cd command, bound to “C-x C-f” in shelldon-minibuffer-local-command-map by default. This requires:
    (setf enable-recursive-minibuffers t)
        

    Personally, I just use dired when I want to navigate.

  • You may of course add any other local minibuffer keybindings you like to shelldon-minibuffer-local-command-map.

shelldon-mode

This is analogous to, and derived from Shell-mode – basically the mode for displaying shelldon output.

  • To search the output history, use the shelldon-output-hist command, and select the command whose output you’d like to open.
  • Output buffer names begin with “*shelldon” such that you may configure display-buffer-alist to change how output windows are displayed. I’m a big fan of side windows, so I have configured things to display output buffers in the right side window by default. You can change this of course, by simply modifying the display-buffer-alist. For example, you could display the output buffer in the bottom side window like so:
    (setf (alist-get "*\\(shelldon.*\\)" display-buffer-alist)
          `((display-buffer-reuse-window display-buffer-in-previous-window display-buffer-in-side-window)
            (side . bottom)
            (slot . 0)
            (reusable-frames . visible)))
        

    The buffer names also contain the executed command, so that may be used as well to configure windows on a per-command basis.

  • You may need to emulate terminal keypresses in some situations, like for interactive menus. I use the term-send- set of functions for this purpose. So I map <up> to term-send-up and <down> to term-send-down.

sh-mode (shell script mode)

  • You may also send commands to Shelldon from a bash script buffer with the shelldon-send-region and shelldon-send-current-line commands. This is actually my preferred way of using shelldon- it is particularly useful when writing full-fledged shell scripts, allowing you to test as you go. Have a look:

./mode-demo.gif

autocompletion

  • I would also highly recommend installing the bash-completion package, and probably some sort of completion enhancement package like selectrum.
  • If you do use some kind of autocompletion extension, you may wish to disable sorting. There’s no universal way to do that unfortunately, but here’s what I do for selectrum, to give you an idea:
      (advice-add #'shelldon-output-history :around
    		(lambda (old-fn)
    		    (let ((selectrum-should-sort nil))
    		    (funcall old-fn))))
        

miscellaneous

  • If you would like shelldon to inherit your startup shell configurations, just pass the “-ic” flags to the shell(credit: http://www.nextpoint.se/?p=864):
    (setq shell-command-switch “-ic”)
        
  • To enable ANSI colors, these must be set:
    (add-hook 'shelldon-mode-hook 'ansi-color-for-comint-mode-on)
    (add-to-list 'comint-output-filter-functions 'ansi-color-process-output)
    (autoload 'ansi-color-for-comint-mode-on "ansi-color" nil t)
        

And that’s about it. Enjoy…

Todos

It might be possible to generalize this for other shells like the python shell.