Usage
Installation
To use MisTTY, first install its package.
(package-vc-install "https://github.com/szermatt/mistty")
You can then call it, as described in Launching.
However, you’ll likely want to configure it and add some key bindings you use often in shells, for example:
(use-package mistty
:bind (("C-c s" . mistty)
;; bind here the shortcuts you'd like the
;; shell to handle instead of Emacs.
:map mistty-prompt-map
;; fish: dir history, more history manipulation
("M-<up>" . mistty-send-key)
("M-<down>" . mistty-send-key)
("M-<left>" . mistty-send-key)
("M-<right>" . mistty-send-key)))
Read on for details on the commands and key bindings configured above.
Launching
To create a new interactive shell buffer in MisTTY mode, call M-x mistty or M-x mistty-create. If you use MisTTY regularly, you’ll want to bind some of these to global shortcuts:
M-x mistty-create launches a new interactive shell in a MisTTY buffer. The shell that is launched is the one that’s configured on M-x configure-option explicit-shell-file-name
If
explicit-shell-file-nameis unset, MisTTY falls back toshell-file-name, then the environment variablesESHELLandSHELL.
M-x mistty-create-other-window does the same, but opens the buffer in another window.
M-x mistty also creates a new MisTTY buffer the first time it is called. Afterwards, it’ll to an existing MisTTY buffer or creating a new one, trying to guess what’s most appropriate.
M-x mistty-other-window does the same, but opens a buffer in another window.
Terminal vs. Scrollback
MisTTY buffers are split into two zones, with different behaviors:
The scrollback zone, is where you can see commands that have been executed and their output.
The terminal zone, marked by a purple line on the left of the window, is where you can type command and interact with the terminal. In this zone, TAB triggers the shell completion, if available. With some shells, you’ll see autosuggestions as you type.
The scrollback zone behaves as a normal Emacs buffer. You can modify it as you see fit.
The terminal zone, on the other hand, limits what you can do: When a shell is attached to the terminal, you can edit the command you’re about to run, but you can’t edit the prompt itself - or rather, if you do change the prompt, your change will be undone by the shell.
The terminal zone is where the magic happens: this is where you can use a mix of Emacs and shell key bindings to edit the command line. The trickiest part is choosing which key bindings you want Emacs to handle and which key bindings you want the shell to handle.
By default, Emacs handles everything but a few key bindings are sent directly to the terminal, bypassing Emacs:
RET, to ask the shell to run the command
TAB, to ask the shell to run command completion,
C-a to ask it to move the cursor to the beginning of the line, and
C-e to ask it to move the cursor to the end of the line.
C-d to ask it to either delete the next character or exit the program.
M-p to ask it to go up, or up the command history, sending C-p to the terminal.
M-n to ask it to go down, or down the command history, sending C-n to the terminal.
M-r to ask it to do backward history search, sending C-r to the terminal.
M-. to ask the shell to insert the last history argument.
In addition, C-c C-c sends the TERM signal to the terminal.
The program attached to the terminal decides what the actual effect of these shortcuts is. Most shells and command-line editing tools supports the shortcuts above by default, but they might not work everywhere as expected.
Warning
MisTTY will not work if you’ve configured your shell to turn on VI mode by default. Please turn it off before trying out MisTTY, for details on how to turn off VI mode only of MisTTY buffers and leave it on otherwise, check out the instructions in Shells for details. VI mode must be turned off even if you just end up controlling it with VI commands using Evil.
To get the most out of MisTTY, it’s worth it to take the time to configure it forward the shell key bindings that you actually use to the terminal and keep everything else behaving as usual for your Emacs configuration.
To bind keys only in the terminal zone, bind them to
:code`mistty-prompt-map`. To bind keys in both zones, bind them to
mistty-mode-map. See examples below.
The following commands are useful to send key sequences to the current shell or program controlling the terminal:
The command
mistty-send-key, called interactively, forwards the key it was called from. It is meant to be bound to the shell key bindings you want to work in the terminal zone map,mistty-prompt-map.For example, searching in the shell command history is usually bound to C-r, MisTTY binds that to M-r, like comint does, but if you’d like it to be accessible using the original key binding, you can do:
(keymap-set mistty-prompt-map "C-r" #'mistty-send-key)If you’d prefer to have the key available in both the scrollback and terminal zones, bind it
mistty-mode-mapinstead.You can also pass arbitrary keys to
mistty-send-key, for example:(defun my-mistty-M-s (n) (interactive "p") (mistty-send-key n (kbd "M-s"))) (keymap-set mistty-prompt-map "C-c a" #'my-mistty-M-s)
The command
mistty-send-last-keyforwards the last key combination of a sequence it was called from to the terminal. For example, C-c C-c is bound tomistty-send-last-keyso that the terminal eventually just gets C-c.
To just try things out, or for shell shortcuts you don’t use regularly, you can use the C-q prefix to bypass Emacs key bindings and send keys directly to the terminal. For example, C-q <right> sends a right arrow key press to the terminal instead of moving the cursor.
If that’s not enough,
C-c C-q, M-x mistty-send-key-sequence sends all keys you press to the terminal until you press C-g.
Fullscreen Mode
MisTTY detects when a program such as less or vi asks to run full screen and splits the MisTTY buffers into:
a terminal buffer, which shows the program output and lets you interact with it. This is a term-mode buffer.
a scrollback buffer, which shows the previous command lines and their output.
C-c C-j or M-x mistty-toggle-buffers switches between these two.
When the program exits, the two buffers are again merged. Note that the output of the full screen app isn’t available in the scrollback.
Command History
MisTTY doesn’t track command history. It relies instead on being able to access the history of the different interactive command-line tools.
The command history available in most shells and command-line editing tools is available in MisTTY using the following shortcuts:
M-p moves up command history
M-n moves down command history
M-r triggers a backward search in command history
M-. insert the last argument from command history.
To get the same key bindings you’d get in a normal terminal, you can
bind C-p, C-n, or C-r to mistty-send-key
in the terminal zone of the MisTTY buffer. For example:
(keymap-set mistty-prompt-map "C-p" #'mistty-send-key)
(keymap-set mistty-prompt-map "C-n" #'mistty-send-key)
(keymap-set mistty-prompt-map "C-r" #'mistty-send-key)
Directory tracking and TRAMP
In order for Emacs to know your shell’s current directory, the shell has to tell MisTTY about it. This is usually done from the prompt.
Bash does it by default, for local shells, when it detects
a terminal of type TERM=eterm-color run from inside Emacs.
Other shells need to be configured to do the same. For more details, see Shells.
If you have configured TRAMP and know that the hosts you ssh into are accessible with the default TRAMP method, you might consider allowing MisTTY to report remote paths on M-x configure-option mistty-allow-tramp-paths