From 3da238e74c6d82253029bd69c69eb142a1a7799e Mon Sep 17 00:00:00 2001 From: evan-liu Date: Fri, 14 Feb 2025 08:35:28 +0000 Subject: [PATCH] deploy: 674a8bb92cdfc26729114c40e704a5cd3d0ba93d --- 404.html | 2 +- assets/js/22dd74f7.e9ef3f5b.js | 1 - assets/js/22dd74f7.fc6fdefd.js | 1 + assets/js/3b4932e3.3834c02f.js | 1 + assets/js/3b4932e3.e78d1b33.js | 1 - assets/js/401b8bd8.084e2653.js | 1 + assets/js/401b8bd8.cfeb25fe.js | 1 - assets/js/42d41a75.7218d6aa.js | 1 - assets/js/42d41a75.7922b276.js | 1 + assets/js/469b4bb6.cf855a1d.js | 1 + assets/js/469b4bb6.fe9411b8.js | 1 - assets/js/58dbb560.8006bc90.js | 1 + assets/js/70906612.b5db6874.js | 1 + assets/js/70906612.ececa388.js | 1 - ...24bb4.b01e0b22.js => c3e24bb4.a8b91b55.js} | 26 +++++++++---------- assets/js/d9f1d629.115dffc3.js | 1 + assets/js/d9f1d629.d4c4e410.js | 1 - .../js/{main.ff88adc2.js => main.a9a8328d.js} | 6 ++--- assets/js/runtime~main.357a1aa7.js | 1 + assets/js/runtime~main.894593e3.js | 1 - editor/index.html | 2 +- examples.json | 2 +- .../caps_lock-to-hyper/index.html | 10 +++---- .../modifier-keys/duo-modifiers/index.html | 14 +++++----- .../launch-apps-layer/index.html | 10 +++---- .../launch-apps-modifier/index.html | 10 +++---- examples/text-input/emoji/index.html | 10 +++---- examples/text-input/symbols/index.html | 10 +++---- examples/vim/leader/index.html | 9 +++++++ imports/index.html | 4 +-- index.html | 4 +-- manipulators/condition/index.html | 4 +-- manipulators/double-tap/index.html | 4 +-- manipulators/from/index.html | 4 +-- .../mouse_motion_to_scroll/index.html | 4 +-- manipulators/to/index.html | 4 +-- rules/duo-layer/index.html | 4 +-- rules/hyper-layer/index.html | 4 +-- rules/layer/index.html | 4 +-- rules/leader-mode/index.html | 4 +-- rules/rule/index.html | 4 +-- rules/simlayer/index.html | 4 +-- search/index.html | 2 +- sitemap.xml | 2 +- utils/index.html | 4 +-- 45 files changed, 93 insertions(+), 95 deletions(-) delete mode 100644 assets/js/22dd74f7.e9ef3f5b.js create mode 100644 assets/js/22dd74f7.fc6fdefd.js create mode 100644 assets/js/3b4932e3.3834c02f.js delete mode 100644 assets/js/3b4932e3.e78d1b33.js create mode 100644 assets/js/401b8bd8.084e2653.js delete mode 100644 assets/js/401b8bd8.cfeb25fe.js delete mode 100644 assets/js/42d41a75.7218d6aa.js create mode 100644 assets/js/42d41a75.7922b276.js create mode 100644 assets/js/469b4bb6.cf855a1d.js delete mode 100644 assets/js/469b4bb6.fe9411b8.js create mode 100644 assets/js/58dbb560.8006bc90.js create mode 100644 assets/js/70906612.b5db6874.js delete mode 100644 assets/js/70906612.ececa388.js rename assets/js/{c3e24bb4.b01e0b22.js => c3e24bb4.a8b91b55.js} (85%) create mode 100644 assets/js/d9f1d629.115dffc3.js delete mode 100644 assets/js/d9f1d629.d4c4e410.js rename assets/js/{main.ff88adc2.js => main.a9a8328d.js} (95%) create mode 100644 assets/js/runtime~main.357a1aa7.js delete mode 100644 assets/js/runtime~main.894593e3.js create mode 100644 examples/vim/leader/index.html diff --git a/404.html b/404.html index 04ebd66..edd82e9 100644 --- a/404.html +++ b/404.html @@ -1,3 +1,3 @@ -karabiner.ts
Skip to main content
\ No newline at end of file diff --git a/examples/modifier-keys/duo-modifiers/index.html b/examples/modifier-keys/duo-modifiers/index.html index 713915d..308289f 100644 --- a/examples/modifier-keys/duo-modifiers/index.html +++ b/examples/modifier-keys/duo-modifiers/index.html @@ -1,6 +1,6 @@ -Duo Modifiers | karabiner.ts

Duo Modifiers

Duo-modifier is an idea combined with home row mods and duo-layer:

info

Adjust basic.simultaneous_threshold_milliseconds to your typing speed and habit.

-
tip

When get started, it can be very useful to show a notification when the -mod(s) are activated, see an example here.

-
function duoModifier(keys, modifier) {
const [firstMod, ...restMods] =
modifier in modifierKeyAliases
? [modifierKeyAliases[modifier]]
: multiModifierAliases[modifier]
return mapSimultaneous(keys.split('')).to(`left_${firstMod}`, restMods)
}

let rules = [
rule('duo-modifiers').manipulators([
duoModifier('fd', '⌘'),
duoModifier('fs', '⌃'),
duoModifier('fa', '⌥'),

duoModifier('ds', '⇧'),

duoModifier('gd', '⌘⇧'),
duoModifier('gs', '⌃⇧'),
duoModifier('ga', '⌥⇧'),

duoModifier('vc', '⌘⌥'),
duoModifier('vx', '⌘⌃'),
duoModifier('cx', '⌥⌃'),

duoModifier('vz', '⌘⌥⌃'),

duoModifier('jk', '⌘'),
duoModifier('jl', '⌃'),
duoModifier('j;', '⌥'),

duoModifier('kl', '⇧'),

duoModifier('hk', '⌘⇧'),
duoModifier('hl', '⌃⇧'),
duoModifier('h;', '⌥⇧'),

duoModifier('m,', '⌘⌥'),
duoModifier('m.', '⌘⌃'),
duoModifier(',.', '⌥⌃'),

duoModifier('m/', '⌘⌥⌃'),
]),
]

-

Open and edit the code in the online editor, -or copy the JSON below and add it to Karabiner-Elements without changes:

-
{
"description": "duo-modifiers",
"manipulators": [
{
"type": "basic",
"from": {
"simultaneous": [
{
"key_code": "f"
},
{
"key_code": "d"
}
]
},
"to": [
{
"key_code": "left_command",
"modifiers": []
}
]
},
{
"type": "basic",
"from": {
"simultaneous": [
{
"key_code": "f"
},
{
"key_code": "s"
}
]
},
"to": [
{
"key_code": "left_control",
"modifiers": []
}
]
},
{
"type": "basic",
"from": {
"simultaneous": [
{
"key_code": "f"
},
{
"key_code": "a"
}
]
},
"to": [
{
"key_code": "left_option",
"modifiers": []
}
]
},
{
"type": "basic",
"from": {
"simultaneous": [
{
"key_code": "d"
},
{
"key_code": "s"
}
]
},
"to": [
{
"key_code": "left_shift",
"modifiers": []
}
]
},
{
"type": "basic",
"from": {
"simultaneous": [
{
"key_code": "g"
},
{
"key_code": "d"
}
]
},
"to": [
{
"key_code": "left_command",
"modifiers": [
"shift"
]
}
]
},
{
"type": "basic",
"from": {
"simultaneous": [
{
"key_code": "g"
},
{
"key_code": "s"
}
]
},
"to": [
{
"key_code": "left_control",
"modifiers": [
"shift"
]
}
]
},
{
"type": "basic",
"from": {
"simultaneous": [
{
"key_code": "g"
},
{
"key_code": "a"
}
]
},
"to": [
{
"key_code": "left_option",
"modifiers": [
"shift"
]
}
]
},
{
"type": "basic",
"from": {
"simultaneous": [
{
"key_code": "v"
},
{
"key_code": "c"
}
]
},
"to": [
{
"key_code": "left_command",
"modifiers": [
"option"
]
}
]
},
{
"type": "basic",
"from": {
"simultaneous": [
{
"key_code": "v"
},
{
"key_code": "x"
}
]
},
"to": [
{
"key_code": "left_command",
"modifiers": [
"control"
]
}
]
},
{
"type": "basic",
"from": {
"simultaneous": [
{
"key_code": "c"
},
{
"key_code": "x"
}
]
},
"to": [
{
"key_code": "left_option",
"modifiers": [
"control"
]
}
]
},
{
"type": "basic",
"from": {
"simultaneous": [
{
"key_code": "v"
},
{
"key_code": "z"
}
]
},
"to": [
{
"key_code": "left_command",
"modifiers": [
"option",
"control"
]
}
]
},
{
"type": "basic",
"from": {
"simultaneous": [
{
"key_code": "j"
},
{
"key_code": "k"
}
]
},
"to": [
{
"key_code": "left_command",
"modifiers": []
}
]
},
{
"type": "basic",
"from": {
"simultaneous": [
{
"key_code": "j"
},
{
"key_code": "l"
}
]
},
"to": [
{
"key_code": "left_control",
"modifiers": []
}
]
},
{
"type": "basic",
"from": {
"simultaneous": [
{
"key_code": "j"
},
{
"key_code": "semicolon"
}
]
},
"to": [
{
"key_code": "left_option",
"modifiers": []
}
]
},
{
"type": "basic",
"from": {
"simultaneous": [
{
"key_code": "k"
},
{
"key_code": "l"
}
]
},
"to": [
{
"key_code": "left_shift",
"modifiers": []
}
]
},
{
"type": "basic",
"from": {
"simultaneous": [
{
"key_code": "h"
},
{
"key_code": "k"
}
]
},
"to": [
{
"key_code": "left_command",
"modifiers": [
"shift"
]
}
]
},
{
"type": "basic",
"from": {
"simultaneous": [
{
"key_code": "h"
},
{
"key_code": "l"
}
]
},
"to": [
{
"key_code": "left_control",
"modifiers": [
"shift"
]
}
]
},
{
"type": "basic",
"from": {
"simultaneous": [
{
"key_code": "h"
},
{
"key_code": "semicolon"
}
]
},
"to": [
{
"key_code": "left_option",
"modifiers": [
"shift"
]
}
]
},
{
"type": "basic",
"from": {
"simultaneous": [
{
"key_code": "m"
},
{
"key_code": "comma"
}
]
},
"to": [
{
"key_code": "left_command",
"modifiers": [
"option"
]
}
]
},
{
"type": "basic",
"from": {
"simultaneous": [
{
"key_code": "m"
},
{
"key_code": "period"
}
]
},
"to": [
{
"key_code": "left_command",
"modifiers": [
"control"
]
}
]
},
{
"type": "basic",
"from": {
"simultaneous": [
{
"key_code": "comma"
},
{
"key_code": "period"
}
]
},
"to": [
{
"key_code": "left_option",
"modifiers": [
"control"
]
}
]
},
{
"type": "basic",
"from": {
"simultaneous": [
{
"key_code": "m"
},
{
"key_code": "slash"
}
]
},
"to": [
{
"key_code": "left_command",
"modifiers": [
"option",
"control"
]
}
]
}
]
}
\ No newline at end of file +
tip

When get started, it can be very useful to show a notification when the mod(s) +are activated.

+

Example code: ( Open in the online editor → )

+
let rules = [
rule('duo-modifiers').manipulators(
duoModifiers({
'⌘': ['fd', 'jk'], // ⌘ first as used the most
'⌃': ['fs', 'jl'], // ⌃ second as Vim uses it
'⌥': ['fa', 'j;'], // ⌥ last as used the least

'⇧': ['ds', 'kl'],

'⌘⇧': ['gd', 'hk'],
'⌃⇧': ['gs', 'hl'],
'⌥⇧': ['ga', 'h;'],

'⌘⌥': ['vc', 'm,'],
'⌘⌃': ['vx', 'm.'],
'⌥⌃': ['cx', ',.'],

'⌘⌥⌃': ['vz', 'm/'],
}),
),
]

function duoModifiers(
v: Partial<
Record<
'⌘' | '⌥' | '⌃' | '⇧' | MultiModifierAlias,
`${LetterKeyCode | KeyAlias}${LetterKeyCode | KeyAlias}`[]
>
>,
) {
let result = []

for (let [m, k] of Object.entries(v)) {
for (let keys of k) {
let id = k + m
let [firstMod, ...restMods] = (
m in modifierKeyAliases
? [modifierKeyAliases[m as ModifierKeyAlias]]
: multiModifierAliases[m as MultiModifierAlias]
) as Array<'command' | 'control' | 'option' | 'shift'>

let to_after_key_up = [toRemoveNotificationMessage(id)]
result.push(
mapSimultaneous(keys.split('') as (LetterKeyCode | KeyAlias)[], {
to_after_key_up,
})
.toNotificationMessage(id, m) // Must go first or to() doesn't work
.to(`left_${firstMod}`, restMods),
)
}
}

return result
}

\ No newline at end of file diff --git a/examples/os-functionality/launch-apps-layer/index.html b/examples/os-functionality/launch-apps-layer/index.html index 6187c2b..e338e4c 100644 --- a/examples/os-functionality/launch-apps-layer/index.html +++ b/examples/os-functionality/launch-apps-layer/index.html @@ -1,6 +1,6 @@ -Launch Apps | Layer | karabiner.ts

Launch Apps | Layer

Launch apps by layer + keys. When press and hold key l to activate the 'launch-app' layer:

  • c: Calendar
  • @@ -12,7 +12,5 @@
  • hyperLayer('l', 'launch-app')
  • duoLayer('l', ';', 'launch-app')
-
let rules = [
layer('l', 'launch-app').manipulators({
c: toApp('Calendar'),
f: toApp('Finder'),
}),
]

-

Open and edit the code in the online editor, -or copy the JSON below and add it to Karabiner-Elements without changes:

-
{
"description": "Layer - launch-app",
"manipulators": [
{
"type": "basic",
"from": {
"key_code": "l"
},
"to": [
{
"set_variable": {
"name": "launch-app",
"value": 1
}
},
{
"set_variable": {
"name": "__layer",
"value": 1
}
}
],
"conditions": [
{
"type": "variable_unless",
"name": "launch-app",
"value": 1
},
{
"type": "variable_unless",
"name": "__layer",
"value": 1
}
],
"to_if_alone": [
{
"key_code": "l"
}
],
"to_after_key_up": [
{
"set_variable": {
"name": "launch-app",
"value": 0
}
},
{
"set_variable": {
"name": "__layer",
"value": 0
}
}
]
},
{
"type": "basic",
"from": {
"key_code": "c"
},
"to": [
{
"shell_command": "open -a \"Calendar\".app"
}
],
"conditions": [
{
"type": "variable_if",
"name": "launch-app",
"value": 1
}
]
},
{
"type": "basic",
"from": {
"key_code": "f"
},
"to": [
{
"shell_command": "open -a \"Finder\".app"
}
],
"conditions": [
{
"type": "variable_if",
"name": "launch-app",
"value": 1
}
]
}
]
}
\ No newline at end of file +

Example code: ( Open in the online editor → )

+
let rules = [
layer('l', 'launch-app').manipulators({
c: toApp('Calendar'),
f: toApp('Finder'),
}),
]

\ No newline at end of file diff --git a/examples/os-functionality/launch-apps-modifier/index.html b/examples/os-functionality/launch-apps-modifier/index.html index cb15b72..ef8f20e 100644 --- a/examples/os-functionality/launch-apps-modifier/index.html +++ b/examples/os-functionality/launch-apps-modifier/index.html @@ -1,13 +1,11 @@ -Launch Apps | Modifier | karabiner.ts

Launch Apps | Modifier

Launch apps by modifier + keys.

  • right control + c: Calendar
  • right control + f: Finder

To use multiple modifiers, use an array, like

withModifier(['left_control', 'left_option'])
// or use alias:
withModifier('‹⌃⌥')
-
let rules = [
rule('Launch Apps').manipulators([
withModifier('right_control')({
c: toApp('Calendar'),
f: toApp('Finder'),
}),
]),
]

-

Open and edit the code in the online editor, -or copy the JSON below and add it to Karabiner-Elements without changes:

-
{
"description": "Launch Apps",
"manipulators": [
{
"type": "basic",
"from": {
"key_code": "c",
"modifiers": {
"mandatory": [
"right_control"
]
}
},
"to": [
{
"shell_command": "open -a \"Calendar\".app"
}
]
},
{
"type": "basic",
"from": {
"key_code": "f",
"modifiers": {
"mandatory": [
"right_control"
]
}
},
"to": [
{
"shell_command": "open -a \"Finder\".app"
}
]
}
]
}
\ No newline at end of file +

Example code: ( Open in the online editor → )

+
let rules = [
rule('Launch Apps').manipulators([
withModifier('right_control')({
c: toApp('Calendar'),
f: toApp('Finder'),
}),
]),
]

\ No newline at end of file diff --git a/examples/text-input/emoji/index.html b/examples/text-input/emoji/index.html index 5366690..48e3453 100644 --- a/examples/text-input/emoji/index.html +++ b/examples/text-input/emoji/index.html @@ -1,6 +1,6 @@ -Input emoji | karabiner.ts

Input emoji

Input emoji by layer + keys. When press and hold key z to activate the 'emoji' layer:

  • j: 😂 (joy)
  • @@ -11,7 +11,5 @@
  • hyperLayer('z', 'emoji')
  • duoLayer('z', 'x', 'emoji')
-
let rules = [
layer('z', 'emoji').manipulators({
j: toPaste('😂'), // joy
}),
]

-

Open and edit the code in the online editor, -or copy the JSON below and add it to Karabiner-Elements without changes:

-
{
"description": "Layer - emoji",
"manipulators": [
{
"type": "basic",
"from": {
"key_code": "z"
},
"to": [
{
"set_variable": {
"name": "emoji",
"value": 1
}
},
{
"set_variable": {
"name": "__layer",
"value": 1
}
}
],
"conditions": [
{
"type": "variable_unless",
"name": "emoji",
"value": 1
},
{
"type": "variable_unless",
"name": "__layer",
"value": 1
}
],
"to_if_alone": [
{
"key_code": "z"
}
],
"to_after_key_up": [
{
"set_variable": {
"name": "emoji",
"value": 0
}
},
{
"set_variable": {
"name": "__layer",
"value": 0
}
}
]
},
{
"type": "basic",
"from": {
"key_code": "j"
},
"to": [
{
"shell_command": "osascript -e '\nset prev to the clipboard\nset the clipboard to \"😂\"\ntell application \"System Events\"\n keystroke \"v\" using command down\n delay 0.1\nend tell\nset the clipboard to prev'"
}
],
"conditions": [
{
"type": "variable_if",
"name": "emoji",
"value": 1
}
]
}
]
}
\ No newline at end of file +

Example code: ( Open in the online editor → )

+
let rules = [
layer('z', 'emoji').manipulators({
j: toPaste('😂'), // joy
}),
]

\ No newline at end of file diff --git a/examples/text-input/symbols/index.html b/examples/text-input/symbols/index.html index e0ed492..14fd3dd 100644 --- a/examples/text-input/symbols/index.html +++ b/examples/text-input/symbols/index.html @@ -1,6 +1,6 @@ -Input symbols | karabiner.ts

Input symbols

Input symbols (which can be used as key alias) by layer + keys. When press and hold key z to activate the 'symbols' layer:

  • , , , , , , , : Paste the symbol.
  • @@ -20,7 +20,5 @@
  • hyperLayer('z', 'symbols')
  • duoLayer('z', 'x', 'symbols')
-
let rules = [
layer('z', 'symbols').manipulators([
withMapper(['←', '→', '↑', '↓', '␣', '⏎', '⌫', '⌦'])((k) =>
map(k).toPaste(k),
),

{ ',': toPaste('‹'), '.': toPaste('›') },

withMapper({ 4: '⇥', 5: '⎋', 6: '⌘', 7: '⌥', 8: '⌃', 9: '⇧', 0: '⇪' })(
(k, v) => map(k).toPaste(v),
),
]),
]

-

Open and edit the code in the online editor, -or copy the JSON below and add it to Karabiner-Elements without changes:

-
{
"description": "Layer - symbols",
"manipulators": [
{
"type": "basic",
"from": {
"key_code": "z"
},
"to": [
{
"set_variable": {
"name": "symbols",
"value": 1
}
},
{
"set_variable": {
"name": "__layer",
"value": 1
}
}
],
"conditions": [
{
"type": "variable_unless",
"name": "symbols",
"value": 1
},
{
"type": "variable_unless",
"name": "__layer",
"value": 1
}
],
"to_if_alone": [
{
"key_code": "z"
}
],
"to_after_key_up": [
{
"set_variable": {
"name": "symbols",
"value": 0
}
},
{
"set_variable": {
"name": "__layer",
"value": 0
}
}
]
},
{
"type": "basic",
"from": {
"key_code": "left_arrow"
},
"to": [
{
"shell_command": "osascript -e '\nset prev to the clipboard\nset the clipboard to \"←\"\ntell application \"System Events\"\n keystroke \"v\" using command down\n delay 0.1\nend tell\nset the clipboard to prev'"
}
],
"conditions": [
{
"type": "variable_if",
"name": "symbols",
"value": 1
}
]
},
{
"type": "basic",
"from": {
"key_code": "right_arrow"
},
"to": [
{
"shell_command": "osascript -e '\nset prev to the clipboard\nset the clipboard to \"→\"\ntell application \"System Events\"\n keystroke \"v\" using command down\n delay 0.1\nend tell\nset the clipboard to prev'"
}
],
"conditions": [
{
"type": "variable_if",
"name": "symbols",
"value": 1
}
]
},
{
"type": "basic",
"from": {
"key_code": "up_arrow"
},
"to": [
{
"shell_command": "osascript -e '\nset prev to the clipboard\nset the clipboard to \"↑\"\ntell application \"System Events\"\n keystroke \"v\" using command down\n delay 0.1\nend tell\nset the clipboard to prev'"
}
],
"conditions": [
{
"type": "variable_if",
"name": "symbols",
"value": 1
}
]
},
{
"type": "basic",
"from": {
"key_code": "down_arrow"
},
"to": [
{
"shell_command": "osascript -e '\nset prev to the clipboard\nset the clipboard to \"↓\"\ntell application \"System Events\"\n keystroke \"v\" using command down\n delay 0.1\nend tell\nset the clipboard to prev'"
}
],
"conditions": [
{
"type": "variable_if",
"name": "symbols",
"value": 1
}
]
},
{
"type": "basic",
"from": {
"key_code": "spacebar"
},
"to": [
{
"shell_command": "osascript -e '\nset prev to the clipboard\nset the clipboard to \"␣\"\ntell application \"System Events\"\n keystroke \"v\" using command down\n delay 0.1\nend tell\nset the clipboard to prev'"
}
],
"conditions": [
{
"type": "variable_if",
"name": "symbols",
"value": 1
}
]
},
{
"type": "basic",
"from": {
"key_code": "return_or_enter"
},
"to": [
{
"shell_command": "osascript -e '\nset prev to the clipboard\nset the clipboard to \"⏎\"\ntell application \"System Events\"\n keystroke \"v\" using command down\n delay 0.1\nend tell\nset the clipboard to prev'"
}
],
"conditions": [
{
"type": "variable_if",
"name": "symbols",
"value": 1
}
]
},
{
"type": "basic",
"from": {
"key_code": "delete_or_backspace"
},
"to": [
{
"shell_command": "osascript -e '\nset prev to the clipboard\nset the clipboard to \"⌫\"\ntell application \"System Events\"\n keystroke \"v\" using command down\n delay 0.1\nend tell\nset the clipboard to prev'"
}
],
"conditions": [
{
"type": "variable_if",
"name": "symbols",
"value": 1
}
]
},
{
"type": "basic",
"from": {
"key_code": "delete_forward"
},
"to": [
{
"shell_command": "osascript -e '\nset prev to the clipboard\nset the clipboard to \"⌦\"\ntell application \"System Events\"\n keystroke \"v\" using command down\n delay 0.1\nend tell\nset the clipboard to prev'"
}
],
"conditions": [
{
"type": "variable_if",
"name": "symbols",
"value": 1
}
]
},
{
"type": "basic",
"from": {
"key_code": "comma"
},
"to": [
{
"shell_command": "osascript -e '\nset prev to the clipboard\nset the clipboard to \"‹\"\ntell application \"System Events\"\n keystroke \"v\" using command down\n delay 0.1\nend tell\nset the clipboard to prev'"
}
],
"conditions": [
{
"type": "variable_if",
"name": "symbols",
"value": 1
}
]
},
{
"type": "basic",
"from": {
"key_code": "period"
},
"to": [
{
"shell_command": "osascript -e '\nset prev to the clipboard\nset the clipboard to \"›\"\ntell application \"System Events\"\n keystroke \"v\" using command down\n delay 0.1\nend tell\nset the clipboard to prev'"
}
],
"conditions": [
{
"type": "variable_if",
"name": "symbols",
"value": 1
}
]
},
{
"type": "basic",
"from": {
"key_code": "0"
},
"to": [
{
"shell_command": "osascript -e '\nset prev to the clipboard\nset the clipboard to \"⇪\"\ntell application \"System Events\"\n keystroke \"v\" using command down\n delay 0.1\nend tell\nset the clipboard to prev'"
}
],
"conditions": [
{
"type": "variable_if",
"name": "symbols",
"value": 1
}
]
},
{
"type": "basic",
"from": {
"key_code": "4"
},
"to": [
{
"shell_command": "osascript -e '\nset prev to the clipboard\nset the clipboard to \"⇥\"\ntell application \"System Events\"\n keystroke \"v\" using command down\n delay 0.1\nend tell\nset the clipboard to prev'"
}
],
"conditions": [
{
"type": "variable_if",
"name": "symbols",
"value": 1
}
]
},
{
"type": "basic",
"from": {
"key_code": "5"
},
"to": [
{
"shell_command": "osascript -e '\nset prev to the clipboard\nset the clipboard to \"⎋\"\ntell application \"System Events\"\n keystroke \"v\" using command down\n delay 0.1\nend tell\nset the clipboard to prev'"
}
],
"conditions": [
{
"type": "variable_if",
"name": "symbols",
"value": 1
}
]
},
{
"type": "basic",
"from": {
"key_code": "6"
},
"to": [
{
"shell_command": "osascript -e '\nset prev to the clipboard\nset the clipboard to \"⌘\"\ntell application \"System Events\"\n keystroke \"v\" using command down\n delay 0.1\nend tell\nset the clipboard to prev'"
}
],
"conditions": [
{
"type": "variable_if",
"name": "symbols",
"value": 1
}
]
},
{
"type": "basic",
"from": {
"key_code": "7"
},
"to": [
{
"shell_command": "osascript -e '\nset prev to the clipboard\nset the clipboard to \"⌥\"\ntell application \"System Events\"\n keystroke \"v\" using command down\n delay 0.1\nend tell\nset the clipboard to prev'"
}
],
"conditions": [
{
"type": "variable_if",
"name": "symbols",
"value": 1
}
]
},
{
"type": "basic",
"from": {
"key_code": "8"
},
"to": [
{
"shell_command": "osascript -e '\nset prev to the clipboard\nset the clipboard to \"⌃\"\ntell application \"System Events\"\n keystroke \"v\" using command down\n delay 0.1\nend tell\nset the clipboard to prev'"
}
],
"conditions": [
{
"type": "variable_if",
"name": "symbols",
"value": 1
}
]
},
{
"type": "basic",
"from": {
"key_code": "9"
},
"to": [
{
"shell_command": "osascript -e '\nset prev to the clipboard\nset the clipboard to \"⇧\"\ntell application \"System Events\"\n keystroke \"v\" using command down\n delay 0.1\nend tell\nset the clipboard to prev'"
}
],
"conditions": [
{
"type": "variable_if",
"name": "symbols",
"value": 1
}
]
}
]
}
\ No newline at end of file +

Example code: ( Open in the online editor → )

+
let rules = [
layer('z', 'symbols').manipulators([
withMapper(['←', '→', '↑', '↓', '␣', '⏎', '⌫', '⌦'])((k) =>
map(k).toPaste(k),
),

{ ',': toPaste('‹'), '.': toPaste('›') },

withMapper({ 4: '⇥', 5: '⎋', 6: '⌘', 7: '⌥', 8: '⌃', 9: '⇧', 0: '⇪' })(
(k, v) => map(k).toPaste(v),
),
]),
]

\ No newline at end of file diff --git a/examples/vim/leader/index.html b/examples/vim/leader/index.html new file mode 100644 index 0000000..79dc4a8 --- /dev/null +++ b/examples/vim/leader/index.html @@ -0,0 +1,9 @@ +Leader key | karabiner.ts

Leader key

To nest leader keys, use variables on leaderMode().

+
    +
  • leader o f: Open Finder
  • +
  • leader r e: Raycast Emoji Picker
  • +
+

Example code: ( Open in the online editor → )

+
let escapeLeader = ['__layer', 'leader', 'leader--'].map(toUnsetVar)
let raycastEmoji = 'emoji-symbols/search-emoji-symbols'

let rules = [
hyperLayer('l', 'leader')
.leaderMode({ sticky: true, escape: [] })
.manipulators([
map('escape').to(escapeLeader),

map('o').toVar('leader--', 'o'), // Open
withCondition(ifVar('leader--', 'o'))([
withMapper([
map('f').toApp('Finder'), // Open Finder
])((x) => x.to(escapeLeader)),
]),

map('r').toVar('leader--', 'r'), // Raycast
withCondition(ifVar('leader--', 'r'))([
withMapper([
map('e').to$(`open raycast://extensions/raycast/${raycastEmoji}`),
])((x) => x.to(escapeLeader)),
]),
]),
]

\ No newline at end of file diff --git a/imports/index.html b/imports/index.html index 236e1af..36e935a 100644 --- a/imports/index.html +++ b/imports/index.html @@ -1,6 +1,6 @@ -Imports | karabiner.ts

Imports

Config created by other tools, or those imported from shared rules, can be imported into karabiner.ts instead of being rewritten.

importJson()

diff --git a/index.html b/index.html index 82a788b..5893d57 100644 --- a/index.html +++ b/index.html @@ -1,6 +1,6 @@ -Intro | karabiner.ts

karabiner.ts

Karabiner-Elements configuration file is in JSON format.

~/.config/karabiner/karabiner.json
{
"profiles": [
{
"name": "Default", // 1
"complex_modifications": {
"rules": [ // 2
{
"description": "Demo Rule",
"manipulators": [ // 3
{
"type": "basic",
"from": { "key_code": "caps_lock" }, // 4
"to": [ // 5
{"key_code": "delete_or_backspace", "modifiers": ["command"]}
],
"conditions": [ // 6
{"type": "variable_if", "name": "test", "value": 1}
]
}
]
}
]
}
}
]
}
diff --git a/manipulators/condition/index.html b/manipulators/condition/index.html index 4d10e17..db3aadb 100644 --- a/manipulators/condition/index.html +++ b/manipulators/condition/index.html @@ -1,6 +1,6 @@ -condition / if*() | karabiner.ts

condition

Most of the features are implemented by adding variable conditions to manipulators. There are a few other types of conditions too.

Condition type
type Condition =
| ({
type: 'frontmost_application_if' | 'frontmost_application_unless'
description?: string
} & ({ bundle_identifiers: string[] } | { file_paths: string[] }))
| {
type:
| 'device_if'
| 'device_unless'
| 'device_exists_if'
| 'device_exists_unless'
identifiers: DeviceIdentifier[]
description?: string
}
| {
type: 'keyboard_type_if' | 'keyboard_type_unless'
keyboard_types: KeyboardType[]
description?: string
}
| {
type: 'input_source_if' | 'input_source_unless'
input_sources: InputSource[]
description?: string
}
| {
type: 'variable_if' | 'variable_unless'
name: string
value: number | boolean | string
description?: string
}
| {
type: 'event_changed_if' | 'event_changed_unless'
value: boolean
description?: string
}
diff --git a/manipulators/double-tap/index.html b/manipulators/double-tap/index.html index e8f762e..bc121a0 100644 --- a/manipulators/double-tap/index.html +++ b/manipulators/double-tap/index.html @@ -1,6 +1,6 @@ -from / mapDoubleTap() | karabiner.ts

mapDoubleTap()

mapDoubleTap('↑').to('↖︎') // double tap up_arrow -> home
Generated JSON
[
{
"type": "basic",
"from": {"key_code": "up_arrow"},
"to": [
{"key_code": "home"}
],
"conditions": [
{"type": "variable_if", "name": "double-tap-up_arrow", "value": 1}
]
},
{
"type": "basic",
"from": {"key_code": "up_arrow"},
"to": [
{"set_variable": {"name": "double-tap-up_arrow", "value": 1}}
],
"conditions": [
{"type": "variable_unless", "name": "double-tap-up_arrow", "value": 1}
],
"to_delayed_action": {
"to_if_canceled": [
{"set_variable": {"name": "double-tap-up_arrow", "value": 0}}
],
"to_if_invoked": [
{"set_variable": {"name": "double-tap-up_arrow", "value": 0}},
{"key_code": "up_arrow"}
]
},
"parameters": {
"basic.to_delayed_action_delay_milliseconds": 200
}
}
]

How doubleTap() works

diff --git a/manipulators/from/index.html b/manipulators/from/index.html index 7bb518e..63dce19 100644 --- a/manipulators/from/index.html +++ b/manipulators/from/index.html @@ -1,6 +1,6 @@ -from / map*() | karabiner.ts

FromEvent and map*()

map() takes any valid full from event definition.

map({ key_code: 'a', modifiers: { mandatory: ['left_command'] } })
FromEvent type
export type FromEvent = (
| { key_code: string | number }
| { consumer_key_code: string | number }
| { pointing_button: string | number }
| { any: 'key_code' | 'consumer_key_code' | 'pointing_button' }
| { simultaneous: Array</*...*/>, simultaneous_options?: {/*...*/} }
) & {
modifiers?: { mandatory?: [/*...*/], optional?: [/*...*/] }
}
diff --git a/manipulators/mouse_motion_to_scroll/index.html b/manipulators/mouse_motion_to_scroll/index.html index e4a65a3..3c34c02 100644 --- a/manipulators/mouse_motion_to_scroll/index.html +++ b/manipulators/mouse_motion_to_scroll/index.html @@ -1,6 +1,6 @@ -type: mouse_motion_to_scroll | karabiner.ts

type: mouse_motion_to_scroll

Most manipulators have type basic. Another manipulator type in Karabiner-Elements is mouse_motion_to_scroll.

type MouseMotionToScrollManipulator = {
type: 'mouse_motion_to_scroll'
from?: { modifiers: FromModifiers }
conditions?: BasicManipulator['conditions']
options?: {
momentum_scroll_enabled?: boolean
speed_multiplier?: number
}
}
diff --git a/manipulators/to/index.html b/manipulators/to/index.html index 7511317..5c04424 100644 --- a/manipulators/to/index.html +++ b/manipulators/to/index.html @@ -1,6 +1,6 @@ -to*() | karabiner.ts

ToEvent

ToEvent type models Karabiner to event definition.

ToEvent type
export type ToEvent = (
| { key_code: string | number }
| { consumer_key_code: string | number }
| { pointing_button: string | number }
| { shell_command: string }
| {
select_input_source: {
language?: string
input_source_id?: string
input_mode_id?: string
}
}
| {
set_variable: {
name: string
value: number | boolean | string
}
}
| { set_notification_message: { id: string; text: string } }
| {
mouse_key: {
x?: number
y?: number
vertical_wheel?: number
horizontal_wheel?: number
speed_multiplier?: number
}
}
| {
sticky_modifier: Partial<
Record<
| 'left_control'
| 'left_shift'
| 'left_option'
| 'left_command'
| 'right_control'
| 'right_shift'
| 'right_option'
| 'right_command'
| 'fn',
'on' | 'off' | 'toggle'
>
>
}
| {
software_function:
| { cg_event_double_click: { button: number } }
| {
set_mouse_cursor_position: {
x: number | `${number}%`
y: number | `${number}%`
screen?: number
}
}
| {
iokit_power_management_sleep_system: { delay_milliseconds?: number }
}
}
) & {
modifiers?: Array<
| 'left_control'
| 'left_shift'
| 'left_option'
| 'left_command'
| 'right_control'
| 'right_shift'
| 'right_option'
| 'right_command'
| 'fn'
| 'caps_lock'
| 'command'
| 'control'
| 'option'
| 'shift'
>
lazy?: boolean
repeat?: boolean
halt?: boolean
hold_down_milliseconds?: number
}

Create ToEvent

diff --git a/rules/duo-layer/index.html b/rules/duo-layer/index.html index b8f0114..83809fd 100644 --- a/rules/duo-layer/index.html +++ b/rules/duo-layer/index.html @@ -1,6 +1,6 @@ -duoLayer() | karabiner.ts

duoLayer()

Duo layer is a step further of hyper layer inspired by @mxstbr's Karabiner Elements configuration. Instead of using hyper or any modifier(s), duo layer use any 2 keys together as the layer trigger, like f + d, which is normally easier to press than f + hyper.

duoLayer('f', 'd').manipulators([
map(1).to(2)
])
diff --git a/rules/hyper-layer/index.html b/rules/hyper-layer/index.html index 126877d..cf75b5d 100644 --- a/rules/hyper-layer/index.html +++ b/rules/hyper-layer/index.html @@ -1,6 +1,6 @@ -hyperLayer() / modifierLayer() | karabiner.ts

hyperLayer()

Hyper layer is inspired by @mxstbr's Karabiner Elements configuration. It requires the hyper key (⌘⌥⌃⇧) be pressed with the layer key to trigger the layer, which avoids the 2 problems from layer/simlayer:

diff --git a/rules/layer/index.html b/rules/layer/index.html index 522abeb..e4f1e66 100644 --- a/rules/layer/index.html +++ b/rules/layer/index.html @@ -1,6 +1,6 @@ -layer() | karabiner.ts

layer()

Layer is a group of manipulators which are only active when a key is pressed and held.

layer('a', 'a-mode').manipulators([
map(1).to(2), // Only when key 'a' is pressed and held
])
Generated JSON in profiles.complex_modifications.rules
{
"description": "Layer - a-mode",
"manipulators": [
{
"type": "basic",
"from": { "key_code": "a" },
"to": [ {"set_variable": {"name": "a-mode", "value": 1}} ],
"to_after_key_up": [ {"set_variable": {"name": "a-mode", "value": 0}} ],
"to_if_alone": [ {"key_code": "a"} ]
},
{
"type": "basic",
"from": {"key_code": "1"},
"to": [{"key_code": "2"}],
"conditions": [ { "type": "variable_if", "name": "a-mode", "value": 1 } ]
}
]
}

How layer works

diff --git a/rules/leader-mode/index.html b/rules/leader-mode/index.html index 081b774..5a96165 100644 --- a/rules/leader-mode/index.html +++ b/rules/leader-mode/index.html @@ -1,6 +1,6 @@ -layer().leaderMode() | karabiner.ts

Leader Mode

layer() (or hyperLayer() / modifierLayer() / duoLayer()) has a "leader mode", which works similar to Vim leader keys: The layer stays activated even after the layer key is released, until one of the action or escape keys is pressed.

diff --git a/rules/rule/index.html b/rules/rule/index.html index 2e89a73..05ef8af 100644 --- a/rules/rule/index.html +++ b/rules/rule/index.html @@ -1,6 +1,6 @@ -rule() | karabiner.ts

rule()

Use rule() to create a group of manipulators.

rule('Demo').manipulators([
map(1).to(2),
])
Generated JSON in profiles.complex_modifications.rules
{
"description": "Demo",
"manipulators": [
{
"type": "basic",
"from": { "key_code": "1" },
"to": [ { "key_code": "2" } ]
}
]
}

Conditions added to rule() will be added to all manipulators in the group.

diff --git a/rules/simlayer/index.html b/rules/simlayer/index.html index 7d25bbd..e58faf6 100644 --- a/rules/simlayer/index.html +++ b/rules/simlayer/index.html @@ -1,6 +1,6 @@ -simlayer() | karabiner.ts

simlayer()

simlayer('a', 'a-mode').manipulators([
map(1).to(2), // Only when key 'a' is pressed and held, then key '1' right after
])
Generated JSON in profiles.complex_modifications.rules
{
"description": "Simlayer - a-mode",
"manipulators": [
{
"type": "basic",
"from": {"key_code": "1", "modifiers": {"optional": ["any"]}},
"to": [{"key_code": "2"}],
"conditions": [{"type": "variable_if", "name": "a-mode", "value": 1}]
},
{
"type": "basic",
"from": {
"simultaneous": [{"key_code": "a"}, {"key_code": "1"}],
"simultaneous_options": {
"detect_key_down_uninterruptedly": true,
"key_down_order": "strict",
"key_up_order": "strict_inverse",
"key_up_when": "any",
"to_after_key_up": [{"set_variable": {"name": "a-mode", "value": 0}}]
},
"modifiers": {"optional": ["any"]}
},
"to": [{"set_variable": {"name": "a-mode", "value": 1}}, {"key_code": "2"}],
"parameters": {"basic.simultaneous_threshold_milliseconds": 200}
}
]
}

How simlayer works

Simlayer is similar to layer, which add a variable on a group of manipulators. diff --git a/search/index.html b/search/index.html index 68bb594..5c0da15 100644 --- a/search/index.html +++ b/search/index.html @@ -1,3 +1,3 @@ -Search the documentation | karabiner.ts