Skip to content

Instantly share code, notes, and snippets.

@ibehnam
Forked from kaushikgopal/karabiner.edn
Created June 1, 2022 18:39
Show Gist options
  • Save ibehnam/d329294c7b2b7bac0679017e5245c605 to your computer and use it in GitHub Desktop.
Save ibehnam/d329294c7b2b7bac0679017e5245c605 to your computer and use it in GitHub Desktop.
My source Karabiner file in Goku's edn format
{
;; :!Ca is keycode :a and prefix a with !C
;; 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
;; P | caps_lock
;; !! | command + control + optional + shift (hyper)
;; code for all this:
;; https://github.com/yqrashawn/GokuRakuJoudo/blob/b9b334a187379f9bc8182ad59e2cca2a1789e9c0/src/karabiner_configurator/keys.clj#L68
;; FROM modifiers
;; to understand better how modifiers work in karabiner
;; karabiner definition of mandatory and optional
;; https://karabiner-elements.pqrs.org/docs/json/complex-modifications-manipulator-definition/from/modifiers/
;; | no modifier
;; input key maps to output key exactly
;; adding any modifier will cancel the event
;; ! | mandatory
;; specified modifier is removed in output (to event)
;; specified modifiers must be present for event to occur
;; adding any other modifier will cancel the event
;; # | optional (single)
;; specified modifier is kept in output (to event)
;; one (or none) of the specified modifiers must be present
;; adding any other modifier will cancel the event
;; ## | optional any
;; specified modifier is removed in output (to event)
;; specified modifiers *must* be present for event to occur
;; adding any other modifier will add to output event
;; (what you typically expect, additional modifiers tacked on)
;;
;; need to prefix C T O S F with ! or #
;;
:profiles {
:Default {
:default true
:sim 50 ;; simultaneous_threshold_milliseconds (def: 50)
;; if keydown event for two different keys are pressed within :sim ms, the keypresses are considered simultaneous
:delay 150 ;; to_delayed_action_delay_milliseconds (def: 500)
;; after :delay ms, the key press is considered to be delayed (used for double-press macros)
:alone 500 ;; to_if_alone_timeout_milliseconds (def: 1000)
;; if keyup event comes within :alone ms from keydown, the key is not just pressed but held
:held 500 ;; to_if_held_down_threshold_milliseconds (def: 500)
;; key is fired twice when :held ms is elapsed (otherwise seen as a hold command) (TODO WHAT IS THIS??)
}
} ;; profiles
; the default value is 250
:simlayer-threshold 500
:templates {
:km "osascript -e 'tell application \"Keyboard Maestro Engine\" to do script \"%s\"'"
:open "open \"%s\""
} ;; templates
;; Define different kinds of keyboards
:devices {
:apple [
{:vendor_id 1452}
{:vendor_id 76}
]
:ap2 [{:vendor_id 1241, :product_id 41618 }] ;; Anne Pro 2 (mechanical)
:msft [{:vendor_id 1118, :product_id 1957 }] ;; Microsoft Keyboard [Ergonomic Sculpt]
:tada68 [{:vendor_id 65261, :product_id 4611 }] ;; Tada68 (mechanical)
:kinesis [{:vendor_id 10730 }] ;; Kinesis Advantage 2 keyboard
:g915 [{:vendor_id 1133}] ;; Logitech G915 keyboard
:kybs [ ;; Default for all keyboards
{:vendor_id 1452}
{:vendor_id 76}
{:vendor_id 1241, :product_id 41618 }
{:vendor_id 1118, :product_id 1957 }
{:vendor_id 65261, :product_id 4611 }
{:vendor_id 10730}
{:vendor_id 1133, :product_id 50501 }
]
:kybs-kinesis [ ;; All keyboards (except Kinesis)
{:vendor_id 1452}
{:vendor_id 76}
{:vendor_id 1241, :product_id 41618 }
{:vendor_id 1118, :product_id 1957 }
{:vendor_id 65261, :product_id 4611 }
{:vendor_id 1133, :product_id 50501 }
]
} ;; devices
;; layers are basically "hyper" keys
;; press this in combination with something else and depending on your rule, make things happen
:layers {
;; :tab-mode {:key :tab}
:caps-mode {:key :caps_lock :alone {:key :escape}}
} ;; layers
;; simlayers are basically "hyper" keys
;; layers works too, but only recommended for non-typing keys like . or tab
;; to use more regular typing keys, use simlayers
:simlayers {
:d-mode {:key :d}
; :f-mode {:key :f}
; :j-mode {:key :j}
:k-mode {:key :k}
} ;; simlayers
:applications {
:terminals [ "^com\\.apple\\.Terminal$",
"^com\\.googlecode\\.iterm2$"]
}
;; main contains multiple manipulators
:main [
;; each manipulator has a description and multiple rules
;;{:des "..." ;; -> description
;; :rules[
;; [<from> <to> <conditions>] ;; -> rule 1
;; [<from> <to> <conditions>] ;; -> rule 2
;; ]}
;; rule [:period ["period-mode" 1] nil {:afterup ["period-mode" 0] :alone :period}]
;; |_____| |_______________| |_| |_________________________________________|
;; <from> <to> <conditions> <other options>
;;
;; karabiner docs: ;; https://pqrs.org/osx/karabiner/json.html#complex_modifications-manipulator-definition
;; <other options> includs ~to_if_alone~, ~to_if_held_down~,~to_after_key_up~, ~to_delayed_action~ and ~parameters~.
;;
;; (custom variables) & modifiers -> Advanced
;; https://github.com/yqrashawn/GokuRakuJoudo/blob/master/examples.org#custom-variable
{:des "testing"
:rules [
;; Alt -> Hyper
;; [:##right_alt :!QWEright_shift]
;; easier reach to modifier keys
;;[:##slash :right_command nil {:alone :slash}]
;; [:##z :left_control nil {:alone :z}]
;; easier key launches
;;[[:f :j] :!Ospacebar] ;; alfred
;; Alt -> [] or Meh(Control Shift Option): secondary thumb keys
;; [:right_alt :!CTOleft_shift :apple]
;; [:##application :!TOleft_shift :g915]
; [:##left_control :!TOleft_shift :apple]
]}
;; ----------------------------------
;; Hardware keyboard mappings
;; ----------------------------------
{:des "Tada68 specific mappings"
:rules [:ap2
[:left_option :left_command]
[:left_command :left_option]
[:right_option :right_control]
]}
{:des "Apple specific mappings"
:rules [:apple
[:##right_command :right_control]
]}
{:des "Tada68 specific mappings"
:rules [:tada68
[:delete_forward :end]
[:escape :grave_accent_and_tilde]
[:grave_accent_and_tilde :home]
[:left_gui :left_alt]
]}
{:des "Microsoft Ergonomic Sculpt Keyboard"
:rules [:msft
[:delete_forward :end]
[:escape :grave_accent_and_tilde]
[:grave_accent_and_tilde :home]
[:left_gui :left_alt]
]}
{:des "Kinesis Advantage2 specific mappings"
:rules [:kinesis
[:non_us_backslash :!QWspacebar] ;; § -> emoji viewer
[:open_bracket :backslash] ;; [ -> \
[:close_bracket :slash] ;; ] -> /
]}
{:des "Logitech G915 remap"
:rules [:g915
[:##right_option :right_control]
[:##left_option :left_command]
[:##left_command :left_option]
]}
;; ----------------------------------
;; Key mappings
;; ----------------------------------
{:des "remap Cmd e -> Alt E for terminals"
;; this is used for edit_command_buffer in fish (edit commands in vim)
:rules [
[:!Ce :!Oe [:terminals]]
]}
{:des "quick bracket/braces sequences"
:rules [:d-mode
;; []
;; [:i :open_bracket :d-mode]
;; [:o :close_bracket :d-mode]
;; d-mode + i (once) → [
;; d-mode + i (twice) → ]
[
:i
[:close_bracket ["dmode-i" 0]]
["dmode-i" 1]
]
[
:i
[["dmode-i" 1]]
nil
{
:delayed
{
:invoked [["dmode-i" 0] :open_bracket]
:canceled [["dmode-i" 0]]
}
}
]
;; {}
;; [:comma :!Sopen_bracket :d-mode]
;; [:period :!Sclose_bracket :d-mode]
;[:left_shift :left_shift nil {:alone :!Sopen_bracket }]
;[:right_shift :right_shift nil {:alone :!Sclose_bracket }]
[
:o
[:!Sclose_bracket ["dmode-o" 0]]
["dmode-o" 1]
]
[
:o
[["dmode-o" 1]]
nil
{
:delayed
{
:invoked [["dmode-o" 0] :!Sopen_bracket]
:canceled [["dmode-o" 0]]
}
}
]
;; ()
;[:##left_option :left_command :g915 {:alone :!S9 }]
;[:##right_option :right_control :g915 {:alone :!S0 }]
;; [:k :!S9 :d-mode]
;; [:l :!S0 :d-mode]
;; d-mode + o (once) → (
;; d-mode + o (twice) → )
[
:k
[:!S0 ["dmode-k" 0]]
["dmode-k" 1]
]
[
:k
[["dmode-k" 1]]
nil
{
:delayed
{
:invoked [["dmode-k" 0] :!S9]
:canceled [["dmode-k" 0]]
}
}
]
]}
{:des "delete sequences"
:rules [
;; delete word
[:w :!Tw [:k-mode :terminals]]
[:w :!Odelete_or_backspace [:k-mode :!terminals]]
;; backspace
[:e :delete_or_backspace :k-mode]
[:d :delete_or_backspace :k-mode]
;[:j :delete_or_backspace :f-mode]
;; training wheels
;; [:delete_or_backspace :vk_none]
;; escape key
;; [:k :escape :j-mode]
;; delete line
[:l :!Tu [:k-mode :terminals]]
[:l :!Cdelete_or_backspace [:k-mode :!terminals]]
;; delete character
[:x :delete_forward :k-mode]
;; Training disable keys
;;[:!Odelete_or_backspace :vk_none :!terminals]
;;[:!CSdelete_or_backspace :vk_none :!terminals]
]}
{:des "caps lock mode: quick reach for cursor etc."
:rules [:caps-mode
;; caps lock : arrow mode
[:##j :##left_arrow ]
[:##k :##down_arrow ]
[:##i :##up_arrow ]
[:##l :##right_arrow ]
;; switch tabs in most apps
;; Cmd Shift [
[:##comma :!CSopen_bracket]
;; Cmd Shift ]
[:##period :!CSclose_bracket]
;; VSCode ctrl cmd →
;; [:!Cleft_arrow :!CTleft_arrow]
;; [:!Cright_arrow :!CTright_arrow]
;; Quick Mouse handles
[:down_arrow {:mkey {:y 1536}}]
[:up_arrow {:mkey {:y -1536}}]
[:left_arrow {:mkey {:x -1536}}]
[:right_arrow {:mkey {:x 1536}}]
[:return_or_enter {:pkey :button1}]
[:!Creturn_or_enter {:pkey :button2}]
;; Quick navigation
[:d :!Oright_arrow ]
[:w :!Oleft_arrow ]
;; ]
;; }
;; {:des "tab-mode: quick open applications"
;; :rules [:tab-mode
[:t [:km "wm: minor left"] ] ;; Window move
[:y [:km "wm: major left"] ] ;; Window move
[:u [:km "wm: half left"] ] ;; Window move
[:o [:km "wm: half right"] ] ;; Window move
[:p [:km "wm: major right"] ] ;; Window move
[:open_bracket [:km "wm: minor right"] ] ;; Window move
;; [:i :up_arrow ]
;; [:j :left_arrow ]
;; [:k :down_arrow ]
;; [:l :right_arrow ]
[:j [:km "wm: split 3 left"] ] ;; Window move
[:k [:km "wm: split 3 center"] ] ;; Window move
[:l [:km "wm: split 3 right"] ] ;; Window move
[:c [:km "wm: center"] ] ;; Window move
[:v [:km "wm: vertical fill"] ] ;; Window move
[:f [:km "wm: full"] ] ;; Window move
;[:j :!QWspacebar ] ;; e(m)oji
;[:k [:km "trigger macro by name"] ] ;; keyboard maestro
;[:l :!CSv ] ;; c(l)ipboard history
;[:semicolon :!TSl ] ;; maps to 1Password autofill
]}
;; {:des "Confirm destructive actions like quit/close twice"
;; :rules [
;; ;; full explanation for how this works
;; ;; https://github.com/yqrashawn/GokuRakuJoudo/blob/a77cccb8e8d4e6a9fb8ef2e6bcfe49a4299e4cb2/examples.org#command-q-twice-to-quit-application
;; [
;; ;; <from> second cmd-q (when variable "command-q" is 1)
;; :!C#Pq
;; ;; <to>, 3 to action
;; ;; 1. call cmd-q
;; ;; 2. set variable "command-q" to 0
;; ;; 3. cleanup the :cmdq notification (omit the thrid item to cleanup notification)
;; [:!Cq ["command-q" 0] [:noti :cmdq]]
;; ;; <condition> when variable "command-q" is 1
;; ["command-q" 1]
;; ]
;; [
;; ;; <from> first cmd-q (when variable "command-q" is 0)
;; :!C#Pq
;; ;; <to>, 2 to action
;; ;; 1. show notification with :id :cmdq, :text "Press Again to QUIT"
;; ;; 2. set variable "command-q" to 1 (for the second press)
;; [[:noti :cmdq "Press Again to QUIT"] ["command-q" 1]]
;; ;; <condition> nil means no required condition
;; nil
;; ;; <additional-option>
;; {
;; ;; to_delayed_action documentation
;; ;; https://karabiner-elements.pqrs.org/docs/json/complex-modifications-manipulator-definition/to-delayed-action/
;; :delayed
;; {
;; ;; run 2 actions when no other key presses after basic.to_delayed_action_delay_milliseconds
;; ;; 1. set variable "command-q" to 0
;; ;; 2. cleanup notification :id :cmdq
;; :invoked [["command-q" 0] [:noti :cmdq]]
;; ;; run 2 actions when another key presses within basic.to_delayed_action_delay_milliseconds
;; ;; 1. set variable "command-q" to 0
;; ;; 2. cleanup notification :id :cmdq
;; :canceled [["command-q" 0] [:noti :cmdq]]
;; }
;; }
;; ]
;; ;; "close application by pressing command-w twice"
;; [:!C#Pw [:!Cw ["command-w" 0] [:noti :cmdw]] ["command-w" 1]]
;; [:!C#Pw [[:noti :cmdw "Press Again to CLOSE"] ["command-w" 1]] nil {:delayed {:invoked [["command-w" 0] [:noti :cmdw]] :canceled [["command-w" 0] [:noti :cmdw]]}} ]
;; ]}
] ;; main list
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment