keycomfort 0.6.0 → 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,6 +1,10 @@
1
1
  # KEYCOMFORT
2
2
  Comfortable keyboard remaps for Karabiner.
3
3
 
4
+ > [!WARNING]
5
+ > Keycomfort is still in **beta**.
6
+ > There will be a lot of breaking changes until `v1.*`.
7
+
4
8
  ## Installation
5
9
  Keycomfort is a command line application.
6
10
  Install it via NPM with `-g` option.
@@ -14337,7 +14337,7 @@ function requireKarabinerge () {
14337
14337
  karabinerge.unless_var = unless_var;
14338
14338
  return karabinerge;
14339
14339
  }var name = "keycomfort";
14340
- var version = "0.5.0";
14340
+ var version = "0.8.0";
14341
14341
  var description = "Comfortable keyboard remaps for Karabiner/AutoHotKey";
14342
14342
  var require$$9 = {
14343
14343
  name: name,
@@ -14358,6 +14358,7 @@ function requireRules () {
14358
14358
  } = requireKarabinerge();
14359
14359
 
14360
14360
  const modding = if_var('keycomfort_layer', 1);
14361
+ const mouse_mode = 'keycomfort_mode_mouse';
14361
14362
  const any = {optional: 'any'};
14362
14363
  const rules = {
14363
14364
 
@@ -14433,64 +14434,68 @@ function requireRules () {
14433
14434
  },
14434
14435
 
14435
14436
  'prev/next word': {
14436
- sonicpi(c, r) {
14437
- r.cond(modding)
14438
- .remap({
14439
- from: key(c.prev),
14440
- to: key('b', 'command')
14441
- })
14442
- .remap({
14443
- from: key(c.next),
14444
- to: key('f', 'command')
14445
- });
14437
+ apps: {
14438
+ sonicpi(c, r) {
14439
+ r.cond(modding)
14440
+ .remap({
14441
+ from: key(c.prev),
14442
+ to: key('b', 'command')
14443
+ })
14444
+ .remap({
14445
+ from: key(c.next),
14446
+ to: key('f', 'command')
14447
+ });
14448
+ },
14449
+ others(c, r) {
14450
+ r.cond(modding)
14451
+ .remap({
14452
+ from: key(c.prev),
14453
+ to: key('left_arrow', 'option')
14454
+ })
14455
+ .remap({
14456
+ from: key(c.next),
14457
+ to: key('right_arrow', 'option')
14458
+ });
14459
+ },
14446
14460
  },
14447
- others(c, r) {
14448
- r.cond(modding)
14449
- .remap({
14450
- from: key(c.prev),
14451
- to: key('left_arrow', 'option')
14452
- })
14453
- .remap({
14454
- from: key(c.next),
14455
- to: key('right_arrow', 'option')
14456
- });
14457
- }
14458
14461
  },
14459
14462
 
14460
14463
  'line start/end': {
14461
- terminal(c, r) {
14462
- r.cond(modding)
14463
- .remap({
14464
- from: key(c.start),
14465
- to: key('home')
14466
- })
14467
- .remap({
14468
- from: key(c.end),
14469
- to: key('end')
14470
- });
14471
- },
14472
- sonicpi(c, r) {
14473
- r.cond(modding)
14474
- .remap({
14475
- from: key(c.start),
14476
- to: key('a', 'control')
14477
- })
14478
- .remap({
14479
- from: key(c.end),
14480
- to: key('e', 'control')
14481
- });
14464
+ apps: {
14465
+ terminal(c, r) {
14466
+ r.cond(modding)
14467
+ .remap({
14468
+ from: key(c.start),
14469
+ to: key('home')
14470
+ })
14471
+ .remap({
14472
+ from: key(c.end),
14473
+ to: key('end')
14474
+ });
14475
+ },
14476
+ sonicpi(c, r) {
14477
+ r.cond(modding)
14478
+ .remap({
14479
+ from: key(c.start),
14480
+ to: key('a', 'control')
14481
+ })
14482
+ .remap({
14483
+ from: key(c.end),
14484
+ to: key('e', 'control')
14485
+ });
14486
+ },
14487
+ others(c, r) {
14488
+ r.cond(modding)
14489
+ .remap({
14490
+ from: key(c.start),
14491
+ to: key('left_arrow', 'command')
14492
+ })
14493
+ .remap({
14494
+ from: key(c.end),
14495
+ to: key('right_arrow', 'command')
14496
+ });
14497
+ },
14482
14498
  },
14483
- others(c, r) {
14484
- r.cond(modding)
14485
- .remap({
14486
- from: key(c.start),
14487
- to: key('left_arrow', 'command')
14488
- })
14489
- .remap({
14490
- from: key(c.end),
14491
- to: key('right_arrow', 'command')
14492
- });
14493
- }
14494
14499
  },
14495
14500
 
14496
14501
  'select'(c, r) {
@@ -14566,133 +14571,141 @@ function requireRules () {
14566
14571
  },
14567
14572
 
14568
14573
  'delete line': {
14569
- atom(c, r) {
14570
- r.cond(modding)
14571
- .remap({
14572
- from: key(c.key),
14573
- to: key('k', ['control', 'shift'])
14574
- });
14575
- },
14576
- vscode(c, r) {
14577
- r.cond(modding)
14578
- .remap({
14579
- from: key(c.key),
14580
- to: key('k', ['command', 'shift'])
14581
- });
14582
- },
14583
- eclipse(c, r) {
14584
- r.cond(modding)
14585
- .remap({
14586
- from: key(c.key),
14587
- to: key('d', 'command')
14588
- });
14574
+ apps: {
14575
+ atom(c, r) {
14576
+ r.cond(modding)
14577
+ .remap({
14578
+ from: key(c.key),
14579
+ to: key('k', ['control', 'shift'])
14580
+ });
14581
+ },
14582
+ vscode(c, r) {
14583
+ r.cond(modding)
14584
+ .remap({
14585
+ from: key(c.key),
14586
+ to: key('k', ['command', 'shift'])
14587
+ });
14588
+ },
14589
+ eclipse(c, r) {
14590
+ r.cond(modding)
14591
+ .remap({
14592
+ from: key(c.key),
14593
+ to: key('d', 'command')
14594
+ });
14595
+ },
14589
14596
  },
14590
14597
  },
14591
14598
 
14592
14599
  'insert line': {
14593
- atom(c, r) {
14594
- r.cond(modding)
14595
- .remap({
14596
- from: key(c.key),
14597
- to: key('return_or_enter', 'command')
14598
- });
14599
- },
14600
- vscode(c, r) {
14601
- r.cond(modding)
14602
- .remap({
14603
- from: key(c.key),
14604
- to: key('return_or_enter', 'command')
14605
- });
14606
- },
14607
- eclipse(c, r) {
14608
- r.cond(modding)
14609
- .remap({
14610
- from: key(c.key),
14611
- to: key('return_or_enter', 'shift')
14612
- });
14600
+ apps: {
14601
+ atom(c, r) {
14602
+ r.cond(modding)
14603
+ .remap({
14604
+ from: key(c.key),
14605
+ to: key('return_or_enter', 'command')
14606
+ });
14607
+ },
14608
+ vscode(c, r) {
14609
+ r.cond(modding)
14610
+ .remap({
14611
+ from: key(c.key),
14612
+ to: key('return_or_enter', 'command')
14613
+ });
14614
+ },
14615
+ eclipse(c, r) {
14616
+ r.cond(modding)
14617
+ .remap({
14618
+ from: key(c.key),
14619
+ to: key('return_or_enter', 'shift')
14620
+ });
14621
+ },
14613
14622
  },
14614
14623
  },
14615
14624
 
14616
14625
  'move line': {
14617
- atom(c, r) {
14618
- r.cond(modding)
14619
- .remap({
14620
- from: key(c.up),
14621
- to: key('up_arrow', ['command', 'control'])
14622
- })
14623
- .remap({
14624
- from: key(c.down),
14625
- to: key('down_arrow', ['command', 'control'])
14626
- });
14627
- },
14628
- vscode(c, r) {
14629
- r.cond(modding)
14630
- .remap({
14631
- from: key(c.up),
14632
- to: key('up_arrow', 'option')
14633
- })
14634
- .remap({
14635
- from: key(c.down),
14636
- to: key('down_arrow', 'option')
14637
- });
14638
- },
14639
- eclipse(c, r) {
14640
- r.cond(modding)
14641
- .remap({
14642
- from: key(c.up),
14643
- to: key('up_arrow', 'option')
14644
- })
14645
- .remap({
14646
- from: key(c.down),
14647
- to: key('down_arrow', 'option')
14648
- });
14649
- },
14650
- sonicpi(c, r) {
14651
- r.cond(modding)
14652
- .remap({
14653
- from: key(c.up),
14654
- to: key('p', ['command', 'control'])
14655
- })
14656
- .remap({
14657
- from: key(c.down),
14658
- to: key('n', ['command', 'control'])
14659
- });
14626
+ apps: {
14627
+ atom(c, r) {
14628
+ r.cond(modding)
14629
+ .remap({
14630
+ from: key(c.up),
14631
+ to: key('up_arrow', ['command', 'control'])
14632
+ })
14633
+ .remap({
14634
+ from: key(c.down),
14635
+ to: key('down_arrow', ['command', 'control'])
14636
+ });
14637
+ },
14638
+ vscode(c, r) {
14639
+ r.cond(modding)
14640
+ .remap({
14641
+ from: key(c.up),
14642
+ to: key('up_arrow', 'option')
14643
+ })
14644
+ .remap({
14645
+ from: key(c.down),
14646
+ to: key('down_arrow', 'option')
14647
+ });
14648
+ },
14649
+ eclipse(c, r) {
14650
+ r.cond(modding)
14651
+ .remap({
14652
+ from: key(c.up),
14653
+ to: key('up_arrow', 'option')
14654
+ })
14655
+ .remap({
14656
+ from: key(c.down),
14657
+ to: key('down_arrow', 'option')
14658
+ });
14659
+ },
14660
+ sonicpi(c, r) {
14661
+ r.cond(modding)
14662
+ .remap({
14663
+ from: key(c.up),
14664
+ to: key('p', ['command', 'control'])
14665
+ })
14666
+ .remap({
14667
+ from: key(c.down),
14668
+ to: key('n', ['command', 'control'])
14669
+ });
14670
+ },
14660
14671
  },
14661
14672
  },
14662
14673
 
14663
14674
  'left/right tab': {
14664
- vscode(c, r) {
14665
- r.cond(modding)
14666
- .remap({
14667
- from: key(c.left),
14668
- to: key('left_arrow', ['command', 'option'])
14669
- })
14670
- .remap({
14671
- from: key(c.right),
14672
- to: key('right_arrow', ['command', 'option'])
14673
- });
14674
- },
14675
- eclipse(c, r) {
14676
- r.cond(modding)
14677
- .remap({
14678
- from: key(c.left),
14679
- to: key('page_up', 'control')
14680
- })
14681
- .remap({
14682
- from: key(c.right),
14683
- to: key('page_down', 'control')
14684
- });
14685
- },
14686
- others(c, r) {
14687
- r.cond(modding)
14688
- .remap({
14689
- from: key(c.left),
14690
- to: key('tab', ['control', 'shift'])
14691
- })
14692
- .remap({
14693
- from: key(c.right),
14694
- to: key('tab', 'control')
14695
- });
14675
+ apps: {
14676
+ vscode(c, r) {
14677
+ r.cond(modding)
14678
+ .remap({
14679
+ from: key(c.left),
14680
+ to: key('left_arrow', ['command', 'option'])
14681
+ })
14682
+ .remap({
14683
+ from: key(c.right),
14684
+ to: key('right_arrow', ['command', 'option'])
14685
+ });
14686
+ },
14687
+ eclipse(c, r) {
14688
+ r.cond(modding)
14689
+ .remap({
14690
+ from: key(c.left),
14691
+ to: key('page_up', 'control')
14692
+ })
14693
+ .remap({
14694
+ from: key(c.right),
14695
+ to: key('page_down', 'control')
14696
+ });
14697
+ },
14698
+ others(c, r) {
14699
+ r.cond(modding)
14700
+ .remap({
14701
+ from: key(c.left),
14702
+ to: key('tab', ['control', 'shift'])
14703
+ })
14704
+ .remap({
14705
+ from: key(c.right),
14706
+ to: key('tab', 'control')
14707
+ });
14708
+ },
14696
14709
  },
14697
14710
  },
14698
14711
 
@@ -14917,81 +14930,170 @@ function requireRules () {
14917
14930
  });
14918
14931
  },
14919
14932
 
14920
- 'l-click'(c, r) {
14921
- r.cond(if_touched(c.fingers, c.area))
14922
- .remap({
14923
- from: key(c.from, any),
14924
- to: {pointing_button: c.to}
14925
- });
14933
+ 'mouse mode': {
14934
+ 'on'(c, r) {
14935
+ r.cond(modding)
14936
+ .cond(if_var(mouse_mode, 0))
14937
+ .remap({
14938
+ from: key(c.on),
14939
+ to: set_var(mouse_mode, 1)
14940
+ });
14941
+ },
14942
+ 'off'(c, r) {
14943
+ r.cond(modding)
14944
+ .cond(if_var(mouse_mode, 1))
14945
+ .remap({
14946
+ from: key(c.off),
14947
+ to: set_var(mouse_mode, 0)
14948
+ });
14949
+ },
14926
14950
  },
14927
14951
 
14928
- 'r-click'(c, r) {
14929
- r.cond(if_touched(c.fingers, c.area))
14930
- .remap({
14931
- from: key(c.from, any),
14932
- to: {pointing_button: c.to}
14933
- });
14952
+ 'mouse speed up/down': {
14953
+ 'mouse mode: on'(c, r) {
14954
+ if (c.touchpad) r.cond(if_touched(0));
14955
+ r.cond(if_var(mouse_mode, 1));
14956
+ mouse_speed(c, r);
14957
+ },
14958
+ 'thumb on touchpad'(c, r) {
14959
+ if (!c.touchpad) return false;
14960
+ r.cond(if_touched(1));
14961
+ mouse_speed(c, r);
14962
+ },
14934
14963
  },
14935
14964
 
14936
- 'm-click'(c, r) {
14937
- r.cond(if_touched(c.fingers, c.area))
14938
- .remap({
14939
- from: key(c.from, any),
14940
- to: {pointing_button: c.to}
14941
- });
14965
+ 'mouse move': {
14966
+ 'mouse mode: on'(c, r) {
14967
+ if (c.touchpad) r.cond(if_touched(0));
14968
+ r.cond(if_var(mouse_mode, 1));
14969
+ mouse_move(c, r);
14970
+ },
14971
+ 'thumb on touchpad'(c, r) {
14972
+ if (!c.touchpad) return false;
14973
+ r.cond(if_touched(1));
14974
+ mouse_move(c, r);
14975
+ },
14942
14976
  },
14943
14977
 
14944
- 'wheel up/down'(c, r) {
14945
- let speed = Math.round(32 * c.speed);
14946
- let flip = c.reverse ? -1 : 1;
14947
- r.cond(if_touched(c.fingers, c.area))
14948
- .remap({
14949
- from: key(c.up, any),
14950
- to: {mouse_key: {vertical_wheel: -speed * flip}}
14951
- })
14952
- .remap({
14953
- from: key(c.down, any),
14954
- to: {mouse_key: {vertical_wheel: speed * flip}}
14955
- });
14978
+ 'mouse buttons': {
14979
+ 'mouse mode: on'(c, r) {
14980
+ if (c.touchpad) r.cond(if_touched(0));
14981
+ r.cond(if_var(mouse_mode, 1));
14982
+ mouse_buttons(c, r);
14983
+ },
14984
+ 'thumb on touchpad'(c, r) {
14985
+ if (!c.touchpad) return false;
14986
+ r.cond(if_touched(1));
14987
+ mouse_buttons(c, r);
14988
+ },
14956
14989
  },
14957
14990
 
14958
- 'wheel left/right'(c, r) {
14959
- let speed = Math.round(32 * c.speed);
14960
- let flip = c.reverse ? -1 : 1;
14961
- r.cond(if_touched(c.fingers, c.area))
14962
- .remap({
14963
- from: key(c.left, any),
14964
- to: {mouse_key: {horizontal_wheel: speed * flip}}
14965
- })
14966
- .remap({
14967
- from: key(c.right, any),
14968
- to: {mouse_key: {horizontal_wheel: -speed * flip}}
14969
- });
14991
+ 'mouse wheel up/down': {
14992
+ 'mouse mode: on'(c, r) {
14993
+ if (c.touchpad) r.cond(if_touched(0));
14994
+ r.cond(if_var(mouse_mode, 1));
14995
+ mouse_wheel_v(c, r);
14996
+ },
14997
+ 'thumb on touchpad'(c, r) {
14998
+ if (!c.touchpad) return false;
14999
+ r.cond(if_touched(1));
15000
+ mouse_wheel_v(c, r);
15001
+ },
14970
15002
  },
14971
15003
 
14972
- 'move mouse by keys'(c, r) {
14973
- let speed = Math.round(1536 * c.speed);
14974
- r.cond(if_touched(c.fingers, c.area))
14975
- .remap({
14976
- from: key(c.up, any),
14977
- to: {mouse_key: {y: -speed}}
14978
- })
14979
- .remap({
14980
- from: key(c.right, any),
14981
- to: {mouse_key: {x: speed}}
14982
- })
14983
- .remap({
14984
- from: key(c.down, any),
14985
- to: {mouse_key: {y: speed}}
14986
- })
14987
- .remap({
14988
- from: key(c.left, any),
14989
- to: {mouse_key: {x: -speed}}
14990
- });
15004
+ 'mouse wheel left/right': {
15005
+ 'mouse mode: on'(c, r) {
15006
+ if (c.touchpad) r.cond(if_touched(0));
15007
+ r.cond(if_var(mouse_mode, 1));
15008
+ mouse_wheel_h(c, r);
15009
+ },
15010
+ 'thumb on touchpad'(c, r) {
15011
+ if (!c.touchpad) return false;
15012
+ r.cond(if_touched(1));
15013
+ mouse_wheel_h(c, r);
15014
+ },
14991
15015
  },
14992
15016
 
14993
15017
  };
14994
15018
 
15019
+ function mouse_speed(c, r) {
15020
+ r.remap({
15021
+ from: key(c.up, any),
15022
+ to: {mouse_key: {speed_multiplier: c.up_to}}
15023
+ })
15024
+ .remap({
15025
+ from: key(c.down, any),
15026
+ to: {mouse_key: {speed_multiplier: c.down_to}}
15027
+ });
15028
+ }
15029
+
15030
+ function mouse_move(c, r) {
15031
+ let speed = Math.round(1536 * c.speed);
15032
+ r.remap({
15033
+ from: key(c.up, any),
15034
+ to: {mouse_key: {y: -speed}}
15035
+ })
15036
+ .remap({
15037
+ from: key(c.right, any),
15038
+ to: {mouse_key: {x: speed}}
15039
+ })
15040
+ .remap({
15041
+ from: key(c.down, any),
15042
+ to: {mouse_key: {y: speed}}
15043
+ })
15044
+ .remap({
15045
+ from: key(c.left, any),
15046
+ to: {mouse_key: {x: -speed}}
15047
+ });
15048
+ // if (c.speed2_key) {
15049
+ // r.remap({
15050
+ // from: key(c.speed2_key, any),
15051
+ // to: {mouse_key: {speed_multiplier: c.speed2}}
15052
+ // });
15053
+ // }
15054
+ }
15055
+
15056
+ function mouse_buttons(c, r) {
15057
+ r.remap({
15058
+ from: key(c.left, any),
15059
+ to: {pointing_button: 'button1'}
15060
+ })
15061
+ .remap({
15062
+ from: key(c.right, any),
15063
+ to: {pointing_button: 'button2'}
15064
+ });
15065
+ r.remap({
15066
+ from: key(c.middle, any),
15067
+ to: {pointing_button: 'button3'}
15068
+ });
15069
+ }
15070
+
15071
+ function mouse_wheel_v(c, r) {
15072
+ let speed = Math.round(32 * c.speed);
15073
+ let flip = c.reverse ? -1 : 1;
15074
+ r.remap({
15075
+ from: key(c.up, any),
15076
+ to: {mouse_key: {vertical_wheel: -speed * flip}}
15077
+ })
15078
+ .remap({
15079
+ from: key(c.down, any),
15080
+ to: {mouse_key: {vertical_wheel: speed * flip}}
15081
+ });
15082
+ }
15083
+
15084
+ function mouse_wheel_h(c, r) {
15085
+ let speed = Math.round(32 * c.speed);
15086
+ let flip = c.reverse ? -1 : 1;
15087
+ r.remap({
15088
+ from: key(c.left, any),
15089
+ to: {mouse_key: {horizontal_wheel: speed * flip}}
15090
+ })
15091
+ .remap({
15092
+ from: key(c.right, any),
15093
+ to: {mouse_key: {horizontal_wheel: -speed * flip}}
15094
+ });
15095
+ }
15096
+
14995
15097
  rules_1 = rules;
14996
15098
  return rules_1;
14997
15099
  }var hasRequiredMain;
@@ -15009,7 +15111,7 @@ function requireMain () {
15009
15111
  const yaml = require$$6;
15010
15112
  const {io, merge, isEmpty} = requireAmekusa_util();
15011
15113
  const {
15012
- RuleSet, Config,
15114
+ Rule, RuleSet, Config,
15013
15115
  if_app, unless_app,
15014
15116
  } = requireKarabinerge();
15015
15117
 
@@ -15044,7 +15146,7 @@ function requireMain () {
15044
15146
 
15045
15147
  const pkg = require$$9;
15046
15148
  const rules = requireRules();
15047
- const defaultsYML = "# === KEYCOMFORT CONFIG ===\n# NOTE:\n# 0 means \"No\"\n# 1 means \"Yes\"\n\npaths:\n karabiner:\n save_as: ~/.config/karabiner/assets/complex_modifications/keycomfort.json\n apply_to: ~/.config/karabiner/karabiner.json\n ahk:\n save_as: ~/Desktop/keycomfort.ahk\n apply_to:\n\nvim_like: 0 # prefer vim-like mappings?\n\nrules: # mapping rules\n\n modifier:\n desc: Use [key] as a special modifier key (Required)\n enable: 1\n key: spacebar\n alone: spacebar\n\n cancel modifier:\n desc: Cancel modifier (<modifier>) with [key]\n enable: 1\n key: left_shift\n\n disable modifier:\n desc: Disable modifier (<modifier>) with <modifier> + [key]\n enable: 1\n key: right_shift + escape\n\n enable modifier:\n desc: Enable modifier (<modifier>) with [key]\n enable: 1\n key: right_shift + escape\n\n arrows:\n desc: <modifier> + { [up] / [right] / [down] / [left] } = Up / Right / Down / Left\n enable: 1\n up: e\n right: f\n down: d\n left: s\n\n page up/down:\n desc: <modifier> + { [up] / [down] } = Page Up / Down\n enable: 1\n up: w\n down: r\n\n prev/next word:\n desc: <modifier> + { [prev] / [next] } = Prev / Next Word\n enable: 1\n prev: a\n next: g\n apps:\n sonicpi: 1\n others: 1\n\n line start/end:\n desc: <modifier> + { [start] / [end] } = Line Start / End\n enable: 1\n start: q\n end: t\n apps:\n terminal: 1\n sonicpi: 1\n others: 1\n\n select:\n desc: <modifier> + { [up] / [right] / [down] / [left] } = Select Up / Right / Down / Left\n enable: 1\n up: i\n right: l\n down: k\n left: j\n vim:\n left: h\n down: j\n up: k\n right: l\n\n indent/outdent:\n desc: <modifier> + { [indent] / [outdent] } = Indent / Outdent\n enable: 1\n indent: o\n outdent: u\n\n backspace/delete:\n desc: <modifier> + { [backspace] / [delete] } = Backspace / Delete\n enable: 1\n backspace: n\n delete: m\n\n delete word:\n desc: <modifier> + [key] = Delete Word\n enable: 1\n key: b\n\n edit:\n desc: <modifier> + { [undo] / [cut] / [copy] / [paste] } = Undo / Cut / Copy / Paste\n enable: 1\n undo: z\n cut: x\n copy: c\n paste: v\n\n delete line:\n desc: <modifier> + [key] = Delete Line\n enable: 1\n key: shift + m\n apps:\n atom: 1\n vscode: 1\n eclipse: 1\n\n insert line:\n desc: <modifier> + [key] = New Line Below\n enable: 1\n key: return_or_enter\n apps:\n atom: 1\n vscode: 1\n eclipse: 1\n\n move line:\n desc: <modifier> + { [up] / [down] } = Move Line Up / Down\n enable: 1\n up: shift + i\n down: shift + k\n vim:\n up: shift + k\n down: shift + j\n apps:\n atom: 1\n vscode: 1\n eclipse: 1\n sonicpi: 1\n\n left/right tab:\n desc: <modifier> + { [left] / [right] } = Left / Right Tab\n enable: 1\n left: 2\n right: 3\n apps:\n vscode: 1\n eclipse: 1\n others: 1\n\n close/open tab:\n desc: <modifier> + { [close] / [open] } = Close / Open Tab\n enable: 1\n close: 1\n open: 4\n\n numpad:\n desc: <modifier> + [trigger] = Numpad Mode ([num1]=1, [num5]=5, [num9]=9)\n enable: 1\n trigger: left_control\n\n num0: b\n num1: n\n num2: m\n num3: comma\n\n num4: j\n num5: k\n num6: l\n\n num7: u\n num8: i\n num9: o\n\n slash: 8\n asterisk: 9\n hyphen: 0\n plus: p\n\n enter: slash\n delete: semicolon\n backspace: h\n\n plus/minus:\n desc: <modifier> + { [plus] / [minus] } = Plus / Minus\n enable: 1\n plus: p\n minus: shift + p\n to:\n plus: shift + equal_sign\n minus: hyphen\n\n backslash:\n desc: <modifier> + [from] = Backslash\n enable: 1\n from: slash\n to: backslash\n\n backtick:\n desc: <modifier> + [from] = Backtick\n enable: 1\n from: quote\n to: grave_accent_and_tilde\n\n tilde:\n desc: <modifier> + [from] = Tilde\n enable: 1\n from: hyphen\n to: shift + grave_accent_and_tilde\n\n pipe:\n desc: <modifier> + [from] = Pipe\n enable: 1\n from: 7\n to: shift + backslash\n\n equal:\n desc: <modifier> + [from] = Equal Sign\n enable: 1\n from: semicolon\n to: equal_sign\n\n enter:\n desc: <modifier> + [from] = Enter\n enable: 1\n from: tab\n to: return_or_enter\n\n underscore:\n desc: <modifier> + [from] = Underscore\n enable: 1\n from: period\n to: shift + hyphen\n\n custom:\n desc: <modifier> + Custom Keys\n enable: 1\n rules:\n # Examples\n # - from: p\n # to: shift + equal_sign\n\n remap capslock:\n desc: Caps Lock = [to] / [alone]\n enable: 1\n to: left_control\n alone: escape\n\n remap l-control:\n desc: Left Control = [to] / [alone]\n enable: 1\n to: left_control\n alone: escape\n\n remap r-control:\n desc: Right Control = [to] / [alone]\n enable: 0\n to: right_control\n alone: escape\n\n remap l-command:\n desc: Left Command = [to] / [alone]\n enable: 0\n to: left_command\n alone: left_command\n\n remap r-command:\n desc: Right Command = [to] / [alone]\n enable: 0\n to: right_command\n alone: right_command\n\n remap l-shift:\n desc: Left Shift = [to] / [alone]\n enable: 0\n to: left_shift\n alone: left_shift\n\n remap r-shift:\n desc: Right Shift = [to] / [alone]\n enable: 0\n to: right_shift\n alone: right_shift\n\n l-click:\n desc: (MultiTouchExtension) Touchpad + [from] = [to]\n enable: 1\n from: j\n to: button1\n fingers: 1\n area: # top/right/bottom/left\n\n r-click:\n desc: (MultiTouchExtension) Touchpad + [from] = [to]\n enable: 1\n from: l\n to: button2\n fingers: 1\n area: # top/right/bottom/left\n\n m-click:\n desc: (MultiTouchExtension) Touchpad + [from] = [to]\n enable: 1\n from: comma\n to: button3\n fingers: 1\n area: # top/right/bottom/left\n\n wheel up/down:\n desc: (MultiTouchExtension) Touchpad + { [up] / [down] } = Wheel Up / Down\n enable: 1\n up: i\n down: k\n speed: 1.0\n reverse: 0\n fingers: 1\n area: # top/right/bottom/left\n\n wheel left/right:\n desc: (MultiTouchExtension) Touchpad + { [left] / [right] } = Wheel Left / Right\n enable: 1\n left: h\n right: semicolon\n speed: 1.0\n reverse: 0\n fingers: 1\n area: # top/right/bottom/left\n\n move mouse by keys:\n desc: (MultiTouchExtension) Touchpad + { [up] / [right] / [down] / [left] } = Move Mouse Up / Right / Down / Left\n enable: 1\n up: e\n right: f\n down: d\n left: s\n speed: 1.0\n fingers: 1\n area: # top/right/bottom/left\n\n\napps:\n others:\n enable: 1\n\n login:\n enable: 1\n id:\n - com.apple.loginwindow\n\n terminal:\n enable: 1\n id:\n - com.apple.Terminal\n - com.googlecode.iterm2\n - org.alacritty\n exe:\n - cmd.exe\n\n vscode:\n enable: 0\n id:\n - com.microsoft.VSCode\n - com.vscodium\n exe:\n - Code.exe\n\n atom:\n enable: 0\n id:\n - com.github.atom\n - dev.pulsar-edit.pulsar\n\n eclipse:\n enable: 0\n id:\n - org.eclipse.platform.ide\n exe:\n - eclipse.exe\n\n sonicpi:\n enable: 0\n id:\n - net.sonic-pi.app\n\n\nkey_labels: # display names for key codes\n spacebar: Space\n return_or_enter: Enter\n grave_accent_and_tilde: Backtick\n button1: Left Click\n button2: Right Click\n button3: Middle Click\n japanese_eisuu: 英数\n japanese_kana: かな\n\n";
15149
+ const defaultsYML = "# === KEYCOMFORT CONFIG ===\n# NOTE:\n# 0 means \"No\"\n# 1 means \"Yes\"\n\npaths:\n karabiner:\n save_as: ~/.config/karabiner/assets/complex_modifications/keycomfort.json\n apply_to: ~/.config/karabiner/karabiner.json\n ahk:\n save_as: ~/Desktop/keycomfort.ahk\n apply_to:\n\nvim_like: 0 # prefer vim-like mappings?\n\nrules: # mapping rules\n\n modifier:\n desc: Use [key] as a special modifier key (Required)\n enable: 1\n key: spacebar\n alone: spacebar\n\n cancel modifier:\n desc: Cancel modifier (<modifier>) with [key]\n enable: 1\n key: left_shift\n\n disable modifier:\n desc: Disable modifier (<modifier>) with <modifier> + [key]\n enable: 1\n key: right_shift + escape\n\n enable modifier:\n desc: Enable modifier (<modifier>) with [key]\n enable: 1\n key: right_shift + escape\n\n arrows:\n desc: <modifier> + { [up] / [right] / [down] / [left] } = Up / Right / Down / Left\n enable: 1\n up: e\n right: f\n down: d\n left: s\n\n page up/down:\n desc: <modifier> + { [up] / [down] } = Page Up / Down\n enable: 1\n up: w\n down: r\n\n prev/next word:\n desc: <modifier> + { [prev] / [next] } = Prev / Next Word\n enable: 1\n prev: a\n next: g\n apps:\n sonicpi: 1\n others: 1\n\n line start/end:\n desc: <modifier> + { [start] / [end] } = Line Start / End\n enable: 1\n start: q\n end: t\n apps:\n terminal: 1\n sonicpi: 1\n others: 1\n\n select:\n desc: <modifier> + { [up] / [right] / [down] / [left] } = Select Up / Right / Down / Left\n enable: 1\n up: i\n right: l\n down: k\n left: j\n vim:\n left: h\n down: j\n up: k\n right: l\n\n indent/outdent:\n desc: <modifier> + { [indent] / [outdent] } = Indent / Outdent\n enable: 1\n indent: o\n outdent: u\n\n backspace/delete:\n desc: <modifier> + { [backspace] / [delete] } = Backspace / Delete\n enable: 1\n backspace: n\n delete: m\n\n delete word:\n desc: <modifier> + [key] = Delete Word\n enable: 1\n key: b\n\n edit:\n desc: <modifier> + { [undo] / [cut] / [copy] / [paste] } = Undo / Cut / Copy / Paste\n enable: 1\n undo: z\n cut: x\n copy: c\n paste: v\n\n delete line:\n desc: <modifier> + [key] = Delete Line\n enable: 1\n key: shift + m\n apps:\n atom: 1\n vscode: 1\n eclipse: 1\n\n insert line:\n desc: <modifier> + [key] = New Line Below\n enable: 1\n key: return_or_enter\n apps:\n atom: 1\n vscode: 1\n eclipse: 1\n\n move line:\n desc: <modifier> + { [up] / [down] } = Move Line Up / Down\n enable: 1\n up: shift + i\n down: shift + k\n vim:\n up: shift + k\n down: shift + j\n apps:\n atom: 1\n vscode: 1\n eclipse: 1\n sonicpi: 1\n\n left/right tab:\n desc: <modifier> + { [left] / [right] } = Left / Right Tab\n enable: 1\n left: 2\n right: 3\n apps:\n vscode: 1\n eclipse: 1\n others: 1\n\n close/open tab:\n desc: <modifier> + { [close] / [open] } = Close / Open Tab\n enable: 1\n close: 1\n open: 4\n\n numpad:\n desc: <modifier> + [trigger] = Numpad Mode ([num1]=1, [num5]=5, [num9]=9)\n enable: 1\n trigger: left_control\n\n num0: b\n num1: n\n num2: m\n num3: comma\n\n num4: j\n num5: k\n num6: l\n\n num7: u\n num8: i\n num9: o\n\n slash: 8\n asterisk: 9\n hyphen: 0\n plus: p\n\n enter: slash\n delete: semicolon\n backspace: h\n\n plus/minus:\n desc: <modifier> + { [plus] / [minus] } = Plus / Minus\n enable: 1\n plus: p\n minus: shift + p\n to:\n plus: shift + equal_sign\n minus: hyphen\n\n backslash:\n desc: <modifier> + [from] = Backslash\n enable: 1\n from: slash\n to: backslash\n\n backtick:\n desc: <modifier> + [from] = Backtick\n enable: 1\n from: quote\n to: grave_accent_and_tilde\n\n tilde:\n desc: <modifier> + [from] = Tilde\n enable: 1\n from: hyphen\n to: shift + grave_accent_and_tilde\n\n pipe:\n desc: <modifier> + [from] = Pipe\n enable: 1\n from: 7\n to: shift + backslash\n\n equal:\n desc: <modifier> + [from] = Equal Sign\n enable: 1\n from: semicolon\n to: equal_sign\n\n enter:\n desc: <modifier> + [from] = Enter\n enable: 1\n from: tab\n to: return_or_enter\n\n underscore:\n desc: <modifier> + [from] = Underscore\n enable: 1\n from: period\n to: shift + hyphen\n\n custom:\n desc: <modifier> + Custom Keys\n enable: 1\n rules:\n # Examples\n # - from: p\n # to: shift + equal_sign\n\n remap capslock:\n desc: Caps Lock = [to] / [alone]\n enable: 1\n to: left_control\n alone: escape\n\n remap l-control:\n desc: Left Control = [to] / [alone]\n enable: 1\n to: left_control\n alone: escape\n\n remap r-control:\n desc: Right Control = [to] / [alone]\n enable: 0\n to: right_control\n alone: escape\n\n remap l-command:\n desc: Left Command = [to] / [alone]\n enable: 0\n to: left_command\n alone: left_command\n\n remap r-command:\n desc: Right Command = [to] / [alone]\n enable: 0\n to: right_command\n alone: right_command\n\n remap l-shift:\n desc: Left Shift = [to] / [alone]\n enable: 0\n to: left_shift\n alone: left_shift\n\n remap r-shift:\n desc: Right Shift = [to] / [alone]\n enable: 0\n to: right_shift\n alone: right_shift\n\n mouse mode:\n desc: <modifier> + { [on] / [off] } = Mouse Mode On / Off\n enable: 1\n on: 9\n off: 0\n\n mouse speed up/down:\n desc: (Mouse) [up] / [down] = Mouse Speed Up / Down\n enable: 1\n touchpad: 1\n up: z\n up_to: 2.0\n down: a\n down_to: .5\n\n mouse move:\n desc: (Mouse) [up] / [right] / [down] / [left] = Move Mouse Up / Right / Down / Left\n enable: 1\n touchpad: 1\n up: e\n right: f\n down: d\n left: s\n speed: 1.0\n\n mouse buttons:\n desc: (Mouse) [left] / [middle] / [right] = Mouse Buttons Left / Middle / Right\n enable: 1\n touchpad: 1\n left: j\n middle: m\n right: l\n\n mouse wheel up/down:\n desc: (Mouse) [up] / [down] = Mouse Wheel Up / Down\n enable: 1\n touchpad: 1\n up: i\n down: k\n speed: 1.0\n\n mouse wheel left/right:\n desc: (Mouse) [left] / [right] = Mouse Wheel Left / Right\n enable: 1\n touchpad: 1\n left: h\n right: semicolon\n speed: 1.0\n\n\napps:\n others:\n enable: 1\n\n login:\n enable: 1\n id:\n - com.apple.loginwindow\n\n terminal:\n enable: 1\n id:\n - com.apple.Terminal\n - com.googlecode.iterm2\n - org.alacritty\n exe:\n - cmd.exe\n\n vscode:\n enable: 0\n id:\n - com.microsoft.VSCode\n - com.vscodium\n exe:\n - Code.exe\n\n atom:\n enable: 0\n id:\n - com.github.atom\n - dev.pulsar-edit.pulsar\n\n eclipse:\n enable: 0\n id:\n - org.eclipse.platform.ide\n exe:\n - eclipse.exe\n\n sonicpi:\n enable: 0\n id:\n - net.sonic-pi.app\n\n\nkey_labels: # display names for key codes\n spacebar: Space\n return_or_enter: Enter\n grave_accent_and_tilde: Backtick\n button1: Left Click\n button2: Right Click\n button3: Middle Click\n japanese_eisuu: 英数\n japanese_kana: かな\n\n";
15048
15150
  const defaults = yaml.parse(defaultsYML);
15049
15151
  const defaultConfig = loc(io.home, '.config', 'keycomfort', 'config.yml');
15050
15152
 
@@ -15225,57 +15327,74 @@ function requireMain () {
15225
15327
  if (userConfig) config = merge(config, userConfig);
15226
15328
  }
15227
15329
  let modifier = config.rules.modifier.key;
15228
- let apps = config.apps;
15229
- let labels = config.key_labels;
15230
- let vim = config.vim_like;
15330
+ let apps = config.apps;
15331
+ let labels = config.key_labels;
15332
+ let vim = config.vim_like;
15231
15333
 
15232
- // run rules
15233
15334
  let ruleSet = new RuleSet('KeyComfort');
15234
- for (let i in rules) {
15235
-
15236
- // rule config
15237
- let rc = config.rules[i];
15238
- if (!rc) continue;
15239
- if (!rc.enable) continue; // rule disabled
15240
15335
 
15336
+ function addRule(rule, rc, desc = undefined) {
15241
15337
  // overwrite conf with vim-like mappings
15242
- if (rc.vim && vim) rc = merge(rc, rc.vim);
15338
+ if (vim && rc.vim) rc = merge(rc, rc.vim);
15243
15339
 
15244
15340
  // format rule description
15245
- let desc = rc.desc.replaceAll(/(?:<modifier>|\[([_0-9a-z]+)\])/gi, (_, m1) => {
15246
- return label(m1 ? rc[m1] : modifier, labels);
15247
- });
15248
-
15249
- let rule = rules[i];
15250
- let newRule;
15341
+ if (!desc) {
15342
+ desc = rc.desc.replaceAll(/(?:<modifier>|\[([_0-9a-z]+)\])/gi, (_, m1) => {
15343
+ return label(m1 ? rc[m1] : modifier, labels);
15344
+ });
15345
+ }
15251
15346
 
15252
- // non app-specific rule
15347
+ // apply rule
15253
15348
  if (typeof rule == 'function') {
15254
- newRule = ruleSet.add(desc);
15255
- rule(rc, newRule);
15256
- continue;
15349
+ let newRule = new Rule(desc);
15350
+ if (rule(rc, newRule) !== false) {
15351
+ ruleSet.add(newRule);
15352
+ }
15353
+ return;
15257
15354
  }
15258
15355
 
15259
- // app-specific rule
15260
- let enabled = []; // enabled apps
15261
- for (let app in rule) {
15262
- if (app == 'others') continue;
15263
- if (!apps[app]) continue; // invalid app
15264
- if (!apps[app].enable) continue; // globally disabled
15265
- if (!rc.apps[app]) continue; // disabled for this rule
15266
- if (isEmpty(apps[app].id)) continue; // no app-id
15267
- enabled = enabled.concat(apps[app].id);
15268
- newRule = ruleSet.add(desc + ` (${app})`);
15269
- newRule.cond(if_app(...apps[app].id));
15270
- rule[app](rc, newRule);
15356
+ // apply app-specific rules
15357
+ if (rule.apps) {
15358
+ let newRule;
15359
+ let enabled = []; // enabled apps
15360
+ for (let app in rule.apps) {
15361
+ if (app == 'others') continue;
15362
+ if (!apps[app]) continue; // uknown app
15363
+ if (!apps[app].enable) continue; // globally disabled
15364
+ if (!rc.apps[app]) continue; // disabled for this rule
15365
+ if (isEmpty(apps[app].id)) continue; // no app-id
15366
+ enabled = enabled.concat(apps[app].id);
15367
+ newRule = new Rule(desc + ` (${app})`);
15368
+ newRule.cond(if_app(...apps[app].id));
15369
+ if (rule.apps[app](rc, newRule) !== false) {
15370
+ ruleSet.add(newRule);
15371
+ }
15372
+ }
15373
+ if (apps.others.enable && rc.apps.others) {
15374
+ newRule = new Rule(desc);
15375
+ if (enabled.length) newRule.cond(unless_app(...enabled));
15376
+ if (rule.apps.others(rc, newRule) !== false) {
15377
+ ruleSet.add(newRule);
15378
+ }
15379
+ }
15380
+ delete rule.apps;
15271
15381
  }
15272
- if (apps.others.enable && rc.apps.others) {
15273
- newRule = ruleSet.add(desc);
15274
- if (enabled.length) newRule.cond(unless_app(...enabled));
15275
- rule.others(rc, newRule);
15382
+
15383
+ // apply branching rules
15384
+ for (let k in rule) {
15385
+ addRule(rule[k], rc, `${desc} (${k})`); // RECURSION
15276
15386
  }
15277
15387
  }
15278
15388
 
15389
+ for (let i in rules) {
15390
+ // rule config
15391
+ let rc = config.rules[i];
15392
+ if (!rc) continue;
15393
+ if (!rc.enable) continue; // rule disabled
15394
+
15395
+ addRule(rules[i], rc);
15396
+ }
15397
+
15279
15398
  let data = ruleSet.toJSON();
15280
15399
  let result = JSON.stringify(data, null, 2);
15281
15400
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "keycomfort",
3
- "version": "0.6.0",
3
+ "version": "0.8.0",
4
4
  "description": "Comfortable keyboard remaps for Karabiner/AutoHotKey",
5
5
  "files": [
6
6
  "dist/keycomfort.js"
@@ -11,9 +11,10 @@
11
11
  "scripts": {
12
12
  "dev": "rollup -c --watch",
13
13
  "test": "echo noop",
14
- "build": "rollup -c && chmod +x ./dist/keycomfort.js",
14
+ "version": "npm --no-git-tag-version version",
15
+ "build": "rollup -c && chmod u+x ./dist/keycomfort.js",
15
16
  "clean": "rm -rf ./dist",
16
- "dist": "npm run clean; NODE_ENV=production npm run build"
17
+ "dist": "npm run clean; NODE_ENV=production npm run build && npm run test"
17
18
  },
18
19
  "repository": {
19
20
  "type": "git",
@@ -22,6 +23,8 @@
22
23
  "keywords": [
23
24
  "keyboard",
24
25
  "remap",
26
+ "accessibility",
27
+ "a11y",
25
28
  "karabiner",
26
29
  "mac",
27
30
  "macos",