From 12d1784d2cf465faef03be5608bb77d81d7438d0 Mon Sep 17 00:00:00 2001 From: Evan Liu Date: Sun, 2 Jun 2024 09:50:47 +1200 Subject: [PATCH 1/6] Add simlayer semicolon --- karabiner/karabiner-config/src/index.ts | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/karabiner/karabiner-config/src/index.ts b/karabiner/karabiner-config/src/index.ts index 196e4a5f..182378b1 100644 --- a/karabiner/karabiner-config/src/index.ts +++ b/karabiner/karabiner-config/src/index.ts @@ -1,10 +1,26 @@ -import { simlayer, to$, writeToProfile } from "karabiner.ts" -const $ = to$ +import { FromKeyParam, map, simlayer, to$ as $, ToKeyParam, withMapper, writeToProfile } from "karabiner.ts" writeToProfile( // "--dry-run", // prints to console "karabiner.ts", // adds it to karabiner.ts profile [ + simlayer("semicolon").description('colonkey (shift)').manipulators([ + { + tab: km('Smart Autocomplete & new line'), + escape: km('Smart Autocomplete & new line'), + }, + withMapper([1, 2, 3, 4, 5])((k) => map(k).to(k, '⌃')), + withMapper([ + 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', + 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', '~', + 'z', 'x', 'c', 'v', 'b', 'n', 'm' + ] as Array)((k) => map(k).to(k, '⇧')), + ]), + + simlayer("s").description('skey (essential)').manipulators([ + map('w').to('←', '⌥').to('→', '⌥⇧') // Highlight word + ]), + simlayer("w").manipulators({ e: km("open: Fantastical"), }), From 51492aaf60c9a12d517e7b45e98eb450458fca22 Mon Sep 17 00:00:00 2001 From: Evan Liu Date: Sun, 2 Jun 2024 10:21:41 +1200 Subject: [PATCH 2/6] Add simlayer s --- karabiner/karabiner-config/src/index.ts | 33 +++++++++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-) diff --git a/karabiner/karabiner-config/src/index.ts b/karabiner/karabiner-config/src/index.ts index 182378b1..47f01dfe 100644 --- a/karabiner/karabiner-config/src/index.ts +++ b/karabiner/karabiner-config/src/index.ts @@ -1,4 +1,4 @@ -import { FromKeyParam, map, simlayer, to$ as $, ToKeyParam, withMapper, writeToProfile } from "karabiner.ts" +import { FromKeyParam, map, rule, simlayer, to$ as $, toKey, ToKeyParam, withMapper, withModifier, writeToProfile } from "karabiner.ts" writeToProfile( // "--dry-run", // prints to console @@ -18,7 +18,35 @@ writeToProfile( ]), simlayer("s").description('skey (essential)').manipulators([ - map('w').to('←', '⌥').to('→', '⌥⇧') // Highlight word + map('w').to('←', '⌥').to('→', '⌥⇧'), // Highlight word + map('quote').to('←', '⌘').to('→', '⌘⇧'), // Highlight current line + + // Or map('e').to('⇥'), + { + e: toKey('tab'), + r: toKey('tab', '⇧'), + + a: toKey('c', '⌘'), // Copy + n: toKey('v', '⌘'), // Paste + o: toKey('x', '⌘'), // Cut + }, + + // Or map('h', '??').to('←'), + withModifier('optionalAny')({ + h: toKey('←'), + j: toKey('↓'), + k: toKey('↑'), + l: toKey('→'), + + b: toKey('←', '⌘'), + m: toKey('→', '⌘'), + }), + ]), + + rule('swap : and ;').manipulators([ + // Or map(';', '?⇪').to(';', '⇧'), + map('semicolon', {optional: 'caps_lock'}).to('semicolon', 'shift'), + map('semicolon', 'shift').to('semicolon') ]), simlayer("w").manipulators({ @@ -29,6 +57,7 @@ writeToProfile( "basic.to_if_alone_timeout_milliseconds": 80, "basic.to_if_held_down_threshold_milliseconds": 50, "basic.to_delayed_action_delay_milliseconds": 0, + 'basic.simultaneous_threshold_milliseconds': 30, "simlayer.threshold_milliseconds": 250, } ) From 2a47248f027e3816111a3195200cb3a7188a217c Mon Sep 17 00:00:00 2001 From: Evan Liu Date: Sun, 2 Jun 2024 10:41:18 +1200 Subject: [PATCH 3/6] Add simlayer tab and period --- karabiner/karabiner-config/src/index.ts | 30 ++++++++++++++++++++++--- 1 file changed, 27 insertions(+), 3 deletions(-) diff --git a/karabiner/karabiner-config/src/index.ts b/karabiner/karabiner-config/src/index.ts index 47f01dfe..8b45a255 100644 --- a/karabiner/karabiner-config/src/index.ts +++ b/karabiner/karabiner-config/src/index.ts @@ -1,4 +1,17 @@ -import { FromKeyParam, map, rule, simlayer, to$ as $, toKey, ToKeyParam, withMapper, withModifier, writeToProfile } from "karabiner.ts" +import { + FromAndToKeyCode, + ifVar, + map, + rule, + simlayer, + to$ as $, + toKey, + toTypeSequence, + withCondition, + withMapper, + withModifier, + writeToProfile +} from "karabiner.ts" writeToProfile( // "--dry-run", // prints to console @@ -12,9 +25,9 @@ writeToProfile( withMapper([1, 2, 3, 4, 5])((k) => map(k).to(k, '⌃')), withMapper([ 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', - 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', '~', + 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', 'grave_accent_and_tilde', 'z', 'x', 'c', 'v', 'b', 'n', 'm' - ] as Array)((k) => map(k).to(k, '⇧')), + ] as FromAndToKeyCode[])((k) => map(k).to(k, '⇧')), ]), simlayer("s").description('skey (essential)').manipulators([ @@ -52,6 +65,17 @@ writeToProfile( simlayer("w").manipulators({ e: km("open: Fantastical"), }), + + simlayer('tab').description('tabkey (things)').manipulators([ + map('j').toVar('in-lang', 'ts') + .to(openInBackground('"dash-plugin://query=.tsprofile%3A&prevent_activation=true"')) + ]), + simlayer('period').manipulators([ + withCondition(ifVar('in-lang', 'ts'))({ + a: toTypeSequence('console.log()←'), + s: toTypeSequence('=>␣'), + }), + ]), ], { "basic.to_if_alone_timeout_milliseconds": 80, From 2162f43b93bbc37a831691b4b7aee4f8d7c3239e Mon Sep 17 00:00:00 2001 From: Evan Liu Date: Sun, 2 Jun 2024 19:53:37 +1200 Subject: [PATCH 4/6] Add modifier simlayer --- karabiner/karabiner-config/src/index.ts | 113 ++++++++++++++++-------- 1 file changed, 75 insertions(+), 38 deletions(-) diff --git a/karabiner/karabiner-config/src/index.ts b/karabiner/karabiner-config/src/index.ts index 8b45a255..8d149a07 100644 --- a/karabiner/karabiner-config/src/index.ts +++ b/karabiner/karabiner-config/src/index.ts @@ -1,5 +1,4 @@ import { - FromAndToKeyCode, ifVar, map, rule, @@ -10,70 +9,108 @@ import { withCondition, withMapper, withModifier, - writeToProfile + writeToProfile, } from "karabiner.ts" +const leftSideNums = [1, 2, 3, 4, 5] as const +const rightSideNums = [6, 7, 8, 9, 0] as const +const numbers = [...leftSideNums, ...rightSideNums] as const +// prettier-ignore +const letters = [ + 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', + 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', + 'z', 'x', 'c', 'v', 'b', 'n', 'm' +] as const +const symbols = ["[", "]", ";", "'", ",", ".", "/"] as const +const lettersAndSymbols = [...letters, ...symbols] as const +const allKeys = [...numbers, ...letters, ...symbols] as const + writeToProfile( // "--dry-run", // prints to console "karabiner.ts", // adds it to karabiner.ts profile [ - simlayer("semicolon").description('colonkey (shift)').manipulators([ + // colonkey (shift) + simlayer("semicolon").manipulators([ { - tab: km('Smart Autocomplete & new line'), - escape: km('Smart Autocomplete & new line'), + tab: km("Smart Autocomplete & new line"), + escape: km("Smart Autocomplete & new line"), }, - withMapper([1, 2, 3, 4, 5])((k) => map(k).to(k, '⌃')), - withMapper([ - 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', - 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', 'grave_accent_and_tilde', - 'z', 'x', 'c', 'v', 'b', 'n', 'm' - ] as FromAndToKeyCode[])((k) => map(k).to(k, '⇧')), + withMapper(leftSideNums)((k) => map(k).to(k, "⌃")), + withMapper([...letters, "`"])((k) => map(k).to(k, "⇧")), ]), - simlayer("s").description('skey (essential)').manipulators([ - map('w').to('←', '⌥').to('→', '⌥⇧'), // Highlight word - map('quote').to('←', '⌘').to('→', '⌘⇧'), // Highlight current line + // qkey (cmd + shift) + simlayer("q").manipulators([ + withMapper([3, 4, ...rightSideNums, ...lettersAndSymbols])((k) => + map(k).to(k, "⌘⇧") + ), + map("␣").to("e", "⌘⌥⇧"), // Selection -> YouTube + ]), + + // ekey (cmd) + simlayer("e").manipulators([ + withMapper(allKeys)((k) => map(k).to(k, "⌘")), + { "␣": km("Explain selected text with ChatGPT") }, + ]), + + // akey (ctrl) + simlayer("a").manipulators([ + withMapper(allKeys)((k) => map(k).to(k, "⌃")), + map("␣").to(9, "⌘⌃"), // Selection -> Google + ]), + + // skey (essential) + simlayer("s").manipulators([ + map("w").to("←", "⌥").to("→", "⌥⇧"), // Highlight word + map("quote").to("←", "⌘").to("→", "⌘⇧"), // Highlight current line // Or map('e').to('⇥'), { - e: toKey('tab'), - r: toKey('tab', '⇧'), + e: toKey("tab"), + r: toKey("tab", "⇧"), - a: toKey('c', '⌘'), // Copy - n: toKey('v', '⌘'), // Paste - o: toKey('x', '⌘'), // Cut + a: toKey("c", "⌘"), // Copy + n: toKey("v", "⌘"), // Paste + o: toKey("x", "⌘"), // Cut }, // Or map('h', '??').to('←'), - withModifier('optionalAny')({ - h: toKey('←'), - j: toKey('↓'), - k: toKey('↑'), - l: toKey('→'), - - b: toKey('←', '⌘'), - m: toKey('→', '⌘'), + withModifier("optionalAny")({ + h: toKey("←"), + j: toKey("↓"), + k: toKey("↑"), + l: toKey("→"), + + b: toKey("←", "⌘"), + m: toKey("→", "⌘"), }), ]), - rule('swap : and ;').manipulators([ + rule("swap : and ;").manipulators([ // Or map(';', '?⇪').to(';', '⇧'), - map('semicolon', {optional: 'caps_lock'}).to('semicolon', 'shift'), - map('semicolon', 'shift').to('semicolon') + map("semicolon", { optional: "caps_lock" }).to("semicolon", "shift"), + map("semicolon", "shift").to("semicolon"), ]), simlayer("w").manipulators({ e: km("open: Fantastical"), }), - simlayer('tab').description('tabkey (things)').manipulators([ - map('j').toVar('in-lang', 'ts') - .to(openInBackground('"dash-plugin://query=.tsprofile%3A&prevent_activation=true"')) + // tabkey (things) + simlayer("tab").manipulators([ + map("j") + .toVar("in-lang", "ts") + .to( + openInBackground( + '"dash-plugin://query=.tsprofile%3A&prevent_activation=true"' + ) + ), ]), - simlayer('period').manipulators([ - withCondition(ifVar('in-lang', 'ts'))({ - a: toTypeSequence('console.log()←'), - s: toTypeSequence('=>␣'), + + simlayer("period").manipulators([ + withCondition(ifVar("in-lang", "ts"))({ + a: toTypeSequence("console.log()←"), + s: toTypeSequence("=>␣"), }), ]), ], @@ -81,7 +118,7 @@ writeToProfile( "basic.to_if_alone_timeout_milliseconds": 80, "basic.to_if_held_down_threshold_milliseconds": 50, "basic.to_delayed_action_delay_milliseconds": 0, - 'basic.simultaneous_threshold_milliseconds': 30, + "basic.simultaneous_threshold_milliseconds": 30, "simlayer.threshold_milliseconds": 250, } ) From 9cf4d392b347d410df111ec27d62cb585d768388 Mon Sep 17 00:00:00 2001 From: Evan Liu Date: Sun, 2 Jun 2024 20:15:23 +1200 Subject: [PATCH 5/6] Add more lang mode --- karabiner/karabiner-config/src/index.ts | 43 ++++++++++++++++++------- 1 file changed, 32 insertions(+), 11 deletions(-) diff --git a/karabiner/karabiner-config/src/index.ts b/karabiner/karabiner-config/src/index.ts index 8d149a07..a9c57b07 100644 --- a/karabiner/karabiner-config/src/index.ts +++ b/karabiner/karabiner-config/src/index.ts @@ -15,16 +15,27 @@ import { const leftSideNums = [1, 2, 3, 4, 5] as const const rightSideNums = [6, 7, 8, 9, 0] as const const numbers = [...leftSideNums, ...rightSideNums] as const -// prettier-ignore const letters = [ - 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', - 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', - 'z', 'x', 'c', 'v', 'b', 'n', 'm' + ...["q", "w", "e", "r", "t", "y", "u", "i", "o", "p"], + ...["a", "s", "d", "f", "g", "h", "j", "k", "l"], + ...["z", "x", "c", "v", "b", "n", "m"], ] as const const symbols = ["[", "]", ";", "'", ",", ".", "/"] as const const lettersAndSymbols = [...letters, ...symbols] as const const allKeys = [...numbers, ...letters, ...symbols] as const +const dash = { + python: open('"dash://.python:"'), + ts: openInBackground( + '"dash-plugin://query=.tsprofile%3A&prevent_activation=true"' + ), + rust: openInBackground( + '"dash-plugin://query=.tsprofile%3A&prevent_activation=true"' + ), + swift: open('"dash-plugin://query=.swiftprofile%3A&prevent_activation=true"'), + go: open('"dash-plugin://query=.goprofile%3A&prevent_activation=true"'), +} + writeToProfile( // "--dry-run", // prints to console "karabiner.ts", // adds it to karabiner.ts profile @@ -98,13 +109,10 @@ writeToProfile( // tabkey (things) simlayer("tab").manipulators([ - map("j") - .toVar("in-lang", "ts") - .to( - openInBackground( - '"dash-plugin://query=.tsprofile%3A&prevent_activation=true"' - ) - ), + map("i").toVar("in-lang", "python").to(dash.python), + map("j").toVar("in-lang", "ts").to(dash.ts), + map("k").toVar("in-lang", "rust").to(dash.rust), + map(";").toVar("in-lang", "go").to(dash.go), ]), simlayer("period").manipulators([ @@ -112,6 +120,19 @@ writeToProfile( a: toTypeSequence("console.log()←"), s: toTypeSequence("=>␣"), }), + withCondition(ifVar("in-lang", "go"))({ + tab: km("w: GoDoc"), + a: toTypeSequence("fmt.Println()←"), + }), + withCondition(ifVar("in-lang", "python"))({ + a: toTypeSequence("print()←"), + }), + withCondition(ifVar("in-lang", "swift"))({ + a: toTypeSequence("print()←"), + }), + withCondition(ifVar("in-lang", "rust"))({ + a: toTypeSequence("log!()←"), + }), ]), ], { From d6a04c7248c3ed0b9ecabf18926fd92732d72cb0 Mon Sep 17 00:00:00 2001 From: Evan Liu Date: Sun, 2 Jun 2024 20:35:28 +1200 Subject: [PATCH 6/6] Add examples for mapSimultaneous() and mouse mapping --- karabiner/karabiner-config/src/index.ts | 33 +++++++++++++++++++------ 1 file changed, 26 insertions(+), 7 deletions(-) diff --git a/karabiner/karabiner-config/src/index.ts b/karabiner/karabiner-config/src/index.ts index a9c57b07..4bd643b3 100644 --- a/karabiner/karabiner-config/src/index.ts +++ b/karabiner/karabiner-config/src/index.ts @@ -1,6 +1,7 @@ import { ifVar, map, + mapSimultaneous, rule, simlayer, to$ as $, @@ -26,12 +27,8 @@ const allKeys = [...numbers, ...letters, ...symbols] as const const dash = { python: open('"dash://.python:"'), - ts: openInBackground( - '"dash-plugin://query=.tsprofile%3A&prevent_activation=true"' - ), - rust: openInBackground( - '"dash-plugin://query=.tsprofile%3A&prevent_activation=true"' - ), + ts: openInBackground('"dash-plugin://query=.tsprofile%3A&prevent_activation=true"'), + rust: openInBackground('"dash-plugin://query=.tsprofile%3A&prevent_activation=true"'), swift: open('"dash-plugin://query=.swiftprofile%3A&prevent_activation=true"'), go: open('"dash-plugin://query=.goprofile%3A&prevent_activation=true"'), } @@ -103,10 +100,32 @@ writeToProfile( map("semicolon", "shift").to("semicolon"), ]), + rule("jsim").manipulators([ + mapSimultaneous(["j", "k"]).to(alfred("search google", "net.deanishe.alfred-searchio")), + mapSimultaneous(["j", ";"]).to(9, "⌘⌥⇧"), // Raycast + mapSimultaneous(["j", "l"]).to("␣", "Hyper"), // Raycast + ]), + + rule("ksim").manipulators([ + mapSimultaneous(["k", "l"]).to(alfred("search dash", "com.kapeli.dash.workflow")), + ]), + simlayer("w").manipulators({ e: km("open: Fantastical"), }), + // dkey (mouse) + simlayer("d").manipulators([ + map("i").to("keypad_hyphen", "⌘"), // Zoom out + map("o").to("keypad_plus", "⌘"), // Zoom in + map("a").to("c", "⌘").to("tab", "⌘"), // Copy & activate previous app + map("j").toMouseKey({ vertical_wheel: 60 }), // Scroll down + map("k").toMouseKey({ vertical_wheel: -60 }), // Scroll down + map("z").toPointingButton("button2"), // Right click + map("v").toPointingButton("button1"), // Left click + map("b").toPointingButton("button3"), // Middle click + ]), + // tabkey (things) simlayer("tab").manipulators([ map("i").toVar("in-lang", "python").to(dash.python), @@ -144,7 +163,7 @@ writeToProfile( } ) -function alfred(identifier: string, bundleId: string, argument: string = "") { +function alfred(identifier: string, bundleId: string, argument = "") { return $( `osascript -e 'tell application id "com.runningwithcrayons.Alfred" to run trigger "${identifier}" in workflow "${bundleId}" with argument "${argument}"'` )