ファイルフォーマット
ファイル形式はJSON
で、拡張子は.sublime-keymap
プラットフォーム毎にファイルが作られます。
- Default (Windows).sublime-keymap
- Default (Linux).sublime-keymap
- Default (OSX).sublime-keymap
また、キーバインドの設定ファイルは、DefaultとUserの2つのファイルがありますがUserほうが優先順位が高いので、自分設定を追加する場合はUserのほうに書いていくほうがいいと思います。Userのほうは一番初めに開くと空っぽのファイルなので[]の入力をお忘れなく。
キーバインドの設定ファイルは、メニューの下記のところに。
- Preferences -> Key Bindings - Default
- Preferences -> Key Bindings - User
キーバインドの構造
-
keys
設定するキー
省略不可 -
command
設定されたキーで、実行するコマンドのコマンド名。
省略不可 -
args
コマンドへ渡す引数。
省略可 -
context
何時このキーバインドを有効にするかを設定する。設定がなければ常に有効になります。
ここの設定で、特定のsyntaxでのみキーバインドを有効にする。みたいなことができるようになります。
省略可
基本形
一番シンプルな設定方法は、こんな感じ。
{ "keys": ["キー"], "command": "コマンド名" }
// キーストロークが1回の時
{ "keys": [ctrl+n], "command": "new_window" },
// キーストロークが2回の時
{ "keys": [ctrl+n, ctrl+w], "command": "new_window"}
・Plugin作りたい人へのTips
このコマンド名はpythonのクラス名になっており、先頭と_の直後を大文字に変更したクラス名を設定します。
例えば上記の例だと NewWindowCommand or NewWindow どちらかのクラス名になっています。
引数がある場合
値をコマンドに渡したい時は、argsに続けて入力します。
{ "keys": ["キー"], "command": "コマンド名", "args": {"変数名": "値"} }
このargsに入る値はコマンドによって異なるので、
insertにのargsに{"by": "characters", "forward": false}を設定したらエラーになります。
// 引数ひとつの時
{ "keys": ["enter"], "command": "insert", "args": {"characters": "\n"} },
// 引数複数の時
{ "keys": ["left"], "command": "move", "args": {"by": "characters", "forward": false} },
// 引数配列の時
{ "keys": ["alt+o"], "command": "switch_file", "args": {"extensions": ["cpp", "c", "h"]} }
command
に 'insert_snippet' を使うと、$0
の位置にキャレットを移動させたり、'${0:$SELECTION}'で、選択文字列を取得したり、スニペット風の引数文字列を使うことができます。
// `{` を入力すると '}' が自動入力され、キャレットが `{}` の間に移動
{ "keys": ["{"], "command": "insert_snippet", "args": {"contents": "{$0}"} },
// 文字列を選択状態で `{` を入力すると '}' が自動入力されて、選択文字列を `{}` で囲む
{ "keys": ["{"], "command": "insert_snippet", "args": {"contents": "{${0:$SELECTION}}"} }
・Plugin作りたい人へのTips
この時pythonのクラスは、こんな感じだと予想されます。
class InsertCommand(sublime_plugin.TextCommand):
def run(self, edit, characters):
class MoveCommand(sublime_plugin.TextCommand):
def run(self, edit, characters, forward):
class SwitchFileCommand(sublime_plugin.WindowCommand):
def run(self, extensions):
引数のInsertCommand, MoveCommandが持っているedit
はテキスト編集したい時にベースクラスからもってくるものです。
ベースクラスは4つあって、その中でもテキストを編集するsublime_plugin.TextCommandを使用する時にだけ必要な引数です。
switch_fileはソースファイルに対応したヘッダファイルを開くコマンドなので、sublime_plugin.WindowCommandになっている。
コンテキストがある場合
コンテキストの構造
-
key
状態を表す
例えば、selection_empty が入っていたら 文字選択をしていない場合 true を返す。
省略不可 -
operator
演算子
例えば、equal, not_equal などがある。
省略可 -
operand
operatorがequal, not_equalならtrue, false、1, 2などを入力。
regex_match, not_regex_match なら正規表現を入力。
省略可 -
match_all
これをtrueにした判定のがすべてtrueにならなければマッチしたことにはならない。
デフォルトではfalse
省略可
コンテキストの設定
コンテキストの使い方はこんな感じ。もちろんcommandによってはargsが入ります。
{ "keys": ["キー"], "command": "コマンド名", "context":
[
{ "key": "キー", "operator": "演算子", "operand": "結果", "match_all": "true or false" }
]
}
keyの一覧
-
num_selections
選択している数 -
selection_empty
何も選択していなければtrue -
preceding_text
キャレットより前の文字がどうなっているかを調べる -
following_text
キャレットより後の文字がどうなっているかを調べる -
has_prev_field
前に使用可能なスニペットフィールドがあればtrue -
has_next_field
後ろに使用可能なスニペットフィールドがあればtrue -
auto_complete_visible
オートコンプリートリストが表示されていればtrue -
panel_visible
何かpanelが表示されていればtrue -
overlay_visible
オーバーレイが表示されていればtrue -
setting.XXX
settingファイルで設定されているXXXの値が返る
値の確認はメニューのPreferences -> Setting - Default
,Preferences -> Setting - User
で確認 -
selector
現在の scope が返ります
Packages -> 'scope名のフォルダ' -> 'scope名.tmLanguage'ファイルの下のほうにあるscopeNameでどんなscope名になってるか確認
こんな風に書いてあるところです
<key>scopeName</key>
<string>source.c++</string>
operatorの一覧
-
equal, not_equal
key と operand が同じだったら実行させたい =equal
違ったら実行させたい =not_equal
-
regex_match, not_regex_match
key で選ばれる文字列が operand の正規表現とマッチするなら実行させたい =regex_match
違ったら実行させたい =not_regex_match
こっちはPythonでいう re.search. 文字列の途中マッチOK -
regex_contains, not_regex_contains
key で選ばれる文字列が operand の正規表現とマッチするなら実行させたい =regex_contains
違ったら実行させたい =not_regex_contains
こっちはPythonでいう re.match. 文字列の途中マッチNG
keyの使用例
num_selections
選択している数
{ "keys": ["escape"], "command": "single_selection", "context":
[
{ "key": "num_selections", "operator": "not_equal", "operand": 1 }
]
}
2つ選択しているので、escapeキーを押すと、single_selectionが実行される
selection_empty
何も選択していなければtrue
{ "keys": ["ctrl+w"], "command": "cut", "context":
[
{ "key": "selection_empty", "operator": "equal", "operand": true }
]
}
何も選択されていないのでtrueになり、ctrl+wを押すと、cutが実行される
preceding_text
キャレットより前の文字がどうなっているかを調べる
{ "keys": ["shift+tab"], "command": "unindent", "context":
[
{ "key": "preceding_text", "operator": "regex_match", "operand": "^[\t ]*" }
]
},
キャレットより前の文字が^[\t ]*にマッチしているので、shift+tabを押すとunindentが実行される
following_text
キャレットより後の文字がどうなっているかを調べる
{ "keys": ["ctrl+j"], "command": "move", "args": {"by": "characters", "forward": true}, "context":
[
{ "key": "following_text", "operator": "regex_match", "operand": ";$" }
]
}
キャレットより後ろの文字が ;$ にマッチしているので、ctrl+j を押すとキャレットがひとつ後ろに移動する
has_prev_field
前に使用可能なスニペットフィールドがあればtrue
{ "keys": ["shift+tab"], "command": "prev_field", "context":
[
{ "key": "has_prev_field", "operator": "equal", "operand": true }
]
},
<snippet>
<description>For Loop</description>
<content><![CDATA[
for( int ${1:i} = 0; $1 < ${2:count}; ${3:++}$1 ){
${0:/* code */}
}
]]></content>
<tabTrigger>for</tabTrigger>
<scope>source.c, source.objc, source.c++, source.objc++</scope>
</snippet>
{2:count}のスニペットフィールドを選択していて、$1のスニペットフィールドがあるのでshift+tabを押すとprev_fieldが実行される
has_next_field
has_prev_fieldの反対
後ろに使用可能なスニペットフィールドがあればtrue
上記の例からhas_prev_field を has_next_fieldに変えた場合、画像は${2:count}のスニペットフィールドを選択していて、${3:++}のスニペットフィールドがあるのでshift+tabを押すとprev_fieldが実行される
auto_complete_visible
オートコンプリートリストが表示されていればtrue
{ "keys": ["escape"], "command": "hide_auto_complete", "context":
[
{ "key": "auto_complete_visible", "operator": "equal", "operand": true }
]
},
表示されているのでtrueになり、escapeキーを押すと、hide_auto_compliteが実行される
panel_visible
何かpanelが表示されていればtrue
{ "keys": ["escape"], "command": "hide_panel", "args": {"cancel": true},
"context":
[
{ "key": "panel_visible", "operator": "equal", "operand": true }
]
},
パネルが表示されているので、hide_panelが実行される
overlay_visible
オーバーレイが表示されていればtrue
{ "keys": ["escape"], "command": "hide_overlay", "context":
[
{ "key": "overlay_visible", "operator": "equal", "operand": true }
]
}
オーバーレイが表示されているので、hide_overlay が実行される
setting.XXX
settingファイルで設定されているXXXの値が返る
値の確認は Preferences -> Setting - Default
, Preferences -> Setting - User
で確認。
"shift_tab_unindent": false
{ "keys": ["shift+tab"], "command": "unindent", "context":
[
{ "key": "setting.shift_tab_unindent", "operator": "equal", "operand": true }
]
}
shift_tab_unindent は falseに設定されているので、 shift_tab_unindent の時にshift+tabを押しても unindent は実行されません。
selector
現在の scope名が返ります
{
"keys": ["ctrl+s"], "command": "generate_snippet_from_raw_snippet", "context":
[
{ "key": "selector", "operator": "equal", "operand": "source.sublimesnippetraw" }
]
}
ctrl+sを押すと、operand で選んだ scopeでのみ generate_snippet_from_raw_snippet が実行されます。
key が panelの場合
key
が panel
になっている時は operand には panelの名称が入ります。
panelの名称一覧
Packageの開発者の人へ
windows: Ctrl+Alt+<alphanum>
OSX: Option+<alphanum>
この組み合わせのキーは非ASCIIコードを入力できなくなる可能性があるので、使用しないほうがいいみたいです。