å¦ä½ę建äøäøŖāē°ä»£āē»ē«ÆēÆå¢ļ¼
Source: Julia Evans
Hello! Recently I ran a terminal survey and I asked people what frustrated them. One person commented:
There are so many pieces to having a modern terminal experience. I wish it all came out of the box.
My immediate reaction was āoh, getting a modern terminal experience isnāt that hard, you just need toā¦.ā, but the more I thought about it, the longer the āyou just need toā¦ā list got, and I kept thinking about more and more caveats.
So I thought I would write down some notes about what it means to me personally to have a āmodernā terminal experience and what I think can make it hard for people to get there.
what is a āmodern terminal experienceā?
Here are a few things that are important to me, with which part of the system is responsible for them:
- multiline support for copy and paste: if you paste 3 commands in your shell, it should not immediately run them all! Thatās scary! (shell, terminal emulator)
- infinite shell history: if I run a command in my shell, it should be saved forever, not deleted after 500 history entries or whatever. Also I want commands to be saved to the history immediately when I run them, not only when I exit the shell session (shell)
- a useful prompt: I canāt live without having my current directory and current git branch in my prompt (shell)
- 24-bit colour: this is important to me because I find it MUCH easier to theme neovim with 24-bit colour support than in a terminal with only 256 colours (terminal emulator)
- clipboard integration between vim and my operating system so that when I copy in Firefox, I can just press
pin vim to paste (text editor, maybe the OS/terminal emulator too) - good autocomplete: for example commands like git should have command-specific autocomplete (shell)
- having colours in
ls(shell config) - a terminal theme I like: I spend a lot of time in my terminal, I want it to look nice and I want its theme to match my terminal editorās theme. (terminal emulator, text editor)
- automatic terminal fixing: If a programs prints out some weird escape codes that mess up my terminal, I want that to automatically get reset so that my terminal doesnāt get messed up (shell)
- keybindings: I want
Ctrl+left arrowto work (shell or application) - being able to use the scroll wheel in programs like
less: (terminal emulator and applications)
There are a million other terminal conveniences out there and different people value different things, but those are the ones that I would be really unhappy without.
how I achieve a āmodern experienceā
My basic approach is:
- use the
fishshell. Mostly donāt configure it, except to:- set the
EDITORenvironment variable to my favourite terminal editor - alias
lstols --color=auto
- set the
- use any terminal emulator with 24-bit colour support. In the past Iāve used GNOME Terminal, Terminator, and iTerm, but Iām not picky about this. I donāt really configure it other than to choose a font.
- use
neovim, with a configuration that Iāve been very slowly building over the last 9 years or so (the last time I deleted my vim config and started from scratch was 9 years ago) - use the base16 framework to theme everything
A few things that affect my approach:
- I donāt spend a lot of time SSHed into other machines
- Iād rather use the mouse a little than come up with keyboard-based ways to do everything
- I work on a lot of small projects, not one big project
some āout of the boxā options for a āmodernā experience
What if you want a nice experience, but donāt want to spend a lot of time on configuration? Figuring out how to configure vim in a way that I was satisfied with really did take me like ten years, which is a long time!
My best ideas for how to get a reasonable terminal experience with minimal config are:
- shell: either
fishorzshwith oh-my-zsh - terminal emulator: almost anything with 24-bit colour support, for example all of these are popular:
- linux: GNOME Terminal, Konsole, Terminator, xfce4-terminal
- mac: iTerm (Terminal.app doesnāt have 256-colour support)
- cross-platform: kitty, alacritty, wezterm, or ghostty
- shell config:
- set the
EDITORenvironment variable to your favourite terminal text editor - maybe alias
lstols --color=auto
- set the
- text editor: this is a tough one, maybe micro or helix? I havenāt used
either of them seriously but they both seem like very cool projects and I
think itās amazing that you can just use all the usual GUI editor commands
(
Ctrl-Cto copy,Ctrl-Vto paste,Ctrl-Ato select all) in micro and they do what youād expect. I would probably try switching to helix except that retraining my vim muscle memory seems way too hard. Also helix doesnāt have a GUI or plugin system yet.
Personally I wouldnāt use xterm, rxvt, or Terminal.app as a terminal emulator, because Iāve found in the past that theyāre missing core features (like 24-bit colour in Terminal.appās case) that make the terminal harder to use for me.
I donāt want to pretend that getting a āmodernā terminal experience is easier than it is though ā I think there are two issues that make it hard. Letās talk about them!
issue 1 with getting to a āmodernā experience: the shell
bash and zsh are by far the two most popular shells, and neither of them provide a default experience that I would be happy using out of the box, for example:
- you need to customize your prompt
- they donāt come with git completions by default, you have to set them up
- by default, bash only stores 500 (!) lines of history and (at least on Mac OS) zsh is only configured to store 2000 lines, which is still not a lot
- I find bashās tab completion very frustrating, if thereās more than one match then you canāt tab through them
And even though I love fish, the fact that it isnāt POSIX does make it hard for a lot of folks to make the switch.
Of course itās totally possible to learn how to customize your prompt in bash
or whatever, and it doesnāt even need to be that complicated (in bash Iād
probably start with something like export PS1='[\u@\h \W$(__git_ps1 " (%s)")]\$ ', or maybe use starship).
But each of these ānot complicatedā things really does add up and itās
especially tough if you need to keep your config in sync across several
systems.
An extremely popular solution to getting a āmodernā shell experience is oh-my-zsh. It seems like a great project and I know a lot of people use it very happily, but Iāve struggled with configuration systems like that in the past ā it looks like right now the base oh-my-zsh adds about 3000 lines of config, and often I find that having an extra configuration system makes it harder to debug whatās happening when things go wrong. I personally have a tendency to use the system to add a lot of extra plugins, make my system slow, get frustrated that itās slow, and then delete it completely and write a new config from scratch.
issue 2 with getting to a āmodernā experience: the text editor
In the terminal survey I ran recently, the most popular terminal text editors
by far were vim, emacs, and nano.
I think the main options for terminal text editors are:
- use vim or emacs and configure it to your liking, you can probably have any feature you want if you put in the work
- use nano and accept that youāre going to have a pretty limited experience (for example I donāt think you can select text with the mouse and then ācutā it in nano)
- use
microorhelixwhich seem to offer a pretty good out-of-the-box experience, potentially occasionally run into issues with using a less mainstream text editor - just avoid using a terminal text editor as much as possible, maybe use VSCode, use
VSCodeās terminal for all your terminal needs, and mostly never edit files in
the terminal. Or I know a lot of people use
codeas theirEDITORin the terminal.
issue 3: individual applications
The last issue is that sometimes individual programs that I use are kind of
annoying. For example on my Mac OS machine, /usr/bin/sqlite3 doesnāt support
the Ctrl+Left Arrow keyboard shortcut. Fixing this to get a reasonable
terminal experience in SQLite was a little complicated, I had to:
- realize why this is happening (Mac OS wonāt ship GNU tools, and āCtrl-Left arrowā support comes from GNU readline)
- find a workaround (install sqlite from homebrew, which does have readline support)
- adjust my environment (put Homebrewās sqlite3 in my PATH)
I find that debugging application-specific issues like this is really not easy and often it doesnāt feel āworth itā ā often Iāll end up just dealing with various minor inconveniences because I donāt want to spend hours investigating them. The only reason I was even able to figure this one out at all is that Iāve been spending a huge amount of time thinking about the terminal recently.
A big part of having a āmodernā experience using terminal programs is just
using newer terminal programs, for example I canāt be bothered to learn a
keyboard shortcut to sort the columns in top, but in htop I can just click
on a column heading with my mouse to sort it. So I use htop instead! But discovering new more āmodernā command line tools isnāt easy (though
I made a list here),
finding ones that I actually like using in practice takes time, and if youāre
SSHed into another machine, they wonāt always be there.
everything affects everything else
Something I find tricky about configuring my terminal to make everything āniceā is that changing one seemingly small thing about my workflow can really affect everything else. For example right now I donāt use tmux. But if I needed to use tmux again (for example because I was doing a lot of work SSHed into another machine), Iād need to think about a few things, like:
- if I wanted tmuxās copy to synchronize with my system clipboard over SSH, Iād need to make sure that my terminal emulator has OSC 52 support
- if I wanted to use iTermās tmux integration (which makes tmux tabs into iTerm tabs), Iād need to change how I configure colours ā right now I set them with a shell script that I run when my shell starts, but that means the colours get lost when restoring a tmux session.
and probably more things I havenāt thought of. āUsing tmux means that I have to change how I manage my coloursā sounds unlikely, but that really did happen to me and I decided āwell, I donāt want to change how I manage colours right now, so I guess Iām not using that feature!ā.
Itās also hard to remember which features Iām relying on ā for example maybe my current terminal does have OSC 52 support and because copying from tmux over SSH has always Just Worked I donāt even realize that thatās something I need, and then it mysteriously stops working when I switch terminals.
change things slowly
Personally even though I think my setup is not that complicated, itās taken me 20 years to get to this point! Because terminal config changes are so likely to have unexpected and hard-to-understand consequences, Iāve found that if I change a lot of terminal configuration all at once it makes it much harder to understand what went wrong if thereās a problem, which can be really disorienting.
So I usually prefer to make pretty small changes, and accept that changes can
might take me a REALLY long time to get used to. For example I switched from
using ls to eza a year or two ago and
while I like it (because eza -l prints human-readable file sizes by default)
Iām still not quite sure about it. But also sometimes itās worth it to make a
big change, like I made the switch to fish (from bash) 10 years ago and Iām
very happy I did.
getting a āmodernā terminal is not that easy
Trying to explain how āeasyā it is to configure your terminal really just made me think that itās kind of hard and that I still sometimes get confused.
Iāve found that thereās never one perfect way to configure things in the terminal that will be compatible with every single other thing. I just need to try stuff, figure out some kind of locally stable state that works for me, and accept that if I start using a new tool it might disrupt the system and I might need to rethink things.