Introduction
I have been a heavy VIM user (and now Neovim user) for many, many years now. It’s to the point where the vim style of navigation and motions are deeply ingrained in my brain and muscle memory. So, naturally, I want to leverage this super power in all parts of my computer experience. This has lead me on a long journey to continually find ways to adapt every aspect of my setup to support at least some semblance of VIM-like feel.
I use a variety of operation systems from MacOS to Linux (I use Arch, btw) to, even still, Windows. Some of these operation systems make it easier than others to accommodate my preferences. Others, such as MacOS (the subject of this post), not so much.
This post will focus on this difficult category of MacOS interface customization. Over the years I have sourced a number of blogs and StackOverflow posts to inform my setup but, most recently I stumbled upon this post by Mastodon user heywoodlh. Many of the topics discussed herein are derived from this post so kudos to them for the inspiration.
Key Components
To make this all work, we’re going to need a handful of applications:
- Vimium - Keyboard navigation for your browser
- Shortcat - Keyboard navigation for your OS
- cliclick - CLI driven mouse actions
- hammerspoon - Automation tool for MacOS
- skhd - Custom shortcuts (used here for calling cliclick with keyboard shortcuts)
Vimium
Vimium provides a way to navigate webpages within your browser using a very vim-native feel. Some of the key features of this plugin that I use every day are:
- hjkl page navigation
- link highlighting
- URL yanking
- searching a page with /, n and N
- gg and G to jump to the top and bottom of a page
These are just some examples of what you can do with the plugin. Be sure to visit the app page linked above for all the different commands that can be used. Additionally, Vimium provides a powerful filtering option to allow you to exclude certain webpages from vim navigation. This is particularly helpful for websites, such as Gmail, that have their own keyboard shortcuts that may conflict or for pages that do not behave as you expect with the plugin.
Shortcat
The article by heywoodlh, referenced above, discusses using a program called Vimac to generate overlays of keyboard-selectable “buttons” within the focused application. Unfortunately, in the intervening years since the post was written, this product has been deprecated and development work has moved to a paid application called Homerow. While I’m sure that Homerow is a fantastic product, and I did try it out briefly, it is a paid application and Shortcat is free (as in beer) and MacOS is my work environment on to which I do not wish to invest money of my own in. Homerow has some features that are missing from Shortcat, such as keyboard driven scrolling, so I would encourage you to check it out if that is appealing to you.
Shortcat provides the same keyboard-selectable overlay that is provided on a webpage by Vimium but does so using the accessibility features of MacOS to provide them within the focused application window. This can be very handy for navigating applications that do not have their own shortcuts or have shortcuts that are unintuitive and can’t be changed (I’m looking at you Slack).
cliclick
Cliclick is a new piece of software to me. It is a CLI tool that allows the execution of mouse and keyboard related actions from the terminal. With this tool, you can fill in any of the gaps in shortcut-based navigation provided by the previous two applications by directly moving and clicking the mouse through the command line. However, doing this through the terminal is quite inconvenient and we need some way to do it with a keyboard shortcut to really tie it all up with a nice bow.
Hammerspoon
Unfortunately, Cliclick does not support scroll wheel activation. It looks like there is a Github issue for this but it has been open for years with no resolution. This is where Hammerspoon comes in. Hammerspoon is a tool for automating tasks on MacOS. It is configured with a Lua script that can be used to execute arbitrary commands and actions. We will use this to scroll the window when we need to. There may even be way to replace cliclick with Hammerspoon entirely but I have not investigated that yet.
skhd
This handy application is the real gem of this entire setup in my opinion and is the key pieces that I took away from the post by heywoodlh. skhd is a generic keyboard shortcut application for MacOS that is configured with a config file ($HOME/.skhd). Using skhd we can execute our cliclick commands from keyboard shortcuts. Heywoodlh provides an excellent configuration example that I’ve directly copied and used in my own configuration and will share here:
ctrl - k : cliclick "m:+0,-20" #up
ctrl - j : cliclick "m:+0,+20" #down
ctrl - l : cliclick "m:+20,+0" #right
ctrl - h : cliclick "m:-20,+0" #left
ctrl + shift - k : cliclick "m:+0,-40" #up (faster)
ctrl + shift - j : cliclick "m:+0,+40" #down (faster)
ctrl + shift - l : cliclick "m:+40,+0" #right (faster)
ctrl + shift - h : cliclick "m:-40,+0" #left (faster)
ctrl - 0x21 : cliclick ku:ctrl c:. #click with ctrl+[
ctrl - 0x1E : cliclick ku:ctrl rc:. #right click with ctrl+]
ctrl + shift - 0x21 : /opt/homebrew/bin/hs -c 'scroll.scrollUp()' #scroll up with ctrl+shift+[
ctrl + shift - 0x1E : /opt/homebrew/bin/hs -c 'scroll.scrollDown()' #scroll down with ctrl+shift+]
Conclusion
That’s it for now. That’s my basic setup. There are a few other small changes I’ve made to the MacOS keyboard defaults such as swapping capslock with escape, for easier access to the escape key from the homerow, but that’s about it.
I hope you find the information above useful and if you have other suggestions on ways to improve this setup or want to share your own setups that help improve your keyboard driven experience on MacOS, please send me an email.