今回やること
Sublime Text2のプラグインはPythonで書きます。
今回は以下の仕様でプラグインを作ってみたいと思います。
- ファイルを保存したときにコマンドを実行する
- 特定のSyntaxモードを選択している時にしか実行できない
- Syntaxモードとコマンドは設定ファイルから読み込む
プラグインの新規作成
メニューからTools->New Plugin…をクリックすると、新規にファイルが作成されます。
クラス名をAutoRunnerに変更して、とりあえず保存します。保存時に勝手に以下のフォルダを指定してくれているはず。
/Users/[username]/Library/Application Support/Sublime Text 2/Packages/User
尚、エラーはコンソールに表示されるのでメニューのView->Show Consoleから予め表示しておきます。また、プラグインはPackages直下に置いておけば自動的に読んでくれます。
保存時の処理をフックする
APIリファレンスを読むと、EventListenerクラスが「Viewが保存されたときに実行される」、on_pre_save(view)を持っていることが分かります。
他にも、閉じられたとき、新規作成時、保存後…などの処理をフックできるようです。
これらを使う為には、sublime_plugin.EventListenerを継承する必要があるのでそのように修正します。また、元から生成されていたコードを削除してon_pre_save(self, view)関数を追加しておきましょう。
動作確認の為、"Hello World!"を表示させる為のコードを追加して保存し、さらにもう1度保存して実際にHello Worldが表示されるかどうか確認します。
import sublime, sublime_plugin
class AutoRunner(sublime_plugin.EventListener):
def on_pre_save(self, view):
sublime.message_dialog("Hello World!")
設定ファイルを読み込む
次に、設定ファイルから値を読み込みます(以下設定ファイル例)。
{
"ignored_packages":
[
"Vintage"
],
"auto_formatter"
{
"command" : "astyleformat",
"syntax" : "UnityC#"
}
}
APIリファレンスによると、view.settings()を使うことでSettingsクラスを取得できるそうです。
上記の設定ファイルの場合、view.settings().get('auto_formatter').get('syntax')で'UnityC#'が取得できます。
コマンドの実行
run_command(string, args…)を使ってコマンドを実行できます。
今回の場合は'astyleformat'コマンドを使用し、引数は使用しないのでrun_command('astyleformat')でフォーマットを実行できます。
実行するコマンドの前後にbegin_edit()とend_edit()を入れておくと、コマンドによる変更が1つの変更の単位として認識され、UndoとRedoが出来るので入れておきましょう。
完成
とりあえず、これだけで簡単にプラグインが動かせます。
Python分からないので何かおかしなところがあったら教えてください。
import re
import sublime, sublime_plugin
# 保存時に設定ファイルのコマンドを実行するプラグイン
class AutoRunner(sublime_plugin.EventListener):
# 保存前のフック処理
def on_pre_save(self, view):
# 設定ファイルから実行するシンタックスと実行コマンド情報を取得する
setting = view.settings().get('auto_formatter')
syntax = setting.get('syntax')
command = setting.get('command')
# 現在設定されているシンタックスモードを取得
current = view.settings().get('syntax')
# シンタックスモードはファイルパスが取得されるので、そこから名称だけ取得
# /AAA/BBB/ccc.tmLanguage => ccc.tmLanguage
filename = re.split('/', current)[-1]
# ccc.tmLanguage => ccc
current_syntax = re.split('\.', filename)[0]
# 設定ファイルのシンタックス値と現在のシンタックスモードが一致していればコマンドを実行
if current_syntax == syntax:
edit = view.begin_edit()
view.run_command(command)
view.end_edit(edit)