9 Months of Full Time Neovim + Tmux
When I first joined 99.co, everyone did development in a really strange way. Almost every backend guy was using a terminal based workflow. I was only using vim
for my side projects for a few years before I joined the company, but not for a moment did I consider that many people would use vim
as their daily drivers for development. Maybe it was due to my old workplace enforcing the development tools we used. I primarily used vim
because I was very comfortable using it. Reaching for the mouse caused me so much pain since I have fractured my right hand twice so far. Never had I thought there were so many nutheads who bothered to get past the notoriously difficult learning curve of vim
. So of course, after looking at these wizards hacking the Gibson using their fancy tmux
/ vim
/ emacs
workflow, I decided I should too, learn tmux
and step up my vim
game. So here's a brief summary of what I've learnt so far. Unfortunately I have not used many GUI editors/IDEs other than Eclipse, so your mileage may vary.
Unix tools that have retired from my workflow
Goodbye grep
, hello Silver Searcher (more commonly known by its scientific symbol ag
). grep
has always been been good at searching small amounts of files, but software projects have grown pretty huge these days, and grep
does not cut the mustard. Some plugins in vim, like fzf.vim
and vim-grepper
, requires the use of grep, which fortunately can be replaced by using ag
, ripgrep
or what have you.
grep
and ag
are for the most part, interchangeable for my use cases. Instead of doing stuff like grep -i 'some string' file.txt
you could replace it with ag -i 'some string' file.txt
.
The terminal as a pseudo IDE
Most of the development tools you need already exists in your terminal. Text editors, terminal multiplexing, searching, linting and all that good jazz exists as command line applications. Terminal based text editors that have stood the test of time have been really good at integrating with these command line applications. Grep is one of them since searching is a very common tool that most programmers use. Stuff like ctags also help tracing code a real pleasure which integrates with vim without the need for special plugins. So ideally, we wanna use these command tools that integrate with our text editor as much as possible.
Some tools that I use without integration is curl
and jq
. I mainly write a lot of endpoints, so curl has been a really good tool for the job. Hell, it's also my client for Elasticsearch because of the way we send queries.
Since I'm a backend guy, I tend to look at databases a lot and I tend to favour CLI tools so that I do not need to use the mouse. Juggling all these is pretty easy if you use a terminal multiplexer, that is, to put multiple shell sessions in one terminal. Since I manage many repositories at work, I can switch windows and panes easily using tmux
, what most people would consider as a pretty awesome terminal multiplexer.
Since running commands are pretty common usage of the terminal (lul), I use fzf
to easily access my history of commands with a pretty nice fuzzy search. Remember part of a command or just lazy to type out the full thing? fzf
is your best friend.
The terminal is very pretty
I have swapped from bash
to zsh
since there are a lot of people who worked on their configurations. So I just copy them if I find them really chic. Oh and it comes with pretty good auto completion for git
and the usual file correction auto completion while ignoring the case. My tmux
has a lot of colours as well as telling me the time and the health of my machine.
Tmux
The screen is currently split into 3. Editor, running the process and an empty shell to do whatever I need to do. To do anything in tmux
, you must first press the prefix button followed by the tmux
command. By default it's control + b. Boy is that an awkward button to press, so I have rebinded my prefix to control + a. So for your own sanity, please rebind control to a more sane button. For me, I replaced caps lock with control since I do not use the caps lock at all. In vim, ~
changes the case of the letter so we can easily do away with caps lock. For the rest of the section, please remember that prefix is control + a for me but by default its control + b.
Creating splits
I have chosen to stick with the default mappings for this. Its prefix followed by "
for a vertical split and prefix followed by %
for a horizontal split.
Jumping around
There are a few ways of jumping between splits. By default it's prefix followed by the arrow keys to navigate, but I have swapped from the arrow keys to hjkl
to move my hands less.
The other way is to show the pane numbers, then press the number shown on the screen as shown in the above screenshot. To show the pane numbers, it's prefix followed by q
. So currently I'm focused on the blue spot. If I wanted to jump to the bottom right, I would have done prefix followed by q
, read the number that is on the bottom right of the screen, which is 2. Then press 2
to jump there.
The numbers on that screenshot above do not last for ever, in my case, I've set it to two seconds when toggled since I'm pretty slow at this. I think by default it's half a second.
Zooming
Although you may have many panes side by side, there are instances where your screen is too small, like my 13 inch macbook. To zoom in, press prefix + z on while on the targeted pane.
There's more
I will not go through in detail about the other functions in tmux
that I use. The numbers at the bottom bar shows the windows I have. Currently I have 3 that I swap with whenever I'm working on different things. The other feature I use are sessions. This allows you to open a new set of tmux
and swap between them. It is denoted by the website
in the screenshot. So currently this session name is called website
.
My full dotfiles for tmux are here: https://github.com/ashwinath/dotfiles/blob/master/.tmux.conf
Effective text editing and code tracing with Vim/Neovim
While there are a lot of things to learn in vim
. Please understand that this is not a vim
tutorial and you should spend some time learning whatever text editor you choose. vim
is notorious for its learning curve but I feel it pays off. Text editors are very personal to each person, but we all do have one common goal, editing text efficiently. I do believe that each developer should be good with their tools and take the time to learn whatever tool they use. If you see something here, you should try doing that with whatever text editor you use as well, you might be surprised that they might have it as well. So here's what I've learnt with vim
so far.
For the uninitiated
Vim is a modal editor. You can think about it as a finite state machine. There are a few modes but I'll go through the important ones.
- Normal
- Insert
- Visual
When you first enter vim
, we always default to normal mode. We can type text while in insert mode and highlight things in visual mode. So what the heck is normal mode?
Normal mode is where all the magic wizardry happens. Here are some common "magic" I use every time I'm in vim
. In normal mode, we have a "language" called motions. Don't memorise the commands, they are pretty much like mnemonics. Each command I talk about do have a mnemonic attached with it.
- Change a word and type something else?
ciw
(change inside word) - Change inside quotes?
ci"
(change inside quotes) - Change inside quotes and the quotes as well?
ca"
(change around quotes) - Delete everything until
(
?dt(
(delete till opening parenthesis)
Other commands that do not really have a mnemonic attached to it but somehow infused in muscle memory. I love jumping about everywhere. I know people will get a headache and have 0 clue on what I'm doing but I'm actually in full control. Vim shines at this. I'm pretty sure there are more like ]]
or [[
which I don't really use. Jumping is one of the best ways to trace code.
g;
jumps cursor back to last edit point (can jump through history)g,
jumps cursor back to newer edit point (jump list history)gg
jumps to the top of the fileG
jumps to bottom of the filecontrol + ]
jumps to ctags definition of functiongd
jumps to initial declartion of the variable.control + o
jumps to the previous jump point (useful for tracing backwards after using ctags jump)control + i
jumps forward in the jump list.*
jumps to the next matching word.#
jumps to the previous matching word. (seeing where the variable is used)control + d
jumps cursor half a page down.control + u
jumps cursor half a page down.zz
centers the cursor in the screen.%
jumps to the matching parenthesis/tag/quotes etc.^
jumps to the start of the line.$
jumps to the end of the line.
These are just vanilla vim
commands. vim
really shines at being customisable since it allows for scripting.
Oh right, if you need to repeat a set of commands, we can always use the macro function. To begin recording a macro, type q
followed by any letter to save the recording to a register. Do whatever you want, then press q
to stop recording. To play the macro, type @
followed by the letter. Generally I will do something like qq
, some action, q
and 100@q
to repeat the action 100 times.
Vim plugins
On top of what vim
provides, it can be further augmented with vimscript
. I'm probably not talented enough to write them but there are pretty much a lot of people who have written plugins for everyone to use. All my plugins are managed by vim-plug
.
nerdtree
Easily see the project structure of your repository. Additional functionality to move files, create files and delete files easily.
vim-surround
Sometimes, we forget to wrap a word in quotes or parenthesis, so issuing the command ysiw"
wraps the word in quotes. For example, this command changes hello
to "hello"
.
nerdcommenter
Easy way to comment out a block while debugging or testing code. Its mapped to <leader> ci
for me.
vim fugitive
Probably one of the best git clients in vim available. In-lines the git blame
command inside vim. I use it to view diffs, merge conflicts, stage files and commit files. Vimcasts has a excellent tutorial on vim fugitive.
fzf.vim
I use this on the command line as well. I've set it to control + p
(resemblance to the control p plugin) to switch between files fast. It's fuzzy search coupled with ag
makes file switching very fast. Sometimes I use it for switching between vim buffers.
tagbar
Since I don't use folds that much, I like a "minimap" of functions, classes, class wide and file wide variables listed nicely. This uses ctags to generate the list of stuff used in the file and I can quickly jump between them by pressing enter.
vim-gutentags
Auto regeneration of ctags
whenever I save a file. Purely a quality of life plugin.
vim-repeat
This plugin just lets you use the .
(repeat) command for all plugins you use as well.
vim-snippets
Generally there are some lines that I type really often and need it during pure concentration while not breaking my flow. One of them is __import__("pdb").set_trace()
while I'm debugging stuff. Typing pdb
followed by the button to trigger the snippet yields that.
vim-grepper
Asynchronous project wide searching. Couple this with ag
and get blazing fast searches. It's bound to !
for me to search for a particular pattern.
ale
Asynchronous lint engine. Checks my code for errors and linting problems. Really good for coding when you are tired or just a mistake prone person.
vim-swoop
So I saw this guy at my workplace who uses emacs
and they had this really cool plugin called helm-swoop
. Very useful for searching all occurrences of a string in a file.
vim-mark
Pretty highlighting of variable names whenever you need it. Like a student highlighting their textbooks but this is automatic. Very good for code tracing.
Conclusion
While vim
, tmux
and living purely in the terminal is pretty cool, it's not for everyone. Best thing you can do for yourself is just to be comfortable and know your tools well. The goal is to be as lazy as possible and having the same output. You can find all my dotfiles here: https://github.com/ashwinath/dotfiles