サブライムのスニペットを使い倒す

#はじめに
サブライムのスニペットを使い倒そうと色々調べた事を書きます。ここで紹介しているスニペットやプラグインは[GitHub](https://github.com/plsplsme/sublime_text)にアップしてみました。

#文字列を適当な文字列で囲む方法

こんな変数が並んでいる時、よく配列にしたくなります。

```php
$foo
$boo
$hoo
```

```php
$array['foo']
$array['boo']
$array['hoo']
```

調べてみると`$TM_SELECTED_TEXT`という環境変数があって、これで選択しているテキストを埋め込む事が出来ます。
これを利用して、変数を選択した時に実行するスニペットはこうなります。

```xml

<!-- php_make_it_array.sublime-snippet -->
<snippet>
	<content><![CDATA[
${1:array}['$TM_SELECTED_TEXT']
]]></content>
	<!-- Optional: Set a tabTrigger to define how to trigger the snippet -->
	<tabTrigger>makeitarray</tabTrigger>
	<!-- Optional: Set a scope to limit where the snippet will trigger -->
	<scope>source.php</scope>
	<description>変数を配列にする</description>
</snippet>
```

ここでtabTrrigerをmakeitarrayにしていますが、TABをトリガにしても動きません。なぜかというと、トリガを入力した時点で選択テキストが消えてしまう為です。

#スニペットを一覧表示から選ぶ

スニペットの一覧表示は、[Tool]->SnippetsもしくはコマンドパレットでSnippetと入力します。これで一覧から実行すれば選択テキストが消えません。

#スニペットの一覧表示を使いやすくする
なお、スニペットのdescriptionタグを使うと、一覧表示にスニペットの詳細を表示できます。これを入れていないと、上記の例ではphp_make_it_arrayが表示されます。descriptionには**日本語が使えます**ので便利だと思います。私の環境だとsnippetのデフォルトにdescriptionが無いので、存在に全く気付きませんでした。

#スニペットをキーバインディングする。
ただ、出来ればキーでスニペットを使いたいですね。そこでキーバインディングに登録します。

```json

    { "keys": ["alt+a"], "command": "insert_snippet", "args": {"name": "Packages/User/snippet/php_make_it_array.sublime-snippet"}}
```

スニペットの存在するフォルダのパスに注意して下さい。

#スニペットをプラグインに組み込む

make_it_arrayの応用として、変数を関数で囲むスニペットも作れます。PHPだとこんな感じです。

```php
#これを
$var
#こうする
trim($var)
```

varをダブルクリックして選択して、関数でラップするスニペットトはこんな感じです。

```xml

<snippet>
	<content><![CDATA[
${1:func}(\$$TM_SELECTED_TEXT)
]]></content>
	<!-- Optional: Set a tabTrigger to define how to trigger the snippet -->
	<tabTrigger>wrapbyfunc</tabTrigger>
	<!-- Optional: Set a scope to limit where the snippet will trigger -->
	<scope>source.php</scope>
	<description>WrapByFunction</description>
</snippet>
```

ただ、これだと`trim($var)`でなくて`$trim($var)`となってしまいます。なぜかというと、ダブルクリックで選択されるのは`var`だけだからです。

```php
#これが
$var
#こうなる
$trim($var)
```

`$`も選択させる方法もあるかもしれないですが、覚えるのが面倒なので`$`をプラグインで消してからスニペットを動かす事にしました。`$`を消すプラグインはこんな感じです。一応、`$`をチェックしているので、他の言語でも応用できると思います。

```py
#delete_variable_symbol.py
import sublime, sublime_plugin
class DeleteVariableSymbolCommand(sublime_plugin.TextCommand):
    def run(self, edit):
        for region in self.view.sel():
            if not region.empty():
                pos = region.begin()
                check_region = sublime.Region(pos,pos-1)

                if self.view.substr(check_region) == '$':
                    self.view.erase(edit,check_region)
```

このプラグインとスニペットを別のプラグインで呼ぶのはこう書きます。

```py
#wrap_by_func.py
import sublime, sublime_plugin

class WrapByFuncCommand(sublime_plugin.TextCommand):
    def run(self, edit):
        self.view.run_command("delete_variable_symbol")
        self.view.run_command("insert_snippet", { "name": "Packages/User/snippet/php_wrap_by_func.sublime-snippet"} )
```

キーバインディングもしましょう。

```json

    { "keys": ["alt+f"], "command": "wrap_by_func"}
```

#スニペットをプラグインに組み込む-応用

いろいろググってたらこんなやり方も出てきました。出典を忘れたのでGitHubにはアップしてません。

```py
import datetime, getpass
import sublime, sublime_plugin

class AddDateCommand(sublime_plugin.TextCommand):
    def run(self, edit):
        self.view.run_command("insert_snippet", { "contents": "//plsplsme %s" %  datetime.date.today().strftime("%Y/%m/%d") } )
```

スニペットの文字列にpythonの関数の返り値を入れ込んでます。これがpythonの機能なのか、run_commandがサポートしているのかは、python初心者の私にはまだ良くわかりません。

#参考資料
スニペットの環境変数などはここに詳しいです。
http://sublimetext.info/docs/en/extensibility/snippets.html