Keyboard tricks from a macOS app dev
This is a collection of keyboard and trackpad workflows that I accumulated over the last 7 years of using a MacBook.
Here are some important abbreviations I am using in this article:
|lcmd||⌘ Left Command||The Command key on the left side of the spacebar|
|rcmd||⌘ Right Command||The Command key on the right side of the spacebar|
|lalt||⌥ Left Option||The Option key on the left side of the spacebar|
|ralt||⌥ Right Option||The Option key on the right side of the spacebar|
|hyper||^ ⌥ ⌘||A rarely used combination of modifiers|
# Key Sequences
In 6 years of using BetterTouchTool I had no idea this feature existed.
It can map any sequence of keys (even modifiers) to any action.
Sequence: individual keys pressed one after the other, not key combos that you press at the same time
In the below video, I map
lcmd to the macOS zoom hotkey:
I only have 2 key sequences at the moment:
lcmd→ Picture-in-Picture Zoom
rcmd→ Superkey Seek
The below video is a demonstration of how I use it to quickly find and click on things that I know they're somewhere on the screen, but I would be too slow to notice-point-and-click with my eyes and trackpad.
rcmd, typing fip then pressing
Enter which clicks on the browser tab with fipple in its title.
You can even hold modifiers while pressing Enter to do the same action that clicking with that modifier would do. In my browser's case I can:
Enterto right click the tab and show the context menu (for muting or pinning the tab, etc)
Enterto close the tab without trying to click on the tiny
# Double Tap
Raycast added the possibility of mapping a double tap modifier combo to summon it.
I personally mapped
⌥ and I like it because it doesn't clash with any other keys while being unique enough to remember.
One thing I noticed though is that it is faster and easier to press
ralt to register a double tap, instead of actually pressing one Option key twice. The reverse direction (right then left) works as well.
One could also use BTT's Key Sequences to map arbitrary double or even triple taps to any action.
For example here I mapped
^ to BTT's GPT action and I use it to convert some ObjC code to Swift:
V in the video are synthesised by BTT, I'm not copy-pasting anything
# One-key app switching
When using more than 3 apps, it becomes annoying to Command Tab Tab Tab... all of the time.
I'd like to switch to exactly the app I need, with a single keypress. Previously I did this by manually assigning
letter to my most used apps, using Karabiner or BTT.
I finally wrote the rcmd app to do the assigning automatically for me, while also adding nice features like show/hide app by pressing the same letter twice, or launch app if not already running etc.
As a bonus, I was able to implement focusing and opening specific projects, documents or windows of an app using the same method.
I have many projects in my code editor and frequently need to switch between them. And when opening up such a project, I also need to open a terminal tab and
cd to the directory of that project.
For some of those I also need to open a specific Sketch or Pixelmator file which contains the graphics of the app or website. And of course, if it's a website, I also need to open the damn webpage in my browser to see how it looks while I develop it.
That's too much work. And way too many things to remember.
And I don't always need all of them at once, I want to be able to open things selectively, so a script that does it all isn't a good choice for me
So I dedicated the
ralt key for opening and switching between these projects.
Configuring rcmd to do the window focusing thingie is a bit convoluted because of the App Store sandbox limitations, but if you have many projects to switch between, it's worth it.
To give you the basics on how to do this:
- Install Hammerspoon and the window switching script from rcmd's Switcher menu
- Manually open the project you want to assign (e.g. open a folder in VSCode)
=(or the key before backspace) to show the assignment menu
Kand then press the letter you want to bind to that project
- Tell rcmd how it can open that window (usually you'd choose Open a file)
if the ralt hotkeys don't do anything after first installing the script, you might need to restart rcmd and Hammerspoon
# Fn key
It always seemed weird to me how we have this
Fn key which only interacts with the function row of keys, backspace and arrows and just takes up keyboard space for the rest of the time.
So of course, after running out of keys to bind, I looked for ways to use that key.
Starting with skhd is really simple:
brew install skhd
brew services start skhd
- Give it the required permissions
- Start adding your hotkeys inside
Simply editing and saving the
skhdrc file will hot reload the changes. Much faster than clicking around in the BTT UI.
Here are some interesting hotkeys I use with skhd:
# Edit skhd config fn + k : code $HOME/.skhdrc # Easy to use Sleep hotkey fn - q : pmset sleepnow # Turn on lights to warm colors fn - w : shortcuts run "Warm Blend" # Connect or disconnect Sidecar fn - s : $HOME/.local/bin/lunar toggle-connection sidecar # Search selected text on Google fn - g : skhd -k 'cmd - c'; open "https://www.google.ro/search?q=$(pbpaste)" # Upload selected file and copy URL to clipboard fn - f : skhd -k 'cmd + alt - c'; \ terminal-notifier -title "Uploading file" -message "$(pbpaste)" -ignoreDnD; \ curl --upload-file "$(pbpaste)" "https://transfer.sh/$(basename $(pbpaste))" | pbcopy; \ terminal-notifier -title "File uploaded" -message "$(pbpaste)" -ignoreDnD # --- Things that need SIP disabled --- () # Decrease window opacity (more transparent) -- "0x1B" => "minus (-)" fn - 0x1B : yabai -m window --opacity $(bc -e "$(yabai -m query --windows --window | jq -r '."opacity"') - 0.05") # Increase window opacity (less transparent) -- "0x18" => "plus (=)", fn - 0x18 : yabai -m window --opacity $(bc -e "$(yabai -m query --windows --window | jq -r '."opacity"') + 0.05") # Toggle Picture-in-Picture for the current window fn - p : yabai -m window --toggle pip
# Text expansions
Everyone has these snippets of text that they type often: email address, phone number, specific emojis, URLs etc.
I use Raycast's Snippets feature to quickly type these things by assigning mnemonics to them.
I also map typos I frequently do to their correct words. Examples:
- oyu -> you
- improt -> import
- stirng -> string
Adding a snippet in Raycast is as simple as copying some text, then opening its clipboard manager and pressing
Here's how I have it configured in case you want to replicate my setup exactly:
# Trackpad gestures
I've been working on MacBooks exclusively for the last 6 years, and the Trackpad has always been right there at the center.
It's such a good input device, with multitouch, Force Touch and great OS support. It would be a shame to neglect it.
I'm using BTT to configure all kinds of gestures for it, the below video shows some of my most used ones:
# Remembering key bindings
How do you keep all this in mind??
I get that question often. And the truth is it's becoming harder and harder.
I cope by dedicating modifiers to sets of actions and by always looking at the places where these key bindings are configured when I need them.
Very often I forget where a hotkey was defined.
About a year ago, I started writing FuzzyKey, a fuzzy search Spotlight-like UI for all types of hotkeys. There are multiple apps doing similar things, but I wanted to take things further.
The defining features would have been:
- Parsers and ingesters for user defined hotkeys in most common apps
- (e.g. keeping an always up-to-date database of hotkeys from
- this could be extensible by users who want to write their own parsers
- (e.g. keeping an always up-to-date database of hotkeys from
- Really good fuzzy search that surfaces the keys most likely to be forgotten
- Easily edit a key binding without having to remember where it's defined
After a few months, me and 2 friends wrote the parser architecture, the key bindings change watchers, a bit of UI, a bit of CLI, and the following parsers:
- Shells: Bash, ZSH, Fish
- Browsers: Chrome (for extension hotkeys)
- Terminals: iTerm, Kitty
- Code Editors: Sublime Text, VSCode, XCode, JetBrains
- Menubar (basically what CheatSheet does)
But there was so much more work to do, and some parsers were already getting compatibility issues from app updates, that we paused working on it.
I gained a lot more experience in macOS app dev, so I'm hoping to revisit this idea soon.
I'm also secretly hoping to start crafting wood flutes and composing music so that I don't have a need for remembering any hotkeys anymore.
Here's my first Romanian Kaval ^_^