Closed chrismo closed 3 years ago
I tried even just doing it straight in karabiner.json, and came up with one approach that was better than what I could get with goku, but still not adequate.
Can you share your config in json format here?
Actually, I kept picking away at this and came up with this .edn. It's only the left arrow, and only option / shift, but so far is working. :)
{:profiles {:Default {:default true
;; simultaneous_threshold_milliseconds (def: 50)
;; keys need to be pressed within this threshold to be considered simultaneous
:sim 50
;; to_delayed_action_delay_milliseconds (def: 500)
;; basically it means time after which the key press is count delayed
:delay 500
;; to_if_alone_timeout_milliseconds (def: 1000)
;; hold for 995s and single tap registered; hold for 1005s and seen as modifier
:alone 1000
;; to_if_held_down_threshold_milliseconds (def: 500)
;; key is fired twice when 500 ms is elapsed (otherwise seen as a hold command)
;; increase this value to allow you to hold a simlayer key longer before the next key is pressed
:held 1000}}
:main [;
{:des "from j to opt+shift+left if opt-shift-arrow-mode"
:rules [[:j :!SOleft_arrow :opt-shift-arrow-mode]]};
{:des "from sim [f,s,j] to opt+shift+left and set opt-shift-arrow-mode until after key_up"
:rules [[{:sim [:f :s :j]
:simo {:interrupt true
:dorder :insensitive
:uorder :insensitive
:afterup {:set ["opt-shift-arrow-mode" 0]}}}
[{:set ["opt-shift-arrow-mode" 1]} :!SOleft_arrow]
nil
{:params {:sim 250}}]]}
{:des "from sim [s,j] to opt+shift+left and set opt-shift-arrow-mode until after key_up and unset opt-arrow _all_ if opt-arrow set"
:rules [:opt-arrow-mode
[{:sim [:s :j]
:simo {:interrupt true
:dorder :insensitive
:uorder :insensitive
:afterup [{:set ["opt-shift-arrow-mode" 0]}
{:set ["opt-arrow-mode" 1]}]}}
[{:set ["opt-shift-arrow-mode" 1]}
{:set ["opt-arrow-mode" 0]}
:!SOleft_arrow]
nil
{:params {:sim 250}}]]}
{:des "from s to opt-shift-arrow-mode if opt-arrow-mode"
:rules [:opt-arrow-mode
[:s
["opt-shift-arrow-mode" 1]
nil
{:afterup [["opt-shift-arrow-mode" 0] ["opt-arrow-mode" 1]]}]]}
{:des "from j to opt+left if opt-arrow-mode"
:rules [:opt-arrow-mode
[:j :!Oleft_arrow]]}
{:des "from sim [f,j] to opt+left and set opt-arrow-mode until after key_up"
:rules [[{:sim [:f :j]
:simo {:interrupt true
:dorder :insensitive
:uorder :insensitive
:afterup {:set ["opt-arrow-mode" 0]}}}
[{:set ["opt-arrow-mode" 1]} :!Oleft_arrow]
nil
{:params {:sim 250}}]]}
;
]
;
}
:rules [[{:sim [:f :s :j]
:simo {:interrupt true
:dorder :insensitive
:uorder :insensitive
:afterup {:set ["opt-shift-arrow-mode" 0]}}}
[{:set ["opt-shift-arrow-mode" 1]} :!SOleft_arrow]
nil
{:params {:sim 250}}]]}
this rule is used 3 times so far with very little variation. is there a way to DRY this out?
bah, there's a use case here that doesn't work, overlapping simultaneous rules and inconsistent afterup behavior - but it's a karabiner issue, not goku. even if that wasn't a problem, there are too many accidental triggers this way during normal typing anyway.
if there are any useful goku tips to do anything that I've done simpler, I'd still like to learn better goku syntax, but ... on the primary issue I'm going to have to take a different approach.
The second links are using just layer, not simlayer, which I'd read wasn't a good option if I type quickly?
This is much simpler - toggle caps-key into the mode, then I can just do everything straightforward.
{:profiles {:Default {:default true
;; simultaneous_threshold_milliseconds (def: 50)
;; keys need to be pressed within this threshold to be considered simultaneous
:sim 50
;; to_delayed_action_delay_milliseconds (def: 500)
;; basically it means time after which the key press is count delayed
:delay 500
;; to_if_alone_timeout_milliseconds (def: 1000)
;; hold for 995s and single tap registered; hold for 1005s and seen as modifier
:alone 1000
;; to_if_held_down_threshold_milliseconds (def: 500)
;; key is fired twice when 500 ms is elapsed (otherwise seen as a hold command)
;; increase this value to allow you to hold a simlayer key longer before the next key is pressed
:held 1000}}
:main [;
{:des "escape kills all home row modifier arrow modes"
:rules [[:escape
[:escape
{:set ["arrows-mode" 0]}
{:set ["shift-mode" 0]}
{:set ["command-mode" 0]}
{:set ["option-mode" 0]}]]]}
{:des "toggle arrows with caps"
:rules [[:caps_lock ["arrows-mode" 0] :arrows-mode]
[:caps_lock ["arrows-mode" 1]]]}
{:des "modifiers"
:rules [:arrows-mode
[:s ["shift-mode" 1] nil {:afterup ["shift-mode" 0]}]
[:d ["command-mode" 1] nil {:afterup ["command-mode" 0]}]
[:f ["option-mode" 1] nil {:afterup ["option-mode" 0]}]]}
{:des "arrows plain"
:rules [[:condi :arrows-mode :!shift-mode :!command-mode :!option-mode]
[:j :left_arrow]
[:k :down_arrow]
[:l :right_arrow]
[:i :up_arrow]]}
{:des "arrows shift"
:rules [[:condi :arrows-mode :shift-mode :!command-mode :!option-mode]
[:j :!Sleft_arrow]
[:k :!Sdown_arrow]
[:l :!Sright_arrow]
[:i :!Sup_arrow]]}
{:des "arrows command"
:rules [[:condi :arrows-mode :!shift-mode :command-mode :!option-mode]
[:j :!Cleft_arrow]
[:k :!Cdown_arrow]
[:l :!Cright_arrow]
[:i :!Cup_arrow]]}
{:des "arrows option"
:rules [[:condi :arrows-mode :!shift-mode :!command-mode :option-mode]
[:j :!Oleft_arrow]
[:k :!Odown_arrow]
[:l :!Oright_arrow]
[:i :!Oup_arrow]]}
{:des "arrows shift-command"
:rules [[:condi :arrows-mode :shift-mode :command-mode :!option-mode]
[:j :!SCleft_arrow]
[:k :!SCdown_arrow]
[:l :!SCright_arrow]
[:i :!SCup_arrow]]}
{:des "arrows shift-option"
:rules [[:condi :arrows-mode :shift-mode :!command-mode :option-mode]
[:j :!SOleft_arrow]
[:k :!SOdown_arrow]
[:l :!SOright_arrow]
[:i :!SOup_arrow]]}
;
]
;
}
@chrismo i wonder if this does what you actually want? it's a snippet from my config.
{
:des "Extend Layer - CapsLock (quick release for ESC)"
:rules [
[:##caps_lock ["extend" 1] [:!symbols :!mouse :!shifted :!system] {:afterup ["extend" 0] :alone :escape}]
:extend
; functions
[:##1 :f1][:##2 :f2][:##3 :f3][:##4 :f4][:##5 :f5][:##6 :f6]
[:##7 :f7][:##8 :f8][:##9 :f9][:##0 :f10][:##hyphen :f11][:##equal_sign :f12]
; modifiers
[:##a :left_control][:##s :left_shift][:##d :left_option][:##f :left_command]
; arrows
[:##j :left_arrow]
[:##k :down_arrow]
[:##i :up_arrow]
[:##l :right_arrow]
; shortcuts
[:##u :!Cleft_arrow :!terminals]
[:##o :!Cright_arrow :!terminals]
[:##z :!Cz][:##x :!Cx][:##c :!Cc][:##v :!Cv]
]
}
Wow! I totally didn't understand what ##
actually did. I thought I knew, but ... that's perfect :) I have a long-hand version of this tracking my own variables to send things like :!SCleft_arrow
that's so much simpler now. I'd be facepalming if I wasn't so happy. Thx again!
I'm not sure I understand everything I see here, but it might be in the right area for what I want to do:
Is there any way I can have home row mods in karabiner using the simultaneous
feature? It's my understanding that just remapping a key with if_alone
won't work because if I type too fast I'll get many false positives (because karabiner doesn't have something like IGNORE_MOD_TAP_INTERRUPT in QMK), but that something like that is achievable with simultaneous
.
Another headscratcher is that I'd want to have home row mods (at least shift on A and ;), while keeping some of my combos, for example the one I have on AS
.
As I've played around with this, I think what I had conceived of is just a bit too nuts for either Karabiner-Elements or goku. The basic idea is to have the left hand home row keys replace shift, option, and command, and the right hand home row keys be arrow keys.
I tried a couple approaches with layers and simlayers, and while just holding the
f
key to go into "command+arrows" worked well and was simple (j,k,i,l being the arrows), adding in thes
key for shift is what got me. I tried even just doing it straight in karabiner.json, and came up with one approach that was better than what I could get with goku, but still not adequate.Anyway - I'm still a n00b and it's totally fine if this is out of scope for what these tools can do, but I've also seen some fairly fancy stuff, so I figured it couldn't hurt to ask.