Thomas Buß

13 Sep 2020

My Keyboard-Driven Dev Setup

Contents

Motivation

Recently, a colleague of mine watched over my shoulder while I was using some of my keyboard-oriented tooling. His reaction was not very surprising. Complete lack of comprehension how anyone can edit files that way, but astonishment over how fast it was. “How can you remember all these shortcuts?” or “That’s way too complicated!” are comments that any Vim or Emacs user has probably heard at some point. I took this as an impulse to write down my thoughts and motivation behind these tools in this blog post. Before I get into what exactly I am using, I want to explain why I started to use keyboard-driven programs.

Besides my code editor(s), many of the other tools on my system use Vim keybindings as well, such as my browser as we will see shortly. But what’s the value of going through the hard (and never-ending) process of learning all these things? Is it just speed? Or showing off to your coworkers?

Well, partly yes. But for me, the most important aspect is flow. The goal is not just to save time by not reaching for the mouse, it’s about staying focussed at the task. As you think about what you have to do, your fingers already typed it in. Thoughts become actions more quickly. This must apply to anything, not just editing text. Executing tests or the program itself must be just as easy, only a few keystrokes away (or might be even completely automatic). Replying to an email is another task where I do not want to waste time (and maybe forget about an important idea) because I had to slowly navigate to the right window and click some button.

Ever watched your mom use a computer?

Everyone knows this situation: Your mother (or some other person who does not use a computer very often) is showing you something on a laptop and she needs to scroll down a page. Most people would probably use the scrolling wheel on your mouse or the trackpad for this. Instead, she uses the mouse to reach for the scrollbar on the right, then clicks and drags the scrollbar down a bit. And you think to yourself “Why on earth would you do that?! That takes so much time!” For anyone who has been using keyboard shortcuts like Vim keybindings to navigate and manipulate text, this feeling you get when mom uses the scrollbar is the same that you get when you watch a coworker do simple text changes like deleting a word by the cumbersome act of mashing that backspace button over and over again. “Why on earth would you do that?! That takes so much time!”

Disclaimer and a little warning

I must admit that this point is very subjective and also opinionated. But I want to encourage you to try some of the things and see for yourself if they can improve your workflow. Feel free to share your experiences in the comments below. Moreover, I think this process is a slow one. When you do everything keyboard-driven all at once, you won’t get anything done, blame it on “obscure” keybindings, and move back to how things were before. I would advice against that. You should start by adopting one tool here and there, not all at once.

Personally, I started using Vim on a daily bases around 2 years ago, so I would say I’m quite ok with it. Then again, I’ve read a comment on one of Brodie Robertson’s YouTube videos from a guy who has been using Vim for 40 years and still learns new stuff from time to time. So there’s not really an end to it. But I think it’s a good thing to keep learning new stuff!

Also, this is not a Vim tutorial. If you want to learn how to use it, there are a ton of resources out there to learn from. Vim even comes with the vimtutor command that teaches the most basic stuff. After that, try to observe what actions you do with your mouse when you’re normally editing text. Most “modern” IDE features (like multiline editing, which has been a part of Vim for like 40 years) can be replaced with Vim and these methods are very well documented in the fan-driven Vim Wiki or other sites on the web.

Now, let’s look at different aspects of a development setup where keyboard-driven approaches can apply.

Operating System and Window Management

On the job, I had to choose between a laptop with Windows or a MacBook. During college, I used both Windows and Linux for programming tasks and found out that I do use the terminal quite a bit for many simple tasks e.g. finding files which contain a certain text or counting words in a text that spreads multiple files. The terminal experience on Windows back then was (and to my understanding still is) poor. Not only do you have multiple different programs (CMD, PowerShell, git bash, and maybe a WSL bash), combining commands to do more complicated tasks is not as easy and straight-forward as with Unix-based operating systems. More importantly, many developer tools nowadays treat MacOS as the first-class operating system, where the package manager Homebrew makes installing and updating things so much easier than on Windows. So I settled for MacOS. As a side note, I’ve even started to use Homebrew on Linux now so I can keep a Brewfile with all the “user facing” programs and install all of them on any of my computers with just a few (almost cross platform identical) commands.

MacOS is not perfect, though. There are two things that bug me the most: First, the window management on “vanilla” MacOS is done poorly. When you have two windows of the same application open, like two browser windows, and you CMD+tab to the browser, it’s not obvious which one of the windows gets focus. Many other smaller things like that are just as confusing (at least for me). There are also no shortcuts to move windows around. To solve this problem, I am using a tool called Magnet (the only non-gratis tool in this article by the way). Magnet let’s you move the active window to a position on your screen (like upper left quadrant, right half etc.) or to other spaces and displays. The pre-configured shortcuts are Vim-oriented, so I had little to change to make it work just like I wanted.

I tried Yabai and used a few tiling window managers on Linux before, but I could not get used to them. Moreover, I do not think that these “pure” tiling window managers like i3 or bspwm provide much more benefits than what Magnet offers. They also make your system completely unusable to other people. On Linux, I use Xfce4 for window management as it is lightweight and supports the same kind of windows placement commands as Magnet.

Window Management is something that especially Linux users like to argue about… I guess because they’re the only ones who have so many options to choose from. I got tired of arguing about the best one. Just choose what works for you.

The second thing that bothers me on MacOS is the way which kind of actions get which keyboard shortcuts. On Windows, it’s actually a little bit better: the Windows-key is for the operating system shortcuts, ctrl and alt are for program shortcuts. This distinction is not perfect, but feels natural and a lot better of what MacOS brings by default. Linux, of course, let’s you customize everything (if you’re willing to dig into some config files). On MacOS, ctrl+left/right changes the current space. CMD is often used by programs, but CMD+Space opens Spotlight and CMD+shift+4 is a screenshot utility. There seems to be no real consensus or distinction between system-level, program-level and content-level shortcuts. You might think this is not important. You might be right. Still, it bothers me.

Terminal and Shell

For terminal emulation, I use Alacritty. It’s open source, works cross-platform (even with the same config file!) and is as minimal as I wanted a terminal emulator to be without sacrificing convenience. Resizing the windows automatically adjust the text (which is not something you take for granted when coming from Linux!), URLs are automatically clickable and the latest version even includes a Vim mode where you can select and copy text, or open URLs without having to use the mouse. I’m pretty happy with it and do not miss any features.

My current shell is ZSH and I think I’ll stick with it for the forseeable future. I tried FISH a while back and really liked its autocomplete features, but the fact that the syntax for shell substitutions or scripts is different bothered me. Now, I use Oh-My-Zsh to augment the missing autocomplete features in ZSH. Checkout https://github.com/zsh-users/ for a collection of nice ZSH plugins. I am, however, thinking about switching to Antigen because oh-my-zsh uses a monorepo for all plugins accessing other repositories for plugins seems to be easier with Antigen.

As a professional programmer, you’ll find yourself in a situation where you need to stay on a specific Java or Node version for compatibility reasons. On the other hand, toying around with newer versions is something you do not want to miss either. The tools sdkman and NVM can help you to easily switch between of Java and Node versions. Need to stay on Java 8 for your current process and still want to try out that new Java feature you heard about on the web? You’re just one sdk use java 14.0.2.j9 away from switching to Java 14. NVM is just as easy.

All these programs usually involve one or more configuration files in your home directory. As you may spend a lot of time configuring things the way you want them and might want to copy these files over to another system, consider using a tool to manage your config files (or “dotfiles”). I recently started using a tool called Stow, which creates symlinks from your home directory’s config files to another folder or, as many people use it, a Git repo that manages all your config files. You can find my dotfiles here.

At the end of this section, I just want to list some smaller utilities that I find useful

  1. My prompt is Powerlevel10k. Not much to say there. I didn’t want to invest to much time into this one.
  2. Ripgrep is a modern replacement for grep with a (in my opinion) easier to use interface.
  3. fd replaces find.
  4. jq is a JSON formatter and querying tool. I use it in a few scripts when interacting with a program that returns JSON like Docker or when accessing RESTful services on the command line.
  5. httpie is an HTTP client.
  6. newsboat is an RSS reader for the terminal. I got frustrated with many web-based RSS readers because they were just to clumsy to use and I don’t see why I would need something like Feedly (which I tried) to use something so simple as RSS.

Neovim (+ Plugins)

Originally, I wanted to include Vim (or Neovim in my case) together with the rest of the command line utilities, but I decided that it deserves a section of it’s own. While I do use Vim on a daily basis, most of the time I use Vim plugins for other IDEs, namely Visual Studio Code and IntelliJ IDEA, depending on what my current project is. Since these IDEs come with a lot of build-in functionality, there’s simply no need to do everything on the command line (as long as the editors have Vim keybindings to manipulate text). My “real” Neovim setup includes a few small- and medium-sized plugins. And since you can use Vim in an SSH session to a server, learning the basics of Vim is something that every programmer or administrator can benefit from.

What my colleagues find very weird at first is that I use relative line numbers in all of my editors, including Neovim. That means that for the line my cursor is currently on, the line number is displayed normally. The line above and the line below it get a 1, then a 2 and so on. The reason for this is that it makes navigating between lines much easier. To go to a specific line very quickly, you just look what it says on the line number and type, e.g. 18k to go up 18 lines. This is, by the way, not a plugin: This is vanilla Vim, just needs to be configured.

Then, there are a few eye-candy plugins like Airline and the Nord Theme to make it all look nice. I have NerdTree and Floaterm installed, but use them very rarely (again, because my IDEs include this already).

There are so many Vim plugins that you can use if you really want to make Vim as powerful as an IDE. I recommend checking out the YouTube channels of Brodie Robertson and Chris@Machine if you want to learn more. Also, https://vimawesome.com/ is a great address to find Vim plugins.

Visual Studio Code (+ Plugins)

As mentioned above, I use the Vim plugin from vscodevim for Visual Studio Code. It’s not a perfect emulation, but it does enough for my needs. Another noteworthy plugin is “Vim quick-scope” from Adam Howard, which highlights letters of words on the current line for jumping with the f/F and t/T Vim shortcuts. Plugins like that are awesome because they do not change the way you use Vim, they teach it to you.

Other plugins I use that are not related to a keyboard-driven setup are a formatter for markdown tables, a PlantUML visualizer, Nord Theme and Material Icon Theme for optics, and a bunch of other plugins that mainly depend on my current work.

Apart from that, I just change a few keyboard shortcuts, but try to stick with the default ones or just use CMD+shift+p and simply type what I want to do.

IntelliJ IDEA (+ Plugins)

Apart from the obligatory Vim plugin for IntelliJ, IdeaVim, I changed even fewer things from the default IDE settings in IntelliJ. There a a few overlapping keyboard shortcuts between Vim and IntelliJ, but you can easily choose which option gets triggered from a little helper window that pop up automatically. There’s also the Keyboard Shortcut Reminder that yells at you when you do an action using the mouse instead of the keyboard. This is also one of these handy, little plugins that do not change the way you work with your IDE, but teach you the keybindings instead. Double-Shift is also a nice way to find options for which you do not remember the shortcut.

Browser

My main browser is Firefox, for development I currently use a Chromium-based browser (currently Vivaldi, but this changes a lot). I do not want to clutter my main browser with plugins that are specific to web development (who wants to have a color picker in the top bar all the time?). This also gives me the ability to set some specific caching options independently from my normal browser. A colleague of mine uses Firefox Developer Edition and is very happy with it, I might switch to that.

Probably less common is that I use Vimium to emulate some Vim keybindings in the browser, so I do not need to use a mouse to scroll or follow a link. I really cannot use a browser anymore without this. If you’re on a page that uses keyboard shortcuts, you can disable all or certain Vim keys from a menu.

What I really which for is a command prompt for the browser, similar to “Double Shift” in IntelliJ. Vivaldi has that, but plugins cannot (to my knowledge) put their actions in that menu as well, which means that you cannot, for example, save to current page to Pocket. There’s probably dozens of users who want that, but I haven’t seen it yet.

I am also trying to use the keyboard for websites as much as I can. For example, pressing Tab twice in WhatsApp Web puts you in the search box for contacts, so you can easily search a contact and hit enter to switch. This conveniently also focuses the text input, so you can just start typing. Programmers of the web: This is sooo useful! Do this more often! If not for me, then please for accessability reasons!

Communication tools

This is a difficult one, as you can’t really choose which one you use based on personal preference. You got to use the one your friends use or your company provides you with. I already talked about WhatsApp Web in the browser section of the article. Here, I tried to focus on desktop application.

In my company, we use Microsoft Teams. Teams and MacOS really do not like each other. Very often, when CMD-tabbing to Teams, it does not focus the main window. Dunno why, and it sucks! If you know the cause or some keyboard-friendly alternative to the official desktop app, please leave a comment below!

Non-virtual tools

This blog post is about my development setup and that does not only include programs. We’re leaving the world of keyboard-driven tools now. There are a few things that you might find useful that have nothing to do with technology.

I recently started again to keep a notebook on my desk and write down what I’m doing as I am doing it. Before I did this, I often times had trouble remembering all the things I did when we talk about it in our Daily Standup or when you’re picking up a task on a Monday. It also helps me to organize things in my head and motivate myself, because I can then look back and see all the things I have accomplished during that day. I stole this idea from Ward Cunningham’s Wiki. If you take one thing away from this blog post, then it’s the link to this page! It’s a gold mine of wisdom!

I’m also trying to drink lots of water during the day, about 2 liters before lunch, 1 liter in the afternoon and another liter after work. When I don’t get enough water one day, I almost always suffer from concentration deficit on the following day. So remember to hydrate yourself!

Another health-related habit of mine: I take every opportunity to walk a few steps. In my company’s office, we do not have height-transferable desks, so I would be sitting most of the time if I didn’t make this a habit.

Final thoughts

Wow, this blog post certainly got longer than I originally thought it would be and more of a rant against MacOS and Microsoft Teams that I hoped.

The main thing to remember is that you want to be productive with keyboard shortcuts. You want to maintain your flow. That does not mean that you need to use terminal applications only. However, most GUIs lack a proper keyboard support for power users and that’s why a lot of the people using keyboard shortcuts stay on the command line.

Hopefully, you now have some ideas how to improve your personal setup. I’d like to hear about your thoughts and experiences in the comments below.

comments powered by Disqus