It is a known thing that running commands that control the terminal like top
in Eshell is problematic – Eshell plays well with commands that take stdin in and put stdout out, but any control codes are just displayed verbatim.
Happily, there is a way around it. You can add any command that needs to control the terminal directly to the variable eshell-visual-commands
(whose default value is '("vi" "screen"
"top" "less" "more" "lynx" "ncftp" "pine" "tin" "trn" "elm")
) and when you run such a command in Eshell, you will be dropped to a term
buffer. (In particular, this means that typing top
in Eshell will work after all – kind of, at least. You will land in another buffer with top
working as it should, but when you press q
, you will still have to close that buffer manually.)
What is perhaps less known (at least I did not know about it until very recently) is that there are two more options like that. One is eshell-visual-options
, which is a list of lists. Each of its elements consists of a command name (a string) and a list of options (also strings). If you run one of those commands in Eshell, giving it at least one of those options, Emacs will automatically turn the “visual” mode on (i.e., run this command in a term buffer). This way you can have a non-visual command which only needs control codes etc. when used with some specific options. (See its docstring for an example use.) It is not too sophisticated – for instance, it knows nothing about getopts
, so if you set it to include some hypothetical option -x
and you run the relevant command with options -xyz
, it won’t catch it – but it can still be useful.
But wait, there’s more! There is also the eshell-visual-subcommands
option. It works in a similar way, only that instead of options (like --help
) it contains subcommands (think log
in git log
). This way, you can make git log ...
“visual”, but not git add log
(and both would be if you included log
in an entry for Git in eshell-visual-options
).
As usual, Emacs turns out to be insanely configurable, even without resorting to writing your own Elisp.