Skip to content

Latest commit

 

History

History
325 lines (278 loc) · 13.7 KB

examples.org

File metadata and controls

325 lines (278 loc) · 13.7 KB

Examples

Examples for users to check as quick reference and source of inspiration. Most docs are comments (start with ;;) in code block.

minimal configuration

Below is the minimal configuration. It does nothing. Make sure you have a profile named “Default” in karabiner.json.

{}

swap key

fromto
;:
shift + ;;
command + ;command + ;
option + ;option + ;
control + ;control + ;
{:main [{:des   "swap ; :"
         :rules [[:semicolon :!Ssemicolon]
                 [:!Ssemicolon :semicolon]]}]}

You can find all keycodes here or using the Karabiner-EventViewer.app.

modifier keys

{:main [{:des   "demo modifier keys"
         :rules [
                 ;; shift 1 to 1
                 ;; !S here means shift
                 [:!S1 :1]
                 ;; 1 to !
                 [:1 :!S1]
                 ;; control shift 1 to 12
                 ;; !TS means control shift
                 [:!TS1 [:1 :2]]]}]}

;; C T O S stands for left_command left_control left_option left_shift
;; Q W E R stands for right_command right_control right_option right_shift

;;;; hyper
;; !! stands for left_command + left_control + left_option + left_shift
;; :!!1 left_command + left_control + left_option + left_shift + 1

right_command to f16

fromto
right_commandf16
left_command + right_commandleft_command + f16
option + right_commandoption + f16
shift + right_commandshift + f16
control + right_commandcontrol + f16
{:main [{:des   "right_command to f16"
         :rules [[:##right_command :f16]]}]}

Note: Other modifier keys works because of the ”##” prefix. If you replace ## with #C (C for left_command), only

> left_command + right_command -> left_command + f16 will work.

Others will be treated like

> control + right_command -> control + right_command

caps_lock to ESC when pressed alone, to ctrl as modifier

{:main [{:des   "caps_lock to esc when pressed alone, to ctrl as modifier"
         :rules [[:##caps_lock :left_control nil {:alone :escape}]]}]}

press j and l simultaneously to f16

{:main [{:des   "press j and l simultaneously to f16"
         :rules [[[:h :j] :f16]]}]}

regular key as modifer key

simlayer, templates example

{:templates {:open "open \"%s\""}
 :layers    {}
 :simlayers {;; make w key a simlayer key
             ;; layers works too, but only recommended for none typing keys
             ;; like . , tab
             ;; or keys like z, which used less often
             :launch-mode {:key :w}}
 :main      [{:des   "launch mode"
              :rules [:launch-mode
                      [:k [:open "/Applications/Emacs.app"]]
                      [:l [:open "/Applications/Google Chrome.app"]]]}]}

same as below config, all conditions (layer, simlayer, application, input-source, device) works this way.

{:templates {:open "open \"%s\""}
 :layers    {}
 :simlayers {:launch-mode {:key :w}}
 :main      [{:des   "launch mode"
              :rules [[:k [:open "/Applications/Emacs.app"] :launch-mode]
                      [:l [:open "/Applications/Google Chrome.app"] :launch-mode]]}]}

layer example

{:templates {:open   "open \"%s\""
             :alfred "osascript -e 'tell application \"Alfred 3\" to run trigger \"%s\" in workflow \"%s\" with argument \"%s\"'"}
 :layers    {:alfred-layer {:key :z}}
 :simlayers {:launch-mode {:key :w}}
 :main      [{:des   "launch mode"
              :rules [:launch-mode
                      [:k [:open "/Applications/Emacs.app"]]
                      [:l [:open "/Applications/Google Chrome.app"]]]}

             {:des   "alfred mode"
              :rules [:alfred-mode
                      [:h [:alf "search repos" "me.lachlan.githubjump"]]
                      [:x [:alf "killProcess" "com.ngreenstein.alfred-process-killer"]]]}]}

below config works as well

{:templates {:open   "open \"%s\""
             :alfred "osascript -e 'tell application \"Alfred 3\" to run trigger \"%s\" in workflow \"%s\" with argument \"%s\"'"}
 :layers    {:alfred-layer {:key :z}}
 :simlayers {:launch-mode {:key :w}}
 :main      [{:des   "character key as modifier key rules"
              :rules [:launch-mode
                      [:k [:open "/Applications/Emacs.app"]]
                      [:l [:open "/Applications/Google Chrome.app"]]
                      :alfred-mode ;; all conditions works this way
                      [:h [:alf "search repos" "me.lachlan.githubjump"]]
                      [:x [:alf "killProcess" "com.ngreenstein.alfred-process-killer"]]]}]}

custom variable

{:main [{:des   "alfred"
         :rules [;; set f16 as the trigger key of alfred
                 ;; press h + l will trigger alfred and set "in-alfred" to 1
                 [[:h :j] [:f16 ["in-alfred" 1]]]

                 :in-alfred ;;;; when "in-alfred" is 1

                 ;; press enter will select one alfred result and set "in-alfred" to 0
                 [:##return_or_enter [:return_or_enter ["in-alfred" 0]]]

                 ;; press esc will exit alfred and set "in-alfred" to 0
                 [:##escape [:escape ["in-alfred" 0]]]

                 ;; press ctrl + j will invoke down_arrow
                 [:!Tj :down_arrow]

                 ;; press ctrl + k will invoke up_arrow
                 [:!Tk :up_arrow]

                 ;; press ctrl + l will invoke return_or_enter and set "in-alfred" to 0
                 [:!Tl [:return_or_enter ["in-alfred 0"]]]]}]}

double-tap right shift twice to enter double shift mode

{:des   "Press right_shift twice to enter double shift mode, press right_shift once to leave it"
                       :rules [[:right_shift ["double-right-shift-mode" 1] ["shift-pressed-once" 1]]
                               [:right_shift [:right_shift ["shift-pressed-once" 1]] ["double-right-shift-mode" 0] {:delayed {:invoked ["shift-pressed-once" 0] :canceled ["shift-pressed-once" 0]}}]
                               :double-right-shift-mode
                               [:right_shift ["double-right-shift-mode" 0]]
                               [:a "say 'know we are in double shift mode'"]]}

use the multitouch feature

{:des "ctrl+y to command+v (trackpad example)"
 :rules
 [;; ctrl+y to command+v
  [:!Ty :!Cv]
  ;; ctrl+y to command+v when one finger on trackpad
  [:!Ty :!Cv :multitouch_extension_finger_count_total]
  ;; ctrl+y to command+v when one finger on trackpad
  [:!Ty :!Cv ["multitouch_extension_finger_count_total" 1]]
  ;; ctrl+y to command+v when two finger on trackpad
  [:!Ty :!Cv ["multitouch_extension_finger_count_total" 2]]
  ;; ctrl+y to command+v when three finger on the upper half of trackpad
  [:!Ty :!Cv ["multitouch_extension_finger_count_upper_half_area" 3]]]}

This syntax don’t support specify negative multitouch conditions. For example:

Don't map a to b when there are three fingers on the trackpad.

device, input-method, application conditions

{:layers        {:z-mode {:key :z}}
 :devices       {;; define devices
                 ;; vendor_id and product_id can be found in Karabiner EventViewer gui
                 :hhkb [{:vendor_id 2131 :product_id 256}]}
 :applications  {;; define applications
                 :Browsers [;; these strings are regex to match applications bundle_identifiers
                            ;; you can find bundle_identifiers in the Info.plist file of an applications
                            ;; eg. in /Applications/Mail.app/Contents/Info.plist
                            ;; search for "CFBundleIdentifier"
                            "^org\\.mozilla\\.firefox$"
                            "^org\\.mozilla\\.firefoxdeveloperedition$"
                            "^com\\.google\\.Chrome$"
                            "^org\\.chromium\\.Chromium$"
                            "^com\\.google\\.Chrome\\.canary$"
                            "^com\\.apple\\.Safari$"]}
 :input-sources {;; define input-source, these data can be founhd in Karabiner EventViewer gui
                 :us {:input_mode_id   ""
                      :input_source_id "com.apple.keylayout.US"
                      :language        "en"}}

 ;; can config like this
 :main [{:des   "contions demo"
         :rules [;; multiple conditions
                          ;;;; when
                 ;; the input-method is :us
                 ;; the activated application is one of app in :Browsers
                 ;; the key is triggered by :hhkb
                 ;; may l key to command + optional + l
                 [:condi :us :hhkb :Browsers :z-mode]
                 [:l :!COi]]}]
 ;; or
 :main [{:des   "contions demo"
         :rules [[:l :!COi [:us :hhkb :Browsers :z-mode]]]}]

 ;; or
 :main [{:des   "contions demo"
         :rules [[:condi :us :hhkb]
                 [:l :!COi [:Browsers :z-mode]]]}]}

profiles

Skip this section if you don’t use profiles.

Since karabiner cli now supports set variables, profiles are mainly used for multiple users using the same machine or between different usages like gaming profile and working profile. Goku doesn’t support that well for now.

Basically, you can define your multiple profiles. Only one of them can be set as the default profile (:default true).

Then you can use profile keyword :Default as conditions or layers keyword. You need to specify each rule to a profile or they will be considered in the default profile.

If you want to have a empty profile for gaming. You can create one in karabiner gui (no need to change anything in goku).

{:profiles {:Default {;; "default true means" rules default goes into this rule if no profiles specified
                      :default true
                      ;; simultaneous key press threshold
                      ;; simlayer is implemented with to_if_alone and simultaneous key press feature
                      :sim     250
                      ;; to_delayed_action_delay_milliseconds
                      ;; checkout karabiner's documentation
                      ;; https://pqrs.org/osx/karabiner/json.html
                      ;; basically it means time after which the key press is count delayed
                      :delay   500
                      ;; https://pqrs.org/osx/karabiner/json.html#to-if-alone
                      ;; to_if_alone_timeout_milliseconds
                      ;; affects to_if_alone behavior
                      ;; simlayer is implemented with to_if_alone and simultaneous key press feature
                      :alone   1000
                      ;; to_if_held_down_threshold_milliseconds
                      ;; check the doc, I don't know what does this mean.
                      ;; maybe press this milliseconds counts a "held" ?
                      :held    500}}}

same key in different mode, from @nikitavoloboev’s config

Use karabiner command-line interface to set variables when you open specifc type of files in your editor.

{:profiles
 {:Default {:default true
            :sim     50
            :delay   80
            :alone   120
            :held    70}}
 :simlayers {:js-mode {:key :period :condi ["in-js" 1]} ;;  karabiner_cli --set-variables {"in-js": 1}
             :go-mode {:key :period :condi ["in-go" 1]} ;;  karabiner_cli --set-variables {"in-go": 1}
             :py-mode {:key :period :condi ["in-python" 1]} ;;  karabiner_cli --set-variables {"in-python": 1}
             :elixir-mode {:key :period :condi ["in-elixir" 1]} ;;  karabiner_cli --set-variables {"in-elixir": 1}
             :rust-mode {:key :period :condi ["in-rust" 1]}} ;;  karabiner_cli --set-variables {"in-rust": 1}
 :main [{:des "jsdot"
         :rules [:js-mode
                 [:a [:c :o :n :s :o :l :e :period :l :o :g :!S9 :!S0 :left_arrow]] ; -> console.log()
                 [:v [:j :a :v :a :s :c :r :i :p :t :spacebar]]]} ; -> javascript
        {:des "godot"
         :rules[:go-mode
                [:a [:f :m :t :period :!Sp :r :i :n :t :l :n :!S9 :!S0 :left_arrow]] ; -> fmt.Println()
                [:v [:g :o :l :a :n :g :spacebar]]]} ; -> golang
        {:des "pydot"
         :rules[:py-mode
                [:a [:p :r :i :n :t :!S9 :!S0 :left_arrow]] ; -> print()
                [:v [:p :y :t :h :o :n :spacebar]]]} ; -> python
        {:des "elixdot"
         :rules[:elixir-mode
                [:a [:!Si :!So :period :p :u :t :s :!S9 :!S0 :left_arrow]] ; -> IO.puts()
                [:v [:e :l :i :x :i :r :spacebar]]]} ; -> elixir
        {:des "rustdot"
         :rules[:rust-mode
                [:a [:p :r :i :n :t :l :n :!S1 :!S9 :!S0 :left_arrow]] ; -> println!()
                [:v [:r :u :s :t :spacebar]]]}]} ; -> rust