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

How my setup looks generally. Ignore the zsh error lol.

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 file
  • G jumps to bottom of the file
  • control + ] jumps to ctags definition of function
  • gd 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

See the project structure on the left.

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

Git blame on the left.
Checking diffs before commits.

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

Fuzzy file finder at the bottom.

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

All tags are listed on the right.

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

Search project wide for string matches.

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 colours for marking different keywords.

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