The Complete Computing Environment

Emacs Shell-Mode is Good Enough


Emacs has Shell Mode, a simple comint-mode backed shell that lets me do simple crap that don't need ncurses or anything like that. It uses bash and works sanely with pipelines, unlock eshell and doesn't eat my keybindings like ansi-term and term. This mode is, really, good for maybe 95% of the time I need to do interactive terminal work, and it's in fact better than a dedicated terminal emulator like Konsole or URXVT – I can drop to normal mode to copy command output; in fact, hitting enter on any line will send that line as terminal input, so when a command says I used it wrong and demands I try unambiguous things again [Trust Unambiguous Inputs], I can copy the suggestion or run it directly.

shell-mode displays buffers in a new window when I do M-x shell which is almost always not what I want, instead opting for them to always appear in the same window as my cursor.

(add-to-list 'display-buffer-alist
             `(,(rx bos "*shell") (display-buffer-same-window)))

When in shell-mode, things like ls on remote systems expect tabs to be 8 characters unless I configure remote systems differently. Doing it here is easier than trying to clean that shit up and it makes things so much more legible and easy to digest.

(add-hook 'shell-mode-hook (lambda () (setq-local tab-width 8)))

I have a simple command I use in lieu of watch for making sure a command succeeds. If there is a flaky download or test suite, I can say please !! and bash will reattempt the last command until it succeeds.

function please () {
    until $@; do sleep 0.5; done
{ ... }:
  programs.bash.profileExtra = ''
(provide 'cce/shell-mode)