I don’t like taking away my hands from the keyboard when I’m working. I do like when everything is “just a click away”, or a keystroke away.
I do lots of stuff on CLI, - logs, process monitoring, creating pull requests, writing code and all it entails (debugging, refactoring, running tests, etc).
As such, my terminal is the app I’m using the most. Inside of it I’m running the rest of my setup which consists primarily of tmux, vim, fish, git, some other cli programs, and a bunch of scripts and aliases.
When working I can usually get by with only 2 apps open - terminal and browser. Nothing else is essential.
Needless to say terminal is crucial in my setup, so it has to be the best I can get.
Criteria to satisfy my needs
A good terminal emulator has to be fast since this is the app I’m spending most of my time in. As such it has to be GPU-accelerated. It has to work on both Mac and Linux (Windows, I’m sorry, not a fan of yours), so it has to have some cross-platformability. It also needs to be open source.
I’ve tried quite a few terminal emulators.
Hyper are notoriously slow. Hyper, being Electron-based, is also a CPU/RAM devourer. Default MacOS Terminal app I just don’t like, and it’s kinda slow-ish as well, not to mention I probably can’t get it on Linux and I doubt it’s open source.
If I were to use a terminal app for once-off tasks, I’d be fine with either iTerm2 or Hyper, but as a terminal is my ultimate workhorse I need it to be performant.
Next up I’ve tried
kitty and they are pretty close in terms of performance with kitty having a bit of an edge over Alacritty (which seemed weird to be because Alacritty is written in rust whereas kitty is in python). When I’ve been choosing, Alacritty claimed to be “the fastest” on their github page. Never trust the writing on the wall, on some setups it may be “the fastest”, check on your own setup with the tasks that you are usually performing. Measuring terminal emulator performance is monkey business anyway. It turned out that on my setup (on my machine) alactritty is tad bit slower than kitty. As they are pretty neck-to-neck, speed is no longer the selling point for me.
kitty is the winner
Ultimately, I fell in love with
kitty, and I would’ve chosen kitty even if it wasn’t faster (provided it’s not slow, of course) than Alacritty. The look and feel felt right, so did the configuration options (colors, font, opening URLs with a mouse click, ablity to disable all the “husk” such as window title, and others).
Don’t get me wrong, alacritty is very decent and you can give it a shot, but choosing what’s right for me is not solely based on numbers, popularity, or features, it’s also a matter of personal preference.
Terminal multiplexor is something that I’ve been staying away from for a long time. I only had experience running GNU screen on remote servers for long tasks. I’d just
ssh into a remote server and run my
bin/long-process in a
screen and then put it in background.
In the past, while working, I would use tabs in
iTerm2 (when I was using it) and I didn’t think a terminal multiplexor would improve my workflow all that much. I was totally wrong. Once I got into a habit of using tmux there was no way back. It simply allows you to slice and dice your terminal screen exactly the way you want it. No need for tabs, or built-in split-screens as you get a finer control. New session is my new workspace, windows are my tabs, within a single window I can have multiple panes. With some
fish scripts I can enhance tmux experience even further.
For a new task (project, or JIRA ticket) I always start a new session (
prefix+: followed by
:new -s <session-name>, or if tmux session is not running yet, use
tmux new -s <session-name> CLI comamdn). From there on, the first window will usually be designated for the editor (vim in my case), and all the other windows will be created as needed (for logs, monitoring, testing, etc).
Inside a single window I can have multiple panes as needed
I already told my story of why did I chose vim as a my go-to editor. In another article I have also described how to make a universal IDE out of vim. TL;DR: VIM can do most of the stuff modern IDEs can do, it has support for most of the programming languages so I don’t have to do IDE hopping, it’s ran inside a terminal and I have a habit of not leaving my terminal while working. It’s also very fast (if you keep the number of plugins to minimum).
My whole vim configuration can be found in my dotfiles. You aready have seen screenshots of what it looks like previously in this article. I’m going only quickly describe what my vim is capable of (aka plugins overview).
Autocomplete, refactoring, jump to definition, etc
I use coc.nvim for LSP support. It adds IDE-like features into vim such as:
- Code autocompletion
- Refactoring (rename symbol, class, etc)
- Go-to definition
- Go-to references
- Method signature tooltip
fzf, fd, and rg makes wonders when it comes to searching for anything.
Ctrl+Pis my fuzzy file search (it works just like you’d expect it to work in any IDE)
<leader>+bblists me all the open buffers
<leader>+/gives me a history of commands
<leader>+FFsearches for a string in all the project’s files (the search is execluding everything that is excluded in
For files explorer I’m using NERDTree (quite famous in vim community). I don’t like it all that much to be honest and looking to replace it, but it does the job and I’m lazy.
gitgutter is super useful as it shows a git diff in sign column as well as a bunch of other useful things it does.
And I’m also using fugitive, mainly to do
git blame right inside the editor. Most of the time for any other git commands I put my vim to background, do git stuff, and then return back to git using
fg command. Or, in some cases, I will make a horizontal tmux pane if I want to have git diff on top and composing a git commit message on the bottom (very useful!).
For debugging I’m using vdebug.
Most useful built-in capabilities
- Macros! This is something that is lacking in most IDEs and usually doesn’t exist in those IDEs’ “vimification” plugins (IdeaVim is pretty good though).
- General navigation (
f+<symbol>, etc) and editing (
cw, etc) in a file.
- Splits (either using
:vsor a keystroke
I was a zsh user for many years. And then I’ve found fish.
Why, Kirill, why? zsh is perfect!
Yeah, zsh is good, but fish is better (for ME! I don’t want to put words in your mouth). You can read why I decided to switch to fish and maybe it will make you want to try fish.
I’m not going to say much in this section. It’s just a preface for the next one.
You can find my scripts, again, in my dotfiles. There are fish scripts, and some other scripts in a ~/bin directory. I will not go through all of them, only the ones which I use the most.
THE most used script.
It allows jumping between projects in no time. All you need is type the project’s name part and it will take you there (provided you have
zoxide installed). Two conditions though - your project has to be a git repo (this is how
p knows it’s a project, not a regular directory). Second condition, - you have to add all the projects’ roots to
$PROJECTS_DIRS env var (i.e.
set -x PROJECTS_DIRS ~/Projects $GOPATH/src)
If a project can not be found by partial name,
p will show a list of projects via
fzf (if it’s installed) and you can auto-complete the project’s name from there. Next time
p will “remember” your choice, and, provided the same search term, will take you to the selected project.
A shortcut for
docker exec -it <container id>. To “ssh” into a container, I just type
@ elasticsearch bash.
Under the hood it uses official GitHub cli tool gh to fetch a list of my PRs and pipe them into FZF for fuzzy find.
Browser openers scripts
There is a bunch of scripts that open browser links for me (not committed to my public git repo).
In the past I used Alfred to have my custom searches, so I could open up links that follow a particular pattern easily. Now I’ve replaced Alfred with a bunch of scripts. When I need to open up a JIRA ticket, for instance I simply type
j on console and
j takes me to the JIRA ticket that (how does it know the name? Don’t you remember? It’s my tmux sessions name).
j can also accept the argument of ticket number, so I can do
It’s really easy to do, by the way. Let me quickly “fish it up” for ya:
function googleopen "https://google.com/?q=$argv"end
google coffeeaddict dev
will take you to https://www.google.com/?q=coffeeaddict%20dev
Gotta be super easy to script it up in bash too, I’m just too lazy to try it.
dnsto quicky add or remove a dns server
proxyto enable proxy (useful with something like
t(alias for taskwarrior which “scopes” to current tmux session using the session name):
That’s it, folks!
Terminal, tmux, vim, and a bunch of scripts is all it takes to almost never lift up hands from the keyboard. Not that it’s an ultimate goal, but it does add up to effectiveness hour by hour, day by day, month by month, year by year…