SublimeText2のキーバインドを、ちょっと突っ込んで解説

  • 127
    いいね
  • 0
    コメント
この記事は最終更新日から1年以上が経過しています。

ファイルフォーマット

ファイル形式はJSONで、拡張子は.sublime-keymap
プラットフォーム毎にファイルが作られます。

  • Default (Windows).sublime-keymap
  • Default (Linux).sublime-keymap
  • Default (OSX).sublime-keymap

また、キーバインドの設定ファイルは、DefaultとUserの2つのファイルがありますがUserほうが優先順位が高いので、自分設定を追加する場合はUserのほうに書いていくほうがいいと思います。Userのほうは一番初めに開くと空っぽのファイルなので[]の入力をお忘れなく。
キーバインドの設定ファイルは、メニューの下記のところに。

  • Perferences -> Key Bindings - Default
  • Perferences -> 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のクラスは、こんな感じだと予想されます。

plugin.py
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ならture, 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

選択している数

Default(Windows).sublime-keymap
  { "keys": ["escape"], "command": "single_selection", "context":
    [
      { "key": "num_selections", "operator": "not_equal", "operand": 1 }
    ]
  }

2つ選択しているので、escapeキーを押すと、single_selectionが実行される
selection_empty

selection_empty

何も選択していなければtrue

Default(Windows).sublime-keymap
  { "keys": ["ctrl+w"], "command": "cut", "context":
    [
      { "key": "selection_empty", "operator": "equal", "operand": true }
    ]
  }

何も選択されていないのでtrueになり、ctrl+wを押すと、cutが実行される
selection_empty

preceding_text

キャレットより前の文字がどうなっているかを調べる

Default(Windows).sublime-keymap
  { "keys": ["shift+tab"], "command": "unindent", "context":
    [
      { "key": "preceding_text", "operator": "regex_match", "operand": "^[\t ]*" }
    ]
  },

キャレットより前の文字が^[\t ]*にマッチしているので、shift+tabを押すとunindentが実行される
preceding_text

following_text

キャレットより後の文字がどうなっているかを調べる

Default(Windows).sublime-keymap
  { "keys": ["ctrl+j"], "command": "move", "args": {"by": "characters", "forward": true}, "context":
    [
      { "key": "following_text", "operator": "regex_match", "operand": ";$" }
    ]
  }

キャレットより後ろの文字が ;$ にマッチしているので、ctrl+j を押すとキャレットがひとつ後ろに移動する
following_text

has_prev_field

前に使用可能なスニペットフィールドがあればtrue

Default(Windows).sublime-keymap
  { "keys": ["shift+tab"], "command": "prev_field", "context":
    [
      { "key": "has_prev_field", "operator": "equal", "operand": true }
    ]
  },
030-for-int-loop-(fori).sublime-snippet
<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_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

Default(Windows).sublime-keymap
  { "keys": ["escape"], "command": "hide_auto_complete", "context":
    [
      { "key": "auto_complete_visible", "operator": "equal", "operand": true }
    ]
  },

表示されているのでtrueになり、escapeキーを押すと、hide_auto_compliteが実行される
auto_complete_visible

panel_visible

何かpanelが表示されていればtrue

Default(Windows).sublime-keymap
  { "keys": ["escape"], "command": "hide_panel", "args": {"cancel": true},
    "context":
    [
      { "key": "panel_visible", "operator": "equal", "operand": true }
    ]
  },

パネルが表示されているので、hide_panelが実行される
panel_visible

overlay_visible

オーバーレイが表示されていればtrue

Default(Windows).sublime-keymap
  { "keys": ["escape"], "command": "hide_overlay", "context":
    [
      { "key": "overlay_visible", "operator": "equal", "operand": true }
    ]
  }

オーバーレイが表示されているので、hide_overlay が実行される
overlay_visible

setting.XXX

settingファイルで設定されているXXXの値が返る
値の確認は Preferences -> Setting - Default, Preferences -> Setting - User で確認。

Preferences.sublime-settings
    "shift_tab_unindent": false
Default(Windows).sublime-keymap
  { "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名が返ります

Default(Windows).sublime-keymap
{
  "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の場合

keypanel になっている時は operand には panelの名称が入ります。

panelの名称一覧

  • find
    find

  • incremental_find
    incremental_find

  • find_in_files
    find_in_files

  • replace
    replace

  • console
    console

Packageの開発者の人へ

windows: Ctrl+Alt+<alphanum>
OSX:  Option+<alphanum>

この組み合わせのキーは非ASCIIコードを入力できなくなる可能性があるので、使用しないほうがいいみたいです。