Edited at

Emacs以外でもStickyKeyを使いたい!

More than 1 year has passed since last update.


更新

2018-04-05 Karabiner Elementsに暫定対応しました!


StickyKeyって?

CamelCaseとかでコーディングしてるとShift-Bなどの離れた2つのキーを同時に入力する機会が多いですよね?

ずっと同じ作業をしていると小指が辛いことになります。

StickyKeyを有効にすると、Shiftボタン、Bボタンの順番で入力すれば同時に入力した状態と同じアクションが実行されます。

Shiftの場合は特にStickyShiftとよぶんですかね?

今回はエンジニアが多用するCamelCaseの入力が楽になるStickyShiftに絞って説明します!


やりたいこと


  • Emacsにはrubikitchさん作のsticky.elという神ツールがありますが、IDEA Intellijでもブラウザでもどこでも使いたんのです!

  • KarabinerにはStickyKeyの設定が用意されていますが、一部の挙動が不便なのでsticky.elの挙動にしたいんです!


sticky.elの素晴らしい挙動


  • StickyKeyに設定されたキーが2回入力された場合は、元のキーを入力する

  • 修飾されたキーの場合は何もしない。


やりかた(OSX)

Karabiner-Elementsを使用します。


設定してみる(セミコロンの例)

Karabiner-ElementsのComplex Modificationsで実現できます。

以下のファイルを追加して読み込めばOKです。


$HOME/.config/karabiner/karabiner.json

{

"title": "Sticky",
"rules": [
{
"description": "sticky",
"manipulators": [
{
"type": "basic",
"from": {
"key_code": "semicolon"
},
"to": [
{
"key_code": "semicolon"
},
{
"set_variable": {
"name": "sticky_pressed",
"value": 0
}
}
],
"conditions": [
{
"type": "variable_if",
"name": "sticky_pressed",
"value": 1
}
]
},
{
"type": "basic",
"from": {
"key_code": "semicolon"
},
"to": [
{
"set_variable": {
"name": "sticky_pressed",
"value": 1
}
}
],
"conditions": [
{
"type": "variable_if",
"name": "sticky_pressed",
"value": 0
}
]
},
{
"type": "basic",
"from": {
"key_code": "a"
},
"to": [
{
"key_code": "a",
"modifiers": [
"shift"
]
},
{
"set_variable": {
"name": "sticky_pressed",
"value": 0
}
}
],
"conditions": [
{
"type": "variable_if",
"name": "sticky_pressed",
"value": 1
}
]
},
{
"type": "basic",
"from": {
"key_code": "b"
},
"to": [
{
"key_code": "b",
"modifiers": [
"shift"
]
},
{
"set_variable": {
"name": "sticky_pressed",
"value": 0
}
}
],
"conditions": [
{
"type": "variable_if",
"name": "sticky_pressed",
"value": 1
}
]
},
{
"type": "basic",
"from": {
"key_code": "c"
},
"to": [
{
"key_code": "c",
"modifiers": [
"shift"
]
},
{
"set_variable": {
"name": "sticky_pressed",
"value": 0
}
}
],
"conditions": [
{
"type": "variable_if",
"name": "sticky_pressed",
"value": 1
}
]
},
{
"type": "basic",
"from": {
"key_code": "d"
},
"to": [
{
"key_code": "d",
"modifiers": [
"shift"
]
},
{
"set_variable": {
"name": "sticky_pressed",
"value": 0
}
}
],
"conditions": [
{
"type": "variable_if",
"name": "sticky_pressed",
"value": 1
}
]
},
{
"type": "basic",
"from": {
"key_code": "e"
},
"to": [
{
"key_code": "e",
"modifiers": [
"shift"
]
},
{
"set_variable": {
"name": "sticky_pressed",
"value": 0
}
}
],
"conditions": [
{
"type": "variable_if",
"name": "sticky_pressed",
"value": 1
}
]
},
{
"type": "basic",
"from": {
"key_code": "f"
},
"to": [
{
"key_code": "f",
"modifiers": [
"shift"
]
},
{
"set_variable": {
"name": "sticky_pressed",
"value": 0
}
}
],
"conditions": [
{
"type": "variable_if",
"name": "sticky_pressed",
"value": 1
}
]
},
{
"type": "basic",
"from": {
"key_code": "g"
},
"to": [
{
"key_code": "g",
"modifiers": [
"shift"
]
},
{
"set_variable": {
"name": "sticky_pressed",
"value": 0
}
}
],
"conditions": [
{
"type": "variable_if",
"name": "sticky_pressed",
"value": 1
}
]
},
{
"type": "basic",
"from": {
"key_code": "h"
},
"to": [
{
"key_code": "h",
"modifiers": [
"shift"
]
},
{
"set_variable": {
"name": "sticky_pressed",
"value": 0
}
}
],
"conditions": [
{
"type": "variable_if",
"name": "sticky_pressed",
"value": 1
}
]
},
{
"type": "basic",
"from": {
"key_code": "i"
},
"to": [
{
"key_code": "i",
"modifiers": [
"shift"
]
},
{
"set_variable": {
"name": "sticky_pressed",
"value": 0
}
}
],
"conditions": [
{
"type": "variable_if",
"name": "sticky_pressed",
"value": 1
}
]
},
{
"type": "basic",
"from": {
"key_code": "j"
},
"to": [
{
"key_code": "j",
"modifiers": [
"shift"
]
},
{
"set_variable": {
"name": "sticky_pressed",
"value": 0
}
}
],
"conditions": [
{
"type": "variable_if",
"name": "sticky_pressed",
"value": 1
}
]
},
{
"type": "basic",
"from": {
"key_code": "k"
},
"to": [
{
"key_code": "k",
"modifiers": [
"shift"
]
},
{
"set_variable": {
"name": "sticky_pressed",
"value": 0
}
}
],
"conditions": [
{
"type": "variable_if",
"name": "sticky_pressed",
"value": 1
}
]
},
{
"type": "basic",
"from": {
"key_code": "l"
},
"to": [
{
"key_code": "l",
"modifiers": [
"shift"
]
},
{
"set_variable": {
"name": "sticky_pressed",
"value": 0
}
}
],
"conditions": [
{
"type": "variable_if",
"name": "sticky_pressed",
"value": 1
}
]
},
{
"type": "basic",
"from": {
"key_code": "m"
},
"to": [
{
"key_code": "m",
"modifiers": [
"shift"
]
},
{
"set_variable": {
"name": "sticky_pressed",
"value": 0
}
}
],
"conditions": [
{
"type": "variable_if",
"name": "sticky_pressed",
"value": 1
}
]
},
{
"type": "basic",
"from": {
"key_code": "n"
},
"to": [
{
"key_code": "n",
"modifiers": [
"shift"
]
},
{
"set_variable": {
"name": "sticky_pressed",
"value": 0
}
}
],
"conditions": [
{
"type": "variable_if",
"name": "sticky_pressed",
"value": 1
}
]
},
{
"type": "basic",
"from": {
"key_code": "o"
},
"to": [
{
"key_code": "o",
"modifiers": [
"shift"
]
},
{
"set_variable": {
"name": "sticky_pressed",
"value": 0
}
}
],
"conditions": [
{
"type": "variable_if",
"name": "sticky_pressed",
"value": 1
}
]
},
{
"type": "basic",
"from": {
"key_code": "p"
},
"to": [
{
"key_code": "p",
"modifiers": [
"shift"
]
},
{
"set_variable": {
"name": "sticky_pressed",
"value": 0
}
}
],
"conditions": [
{
"type": "variable_if",
"name": "sticky_pressed",
"value": 1
}
]
},
{
"type": "basic",
"from": {
"key_code": "q"
},
"to": [
{
"key_code": "q",
"modifiers": [
"shift"
]
},
{
"set_variable": {
"name": "sticky_pressed",
"value": 0
}
}
],
"conditions": [
{
"type": "variable_if",
"name": "sticky_pressed",
"value": 1
}
]
},
{
"type": "basic",
"from": {
"key_code": "r"
},
"to": [
{
"key_code": "r",
"modifiers": [
"shift"
]
},
{
"set_variable": {
"name": "sticky_pressed",
"value": 0
}
}
],
"conditions": [
{
"type": "variable_if",
"name": "sticky_pressed",
"value": 1
}
]
},
{
"type": "basic",
"from": {
"key_code": "s"
},
"to": [
{
"key_code": "s",
"modifiers": [
"shift"
]
},
{
"set_variable": {
"name": "sticky_pressed",
"value": 0
}
}
],
"conditions": [
{
"type": "variable_if",
"name": "sticky_pressed",
"value": 1
}
]
},
{
"type": "basic",
"from": {
"key_code": "t"
},
"to": [
{
"key_code": "t",
"modifiers": [
"shift"
]
},
{
"set_variable": {
"name": "sticky_pressed",
"value": 0
}
}
],
"conditions": [
{
"type": "variable_if",
"name": "sticky_pressed",
"value": 1
}
]
},
{
"type": "basic",
"from": {
"key_code": "u"
},
"to": [
{
"key_code": "u",
"modifiers": [
"shift"
]
},
{
"set_variable": {
"name": "sticky_pressed",
"value": 0
}
}
],
"conditions": [
{
"type": "variable_if",
"name": "sticky_pressed",
"value": 1
}
]
},
{
"type": "basic",
"from": {
"key_code": "v"
},
"to": [
{
"key_code": "v",
"modifiers": [
"shift"
]
},
{
"set_variable": {
"name": "sticky_pressed",
"value": 0
}
}
],
"conditions": [
{
"type": "variable_if",
"name": "sticky_pressed",
"value": 1
}
]
},
{
"type": "basic",
"from": {
"key_code": "w"
},
"to": [
{
"key_code": "w",
"modifiers": [
"shift"
]
},
{
"set_variable": {
"name": "sticky_pressed",
"value": 0
}
}
],
"conditions": [
{
"type": "variable_if",
"name": "sticky_pressed",
"value": 1
}
]
},
{
"type": "basic",
"from": {
"key_code": "x"
},
"to": [
{
"key_code": "x",
"modifiers": [
"shift"
]
},
{
"set_variable": {
"name": "sticky_pressed",
"value": 0
}
}
],
"conditions": [
{
"type": "variable_if",
"name": "sticky_pressed",
"value": 1
}
]
},
{
"type": "basic",
"from": {
"key_code": "y"
},
"to": [
{
"key_code": "y",
"modifiers": [
"shift"
]
},
{
"set_variable": {
"name": "sticky_pressed",
"value": 0
}
}
],
"conditions": [
{
"type": "variable_if",
"name": "sticky_pressed",
"value": 1
}
]
},
{
"type": "basic",
"from": {
"key_code": "z"
},
"to": [
{
"key_code": "z",
"modifiers": [
"shift"
]
},
{
"set_variable": {
"name": "sticky_pressed",
"value": 0
}
}
],
"conditions": [
{
"type": "variable_if",
"name": "sticky_pressed",
"value": 1
}
]
},
{
"type": "basic",
"from": {
"key_code": "grave_accent_and_tilde"
},
"to": [
{
"set_variable": {
"name": "sticky_pressed",
"value": 0
}
},
{
"key_code": "grave_accent_and_tilde",
"modifiers": [
"shift"
]
}
],
"conditions": [
{
"type": "variable_if",
"name": "sticky_pressed",
"value": 1
}
]
},
{
"type": "basic",
"from": {
"key_code": "1"
},
"to": [
{
"key_code": "1",
"modifiers": [
"shift"
]
},
{
"set_variable": {
"name": "sticky_pressed",
"value": 0
}
}
],
"conditions": [
{
"type": "variable_if",
"name": "sticky_pressed",
"value": 1
}
]
},
{
"type": "basic",
"from": {
"key_code": "2"
},
"to": [
{
"key_code": "2",
"modifiers": [
"shift"
]
},
{
"set_variable": {
"name": "sticky_pressed",
"value": 0
}
}
],
"conditions": [
{
"type": "variable_if",
"name": "sticky_pressed",
"value": 1
}
]
},
{
"type": "basic",
"from": {
"key_code": "3"
},
"to": [
{
"key_code": "3",
"modifiers": [
"shift"
]
},
{
"set_variable": {
"name": "sticky_pressed",
"value": 0
}
}
],
"conditions": [
{
"type": "variable_if",
"name": "sticky_pressed",
"value": 1
}
]
},
{
"type": "basic",
"from": {
"key_code": "4"
},
"to": [
{
"key_code": "4",
"modifiers": [
"shift"
]
},
{
"set_variable": {
"name": "sticky_pressed",
"value": 0
}
}
],
"conditions": [
{
"type": "variable_if",
"name": "sticky_pressed",
"value": 1
}
]
},
{
"type": "basic",
"from": {
"key_code": "5"
},
"to": [
{
"key_code": "5",
"modifiers": [
"shift"
]
},
{
"set_variable": {
"name": "sticky_pressed",
"value": 0
}
}
],
"conditions": [
{
"type": "variable_if",
"name": "sticky_pressed",
"value": 1
}
]
},
{
"type": "basic",
"from": {
"key_code": "6"
},
"to": [
{
"key_code": "6",
"modifiers": [
"shift"
]
},
{
"set_variable": {
"name": "sticky_pressed",
"value": 0
}
}
],
"conditions": [
{
"type": "variable_if",
"name": "sticky_pressed",
"value": 1
}
]
},
{
"type": "basic",
"from": {
"key_code": "7"
},
"to": [
{
"key_code": "7",
"modifiers": [
"shift"
]
},
{
"set_variable": {
"name": "sticky_pressed",
"value": 0
}
}
],
"conditions": [
{
"type": "variable_if",
"name": "sticky_pressed",
"value": 1
}
]
},
{
"type": "basic",
"from": {
"key_code": "8"
},
"to": [
{
"key_code": "8",
"modifiers": [
"shift"
]
},
{
"set_variable": {
"name": "sticky_pressed",
"value": 0
}
}
],
"conditions": [
{
"type": "variable_if",
"name": "sticky_pressed",
"value": 1
}
]
},
{
"type": "basic",
"from": {
"key_code": "9"
},
"to": [
{
"key_code": "9",
"modifiers": [
"shift"
]
},
{
"set_variable": {
"name": "sticky_pressed",
"value": 0
}
}
],
"conditions": [
{
"type": "variable_if",
"name": "sticky_pressed",
"value": 1
}
]
},
{
"type": "basic",
"from": {
"key_code": "0"
},
"to": [
{
"key_code": "0",
"modifiers": [
"shift"
]
},
{
"set_variable": {
"name": "sticky_pressed",
"value": 0
}
}
],
"conditions": [
{
"type": "variable_if",
"name": "sticky_pressed",
"value": 1
}
]
},
{
"type": "basic",
"from": {
"key_code": "hyphen"
},
"to": [
{
"key_code": "hyphen",
"modifiers": [
"shift"
]
},
{
"set_variable": {
"name": "sticky_pressed",
"value": 0
}
}
],
"conditions": [
{
"type": "variable_if",
"name": "sticky_pressed",
"value": 1
}
]
},
{
"type": "basic",
"from": {
"key_code": "equal_sign"
},
"to": [
{
"key_code": "equal_sign",
"modifiers": [
"shift"
]
},
{
"set_variable": {
"name": "sticky_pressed",
"value": 0
}
}
],
"conditions": [
{
"type": "variable_if",
"name": "sticky_pressed",
"value": 1
}
]
},
{
"type": "basic",
"from": {
"key_code": "quote"
},
"to": [
{
"key_code": "quote",
"modifiers": [
"shift"
]
},
{
"set_variable": {
"name": "sticky_pressed",
"value": 0
}
}
],
"conditions": [
{
"type": "variable_if",
"name": "sticky_pressed",
"value": 1
}
]
},
{
"type": "basic",
"from": {
"key_code": "comma"
},
"to": [
{
"key_code": "comma",
"modifiers": [
"shift"
]
},
{
"set_variable": {
"name": "sticky_pressed",
"value": 0
}
}
],
"conditions": [
{
"type": "variable_if",
"name": "sticky_pressed",
"value": 1
}
]
},
{
"type": "basic",
"from": {
"key_code": "period"
},
"to": [
{
"key_code": "period",
"modifiers": [
"shift"
]
},
{
"set_variable": {
"name": "sticky_pressed",
"value": 0
}
}
],
"conditions": [
{
"type": "variable_if",
"name": "sticky_pressed",
"value": 1
}
]
},
{
"type": "basic",
"from": {
"key_code": "open_bracket"
},
"to": [
{
"key_code": "open_bracket",
"modifiers": [
"shift"
]
},
{
"set_variable": {
"name": "sticky_pressed",
"value": 0
}
}
],
"conditions": [
{
"type": "variable_if",
"name": "sticky_pressed",
"value": 1
}
]
},
{
"type": "basic",
"from": {
"key_code": "close_bracket"
},
"to": [
{
"key_code": "close_bracket",
"modifiers": [
"shift"
]
},
{
"set_variable": {
"name": "sticky_pressed",
"value": 0
}
}
],
"conditions": [
{
"type": "variable_if",
"name": "sticky_pressed",
"value": 1
}
]
},
{
"type": "basic",
"from": {
"key_code": "backslash"
},
"to": [
{
"key_code": "backslash",
"modifiers": [
"shift"
]
},
{
"set_variable": {
"name": "sticky_pressed",
"value": 0
}
}
],
"conditions": [
{
"type": "variable_if",
"name": "sticky_pressed",
"value": 1
}
]
},
{
"type": "basic",
"from": {
"key_code": "slash"
},
"to": [
{
"key_code": "slash",
"modifiers": [
"shift"
]
},
{
"set_variable": {
"name": "sticky_pressed",
"value": 0
}
}
],
"conditions": [
{
"type": "variable_if",
"name": "sticky_pressed",
"value": 1
}
]
}
]
}
]
}



最後に

Karabiner-Elementsではsticky機能がなくなりましたが力技で解決しました💪

それ以外にもHammerSpoonでも近い動作を実現できたのですが、微妙に期待する動作を実現できなかったので諦めました。

コーディング速度もチョイチョイアップです。