Skip to content

Latest commit

 

History

History
1860 lines (1716 loc) · 58.3 KB

modifications.org

File metadata and controls

1860 lines (1716 loc) · 58.3 KB

Pablo’s Karabiner modifications

Introduction

Steps to try my layout:

  1. If you have a normal keyboard, proceed to step (2). If you have a special keyboard like the Moonlandeer or the Kinesis Advantage, use their configuration software to map the thumb keys as follows:
    • left-hand thumb keys:
      • left key: left control
      • middle key: left option
      • right key: left command
    • right-hand thumb keys:
      • left key: spacebar
      • middle key: right command
      • right key: right option
  2. Install Karabiner-Elements.
  3. Install goku.
  4. Clone this repo and load the config in dotfiles/karabiner/karabiner.edn.

Note: the karabiner.edn file is generated by “tangling” the code blocks in the modifications.org file, which is the file you are currently reading. If you use Emacs and would like to play around with my config, you may want to edit this file and tangle it, instead of editing karabiner.edn directly.

Table of contents

Profiles

It seems that there is no way to set the relevant delay for a simlayer, so the only alternative is to recreate the spacebar simlayer functionality as a series of individual modifications. Then the delay would, I believe, be controlled by the sim variable (since spacebar + each of the keys it currently modifies in the simlayer would be considered simultaneous key presses).

{
:profiles {
           :Default {:default true

alone

alone (to_if_alone_timeout_miliseconds): if a key is held for at least this long, releasing it will not trigger its alone mapping.

Example:

{:des "caps -> escape (alone) left_option (held)"
 :rules [
         [:##caps_lock :left_option nil {:alone :escape}]
         ]}

If caps_lock is held for at least 100 miliseconds, it will not trigger escape.

:alone   200

held

held (to_if_held_down_threshold_miliseconds): if a key is held for at least this long, it will trigger its held mapping.

:held    350

delay

delay (to_delayed_action_delay_miliseconds): for rules defining some behavior when a succession of two keys is pressed, the second key will trigger the behavior if pressed within this many miliseconds after the first key. I haven’t defined any such rules, so the value below has no effect on my configuration.

:delay   300

sim

sim (simultaneous_threshold_miliseconds): keys need to be pressed within these many miliseconds to be considered simultaneous. This doesn’t apply to modifier keys, but to “normal” keys (e.g. q + k to launch Karabiner).

:sim   150

simlayer threshold

:simlayer-threshold 250}} ; default

Tos

:tos {
      ;; macOS
      :⇧ {:key :left_shift}
      :⌘ {:key :left_command}
      :⌥ {:key :left_option}
      :⌃ {:key :left_control}
      :🌐 {:key :fn}
      :⌘⌃ {:key :Cleft_control}

      ;; Emacs
      :S- {:key :left_shift} ; S
      :A- {:key :right_command} ; Q
      :C- {:key :left_control} ; T
      :H- {:key :left_command} ; C
      :M- {:key :left_option} ; O
      :s- {:key :right_control} ; W
      :A-C- {:key :!Qleft_control}
      :A-H- {:key :!Qleft_command}
      :A-M- {:key :!Qleft_option}
      :A-s- {:key :!Qright_control}

      ;; symbols
      :exclamation_mark {:key :!S1}
      :at_sign {:key :!S2}
      :number_sign {:key :!S3}
      :dollar_sign {:key :!S4}
      :percent_sign {:key :!S5}
      :caret {:key :!S6}
      :ampersand {:key :!S7}
      :asterisk {:key :!S8}
      :open_parenthesis {:key :!S9}
      :close_parenthesis {:key :!S0}
      :underscore {:key :!Shyphen}
      :plus_sign {:key :!Sequal_sign}
      :open_brace {:key :!Sopen_bracket}
      :close_brace {:key :!Sclose_bracket}
      :vertical_bar {:key :!Sbackslash}
      :double_quote {:key :!Squote}
      :open_double_quote {:key :!Eopen_bracket}
      :close_double_quote {:key :!SEopen_bracket}
      :open_single_quote {:key :!Eclose_bracket}
      :close_single_quote {:key :!SEclose_bracket}
      :tilde {:key :!Sgrave_accent_and_tilde}
      :en_dash {:key :!Ehyphen}
      :em_dash {:key :!SEhyphen}

      ;; diacritics
      ;; note that many of the mappings below require ABC - Extended as the macOS input source
      :overdot {:key :!Ew}
      :underdot {:key :!Ex}
      :accute_accent {:key :!Ee}
      :double_acute_accent {:key :!Ej}
      :grave_accent {:key :!Egrave_accent_and_tilde}
      :umlaut {:key :!Eu}
      :undercomma {:key :!Ep}
      :underbar {:key :!Eh}
      :macron {:key :!Ea}
      :breve {:key :!Eb}
      :hook {:key :!Ez}
      :horn {:key :!Ei}
      :circumflex {:key :!E6}
      :cedilla {:key :!Ec}
      :overring {:key :!Ek}
      :stroke {:key :!El}
      :caron {:key :!Ev}
      :ogonek {:key :!Em}
      :tilde_accent {:key :!En}

      ;; “special” chars
      :ø {:key :!Eo}
      :œ {:key :!Eq}
      :ß {:key :!Es}
      :ð {:key :!Ed}
      :þ {:key :!Et}
      :¡ {:key :!E1}
      :¿ {:key :!ESslash}
      :« {:key :!Ebackslash}
      :» {:key :!SEbackslash}
      :• {:key :!O8}
      :£ {:key :!E3}
      :€ {:key :!ES2}
      :… {:key :!Esemicolon}

      ;; math
      := {:key :equal_sign}
      :+ {:key :!Sequal_sign}
      :≠ {:key :!Eequal_sign}
      :÷ {:key :!Eslash}
      :± {:key :!ESequal_sign}
      :≤ {:key :!Ecomma}
      :≥ {:key :!Eperiod}
      }

Modifiers

:modifiers {
            ;; macOS
            :⇧ [:left_shift]
            :⌘ [:left_command]
            :⌥ [:left_option]
            :⌃ [:left_control]
            :⇧⌘ [:left_shift :left_command]
            :⇧⌥ [:left_shift :left_option]
            :⇧⌃ [:left_shift :left_control]
            :⌘⌥ [:left_command :left_option]
            :⌘⌃ [:left_command :left_control]
            :⌥⌃ [:left_option :left_control]
            :⇧⌘⌥ [:left_shift :left_command :left_option]
            :⇧⌘⌃ [:left_shift :left_command :left_control]
            :⇧⌥⌃ [:left_shift :left_option :left_control]
            :⌘⌥⌃ [:left_command :left_option :left_control]
            :⇧⌘⌥⌃ [:left_shift :left_command :left_option :left_control]

            ;; Emacs
            :S- [:left_shift]
            :A- [:right_command]
            :C- [:left_control]
            :H- [:left_command]
            :M- [:left_option]
            :s- [:right_control]
            :A-C- [:right_command :left_control]
            :A-H- [:right_command :left_command]
            :A-M- [:right_command :left_option]
            :A-s- [:right_command :right_control]
            :C-H- [:left_control :left_command]
            :C-M- [:left_control :left_option]
            :C-s- [:left_control :right_control]
            :H-M- [:left_command :left_option]
            :H-s- [:left_command :right_control]
            :M-s- [:left_option :right_control]
            :A-C-H- [:right_command :left_control :left_command]
            :A-C-M- [:right_command :left_control :left_option]
            :A-C-s- [:right_command :left_control :right_control]
            :A-H-M- [:right_command :left_command :left_option]
            :A-H-s- [:right_command :left_command :right_control]
            :A-M-s- [:right_command :left_option :right_control]
            :C-H-M- [:left_control :left_command :left_option]
            :C-H-s- [:left_control :left_command :right_control]
            :C-M-s- [:left_control :left_option :right_control]
            :H-M-s- [:left_command :left_option :right_control]
            :A-C-H-M- [:right_command :left_control :left_command :left_option]
            :A-C-H-s- [:right_command :left_control :left_command :right_control]
            :A-C-M-s- [:right_control :left_control :right_command :left_option]
            :A-H-M-s- [:right_command :left_command :left_option :right_control]
            :C-H-M-s- [:left_control :left_command :left_option :right_control]
            :A-C-H-M-s- [:left_control :left_command :left_option :right_control :right_command]
            }

Applications

:applications {
               :anki ["net.ankiweb.dtop"]
               :chrome ["com.google.Chrome"]
               :emacs ["org.gnu.Emacs"]
               :firefox ["org.mozilla.firefox"]
               :safari ["com.apple.Safari"]
               :steam [:paths ".*/Application Support/Steam.*"]
               }

Devices

:devices {
         :corne [{:vendor_id 7504}]
         :moonlander [{:vendor_id 12951}]
         }

Layers

:layers {
         :k-mode {:key :quote :condi :chrome}
         }

Simlayers

:simlayers {
            :b-mode {:key :b}
            :f-mode {:key :f}
            :j-mode {:key :j}
            :k-mode {:key :k}
            :m-mode {:key :m}
            :p-mode {:key :p}
            :q-mode {:key :q}
            :v-mode {:key :v}
            :x-mode {:key :x :condi :emacs}
            :y-mode {:key :y}
            :z-mode {:key :z}
            :comma-mode {:key :comma :condi :emacs}
            :period-mode {:key :period}
            :semicolon-mode {:key :semicolon}
            :slash-mode {:key :slash}
            }

Templates

:templates {:alfred "osascript -e 'tell application \"Alfred 4\" to run trigger \"%s\" in workflow \"%s\" with argument \"%s\"'"
            :km "osascript -e 'tell application \"Keyboard Maestro Engine\" to do script \"%s\"'"
            :open "open \"%s\""
            :insert "~/Library/CloudStorage/Dropbox/dotfiles/bin/char_input \"%s\""
            }

Note that the :insert template inserts an arbitrary character by calling a bash script that in turn calls an AppleScript. There may be a simpler way of doing this, but that’s how I managed to do it. Here are the scripts I’m using:

#!/bin/bash
osascript $HOME/Library/Scripts/inputCharacter.scpt "$1"
on run argv
    set the clipboard to (item 1 of argv)
    tell application "System Events"
        keystroke "v" using {command down}
    end tell
end run

Main

:main [

individual bindings

caps_lock

{:des "Disable caps_lock"
 :rules [
         [:caps_lock :vk_none]
         ]}

left_control

{:des "Emacs: left_control → C-g (alone) M- (held)"
 :rules [
         [:!Ch {:modi :A-H-M-s- :key :h} :emacs] ; circumvent macOS ⌘h
         [:!CQh {:modi :A-C-H-s- :key :h} :emacs] ; circumvent macOS ⌘⌥h
         [:##left_control :M- [:!steam :emacs] {:alone {:modi :C- :key :g}}]
         ]}
{:des "Outside Emacs: left_control → escape (alone) | ⌥ (held)"
 :rules [
         [:##left_control :⌥ [:!steam :!emacs] {:alone :escape}]
         ]}

left_option

{:des "Emacs: left_option → toggle tabs/windows (alone) | S- (held)"
 :rules [
         [:##left_option :S- :emacs {:alone :return_or_enter}]
         ]}
{:des "Outside Emacs: left_option → toggle tabs/windows (alone) | ⇧ (held)"
 :rules [
         [:##left_option :⇧ :!emacs {:alone :return_or_enter}]
         ]}

Since the same key now triggers shift and return, we can no longer trigger shift + return. So we define a special binding to trigger this key event via shift + spacebar (the latter is triggered by right_command, as defined in a section below).

{:des "left_option + right_command → ⇧ + enter"
 :rules [
         [:!Sright_command {:modi :⇧ :key :return_or_enter}]
         ]}

Since the same key now triggers shift and return, we can no longer trigger shift + return. So we define a special binding to trigger this key event via shift + spacebar (the latter is triggered by right_command, as defined in a section below).

{:des "left_option + right_command → ⇧ + enter"
 :rules [
         [:!Sright_command {:modi :⇧ :key :return_or_enter}]
         ]}

left_command

When tapped, the left_command key toggles between the two most recent windows (in Emacs) or tabs (in a browser). In Emacs, I do this by binding C-H-0 to my custom command window-extras-switch-to-last-window. In Chrome, I do this by installing the extensions CLUT (Chrome) and Last Tab (Firefox) and configuring ⌘⌃0 as the keyboard shortcut for each.

{:des "Emacs: left_command → other window (alone) | H- (held)"
 :rules [
         [:##left_command :H- :emacs {:alone {:modi :C-H- :key :0}}]
         ]}
{:des "Outsie Emacs: left_command → other tab (alone) | ⌘ (held)"
 :rules [
         [:##left_command :⌘ :!emacs {:alone {:modi :⌘⌃ :key :0}}]
         ]}

spacebar

The spacebar triggers control when held and toggles between apps when tapped. In addition, if the spacebar is tapped while the command key is held, it will toggle instead between buffers (in Emacs) or windows (outside Emacs).

{:des "Emacs: spacebar → C- (held) | ⌘tab (alone)"
 :rules [
         [:!Cspacebar {:modi :A-H-M-s- :key :spacebar} :emacs] ; files-extras-switch-to-alternate-buffer
         [:##spacebar :C- :emacs {:alone {:modi :⌘ :key :tab}}]
         ]}
{:des "Outside Emacs: spacebar → ⌃ (held) | ⌘tab (alone)"
 :rules [
         [:!Cspacebar {:modi :⌘ :key :grave_accent_and_tilde} :!emacs] ; move focus to next window
         [:##spacebar :⌃ :!emacs {:alone {:modi :⌘ :key :tab}}]
         ]}

right_command

{:des "Emacs: right_command + left_command → A-H- (held) "
:rules [
        [[:right_command :left_command] :A-H- :emacs {:alone {:modi :A- :key :spacebar}}]
        ]}
{:des "Emacs: right_command + left_shift → A-"
:rules [
        [[:right_command :left_option] :A- :emacs]
        ]}
{:des "Emacs: right_command + spacebar → A-C-"
:rules [
        [[:right_command :spacebar] :A-C- :emacs]
        ]}
{:des "Emacs: right_command + left_control → A-M-"
:rules [
        [[:right_command :left_control] :A-M- :emacs]
        ]}
{:des "Emacs: right_command + right_option → A-s-"
:rules [
        [[:right_command :right_option] :A-s- :emacs]
        ]}
{:des "Emacs: right_command → spacebar"
 :rules [
         [:##right_command :spacebar :emacs]
         ]}
{:des "Outside Emacs: right_command → spacebar"
 :rules [
         [:##right_command :spacebar :!emacs]
         ]}

right_option

{:des "Emacs: right_option → other window (alone) | s- (held)"
 :rules [
         [:##right_option :s- :emacs {:alone :tab}]
         ]}
{:des "outside Emacs: right_option → other window (alone) | ⌥ (held)"
 :rules [
         [:##right_option :⌥ :!emacs {:alone :tab}]
         ]}

mouse

My Logitech MX Anywhere 3S mouse does not have a tilting wheel, so I remap the side buttons to trigger the relevant tab navigation shortcuts when pressed while the shift key is held. Note that for these “extra” mouse buttons to be detected by Karabiner, you may need to enable the relevant device in the “Devices” section.

{:des "left_shift + side mouse buttons → navigate open tabs"
 :rules [
         [{:pkey :button4 :modi :left_shift} :!COleft_arrow]
         [{:pkey :button5 :modi :left_shift} :!COright_arrow]
         ]}

layers

b-mode

  • The right-hand top row keys control window placement, via Emacs Lisp commands in Emacs, or via Rectangle otherwise.
  • The right-hand home row keys control playback.
    • l triggers a Keyboard Maestro script that runs the AppleScript included below.
  • The right-hand bottom row keys control volume.
  • h and n control dictation and narration, respectively.
    • The keyboard shortcuts need to be set under Settings > Keyboard > Dictation > Shortcut (for dictation) and Settings > Accessibility > Spoken content > Speak selection (for narration).
{:des "b-mode (media controls, window sizing)"
 :rules [:b-mode
         [:u {:modi :C-H- :key :u} :emacs] ; frame-extras-left-half
         [:u {:modi :⇧⌘⌥⌃ :key :u}] ; Rectangle, left half
         [:p {:modi :C-H- :key :p} :emacs] ; frame-extras-right-half
         [:p {:modi :⇧⌘⌥⌃ :key :p}] ; Rectangle, right half
         [:i {:modi :C-H- :key :i} :emacs] ; frame-extras-maximize-frame
         [:i {:modi :⇧⌘⌥⌃ :key :i}] ; Rectangle, maximize
         [:o {:modi :⇧⌘⌥⌃ :key :o}] ; Rectangle, center
         [:j :rewind]
         [:x {:modi :⇧⌘⌃ :key :3}] ; Copy picture of screen to the clipboard
         [:k :play_or_pause]
         [:semicolon :fast_forward]
         [:comma :volume_increment]
         [:period :volume_decrement]
         [:m :mute]
         [:c {:modi :C-M-s- :key :c} :emacs] ; connect to bluetooth device
         [:g {:modi :C-M-s- :key :g} :emacs] ; toggle langs
         [:h {:modi :⇧⌘⌥⌃ :key :0}] ; dictation
         [:n {:modi :⇧⌘⌥⌃ :key :1}] ; narration (Settings > Accessibility > Spoken content > Speak selection)
         ]}
using terms from application "Spotify"
  if player state of application "Spotify" is paused then
    tell application "Spotify" to play
  else
    tell application "Spotify" to pause
  end if
end using terms from

f-mode

{:des "f-mode (special chars)"
 :rules [:f-mode
         [:d :ð]
         [:e :…]
         [:i :¡]
         [:o :ø]
         [:p :£]
         [:q :œ]
         [:r :€]
         [:s :ß]
         [:t :þ]
         [:u :•]
         [:slash :¿]
         [:comma :«]
         [:period :»]
         ]
 }

j-mode

{:des "j-mode (deletion)"
 :rules [:j-mode
         [:a {:modi :C-H-M- :key :a} :emacs]
         [:!Wa {:modi :C-H-M-s- :key :a} :emacs]
         [:!WQa {:modi :A-C-H-M-s- :key :a} :emacs]
         [:s {:modi :C-H-M- :key :s} :emacs]
         [:s :delete_or_backspace :!emacs]
         [:d {:modi :C-H-M- :key :d} :emacs]
         [:d :delete_forward :!emacs]
         [:f {:modi :C-H-M- :key :f} :emacs]
         [:!Wf {:modi :C-H-M-s- :key :f} :emacs]
         [:!WQf {:modi :A-C-H-M-s- :key :f} :emacs]
         [:q {:modi :C-H-M- :key :q} :emacs]
         [:!Wq {:modi :C-H-M-s- :key :q} :emacs]
         [:!WQq {:modi :A-C-H-M-s- :key :q} :emacs]
         [:q {:modi :⌥ :key :delete_or_backspace} :!emacs]
         [:w {:modi :C-H-M- :key :w} :emacs]
         [:!Ww {:modi :C-H-M-s- :key :w} :emacs]
         [:!WQw {:modi :A-C-H-M-s- :key :w} :emacs]
         [:w {:modi :⌘ :key :delete_or_backspace} :!emacs]
         [:e {:modi :C-H-M- :key :e} :emacs]
         [:!We {:modi :C-H-M-s- :key :e} :emacs]
         [:!WQe {:modi :A-C-H-M-s- :key :e} :emacs]
         [:e {:modi :⌃ :key :k} :!emacs]
         [:r {:modi :C-H-M- :key :r} :emacs]
         [:!Wr {:modi :C-H-M-s- :key :r} :emacs]
         [:!WQr {:modi :A-C-H-M-s- :key :r} :emacs]
         [:r {:modi :⌥ :key :delete_forward} :!emacs]
         [:z {:modi :C-H-M- :key :z} :emacs]
         [:!Wz {:modi :C-H-M-s- :key :z} :emacs]
         [:!WQz {:modi :A-C-H-M-s- :key :z} :emacs]
         [:z {:modi :⌘ :key :delete_or_backspace} :!emacs]
         [:x {:modi :C-H-M- :key :x} :emacs]
         [:!Wx {:modi :C-H-M-s- :key :x} :emacs]
         [:!WQx {:modi :A-C-H-M-s- :key :x} :emacs]
         [:x {:modi :⌘⌥ :key :left_arrow} :!emacs]
         [:c {:modi :C-H-M- :key :c} :emacs]
         [:!Wc {:modi :C-H-M-s- :key :c} :emacs]
         [:!WQc {:modi :A-C-H-M-s- :key :c} :emacs]
         [:c {:modi :⌘⌥ :key :right_arrow} :!emacs]
         [:v {:modi :C-H-M- :key :v} :emacs]
         [:!Wv {:modi :C-H-M-s- :key :v} :emacs]
         [:!WQv {:modi :A-C-H-M-s- :key :v} :emacs]
         [:v {:modi :⌘ :key :delete_forward} :!emacs]
         [:b {:modi :C-H-M- :key :b} :emacs]
         [:t {:modi :C-H-M- :key :t} :emacs]
         [:t :home :!emacs]
         [:g {:modi :C-H-M- :key :g} :emacs]
         [:g :end :!emacs]
         [:!Wd {:modi :C-H-M-s- :key :d} :emacs]
         [:!Ws {:modi :C-H-M-s- :key :s} :emacs]
         ]}

k-mode

{:des "k-mode (website-specific)"
 :rules [:k-mode
         [:a [:km "Local website a"]]
         [:b [:km "Local website b"]]
         [:c [:km "Local website c"]]
         [:d [:km "Local website d"]]
         [:e [:km "Local website e"]]
         [:f [:km "Local website f"]]
         [:g [:km "Local website g"]]
         [:h [:km "Local website h"]]
         [:i [:km "Local website i"]]
         [:j [:km "Local website j"]]
         [:l [:km "Local website l"]]
         [:!Sl [:km "Local website Sl"]]
         [:!Cl [:km "Local website Cl"]]
         [:!CSl [:km "Local website CSl"]]
         [:m [:km "Local website m"]]
         [:n [:km "Local website n"]]
         [:o [:km "Local website o"]]
         [:p [:km "Local website p"]]
         [:r [:km "Local website r"]]
         [:s [:km "Local website s"]]
         [:t [:km "Local website t"]]
         [:u [:km "Local website u"]]
         [:y [:km "Local website y"]]
         [:z [:km "Local website z"]]
         [:x [:km "Local website x"]]
         [:v [:km "Local website v"]]
         [:w [:km "Local website w"]]
         [:semicolon [:km "Local website semicolon"]]
         [:comma [:km "Local website comma"]]
         [:period [:km "Local website period"]]
         [:slash [:km "Local website slash"]]
         [:return_or_enter [:km "Local website return_or_enter"]]
         ;; [:spacebar [:km "Local website spacebar"]]
         ]}

m-mode

{:des "m-mode (math symbols)"
 :rules [:m-mode
         [:e :=]
         [:p :+]
         [:q :≠]
         [:d :÷]
         [:o :±]
         [:x [:insert "×"]]
         [:comma :≤]
         [:period :≥]
         ]}

[#4] Fix m-mode problems

E.g. “me” sometimes inserts =

p-mode

{:des "p-mode (diacritics)"
 :rules [:p-mode
         [:a :macron]
         [:b :breve]
         [:c :cedilla]
         [:e :accute_accent]
         [:g :undercomma]
         [:h :underbar]
         [:i :horn]
         [:j :double_acute_accent]
         [:k :overring]
         [:l :stroke]
         [:m :ogonek]
         [:n :tilde_accent]
         [:r :grave_accent]
         [:u :umlaut]
         [:v :caron]
         [:w :underdot]
         [:x :overdot]
         [:y :circumflex]
         [:z :hook]
         ]
 }

q-mode

{:des "q-mode (apps)"
 :rules [:q-mode
         [:b [:open "/Applications/qBitTorrent.app"]]
         [:d [:open "/System/Library/CoreServices/Finder.app"]]
         [:e [:open "/Applications/Emacs.app"]]
         [:f [:open "/Applications/Firefox.app"]]
         [:g [:open "/Applications/Goldendict.app"]]
         [:h [:open "/Applications/Google Chrome.app"]]
         [:i [:open "/Applications/Anki.app"]]
         [:j [:km "open: System Preferences"]]
         [:k [:open "/Applications/Keyboard Maestro.app"]]
         [:l [:open "/Applications/DeepL.app"]]
         [:m [:open "/Applications/Media Center 29.app"]]
         [:o [:open "/Applications/zoom.us.app"]]
         [:p [:open "/Applications/Beeper.app"]]
         [:r [:open "/Applications/Karabiner-Elements.app"]]
         [:s [:open "/Applications/Slack.app"]]
         [:t [:open "/System/Applications/Utilities/Terminal.app"]]
         [:v [:open "/Applications/mpv.app"]]
         [:w [:open "/Applications/HoudahSpot.app"]]
         [:x [:open "/Applications/Plex Media Server.app/"]]
         [:y [:open "/Applications/Spotify.app"]]
         [:comma [:open "/Applications/Home Assistant.app"]]
         [:period [:open "/Applications/Tor Browser.app"]]
         ]}

v-mode

{:des "v-mode (numbers)"
 :rules [:v-mode
         [:i :8]
         [:##i :##8]
         [:j :4]
         [:##j :4]
         [:k :5]
         [:##k :5]
         [:l :6]
         [:##l :6]
         [:m :1]
         [:##m :1]
         [:o :9]
         [:##o :9]
         [:u :7]
         [:##u :7]
         [:comma :2]
         [:##comma :2]
         [:period :3]
         [:##period :3]
         [:p :0]
         [:##p :0]
         [:semicolon :period]
         [:##semicolon :period]
         ]
 }

x-mode

{:des "x-mode (avy)"
 :rules [:x-mode
         [:a [{:modi :C-H-s- :key :a}]]
         [:b [{:modi :C-H-s- :key :b}]]
         [:c [{:modi :C-H-s- :key :c}]]
         [:d [{:modi :C-H-s- :key :d}]]
         [:e [{:modi :C-H-s- :key :e}]]
         [:f [{:modi :C-H-s- :key :f}]]
         [:g [{:modi :C-H-s- :key :g}]]
         [:h [{:modi :C-H-s- :key :h}]]
         [:i [{:modi :C-H-s- :key :i}]]
         [:j [{:modi :C-H-s- :key :j}]]
         [:k [{:modi :C-H-s- :key :k}]]
         [:l [{:modi :C-H-s- :key :l}]]
         [:m [{:modi :C-H-s- :key :m}]]
         [:n [{:modi :C-H-s- :key :n}]]
         [:o [{:modi :C-H-s- :key :o}]]
         [:p [{:modi :C-H-s- :key :p}]]
         [:q [{:modi :C-H-s- :key :q}]]
         [:r [{:modi :C-H-s- :key :r}]]
         [:s [{:modi :C-H-s- :key :s}]]
         [:t [{:modi :C-H-s- :key :t}]]
         [:u [{:modi :C-H-s- :key :u}]]
         [:v [{:modi :C-H-s- :key :v}]]
         [:w [{:modi :C-H-s- :key :w}]]
         [:y [{:modi :C-H-s- :key :y}]]
         [:z [{:modi :C-H-s- :key :z}]]
         [:semicolon [{:modi :C-H-s- :key :semicolon}]]
         [:comma [{:modi :C-H-s- :key :comma}]]
         [:period [{:modi :C-H-s- :key :period}]]
         [:slash [{:modi :C-H-s- :key :slash}]]
         [:spacebar [{:modi :C-H-s- :key :spacebar}]]
         [:return_or_enter [{:modi :C-H-s- :key :return_or_enter}]]
         [:tab [{:modi :C-H-s- :key :tab}]]
         ]}

y-mode

{:des "y-mode (mouse, screenshots)"
 :rules [:y-mode
         [:b {:modi :⇧⌘ :key :5}] ; Screenshot and recording options
         [:c {:modi :⇧⌘ :key :4}] ; Save picture of selected area to a file
         [:d {:mkey {:y 1500}}]
         [:e {:mkey {:y 4500}}]
         [:a {:mkey {:x -1500}}]
         [:f {:mkey {:x 1500}}]
         [:q {:mkey {:x -4500}}]
         [:r {:mkey {:x 4500}}]
         [:s {:mkey {:y -1500}}]
         [:v {:modi :⇧⌘⌃ :key :4}] ; Copy picture of selected area to the clipboard
         [:w {:mkey {:y -4500}}]
         [:z {:modi :⇧⌘ :key :3}] ; Save picture of screen as a file
         [:right_command :button2]
         [:return_or_enter :button1]
         ]}

z-mode

[2021-03-23 Tue 09:18] I’ve added ## to u and p. This allows for the use of shift. Not sure if this addition will have any unexpected side effects, so testing it on these two words only. If everything looks fine in a few days, you can extend this modification to all other relevant letters.

[2021-03-25 Thu 08:30] Next task is to create corresponding versions of many of the motion key mappings that move the screen rather than the cursor.

{:des "z-mode (navigation)"
 :rules [:z-mode
         [:b {:modi :A-C-s- :key :b} :emacs]
         [:c {:modi :A-C-s- :key :c}]
         [:d {:modi :A-H-M-s- :key :d} :emacs] ; WTQ intercepted by OSX
         [:e {:modi :A-C-s- :key :e} :emacs]
         [:f [{:modi :⌘⌃ :key :n} {:modi :⌘⌃ :key :h}] :chrome] ; Google Docs next heading
         [:f {:modi :A-C-s- :key :f}]
         [:g {:modi :A-C-s- :key :g} :emacs]
         [:h {:modi :A-C-s- :key :h} :emacs]
         [:##h :page_down]
         [:i {:modi :A-C-s- :key :i} :emacs]
         [:##i {:modi :⌥ :key :up_arrow}]
         [:j :left_arrow]
         [:##j :left_arrow]
         [:k :up_arrow]
         [:##k :up_arrow]
         [:l :down_arrow]
         [:##l :down_arrow]
         [:m {:modi :A-C-s- :key :m} :emacs]
         [:##m {:modi :⌘ :key :left_arrow}]
         [:n {:modi :A-C-s- :key :n} :emacs]
         [:o {:modi :A-C-s- :key :o} :emacs]
         [:##o {:modi :⌥ :key :down_arrow}]
         [:p {:modi :A-C-s- :key :p} :emacs]
         [:##p {:modi :⌥ :key :right_arrow}]
         [:r [{:modi :⌘⌃ :key :p} {:modi :⌘⌃ :key :h}] :chrome] ; Google Docs previous heading
         [:r {:modi :A-C-s- :key :r} :emacs]
         [:s {:modi :A-C-s- :key :s} :emacs]
         [:t {:modi :A-C-s- :key :t} :emacs]
         [:u {:modi :A-C-s- :key :u} :emacs]
         [:##u {:modi :⌥ :key :left_arrow}]
         [:v {:modi :A-C-s- :key :v} :emacs]
         [:w {:modi :A-C-s- :key :w} :emacs]
         [:x {:modi :A-C-s- :key :x}]
         [:y {:modi :A-C-s- :key :y} :emacs]
         [:##y :page_up]
         [:spacebar {:modi :A-C-s- :key :spacebar} :emacs]
         [:spacebar {:modi :⌘ :key :up_arrow} :chrome] ; in Chrome, move to top
         [:spacebar :home]
         [:comma {:modi :A-C-s- :key :comma} :emacs]
         [:##comma {:modi :⌘ :key :up_arrow}]
         [:period {:modi :A-C-s- :key :period} :emacs]
         [:##period {:modi :⌘ :key :down_arrow}]
         [:right_command {:modi :A-C-s- :key :tab} :emacs]
         [:right_command {:modi :⌘ :key :down_arrow} :chrome] ; in Chrome, move to bottom
         [:right_command :end]
         [:semicolon :right_arrow]
         [:##semicolon :right_arrow]
         [:slash {:modi :A-C-s- :key :slash} :emacs]
         [:##slash {:modi :⌘ :key :right_arrow}]
         [:tab {:modi :A-C-s- :key :tab} :emacs]
         ;; [:##tab :home]
         ]}

comma-mode

{:des "comma-mode (transposition)"
 :rules [:comma-mode
         [:a {:modi :A-H-M- :key :a}]
         [:b {:modi :A-H-M- :key :b}]
         [:c {:modi :A-H-M- :key :c}]
         [:d {:modi :A-H-M- :key :d}]
         [:e {:modi :A-H-M- :key :e}]
         [:f {:modi :A-H-M- :key :f}]
         [:g {:modi :A-H-M- :key :g}]
         [:h {:modi :A-H-M- :key :h}]
         [:i {:modi :A-H-M- :key :i}]
         [:j {:modi :A-H-M- :key :j}]
         [:l {:modi :A-H-M- :key :l}]
         [:n {:modi :A-H-M- :key :n}]
         [:o {:modi :A-H-M- :key :o}]
         [:p {:modi :A-H-M- :key :p}]
         [:q {:modi :A-H-M- :key :q}]
         [:r {:modi :A-H-M- :key :r}]
         [:s {:modi :A-H-M- :key :s}]
         [:t {:modi :A-H-M- :key :t}]
         [:u {:modi :A-H-M- :key :u}]
         [:v {:modi :A-H-M- :key :v}]
         [:w {:modi :A-H-M- :key :w}]
         [:x {:modi :A-H-M- :key :x}]
         [:y {:modi :A-H-M- :key :y}]
         [:z {:modi :A-H-M- :key :z}]
         [:semicolon {:modi :A-H-M- :key :semicolon}]
         [:period {:modi :A-H-M- :key :period}]
         [:slash {:modi :A-H-M- :key :slash}]
         [:spacebar {:modi :A-H-M- :key :spacebar}]
         [:return_or_enter {:modi :A-H-M- :key :return_or_enter}]
         [:tab {:modi :A-H-M- :key :tab}]
         ]}

period-mode

{:des "period-mode (manipulation)"
 :rules [:period-mode
         [:a {:modi :A-C-H- :key :a}]
         [:b {:modi :A-C-H- :key :b}]
         [:c {:modi :A-C-H- :key :c}]
         [:d {:modi :A-C-H- :key :d}]
         [:e {:modi :A-C-H- :key :e}]
         [:f {:modi :A-C-H- :key :f}]
         [:g {:modi :A-C-H- :key :g}]
         [:h {:modi :A-C-H- :key :h}]
         [:i {:modi :A-C-H- :key :i}]
         [:j {:modi :A-C-H- :key :j}]
         [:k {:modi :A-C-H- :key :k}]
         [:l {:modi :A-C-H- :key :l}]
         [:m {:modi :A-C-H- :key :m}]
         [:n {:modi :A-C-H- :key :n}]
         [:o {:modi :A-C-H- :key :o}]
         [:p {:modi :A-C-H- :key :p}]
         [:q {:modi :A-H-M-s- :key :9}] ; QCOq triggers ⌘⌃Q (lock screen)
         [:r {:modi :A-C-H- :key :r}]
         [:s {:modi :A-C-H- :key :s}]
         [:t {:modi :A-C-H- :key :t}]
         [:u {:modi :A-C-H- :key :u}]
         [:v {:modi :A-C-H- :key :v}]
         [:w {:modi :A-C-H- :key :w}]
         [:x {:modi :A-C-H- :key :x}]
         [:y {:modi :A-C-H- :key :y}]
         [:z {:modi :A-C-H- :key :z}]
         [:semicolon {:modi :A-C-H- :key :semicolon}]
         [:comma {:modi :A-C-H- :key :comma}]
         [:slash {:modi :A-C-H- :key :slash}]
         [:spacebar {:modi :A-C-H- :key :spacebar}]
         [:return_or_enter {:modi :A-C-H- :key :return_or_enter}]
         ]}

semicolon-mode

  • Insert image of key layout
  • Explain “logic” behind layout (e.g. single quotes, double quotes, and dashes as triplets in successive lines)
{:des "semicolon (symbols)"
 :rules [:semicolon-mode
         [:##a :percent_sign]
         [:##b :grave_accent_and_tilde]
         [:##c :open_bracket]
         [:##d :close_parenthesis]
         [:##e :number_sign]
         [:##f :asterisk]
         [:##g :caret]
         [:##h :ampersand]
         [:##i :open_single_quote]
         [:##j :double_quote]
         [:##k :open_double_quote]
         [:##l :close_double_quote]
         [:##m :hyphen]
         [:##n :tilde]
         [:##o :close_single_quote]
         [:##q :exclamation_mark]
         [:##r :dollar_sign]
         [:##s :open_parenthesis]
         [:##t :backslash]
         [:##u :quote]
         [:##v :close_bracket]
         [:##w :at_sign]
         [:##x :close_brace]
         [:##y :vertical_bar]
         [:##z :open_brace]
         [:##comma :en_dash]
         [:##period :em_dash]
         [:##right_command :underscore]
         ]}

slash-mode

{:des "slash simlyaer → org-mode (Emacs) | app-specific macros (outside Emacs)"
 :rules [:slash-mode
         [:a {:modi :C-H-M-s- :key :a} :emacs]
         [:b {:modi :C-H-M-s- :key :b} :emacs]
         [:c {:modi :C-H-M-s- :key :c} :emacs]
         [:d {:modi :C-H-M-s- :key :d} :emacs]
         [:e {:modi :C-H-M-s- :key :e} :emacs]
         [:f {:modi :C-H-M-s- :key :f} :emacs]
         [:g {:modi :C-H-M-s- :key :g} :emacs]
         [:h {:modi :C-H-M-s- :key :h} :emacs]
         [:i {:modi :C-H-M-s- :key :i} :emacs]
         [:j {:modi :C-H-M-s- :key :j} :emacs]
         [:m {:modi :C-H-M-s- :key :m} :emacs]
         [:n {:modi :C-H-M-s- :key :n} :emacs]
         [:o {:modi :C-H-M-s- :key :o} :emacs]
         [:p {:modi :C-H-M-s- :key :p} :emacs]
         [:q {:modi :C-H-M-s- :key :q} :emacs]
         [:r {:modi :C-H-M-s- :key :r} :emacs]
         [:s {:modi :C-H-M-s- :key :s} :emacs]
         [:t {:modi :C-H-M-s- :key :t} :emacs]
         [:u {:modi :C-H-M-s- :key :u} :emacs]
         [:v {:modi :C-H-M-s- :key :v} :emacs]
         [:w {:modi :C-H-M-s- :key :w} :emacs]
         [:z {:modi :C-H-M-s- :key :z} :emacs]
         [:x {:modi :C-H-M-s- :key :x} :emacs]
         [:y {:modi :C-H-M-s- :key :y} :emacs]
         [:period {:modi :C-H-M-s- :key :period} :emacs]
         [:a [:km "Local app a"] :!emacs]
         [:b [:km "Local app b"] :!emacs]
         [:c [:km "Local app c"] :!emacs]
         [:d [:km "Local app d"] :!emacs]
         [:e [:km "Local app e"] :!emacs]
         [:f [:km "Local app f"] :!emacs]
         [:g [:km "Local app g"] :!emacs]
         [:h [:km "Local app h"] :!emacs]
         [:i [:km "Local app i"] :!emacs]
         [:j [:km "Local app j"] :!emacs]
         [:k [:km "Local app k"] :!emacs]
         [:l [:km "Local app l"] :!emacs]
         [:m [:km "Local app m"] :!emacs]
         [:n [:km "Local app n"] :!emacs]
         [:o [:km "Local app o"] :!emacs]
         [:p [:km "Local app p"] :!emacs]
         [:q [:km "Local app q"] :!emacs]
         [:r [:km "Local app r"] :!emacs]
         [:s [:km "Local app s"] :!emacs]
         [:t [:km "Local app t"] :!emacs]
         [:u [:km "Local app u"] :!emacs]
         [:v [:km "Local app v"] :!emacs]
         [:w [:km "Local app w"] :!emacs]
         [:x [:km "Local app x"] :!emacs]
         [:y [:km "Local app y"] :!emacs]
         [:z [:km "Local app z"] :!emacs]
         [:0 [:km "Local app 0"] :!emacs]
         [:1 [:km "Local app 1"] :!emacs]
         [:2 [:km "Local app 2"] :!emacs]
         [:3 [:km "Local app 3"] :!emacs]
         [:4 [:km "Local app 4"] :!emacs]
         [:5 [:km "Local app 5"] :!emacs]
         [:6 [:km "Local app 6"] :!emacs]
         [:7 [:km "Local app 7"] :!emacs]
         [:8 [:km "Local app 8"] :!emacs]
         [:9 [:km "Local app 9"] :!emacs]
         [:semicolon [:km "Local app semicolon"] :!emacs]
         [:comma [:km "Local app comma"] :!emacs]
         [:period [:km "Local app period"] :!emacs]
         [:return_or_enter [:km "Local app return_or_enter"] :!emacs]
         [:spacebar [:km "Local app spacebar"] :!emacs]
         ]}

end

]}

Appendices

Useful links

Tutorials

Configuration files

Meta

Goku modifier letters

lettermodifier
Cleft_command
Tleft_control
Oleft_option
Sleft_shift
Ffn
Qright_command
Wright_control
Eright_option
Rright_shift

List of keys

Souce: GitHub
  • category: Modifier keys
  • name: caps_lock
  • name: left_control
  • name: left_shift
  • name: left_option
  • name: left_command
  • name: right_control
  • name: right_shift
  • name: right_option
  • name: right_command
  • name: fn
  • category: Controls and symbols
  • name: return_or_enter
  • name: escape
  • name: delete_or_backspace
  • name: delete_forward
  • name: tab
  • name: spacebar
  • name: hyphen label: hyphen (-)
  • name: equal_sign label: equal_sign (=)
  • name: open_bracket label: open_bracket [
  • name: close_bracket label: close_bracket ]
  • name: backslash label: backslash (\)
  • name: non_us_pound
  • name: semicolon label: semicolon (;)
  • name: quote label: quote (‘)
  • name: grave_accent_and_tilde label: grave_accent_and_tilde ()
  • name: comma label: comma (,)
  • name: period label: period (.)
  • name: slash label: slash (/)
  • name: non_us_backslash
  • category: Arrow keys
  • name: up_arrow
  • name: down_arrow
  • name: left_arrow
  • name: right_arrow
  • name: page_up
  • name: page_down
  • name: home
  • name: end
  • category: Letter keys
  • name: a
  • name: b
  • name: c
  • name: d
  • name: e
  • name: f
  • name: g
  • name: h
  • name: i
  • name: j
  • name: k
  • name: l
  • name: m
  • name: n
  • name: o
  • name: p
  • name: q
  • name: r
  • name: s
  • name: t
  • name: u
  • name: v
  • name: w
  • name: x
  • name: y
  • name: z
  • category: Number keys
  • name: ‘1’
  • name: ‘2’
  • name: ‘3’
  • name: ‘4’
  • name: ‘5’
  • name: ‘6’
  • name: ‘7’
  • name: ‘8’
  • name: ‘9’
  • name: ‘0’
  • category: Function keys
  • name: f1
  • name: f2
  • name: f3
  • name: f4
  • name: f5
  • name: f6
  • name: f7
  • name: f8
  • name: f9
  • name: f10
  • name: f11
  • name: f12
  • name: f13
  • name: f14
  • name: f15
  • name: f16
  • name: f17
  • name: f18
  • name: f19
  • name: f20
  • name: f21 not_to: true
  • name: f22 not_to: true
  • name: f23 not_to: true
  • name: f24 not_to: true
  • category: Media controls
  • name: display_brightness_decrement not_from: true
  • name: display_brightness_increment not_from: true
  • name: mission_control not_from: true
  • name: launchpad not_from: true
  • name: dashboard not_from: true
  • name: illumination_decrement not_from: true
  • name: illumination_increment not_from: true
  • name: rewind not_from: true
  • name: play_or_pause not_from: true
  • name: fastforward not_from: true
  • name: mute
  • name: volume_decrement
  • name: volume_increment
  • name: eject not_from: true
  • name: apple_display_brightness_decrement not_from: true
  • name: apple_display_brightness_increment not_from: true
  • name: apple_top_case_display_brightness_decrement not_from: true
  • name: apple_top_case_display_brightness_increment not_from: true
  • category: Keypad keys
  • name: keypad_num_lock
  • name: keypad_slash
  • name: keypad_asterisk
  • name: keypad_hyphen
  • name: keypad_plus
  • name: keypad_enter
  • name: keypad_1
  • name: keypad_2
  • name: keypad_3
  • name: keypad_4
  • name: keypad_5
  • name: keypad_6
  • name: keypad_7
  • name: keypad_8
  • name: keypad_9
  • name: keypad_0
  • name: keypad_period
  • name: keypad_equal_sign
  • name: keypad_comma
  • category: Virtual Keys
  • name: vk_none label: vk_none (disable this key) not_from: true
  • category: Keys in pc keyboards
  • name: print_screen
  • name: scroll_lock
  • name: pause
  • name: insert
  • name: application
  • name: help
  • name: power
  • name: execute not_to: true
  • name: menu not_to: true
  • name: select not_to: true
  • name: stop not_to: true
  • name: again not_to: true
  • name: undo not_to: true
  • name: cut not_to: true
  • name: copy not_to: true
  • name: paste not_to: true
  • name: find not_to: true
  • category: International keys
  • name: international1
  • name: international2 not_to: true
  • name: international3
  • name: international4 not_to: true
  • name: international5 not_to: true
  • name: international6 not_to: true
  • name: international7 not_to: true
  • name: international8 not_to: true
  • name: international9 not_to: true
  • name: lang1
  • name: lang2
  • name: lang3 not_to: true
  • name: lang4 not_to: true
  • name: lang5 not_to: true
  • name: lang6 not_to: true
  • name: lang7 not_to: true
  • name: lang8 not_to: true
  • name: lang9 not_to: true
  • category: Japanese
  • name: japanese_eisuu label: 英数キー
  • name: japanese_kana label: かなキー
  • name: japanese_pc_nfer label: PCキーボードの無変換キー not_to: true
  • name: japanese_pc_xfer label: PCキーボードの変換キー not_to: true
  • name: japanese_pc_katakana label: PCキーボードのかなキー not_to: true
  • category: Others
  • name: keypad_equal_sign_as400 not_to: true
  • name: locking_caps_lock not_to: true
  • name: locking_num_lock not_to: true
  • name: locking_scroll_lock not_to: true
  • name: alternate_erase not_to: true
  • name: sys_req_or_attention not_to: true
  • name: cancel not_to: true
  • name: clear not_to: true
  • name: prior not_to: true
  • name: return label: rarely used return (HID usage 0x9e) not_to: true
  • name: separator not_to: true
  • name: out not_to: true
  • name: oper not_to: true
  • name: clear_or_again not_to: true
  • name: cr_sel_or_props not_to: true
  • name: ex_sel not_to: true
  • name: left_alt label: left_alt (equal toleft_option)
  • name: left_gui label: left_gui (equal toleft_command)
  • name: right_alt label: right_alt (equal toright_option)
  • name: right_gui label: right_gui (equal toright_command)
  • name: vk_consumer_brightness_down label: vk_consumer_brightness_down (equal todisplay_brightness_decrement) not_from: true
  • name: vk_consumer_brightness_up label: vk_consumer_brightness_up (equal todisplay_brightness_increment) not_from: true
  • name: vk_mission_control label: vk_mission_control (equal tomission_control) not_from: true
  • name: vk_launchpad label: vk_launchpad (equal tolaunchpad) not_from: true
  • name: vk_dashboard label: vk_dashboard (equal todashboard) not_from: true
  • name: vk_consumer_illumination_down label: vk_consumer_illumination_down (equal toillumination_decrement) not_from: true
  • name: vk_consumer_illumination_up label: vk_consumer_illumination_up (equal toillumination_increment) not_from: true
  • name: vk_consumer_previous label: vk_consumer_previous (equal torewind) not_from: true
  • name: vk_consumer_play label: vk_consumer_play (equal toplay) not_from: true
  • name: vk_consumer_next label: vk_consumer_next (equal tofastforward) not_from: true
  • name: volume_down label: volume_down (equal tovolume_decrement)
  • name: volume_up label: volume_up (equal tovolume_increment`)

Letter frequencies

Source: Wikipedia

letterfreqnormalizedused
E0.130001.
T0.091001.4285714
A0.082001.5853659
O0.075001.7333333
I0.070001.8571429
N0.067001.9402985
S0.063002.0634921
H0.061002.1311475
R0.060002.1666667
D0.043003.0232558
L0.040003.25
C0.028004.6428571
U0.028004.6428571
M0.024005.4166667
W0.024005.4166667
F0.022005.9090909t
G0.020006.5
Y0.020006.5
P0.019006.8421053t
B0.015008.6666667t
V0.0098013.265306t
K0.0077016.883117t
J0.0015086.666667t
X0.0015086.666667t
Q0.00095136.84211t
Z0.00074175.67568t

Local variables