rcmdnk's blog
Last update

20170830_vimode_200_200

Karabiner-Elements がある程度開発が進んで、 とりあえず今BetterTouchTool で設定しているショートカットは全部移行出来そうだったので 移行してみました。

Karabiner-ElementはJSON形式で設定を書いていきますが KE-complex_modifications というレポジトリを使って作成すると 複雑な設定もより簡単に簡潔に書く事が出来て さらにその設定をGitHub Pagesを通して簡単に公開できます。

Sponsored Links

Karabiner-Elements

とりあえずKarabiner-Elementsについて色々調べたことに関してはこの前まとめてみました。

KE-complex_modifications

KE-complex_modifications はKarabiner-Elementsで Complex Modificationsにウェブからルールを追加しようとした場合に 表示されるルールが入っているレポジトリです。

この中では元々ERB形式で設定を書き、 それをerb2json.rbというスクリプトでJSONに変換しています。

これによって同じような設定をまとめて書いたり、 アプリの定義などを短いエイリアスで呼び出したりすることで 簡潔に書いていく事が出来ます。

また、ルールを追加するために表示されるページのHTMLファイルも含まれていて、 これもERB形式で書かれていてHTMLにerb2html.rbというスクリプトで変換されますが、 これを使って自分の設定をImport出来る様なページを簡単に作る事も出来ます。

作ったJSONファイルを直接~/.config/karabiner/assets/complex_modifications/に入れたり、 ~/.config/karabiner/karabiner.jsonに加えたりしても良いですが、 管理したりまたウェブページとして公開したりしたい場合は KE-complex_modifications をForkして作業するのがオススメです。

フォークしてレポジトリを準備する

まずGitHubの KE-complex_modifications へ行ってレポジトリをForkします。

ウェブページとして公開したい場合は SettingsGitHub Pagesの項目に行って、 Sourceからmaster branch /docs folderを選びます。

githubpages

しばらくして上の絵の様にYour site is published at…が出て、 左側に緑のチェックマークが出たら そのURLでdocsにあるファイルが公開されているはずです。

上の例ではカスタムドメインを使っているのでURLがあれですが、 カスタムドメインを使ってなければ

http://<username>.github.io/KE-complex_modifications/

といったURLになります。

Forkしたままレポジトリの内容をいじってなければ Karabiner-Elements complex_modifications rules と同じものが表示されるはずです。

この新しく作った自分のページからもImportを押せばKarabiner-Elementsを使ってルールがインポート出来ることが確認出来ると思います。

docsだけを他の所で公開したり他のレポジトリでGithub Pagesとして公開する事も可能ですが、 docsを使えばmasterブランチでソースコードと同時にpushするだけで 公開ページが出来るので便利です。

このブランチですが、masterという名前のブランチしか指定出来ない様です。 Default branchを変更しても関係なしにこの項目にはmasterブランチのみが出ます。 さらにDefault branchを他のブランチにして masterを消してみるとSourceNoneになって他のが選べなくなります。

ので、Forkしたレポジトリですがmasterブランチを使って作業します。 Pull Requestを送るための作業ではないのでそれほど気にしなくて良い?

その他GitHubでやることとしては Issuesを有効にしておくともしかすると誰かがルールを使って問題を報告してくれるかもしれません。

また、このレポジトリには.travis.ymlがあるので、 Travis CIのアカウントを持っていて、 これを使ってテストをしたい場合にはTravis CI側で連携しておいてください。

まあ、このテストはmakeをするだけなのでなくてもいいかなとは思いますが。

make用スクリプトの修正

レポジトリのトップでmakeとするとERBを変換する作業を行ってくれますが、 この際、スクリプト中でRubyへのパスが/usr/bin/rubyに固定されてる為に Homebrewなどで別途Rubyを入れて、GEM_HOMEなどのパラメーターを 設定しているとエラーが出ます。

$ make
sh scripts/update-json.sh
/usr/bin/ruby scripts/erb2html.rb < src/index.html.erb > docs/index.html
/usr/local/gems/gems/json-2.1.0/lib/json/ext/parser.bundle: [BUG] Segmentation fault
ruby 2.0.0p648 (2015-12-16 revision 53162) [universal.x86_64-darwin16]

-- Crash Report log information --------------------------------------------

特段システムのRubyを使いたい理由も無いのでこれらは /usr/bin/env rubyの様にするなりしてその環境で使える様にすればエラーは出なくなります。

ということで、Makefilescripts*以下にあるいくつかのファイルについて 以下の様な修正をしてあげます。

do not fix path to ruby executable (for make) by rcmdnk · Pull Request #101 · pqrs-org/KE-complex_modifications

これについては元のレポジトリにPull Requestを送っておきました。

修正が出来たらとりあえずmakeをして 問題なく終了することを確かめます。

ファイルの整理

色々な設定ファイルが入っていてそこに自分用のファイルを追加しても良いですが ごちゃごちゃしてしまうので不要なものは削除していきます。

まず、src/jsonに行って 全てのファイルを削除して personal_rcmdnk.json.erbの様な自分用ERBファイルを必要なだけ作ります。

とりあえずpersonal_tekezo.json.erbとか適当なファイルをコピーして始めた方がやりやすいかと思います。

次にsrc/extra_descriptionsの中にあるファイルも全部削除して、 必要であればpersonal_rcmdnk.json.htmlと言った名前の 上で作ったERBファイルから.erbを除いて.htmlを付けた形のファイルを作ります。

これも最初は適当に元々あるファイルをコピーして編集すれば楽だと思います。 (単純なhtmlファイルですが。)

src/example.html.erbも必要が無いので削除します。

同様にdocs/jsonの中にあるJSONファイル、 docs/example.htmlも削除します。

自分で作るJSONファイルはmakeで出来るので docs/jsonの中に自分で作る必要はありません。

src/jsonの方にERBファイルを作らずにdocs/jsonの方に 直接JSONファイルを書いていっても実用上問題ありませんが、 間違えてsrc/jsonに該当ファイルを作ってしまうと上書きされてしまうので KE-complex_modificationsを使うなら src/jsonでERBファイルをアップデートしていった方が良いと思います。

ERBファイルの方に関しては無理にRubyの記述を使わずに JSONで直接書いても問題ないので 特に他からコピペしたりする時とかはRubyの記述を気にせずに JSONのまま書いてしまっても良いと思います。

後々の為にerb2json.rbの関数を使うと見やすくなるとは思いますが。

次に、Makefileの中の

/usr/bin/ruby scripts/erb2html.rb < src/example.html.erb > docs/example.html

の行を削除します。example.htmlを削除したので。

次にsrc/index.html.erbを編集します。

色々変えたいところですが、とりあえず

$groups = ""

となってるところより下にadd_groupがいくつかありますが Personal Settings以外のものを全部消します。

Personal Settingsの所を

add_group("Personal Settings","personal_settings",[
    "docs/json/personal_rcmdnk.json"
])

の様に自分のファイルの名前を書いてそれだけにします。

ここまで来たらmake出来るはずなので トップディレクトリに行って

$ make

します。 成功したら

$ open docs/index.html

などしてウェブページを開いてみて オフィシャルなImportページと同様のものの中に Personal Segginsだけがあるものが見えれば成功です。

その他細かい所の変更

必ずする必要は無いですが、READMEやindex.htmlの中に 色々リンクがあるのでそれを修正。

README.mdには

# KE-complex_modifications

complex_modifications for Karabiner-Elements.

https://pqrs.org/osx/karabiner/complex_modifications/

と言った記述があるので、それを

# KE-complex_modifications

complex_modifications for Karabiner-Elements by <user>.

http://<user>.github.io/KE-complex_modifications/

といった感じに自分のGitHub Pagesへのリンクに変更。

src/index.html.srbの中では

src/index.html.erb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
     <meta name="viewport" content="width=device-width, initial-scale=1">
-    <title>Karabiner-Elements complex_modifications rules</title>
+    <title>Karabiner-Elements complex_modifications rules by <user></title>
     <link href="assets/bootstrap-3.3.7-dist/css/bootstrap.min.css" rel="stylesheet">
...
         <div class="navbar-header">
-          <a class="navbar-brand" href="https://pqrs.org/osx/karabiner/complex_modifications/">Karabiner-Elements complex_modifications rules</a>
+          <a class="navbar-brand" href="//<user>.github.io/KE-complex_modifications/">Karabiner-Elements complex_modifications rules by <user></a>
         </div>
...
       <div class="text-right" style="margin-bottom: 30px">
-        <a href="https://github.com/pqrs-org/KE-complex_modifications">GitHub</a>
+        <a href="//github.com/<user>/KE-complex_modifications/">GitHub</a>
       </div>

この辺りを自分用に書き換えています。

extra_descriptionsについて

src/extra_descriptionsにはdocs/jsonに作られるファイルに対応する 説明書を作りますが、 これは無くても構いません。

対応するファイルがある場合、 ウェブページに追加の説明が追加されます。

vimode

上の図はオフィシャルのインポートページのものですが、 書く項目をクリックすると詳細が表示されます。

この時、表示されるタイトル(ここではVi Mode (rev 4.2))は JSONファイルの中のtitleの項目が表示されます。

その下にある設定項目(Vi Mode [S as Trigger Key]Vi Mode [D as Trigger Key] (recommended))は JSONファイルの中でrulesの項目のなかの各項にあるdescriptionの値です。

さらにsrc/extra_descriptionsに対応するファイルがあれば その下にHTMLがそのまま追加されます。

なので元々あるファイルを見てもらえば分かりますが、

<p style="margin-top: 20px; font-weight: bold">
  Moving Around
</p>

<table class="table">
  <tr>
    <td>Trigger Key + H/J/K/L</td>
    <td>Arrow Keys</td>
....

といった感じの単純なHTMLが入っています。

各項目を項目名だけでは分かりづらい所を説明したり、実際に行われるキーマップを記述したりすると分かりやすいです。

json.erbを書いてみる

元々src/jsonの中にあるものを参考にしていけば大体出来る事がわかると思いますが、 とりあえず事始め的なメモ。

基本的な形

とりあえず、一番単純な形としては

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
{
  "title": "Personal rules (@rcmdnk)",
  "rules": [
    {
      "description": "Change Control-a  to Command-b",
      "manipulators": [
        {
          <%# Control-A to Command-B %>
          "type": "basic",
          "from": <%= from("a", ["control"], ["caps_lock"]) %>,
          "to": <%= to([["b", ["command"]]]) %>
        },
        {
          <%# Control-C to D %>
          "type": "basic",
          "from": <%= from("c", ["control"], ["any"]) %>,
          "to": <%= to([["d"]]) %>
        }
      ]
    },
    {
      "description": "Change Control-e  to Command-f",
      "manipulators": [
        {
          <%# Control-E to F %>
          "type": "basic",
          "from": <%= from("e", ["control"], []) %>,
          "to": <%= to([["f"]]) %>
        }
      ]
    }
  ]
}

の様な形になるかと思います。 1つのmanipulatorsの中にある項目はComplex Modificationsの所で Enable出来る1つの固まりになります。

上の場合は2つの項目が出来、 1つ目の項目では2つのキーマップを同時に行う事になります。

また、ERBファイル中では<%#...%> で囲まれた部分がコメントになります。

これもJSONファイルを直接書くよりも整理しやすいポイントです。

from/to関数

上では前に見たJSONファイルと違い、<%=...%>で括られた部分があります。

この部分がRubyのスクリプトによって処理される部分です。 上にあるformtoというは関数で これらはscripts/erb2json.rbの中で定義されています。

"from": <%= from("a", ["control"], ["caps_lock"]) %>,

"from": {
  "key_code": "a",
  "modifiers": {
    "mandatory": [
      "control"
    ],
    "optional": [
      "caps_lock"
    ]
  }
}

と言った形で、1-3番目の引数がそれぞれkey_codemodifiersmandatorymodifiersoptionalに入ります。

"to": <%= to([["b", ["command"]]]) %>

"to": [
  {
    "key_code": "b",
    "modifiers": [
      "command"
    ]
  }
]

と言った形で、引数には1つの配列を取りますが、 各項目の1番目がkey_code、2番目があればそれをmodifiersに設定します。

toshell_commandとかを使いたい場合にはこの関数はそのままでは使えないですし、 特に使うこともないので

"to": [{"shell_command": "command"}]

の様に直接書いてしまいます。

ちなみにoptionalのところは押してあっても同様の操作を行う修飾キーを入れますが、 []で何も指定しなくても良いのですが 例の中にcaps_lockを書いてあるのが多かったので。

逆に他に何が押されてても常に同じ動作にしたければanyを指定する事もできます。 (この辺はKarabiner-Elements自体の仕様。)

each_key関数

each_key関数を使うと複数の同じ様な設定を一気に書くことが出来ます。

1
2
3
4
5
6
7
8
9
10
11
12
{
  "description": "Change cmd-ctrl-h/j/k/l to arrow keys",
  "manipulators":
  <%=
    each_key(
      source_keys_list: ["h", "j", "k", "l"],
      dest_keys_list: ["left_arrow", "down_arrow", "up_arrow", "right_arrow"],
      from_mandatory_modifiers: ["control", "command"],
      as_json: true
    )
  %>
}

これで

  • --H to Left Arrow
  • --J to Down Arrow
  • --K to Up Arrow
  • --L to Right Arrow

の項目を設定しています。

入力のキーと出力のキーで修飾キーが同じ事が条件です。

基本となる入力キーをsource_keys_listに 出力キーをdest_keys_listに配列で記述します。

入力のキーに付く修飾キーはfrom_mandatory_modifiersに、 出力のキーに付く修飾キーは上にはないですがto_modifiersに書きます。

これ以外にfrom_optional_modifiersto_pre_eventsto_post_eventsconditionsas_jsonの引数があります。

最後のas_jsonだけは設定項目ではなくて、出力をJSON形式にするか 各項目をRubyの型のまま出力するかを決めます。 デフォルトはfalseです。

上の様な場合は直接JSONで書き出したいのでtrueにしていますが、 例えば複数の修飾キーが違うeach_keyを同じ項目に入れたい場合、

1
2
3
4
5
6
7
8
9
10
11
12
13
{
  "description": "Change cmd-ctrl-h/j/k/l to arrow keys",
  "manipulators":
  <%=
    manipulators = each_key(
      ...
    )
    manipulators += each_key(
      ...
    )
    JSON.generate(manipulators)
  %>
}

みたいな感じで足していった後にまとめてJSONで出力します。 それぞれ直接書き出してしまうと最初のeach_keyの項目群の後に,が無いので バグってしまうので。

まあ、,だけ間に書いても出来ますが上の様な形の方がより綺麗かな、と。

forntmost_application_if/frontmost_application_unless

forntmost_application_if/frontmost_application_unlessは 特定のアプリのみに有効にしたりするconditionsを作ってくれる関数です。

1
2
3
4
"type": "basic",
"from": <%= from("a", ["control"], ["caps_lock"]) %>,
"to": <%= to([["b", ["command"]]]) %>,
"conditions": [ <%= frontmost_application_if("browser") %> ]

みたいな感じで使います。 conditionsの部分は

1
2
3
4
5
6
7
8
9
10
"conditions": [
  {
    "type": "frontmost_application_if",
    "bundle_identifiers": [
      "^org\\.mozilla\\.firefox$",
      "^com\\.google\\.Chrome$",
      "^com\\.apple\\.Safari$"
    ]
  }
]

とFirefox、Google Chrome、Safariの3つが指定される様に変換されます。

この定義もscripts/erb2json.rbの中にあって、 他にはterminalemacsemacs_key_bindings_exceptionremote_desktopvivirtual_machine と言った項目がありそれぞれアプリが指定されています。

通常のアルファベットキーとを使う様な項目は ターミナル上やVim、Emacs上で邪魔になる事が多いので そういった場合はemacs_key_bindings_exception

"conditions": [ <%= frontmost_application_unless("emacs_key_bindings_exception") %> ]

をしておくと良いです。emacs...ですがこの中にはターミナル(iTerm2やX11(つまりはX11上のxterm)等も含む)は勿論、viの項目も入っています。

必要であれば自分でアプリをscripts/erb2json.rbに加えれば自分用のものが使える様になります。

KE-complex_modifications/erb2json.rb at master · rcmdnk/KE-complex_modifications

この中ではMicrosoft Officeが加えられてます。

frontmost_applicationの関数の中で 最初の方に<name>_bundle_indentifiersと言う配列を作って その中にアプリのIDを入れ(IDの求め方はこの前のポスト)、 app_aliases.each do |app_alias|の後に使いたいエイリアス名でwhenを作って 自分で作った配列や必要な配列をbundle_identifiersconcatします。

forntmost_application_if/frontmost_application_unlessをeach_keyの中で使う

もし、each_keyの所で使いたい場合は

1
2
3
4
5
6
7
8
each_key(
  source_keys_list: ["i", "o"],
  dest_keys_list: ["close_bracket", "open_bracket"],
  from_mandatory_modifiers: ["control"],
  to_modifiers: ["command"],
  conditions: [frontmost_application_unless("emacs_key_bindings_exception")],
  as_json: true
)

と書いてしまうとこのconditionsの項目だけこの時点で1回JSON化されてしまい、 その後もう一度JSON化されるので この時に余計なエスケープがついて正しく動作しなくなります。

そこでちょっとerb2json.rbを改造して Rubyの型のまま出力出来る様にします。

frontmost_applicationas_json=trueの引数を追加、

1
2
3
4
5
6
unless bundle_identifiers.empty?
  JSON.generate({
                  "type" => type,
                  "bundle_identifiers" => bundle_identifiers,
                })
end

となってるところを

1
2
3
4
5
6
7
8
9
10
11
unless bundle_identifiers.empty?
  data = {
    "type" => type,
    "bundle_identifiers" => bundle_identifiers
  }
  if as_json
    JSON.generate(data)
  else
    data
  end
end

と変更します。

さらにfrontmost_application_if/frontmost_application_unlessにもas_json=trueの引数を加え、 中でfrontmost_applicationを呼ぶ時にas_jsonを最後の引数として加えます。

これで、

1
2
3
4
5
6
7
8
each_key(
  source_keys_list: ["i", "o"],
  dest_keys_list: ["close_bracket", "open_bracket"],
  from_mandatory_modifiers: ["control"],
  to_modifiers: ["command"],
  conditions: [frontmost_application_unless("emacs_key_bindings_exception", false)],
  as_json: true
)

としてあげれば正しく動作するJSONが出来上がります。

pointing_button

erb2json.rbの中のfrom/to関数は key_codeに関するものだけなので pointing_buttonにするものも加えました。

key_codeのものをそのままpointing_buttonに変える様にするだけで簡単に出来ます。

ちなみに "pointing_button": "button1"が左クリック、 "pointing_button": "button2"が右クリック、 で、 実際toの方に指定するとキーボードショートカットでクリックすることが出来ました。

ただ、

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
{
  "description": "Browser: Swap ctrl-left click and cmd-left click (Not working)",
  "manipulators": [
    {
      "type": "basic",
      "from": <%= from_button("button1", ["control"]) %>,
      "to": <%= to_button([["button1", ["command"]]]) %>,
      "conditions": [ <%= frontmost_application_if("browser") %> ]
    },
    {
      "type": "basic",
      "from": <%= from_button("button1", ["command"]) %>,
      "to": <%= to_button([["button1", ["control"]]]) %>,
      "conditions": [ <%= frontmost_application_if("browser") %> ]
    }
  ]
}

みたいな感じでfromに指定してみると上手く動作しません。 (出力のJSONファイルも特に問題ないはず。)

ちょっと良く分かりませんが、 マウスの入力に関することなので 今のところこういった設定はBetterTouchToolの方で行う事にしています。

device_if/device_unless

ちょっとHHKBのみに対する設定をしたかったのでdevice_ifconditionsで 使いたかったのですが直接書くのもあれなので、 frontmost_application_ifを真似してdevice_ifという関数をerb2json.rbの中に作りました。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
{
  "description": "For HHKB (Esc to `(~))",
  "manipulators": [
    {
      "type": "basic",
      "from": <%= from("escape", []) %>,
      "to": <%= to([["grave_accent_and_tilde", []]]) %>,
      "conditions": [ <%= device_if("hhkb") %> ]
    },
    {
      "type": "basic",
      "from": <%= from("escape", ["shift"]) %>,
      "to": <%= to([["grave_accent_and_tilde", ["shift"]]]) %>,
      "conditions": [ <%= device_if("hhkb") %> ]
    }
  ]
}

こんな感じで使えます。

erb2json.rbの変更箇所について

上記のerb2json.rbに関する変更は全て

KE-complex_modifications/erb2json.rb at master · rcmdnk/KE-complex_modifications

の中でやっています。

makeしてテスト

一通り変更出来たりしたら、 トップディレクトリでmakeしてJSONファイルを作ります。

出来たdocs/json/personal_rcmdnk.jsonなどをテストするために ~/.config/karabiner/assets/complex_modificationsにコピーします。

正しく機能すればKarabiner-Elementsの環境設定の Complex ModificationsからAdd ruleをした時に 自分で作った設定が表示されるはずです。

そこで必要な設定をEnableしたりして試します。

特にGitHubでの管理とかを考えないのであればそのまま使えばOK。

また、このmakeですが、使うスクリプトの中で src/json/example.json.erbとそれに対応する出力ファイルの docs/json/example.jsonのタイムスタンプを比較して docsの方が新しければ既に変換を行ったとしてスキップする様になっています。

これがちょっと面倒なのがscripts/erb2json.rbをちょっと編集して手を加えたりした時に ERBファイルに変更が無いとmakeしても何もしてくれません。

この場合、make rebuildすると一度src側のERBファイルにtouchして タイムスタンプを更新して新規変換を全てのファイルについてしてくれます。

ただ、大きな大量のファイルが無い限りmakeにかかる時間はほとんど気にならないレベルなので makeしたら毎回全て変換し直してくれたほうが楽かな、とも思います。

もしそうしたい場合には scripts/update-json.sh

src/update-json.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
 for srcfile in src/json/*.erb; do
   dstfile="docs/json/`basename $srcfile .erb`"
-  if [ "$srcfile" -nt "$dstfile" ]; then
+  #if [ "$srcfile" -nt "$dstfile" ]; then
     if scripts/erb2json.rb < "$srcfile" > "$dstfile"; then
       echo "$dstfile"
     else
@@ -10,5 +10,5 @@ for srcfile in src/json/*.erb; do
       rm -f "$dstfile"
       exit 1
     fi
-  fi
+  #fi
 done

な感じでタイムスタンプのチェックをしないように変更してしまうのもありかな、と思います。

GitHubにpush、ウェブページを確認

出来上がったファイルをGitHubにPushしておきます。

$ make
$ git add -A
$ git commit -a -m "added my modifications"
$ git push

これでdocsのJSONファイルとHTMLファイルの両方がアップデートされるので http://<user>.github.io/KE-complex_modifications/ に行くと自分の設定がImport出来る様になってるはずです。

試しに設定をImportしてみてちゃんと設定が反映されればOK。 (テストでコピーしたままだと重複するので先に一旦全て設定をComplex ModificationsからRemoveした上で Add ruleの所でもゴミ箱ボタンを押して削除しておいた方が良いです。 Add ruleの所の設定は ~/.config/karabiner/assets/complex_modificationsからファイル直接削除しても同じです。)

ちなみにウェブからImportするとそのファイルも ~/.config/karabiner/assets/complex_modifications に入りますが、この際は元々のファイル名ではなくてファイル名が適当な数字の付いたJSONになっています。 のでそれらのファイルを削除する時は環境設定からAdd ruleで項目名を見て削除した方が簡単です。

makeで作られるファイルについてもGitHubに送るので(というかそれがウェブに表示されるものなので) 今後GitHubに変更をpushする際には必ずmakeをしてからにするようにします。

この部分をCIにまかせて、例えば他のブランチで開発を進め、そのブランチにPushすると makeしてmasterブランチに送る、みたいなことをしても良いかもしれませんが まあ必要があれば。 通常は手元でmakeしてテストしてから送ると思うのでそれ程必要でもないかな、と。 (CIの中でpushするのは鍵の設定とか結構面倒なので。)

その他気になったこと

修飾キー

この前のポストでも書きましたが、 Karabiner-Elementsを起動すると 環境設定キーボードキーボード から設定できる修飾キーの設定は無視されます。

CapsをControlやCommandに割り当てたい場合には Karabiner-Elementsの中で設定する必要があります。

これらは簡単にSimple Modificationsから設定できます。

IMEのチェック

以前Karabinerで出来て居た項目は大体出来る様になりました。

mac/private.xml at master · rcmdnk/mac

1つどうしても出来ない設定が Vimを使ってる時にIMEをオフにしてかつノーマルモードに一気に戻る設定です。

無いとかなり不便なんですが今のところKarabiner-ElementsにIMEの状態をチェックしたり変更する方法が無い様なので出来てません。

通常のVimだけならESCをIMEの環境設定の方でIME offに割り当て、 Vim上でとにかくESCを2回送る様にすれば良いだけなのですが、 ターミナル上でGNU screenを使ってる場合、 コピーモードに入るのと終了するのが共にESC(または-[)なので ターミナル上で常に2回ESCが送られるとコピーモードが使えなくなってしまいます。

IMEの操作がどれだけ難しいものか分からないですが出来る様になったら嬉しいな、と。

追記: 2017/08/30

GNU screen側の設定をいじってコピーモードでESCを無効化し、 単純にESCを複数回とEISUを送る設定をKarabiner-Elementsで することである程度上手く行く設定ができました。

追記ここまで

iTerm2でのOption to Commandの設定

上で書いてますが、iTerm2ではCommandキーは基本的にはMetaキー(Windows/LinuxでのAlt的な)としては働きません。 MacではCommandキーを使ったショートカットが多用されてるためそちらに使いたいからです。

代わりに設定からOptionキーをMetaキーとして使う設定があります。

さらにiTerm2の設定でCommandキーとOptionキーを交換する設定があるので これらを組み合わせる事でCommandキーをMetaキーとして使う事が出来てその設定が上に書いたものです。

ただしこの設定をしてしまうとiTerm2上でCommandキーが有無を言わさずOptionキーと認識されるので Commandキーを使ったショートカットがことごとく使えなくなります。

元々CommandキーをMetaキーとしてターミナル上で使いたいから良いのでは、といことはあるのですが、 例えばCommand+Controlを修飾キーとして使う複雑なショートカットを全体設定で使ってたりしていて(Spotlightの呼び出しだったり)、 それらも使えなくなって結構不便です。

そういった場合はiTerm2上だけでOptionキーに変更したショートカットを作れば使えますが いくつも重複を作ることになってしまいます。

で、この設定をしたのはそもそもBetterTouchToolでうまい具合にCommandとOptionの変更が送れないことが原因でした。

それ以前は OptionでのMetaキーを有効にだけして、 Karabinerで必要なもの(Command-a, Command-b..)だけOption修飾に変換して(Option-a, Option-b)送っていました。

同様のことがBetterTouchToolだとどうも命令するレイヤーがiTerm2の設定に比べて低い(高い?)せいか命令が効きませんでした。

Karabiner-Elementsで試した所以前同様に上手く行ったのでその設定を加えました。

必要なもの、と言っても実はほとんどのキーで、nvw以外で 設定するので、以前は結構書くのが大変でした。

ですが、今回erb2json.rbを使えば

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
{
  "description": "iTerm2 command (Meta) keys",
  "manipulators":
  <%=
    # Other than n, v, w
    iterm2Keys = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l",
                 "m", "o", "p", "q", "r", "s", "t", "u", "x", "y", "z"]
    each_key(
      source_keys_list: iterm2Keys,
      dest_keys_list: iterm2Keys,
      from_mandatory_modifiers: ["command"],
      to_modifiers: ["option"],
      conditions: [frontmost_application_if("iterm2", false)],
      as_json: true
    )
  %>
}

だけで済みます。便利。

入力ソースの変更

IMEの変更ですが、デフォルトだと

  • 入力ソース
    • 前の入力ソースを選択: -Space
    • 入力メニューの次のソースを選択: --Space

となっていますが、これを -Space-Space の両方のキーで入力メニューの次のソースを選択 をする様にしたい場合。

前の入力ソースを選択はソース一覧が表示されて変換にちょっと時間がかかるので 通常*入力メニューの次のソースを選択を使いたいので。 **次のとは言っても入力ソースはGoogle IMEの日本語、英数だけなので常にトグルします。

BetterTouchToolで直接その設定を書こうとすると、 -Space--Spaceを割り当てても デフォルトの-Spaceの設定が邪魔をして 前の入力ソースを選択の時に出る一覧が出てきてしまいます。

なので仕方なく環境設定の方で直接ショートカットを設定していました。

実用上はそれでも問題ないのですが、新しい環境に行った時に 設定忘れが起きやすいので出来ればアプリの設定ファイルとかでまとめて管理したい所。

これをKarabiner-Elementsで試してみた所、 環境設定の状態をデフォルトのままにしたままでも -Spaceで正しく 入力メニューの次のソースを選択を使う事が出来ました。

これもiTerm2の時と同様にキーバインドを扱うレイヤーがBetterTouchToolとKarabiner-Elementsで違うからだと思います。

Vim Emulation

より本格的なVimのエミュレーションですが、 Karabinerの時に作った様なものが今の状態でもできそうな気はします。

erb2json.rbに適当に便利関数を加えて行けばより簡単に作れる感じもします。

そのうち。

今使ってるもの

今のところ作ったものは以下に置いてあってImportすることが出来ます。

Karabiner-Elements complex_modifications rules by rcmdnk

全部で12の項目があります。

ホントに自分だけで使うもので常に全部使うのであれば1つ1つEnableする手間があるので 全部同じmanipulatorsに入れてしまっても良いと思います。

まあ、多分安定して変更が少なくなったら、必要な項目をEnableした状態で ~/.config/karabiner/karabiner.json自体をdotfiles的に管理するのが良いかな、と思います。

追記: 2017/08/30

試しにkarabiner.jsonを別の管理ディレクトリに置いてそこへの シンボリックリンクを~/.config/karabiner/karabiner.json に作って見ましたが、 とりあえずファイルの更新の時に新たなファイルになる、というような事はなさそうでした。

ただ、シンボリックリンクにしたらどうもきちんと設定が読み込めないのか 何か混乱するのかキーの設定が反映されなくなりました。

環境設定の方で見えていても駄目で、再び立ち上げると設定が消えてたりすることも。

とうことで設定ファイルをリンクにするのはちょっと辞めておいた方が良さそうです。

追記ここまで

Sponsored Links
Sponsored Links

« GitHubでForkしたレポジトリにIssuesを付ける VimでNormalモード切り替え時にIMEをOFFにする、をMacでKarabiner-Elementsを使って実現する »