⤴️ shortcuts
Last modified on June 01, 2022
This is my literate config for goku. It is a succint, powerful way to define keyboard shortcuts in macOS.
inspiration taken from these goku configs:
Interactive Keyboard Layout
Hover over a key to see where it leads!
,---,---,---,---,---,---,---,---,---,---,---,---,---,-------,
❘ ~ ❘ 1 ❘ 2 ❘ 3 ❘ 4 ❘ 5 ❘ 6 ❘ 7 ❘ 8 ❘ 9 ❘ 0 ❘ - ❘ + ❘ <- ❘
❘---’-,-’-,-’-,-’-,-’-,-’-,-’-,-’-,-’-,-’-,-’-,-’-,-’-,-----❘
❘ ->❘ ❘ Q ❘ W ❘ E ❘ R ❘ T ❘ Y ❘ U ❘ I ❘ O ❘ P ❘ [ ❘ ] ❘ \ ❘
❘-----’,--’,--’,--’,--’,--’,--’,--’,--’,--’,--’,--’,--’-----❘
❘ Caps ❘ A ❘ S ❘ D ❘ F ❘ G ❘ H ❘ J ❘ K ❘ L ❘ ; ❘ ’ ❘ Return ❘
❘------’-,-’-,-’-,-’-,-’-,-’-,-’-,-’-,-’-,-’-,-’-,-’--------❘
❘ Shift ❘ Z ❘ X ❘ C ❘ V ❘ B ❘ N ❘ M ❘ , ❘ . ❘ / ❘ Shift ❘
❘------,-’---’,--’,--’---’---’---’---’---’-,-’---’--,-------❘
❘ ctrl ❘ alt ❘cmd❘ ❘cmd| alt ❘ ❘
’------’------’---’----------------------’---’------’-------’
Guide
For more info on configuring Goku, see the tutorial.
Guide lifted from kaushikgopal. To understand better how modifiers work in karabiner, see the karabiner definition of mandatory and optional: karabiner modifiers documentation
Modifier | Meaning |
---|---|
! | mandatory (w/o modifier changes behavior) |
# | optional (but at least one necessary) |
C | left command |
T | left control |
O | left option |
S | left shift |
F | fn |
Q | right command |
W | right control |
E | right option |
R | right shift |
## | optional any |
!! | command + control + optional + shift (hyper) |
Profiles
{;;beginning bracket for whole data structure -- don't delete! :profiles { :Ketan { :default true :sim 500 ;; simultaneous_threshold_milliseconds (def: 50) ;; keys need to be pressed within this threshold to be considered simultaneous :delay 80 ;; to_delayed_action_delay_milliseconds (def: 500) ;; basically it means time after which the key press is count delayed :alone 500 ;; to_if_alone_timeout_milliseconds (def: 1000) ;; hold for 995s and single tap registered; hold for 1005s and seen as modifier :held 1000 ;; to_if_held_down_threshold_milliseconds (def: 500) ;; key is fired twice when 500 ms is elapsed (otherwise seen as a hold command) } } ;; profiles
Templates
:templates { :km "osascript -e 'tell application \"Keyboard Maestro Engine\" to do script \"%s\" with parameter \"%s\"'" ;; Removed the quotes around %s because it makes it not able to open files too :open "open '%s'" :smarturl "osascript ~/.dotfiles/open_url_smart.scpt '%s'" :openwith "open -a '%s' '%s'" :openhide "open '%s' -gj" :withsecret "source ~/.dotfiles/.secrets && %s" :withsecretsmarturl "source ~/.dotfiles/.secrets && osascript ~/.dotfiles/open_url_smart.scpt %s" :alfred "osascript -e 'tell application \"Alfred 4\" to run trigger \"%s\" in workflow \"%s\" with argument \"%s\"'" :wallpaper "osascript -e 'tell application \"Finder\" to set desktop picture to POSIX file \"%s\"'" :elisp "/usr/local/bin/emacsclient --eval '(progn (select-frame-set-input-focus (selected-frame))%s)'" } ;; templates
Layers & Simlayers
:layers { :tab-mode {:key :tab :afterup [{:set ["yabai-move-mode" 0]} {:set ["yabai-focus-mode" 0]} {:set ["yabai-display-mode" 0]} {:set ["chrome-movement-mode" 0]} {:set ["chrome-rearrange-tab-mode" 0]}]} :yabai-move-mode {:key :w :condi :tab-mode} :yabai-focus-mode {:key :f :condi :tab-mode} :yabai-display-mode {:key :d :condi :tab-mode} :chrome-movement-mode {:key :t :condi :tab-mode} ;;TODO make this work :chrome-history-mode {:key :g :condi :tab-mode} ;;TODO make this work :chrome-rearrange-tab-mode {:key :r :condi :tab-mode} :vim-mode {:key :z} :tilde-mode {:key :grave_accent_and_tilde} } :simlayers { :slash-mode {:key :slash} :q-key-mode {:key :q} :x-key-mode {:key :x} :jupyter-mode {:key :j} :o-key-mode {:key :o} :comma-mode {:key :comma} :wallpaper-mode {:key :w} }
Main
begin main
:main [{ :des "see karabiner.org for documentation.", :rules [
right cmd/option => previous app
Switch to the previous application with right command/option -- right command hides the current app, right option doesn’t.
[:right_command :right_command nil {:alone [:elisp "(set-transient-map doom-leader-map)"]}] [:right_option :right_option nil {:alone [:km "Previous Application"]}]
Links to “right cmd/option => previous app”
- Interactive Keyboard Layout (Interactive Keyboard Layout)
caps lock alone = escape, with other keys = ctrl
This is a really nice mapping -- it simultaneously makes hitting escape much easier, and
[:##caps_lock :left_control nil {:alone :escape}]
Links to “caps lock alone = escape, with other keys = ctrl”
- Interactive Keyboard Layout (Interactive Keyboard Layout)
function keys
Brightness controls (matching the default mappings in macOS):
[:f1 :display_brightness_decrement] [:f2 :display_brightness_increment]
Commands to access my various org-agenda views; looking at future tasks, looking at today’s tasks, and reviewing tasks that I already got done.
[:f3 [:elisp "(ketan0/look-ahead nil)"]] [:f4 [:elisp "(ketan0/new-agenda)"]] [:f4 [:elisp "(ketan0/weekly-review nil)"]]
Some spotify specific commands; these are nice to control spotify playback in the background, e.g. to adjust Spotify’s volume relative to the volume of a video I’m watching.
tell application "Spotify" set vol to sound volume set vol to vol - 10 if vol is less than 0 then set vol to 0 end if set the sound volume to vol end tell
tell application "Spotify" set vol to sound volume set vol to vol + 10 if vol is greater than 100 then set vol to 100 end if set the sound volume to vol end tell
[:f7 "osascript -e 'tell application \"Spotify\" to previous track'"] [:f8 "osascript -e 'tell application \"Spotify\" to playpause'"] [:f9 "osascript -e 'tell application \"Spotify\" to next track'"] [:!Sf11 "osascript ~/.dotfiles/decrease_music_volume.scpt"] [:!Sf12 "osascript ~/.dotfiles/increase_music_volume.scpt"]
Brightness controls (matching the default mappings in macOS):
[:f10 :mute] [:f11 :volume_decrement] [:f12 :volume_increment]
yabai-move-mode (tab + w + {hjkl})
Move the current window directionally in the yabai tiling setup.
:yabai-move-mode [:c [:yabai "window --grid 16:10:3:1:4:12"]] [:h [:yabai "window --warp west"]] [:j [:yabai "window --warp south"]] [:k [:yabai "window --warp north"]] [:l [:yabai "window --warp east"]] [:b [:yabai "space --balance" ]] [:0 [:yabai "window --opacity 0.0"]] [:1 [:yabai "window --opacity 0.1"]] [:2 [:yabai "window --opacity 0.2"]] [:3 [:yabai "window --opacity 0.3"]] [:4 [:yabai "window --opacity 0.4"]] [:5 [:yabai "window --opacity 0.5"]] [:6 [:yabai "window --opacity 0.6"]] [:7 [:yabai "window --opacity 0.7"]] [:8 [:yabai "window --opacity 0.8"]] [:9 [:yabai "window --opacity 0.9"]] [:grave_accent_and_tilde [:yabai "window --opacity 1.0"]] [:s [:yabai "window --toggle split"]]
yabai-focus-mode (tab + f + {hjkl})
Move focus to the left/top/bottom/right of the current window.
:yabai-focus-mode [:g [:yabai "space --focus prev"]] [:h [:yabai "window --focus west"]] [:j [:yabai "window --focus south"]] [:k [:yabai "window --focus north"]] [:l [:yabai "window --focus east"]] [:semicolon [:yabai "space --focus next"]]
yabai-display-mode (currently unused)
:yabai-display-mode [:h [:yabai "display --focus prev"]] [:l [:yabai "display --focus next"]]
yabai-adjust-mode (tab + d + {hl})
:yabai-adjust-mode [:h [:yabai "window --ratio rel:-0.02"]] [:j [:yabai "window --ratio rel:0.02"]] [:k [:yabai "window --ratio rel:-0.02"]] [:l [:yabai "window --ratio rel:0.02"]]
chrome-history-mode (tab + g + {hl})
Move backward/forward in Chrome history.
:chrome-history-mode [:h :!Copen_bracket] [:l :!Cclose_bracket]
chrome-movement-mode (tab + t + {hl})
Move to the tab left/right of the current tab.
:chrome-movement-mode [:h :!TStab] [:l :!Ttab]
chrome-rearrange-tab-mode (tab + r + {hl})
Move current tab left/right. Need this Chrome extension for this to work.
:chrome-rearrange-tab-mode [:h :!TSleft_arrow] [:l :!TSright_arrow]
tab-mode (tab)
Mostly for opening apps, and some other convenient shortcuts like toggling dark mode and emojis.
Toggle system dark mode, as well as the emacs theme. (See ketan0/responsive-theme for details)
tell application "System Events" tell appearance preferences set dark mode to not dark mode do shell script "/opt/homebrew/bin/emacsclient --eval '(load-theme (ketan0/responsive-theme) t)'" end tell end tell
:tab-mode [:spacebar :!CTspacebar] ;; open emoji picker [:return_or_enter [:yabai "window --toggle float"]] [:comma [:km "Open Messenger" "hide"]] [:3 "osascript ~/.dotfiles/toggle_dark_mode.scpt"] [:4 [:km "Open Finder"]] [:a [:km "Open Music" "hide"]] [:x [:km "Open Chrome" "hide"]] [:c [:km "Open Safari" "hide"]] [:k [:km "Open Keyboard Maestro" "hide"]] [:e [:km "Open Emacs" "hide"]] [:i [:km "Open iTerm" "hide"]] [:m [:km "Open Messages" "hide"]] [:s [:km "Open Spotify" "hide"]] ;; [:n [:km "Open Neo4j" "hide"]] [:v [:km "Open Zoom" "hide"]] ;; [:q [:km "Open Qutebrowser"]] ;; [:x [:km "Open Xcode"]] ;; [:w [:km "Open Word"]]
q-key-mode (q)
:q-key-mode [:grave_accent_and_tilde [:km "Open Stickies"]] [:a [:km "Open Music"]] [:x [:km "Open Chrome"]] [:s [:km "Open Spotify"]] [:c [:km "Open Safari"]] [:k [:km "Open Keyboard Maestro"]] [:e [:km "Open Emacs"]] [:i [:km "Open iTerm"]] [:m [:km "Open Messages"]] [:comma [:km "Open Messenger"]] [:n [:km "Open Neo4j"]] [:v [:km "Open Zoom"]]
x-key-mode (x)
app = Application.currentApplication() app.includeStandardAdditions = true const currentTab = Application('Safari').windows[0].currentTab const url = currentTab.url() const name = currentTab.name() app.openLocation(`org-protocol://roam-ref?template=r&ref=${encodeURIComponent(url)}&title=${encodeURIComponent(name)}`)
:x-key-mode [:a [:elisp "(ketan0/new-agenda)"]] [:c "screencapture -ic"] [:w [:elisp "(ketan0/look-ahead nil)"]] [:s [:elisp "(+org-capture/open-frame nil \"s\")"]] [:t [:elisp "(+org-capture/open-frame nil \"t\")"]] [:d [:elisp "(+org-capture/open-frame nil \"d\")"]] [:i [:elisp "(+org-capture/open-frame nil \"i\")"]] [:g "osascript -l JavaScript ~/.dotfiles/org_roam_capture.scpt"] ;; create new org-roam note [:spacebar [:elisp "(+org-capture/open-frame)"]] [:r [:elisp "(org-roam-node-random)"]] [:j [:elisp "(org-journal-new-entry nil)"]]
tilde-mode
Using this mode to “focus” / “unfocus” with the Focus app for MacOS.
Also, toggle Do Not Disturb.
my setDoNoDisturbTo() -- https://github.com/sindresorhus/do-not-disturb/issues/9 on setDoNoDisturbTo() set checkDNDstatusCMD to ¬ {"defaults read", space, ¬ "com.apple.ncprefs.plist", ¬ space, "dnd_status"} as string set statusOfDND to ¬ (do shell script checkDNDstatusCMD) ¬ as boolean if not statusOfDND display notification "Turning on Do Not Disturb..." set OnOffData to "62706C6973743030D60102030405060708080A08085B646E644D6972726F7265645F100F646E64446973706C6179536C6565705F101E72657065617465644661636574696D6543616C6C73427265616B73444E445875736572507265665E646E64446973706C61794C6F636B5F10136661636574696D6543616E427265616B444E44090808D30B0C0D070F1057656E61626C6564546461746556726561736F6E093341C2B41C4FC9D3891001080808152133545D6C828384858C9499A0A1AAACAD00000000000001010000000000000013000000000000000000000000000000AE" else set OnOffData to "62706C6973743030D5010203040506070707075B646E644D6972726F7265645F100F646E64446973706C6179536C6565705F101E72657065617465644661636574696D6543616C6C73427265616B73444E445E646E64446973706C61794C6F636B5F10136661636574696D6543616E427265616B444E44090808080808131F3152617778797A7B0000000000000101000000000000000B0000000000000000000000000000007C" end if set changeDNDstatusCMD to ¬ {"defaults write", space, ¬ "com.apple.ncprefs.plist", ¬ space, "dnd_prefs -data", space, OnOffData, ¬ space, "&&", ¬ "defaults write", space, ¬ "com.apple.ncprefs.plist", ¬ space, "dnd_status ", not statusOfDND, space, ¬ "&& killall usernoted && killall ControlCenter"} as string do shell script changeDNDstatusCMD if statusOfDND display notification "Turned off Do Not Disturb." end if end setDoNoDisturbTo
:tilde-mode [:d "osascript ~/.dotfiles/toggle_dnd.scpt"] [:f [:openhide "focus://focus?minutes=60"]] [:t [:openhide "focus://toggle"]] [:u [:openhide "focus://unfocus"]] [:comma [:open "focus://preferences"]]
comma-mode
Just some like random stuff. Open notes, zoom links, twitter, typing tests.
Open History Trends Unlimited chrome extension
tell application "Google Chrome" to open location "chrome-extension://pnmchffiealhkdloeffcdnbgdnedheme/search.html"
Open a URL, but only if it’s not already a tab. If it’s a tab, then go to that tab.
on run (clp) -- given "block" argument on command line, block certain sites from 9am to 9pm if clp's length is 2 and clp's item 2 = "block" tell (current date) to set currentHour to (its hours) if currentHour >= 9 and currentHour < 21 display notification "Blocked!" return end if end if tell application "Safari" repeat with w in windows set i to 1 repeat with t in tabs of w if URL of t starts with clp's item 1 then set current tab of w to t -- set active tab index of w to i tell w set index to 1 end tell -- delay 0.05 -- do shell script "open -a Safari" tell application "System Events" perform action "AXRaise" of front window of application process "Safari" end tell activate return end if set i to i + 1 end repeat end repeat open location clp's item 1 activate end tell end run
Check my calendar; if there’s an event with a zoom link, open the zoom link.
use script "CalendarLib EC" version "1.1.5" use scripting additions use framework "Foundation" property NSRegularExpressionCaseInsensitive : a reference to 1 property NSRegularExpression : a reference to current application's NSRegularExpression -- fetch properties of events for next week set now to current date set theStore to fetch store set theCal to fetch calendar "Calendar" cal type cal exchange event store theStore -- change to suit set theEvents to fetch events starting date now ending date now searching cals {theCal} event store theStore -- get events that are occurring currently if length of theEvents is 0 display notification "No events currently!" return end if set theEvent to (item 1 of theEvents) set theEventRecord to event info for event theEvent set theEventNotes to (get event_description of theEventRecord) if theEventNotes is missing value display notification "Couldn't find the zoom link. Opening calendar..." tell application "Calendar" to activate return end if set theNSStringSample to current application's NSString's stringWithString:theEventNotes set passcodePattern to "Password:(?:\\s|\\n)+(\\d{6})" set thePasscodeRegEx to NSRegularExpression's regularExpressionWithPattern:passcodePattern options:NSRegularExpressionCaseInsensitive |error|:(missing value) set aMatch to thePasscodeRegEx's firstMatchInString:theNSStringSample options:0 range:[0, theNSStringSample's |length|] if aMatch is not missing value then set partRange to (aMatch's rangeAtIndex:1) as record set passcode to (theNSStringSample's substringWithRange:partRange) as text set the clipboard to passcode -- copy the passcode in case zoom prompts for it else display notification "Couldn't find the passcode." end if set zoomLinkPattern to "https:\\/\\/(?:.+\\.)?zoom\\.us\\/j\\/(\\d+)\\?pwd=([a-zA-Z0-9]+)" set theZoomLinkRegEx to NSRegularExpression's regularExpressionWithPattern:zoomLinkPattern options:NSRegularExpressionCaseInsensitive |error|:(missing value) set aMatch to theZoomLinkRegEx's firstMatchInString:theNSStringSample options:0 range:[0, theNSStringSample's |length|] if aMatch is not missing value then set partRange to (aMatch's rangeAtIndex:1) as record set zoomConfNo to (theNSStringSample's substringWithRange:partRange) as text set partRange to (aMatch's rangeAtIndex:2) as record set zoomPwd to (theNSStringSample's substringWithRange:partRange) as text display notification "Starting zoom..." open location "zoommtg://zoom.us/join?confno=" & zoomConfno & "&pwd=" & zoomPwd else display notification "Couldn't find the zoom link. Opening calendar..." tell application "Calendar" to activate end if
I really like Safari, but sometimes need to use Chrome for various extensions etc. Solution: have Safari => Chrome shortcut.
tell application "Safari" set theURL to URL of current tab of window 1 tell application "Google Chrome" to open location theURL end tell
Download a video from youtube with one keyboard shortcut, using the wonderful youtube-dl
.
tell application "Safari" set theURL to URL of current tab of window 1 display notification "/opt/homebrew/bin/youtube-dl -o \"~/Downloads/%(title)s.%(ext)s\" '" & theURL & "'" do shell script "/opt/homebrew/bin/youtube-dl -o \"~/Downloads/%(title)s.%(ext)s\" '" & theURL & "'" end tell
:comma-mode [:1 [:withsecretsmarturl "$PSYCH_LECTURE_LINK"]] [:3 [:withsecret "open $PAC_PROJECT_ZOOM_LINK"]] ;; add title bar to frame ;; (I use the --with-no-title-bars patch for emacs-mac, but sometimes I like the title bar) [:a [:elisp "(setq mac-use-title-bar t)(setq ketan0/old-frame (selected-frame)) (make-frame)(delete-frame ketan0/old-frame)"]] [:b "osascript ~/.dotfiles/open_in_chrome.scpt"] [:c [:open "/Users/ketanagrawal/garden-simple/org/private/capture.org"]] [:d [:open "https://drive.google.com/drive/my-drive"]] [:o [:open "http://doc.new"]] ;; new google doc [:e [:open "/Users/ketanagrawal/.dotfiles/doom.d/config.el"]] [:f [:smarturl "https://www.keyhero.com/free-typing-test/" "block"]] ;; [:h [:km "Github => Emacs"]] [:h "osascript /Users/ketanagrawal/.dotfiles/open_chrome_history.scpt"] [:i [:smarturl "https://www.keyhero.com/typing-instant-death/" "block"]] [:j [:smarturl "http://localhost:8888"]] [:k [:smarturl "https://laboratory.ketan.me"]] [:l "osascript /Users/ketanagrawal/.dotfiles/open_current_zoom_link.scpt"] [:m [:smarturl "https://outlook.office.com/" "block"]] [:n [:openwith "Google Chrome" "https://www.netflix.com/title/80199128"]] [:u "osascript /Users/ketanagrawal/.dotfiles/download_video.scpt"] [:p [:withsecretsmarturl "$PAC_PROGRESS_DOC_LINK"]] [:q [:withsecretsmarturl "$HCI_PROGRESS_DOC_LINK"]] [:t [:smarturl "https://twitter.com/i/bookmarks" "block"]] [:r [:open "/Users/ketanagrawal/garden-simple/org/private/todos.org"]] [:s [:open "/Users/ketanagrawal/.dotfiles/karabiner.org"]] ;; [:v [:open "https://healthy.verily.com/"]] ;; covid testing [:v [:open "https://home.color.com/sign-in?next=%2Fcovid%2Factivation"]] ;; [:v [:openwith "Emacs" "/Users/ketanagrawal/Dropbox/Apps/GoodNotes 5/GoodNotes/vision.pdf"]] [:y [:openwith "Emacs" "/Users/ketanagrawal/.dotfiles/yabairc"]] [:z [:withsecret "open $MY_ZOOM_LINK"]]
wallpaper-mode
:wallpaper-mode [:g [:wallpaper "/System/Library/Desktop Pictures/Solar Gradients.heic"]] [:s [:wallpaper "/Users/ketanagrawal/Desktop/wallpapers/simple-subtle-abstract-dark-minimalism-4k-u9.jpg"]] [:x [:wallpaper "/Users/ketanagrawal/Desktop/wallpapers/paint_colorful_overlay_139992_1440x900.jpg"]] [:y [:wallpaper "/Users/ketanagrawal/Desktop/wallpapers/background_paint_stains_light_76087_1440x900.jpg"]]
vim-mode (z)
These are super, super useful for navigating text fields, search autosuggestions, etc. Essentially, z+{hjkl}
bindings are replacing the arrow keys, but in a much more convenient (and vim-like) location. z+{bw}
are simulating the word-wise motions in vim. z+delete
isn’t necessarily vim-esque, but it’s quite useful for deleting typos (much easier to just redo the word, lots of times.) Whenever I use another machine I find myself missing these a lot.
:vim-mode [:##h :left_arrow] ;; hjkl navigation everywhere + Shift [:##j :down_arrow] [:##k :up_arrow] [:##l :right_arrow] [:##b :!Oleft_arrow] [:##w :!Oright_arrow] [:delete_or_backspace :!Odelete_or_backspace]
end main
]}] ;;end main
Applications
:applications [ :Emacs ["^org\\.gnu\\.Emacs$"] :Chrome ["^com\\.google\\.Chrome$", "^org\\.chromium\\.Chromium$", "^com\\.google\\.Chrome\\.canary$"] ] } ;;ending bracket for whole data structure -- don't delete!
Links to “⤴️ shortcuts”
👾 programming
Hey! These are some snippets of various languages that can be run straight out of org mode.
connected to a lot of these things is my goku (karabiner) config.
print('Hello, world!')
Hello, world!
Reduce friction to getting to the things you really want.
Talk about ⤴️ shortcuts -- want to get shortcuts to things that I want to encourage.
You will take the path of least resistance, at least in some ways.
Good rule of thumb.
keyboards
Despite spinning a lot of cycles thinking about ⤴️ shortcuts and the like, I’ve never thought too hard about this input device itself -- the keyboard.
I’ve been perfectly happy typing away on Macbook keyboards for the last 15+ years (having used a 2015 MBA and 2021 MBP, I managed to completely avoid the butterfly keyboard generation, thank god.) But now, I’ve been asked by my future employer what kind of keyboard I want, so here’s the space I’ll think about that in!
After reading the wiki of r/MechanicalKeyboards, I am very intrigued. I might have to go find a Fry’s or something and test out some keyboards.
WASD keyboards in Fremont -- those keyboards look sooooo slick. wowowow. might have to hit that up for personal use 😉
I could imagine making some sort of symsys-y design on my keyboard....that would be really cool. I’d have to think a bit harder about what is meaningful to me.
....also the all-black keyboard is a fucking vibe tho.
transactivos (Conversational threads > ⤴️ shortcuts as a worm that has eaten into my habits)
Not sure whether they’re good or bad, but they’re powerful, that’s all I’ll say. Reducing the friction to certain actions that I find favorable, to the point where I do them subconsciously, is powerful.