Hatena::ブログ(Diary)

日記

2012-10-01

Sublime Text 2 のプラグインの作成方法

Sublime Text 2 は Python により拡張することが可能です。この記事ではプラグインの作成方法について自分が調べたことをメモとして書いておきます。間違っていたらコメントなどでツッコミをお願いします。

APIリファレンス

Sublime Text 2 にアクセスするAPIAPI Reference - Sublime Text 2 Documentationリファレンスがあるのでそれを参考にしてください。 個人的には提供されているAPIの数は少ない印象です。

プラグインの種類

プラグインは、Sublime Text 2 が提供するベースクラスを継承することで実装します。単に継承するだけでプラグインとして認識されます。

ベースクラスは以下の4種類があります。

  • ApplicationCommand
  • WindowCommand
  • TextCommand
  • EventListener

上の3つはコマンドプラグインです。キーマップで設定して呼び出します。 EventListener はイベント発生時にメソッドがコールバックとして呼び出されます。

コマンドプラグイン

Sublime Text 2 のメニューから Tools→New Plugin を選択すると、以下のコードが未保存のファイルとして開かれます。このコードは、ファイルの先頭に "Hello, World!" という文字列を挿入するプラグインになります。

import sublime, sublime_plugin

class ExampleCommand(sublime_plugin.TextCommand):
    def run(self, edit):
        self.view.insert(edit, 0, "Hello, World!")

ポイントは、以下の4点です。

sublime_plugin.TextCommand を継承した場合は、 self.view を使って現在編集中のファイルにアクセスできます。同様に、sublime_plugin.WindowCommand を継承した場合は self.window を使ってウィンドウにアクセスできます。 ApplicationCommand と EventListener はフィールドには何も持ちません。

また、 sublime モジュールに定義されている関数も利用できます。利用できるAPIの情報はAPIリファレンスを参照してください。

view や window はコンストラクタ引数として渡されるので、コンストラクタを書く場合は自分で保持するか、ベースクラスのコンストラクタを呼び出します。

自分で保持する場合:

import sublime, sublime_plugin

class ExampleCommand(sublime_plugin.TextCommand):
    def __init__(self, view):
        self.view = view

    def run(self, edit):
        self.view.insert(edit, 0, "Hello, World!")

ベースクラスのコンストラクタを呼び出す場合:

import sublime, sublime_plugin

class ExampleCommand(sublime_plugin.TextCommand):
    def __init__(self, view):
        super(ExampleCommand, self).__init__(view)

    def run(self, edit):
        self.view.insert(edit, 0, "Hello, World!")

配置

自作したプラグインは、 Windows の場合は

C:\Users\(ユーザー名)\AppData\Roaming\Sublime Text 2\Packages\User

に .py ファイルを配置することで認識されます。他のOSに関しても、 (データディレクトリ)/Packages/User の下に配置すればよいみたいです。データディレクトリの位置は Basic Concepts — Sublime Text Unofficial Documentation を参照。

User ディレクトリはユーザー用なので、プラグインを配布する場合は別ディレクトリにする必要があると思いますが、その方法は調べていません。

コマンド名

定義したコマンドを呼び出す場合は、コマンド名を指定します。クラス名から末尾の"Command"を取ってスネークケースにした文字列がコマンド名となります。例えば、"CamelCaseCommand" クラスのコマンド名は、"camel_case" となります。

詳細は Plugins — Sublime Text Unofficial Documentation を参照してください。

コマンド実行

定義したコマンドをPythonコンソールから実行してみるには、 まず ctrl+@(Windowsの場合)を押してPythonコンソールを表示して、以下のコードを実行します。

# TextCommandを継承したコマンドを実行
view.run_command('example')

# WindowCommandを継承したコマンドを実行
window.run_command('example')

# ApplicationCommandを継承したコマンドを実行
sublime.run_command('example')
キーマップ

キーボードショートカットに割り当ててコマンドを実行する場合は、自分の設定ファイルに追加します。メニューの Preferences→KeyBinding - User を選択し、開かれたファイルを以下のように編集します。

[
    {
        "command": "example", // コマンド名
        "keys": ["ctrl+m"] // Ctrl+m に割り当て
    },

    // 以下自分用キーマップ設定
    { "keys": ["ctrl+h"], "command": "left_delete" }
]

設定ファイルには、C言語Javascript 形式のコメントを書けます。また、配列の最後の要素の後ろにカンマを付けるとエラーになるので注意してください。

イベントリスナープラグイン

ファイルを開いた時など、特定のタイミングで処理を実行したい場合は EventListener クラスを継承してイベントリスナーを作成します。 継承するだけでイベントリスナーとして登録され、イベント発生時に対応するメソッドが呼び出されます。

以下のコードでは、すべてのイベントを空関数として実装していますが、普通は必要なものだけ実装すれば良いです。ちなみに、自動補完を実装するのに必要な on_query_completions はなぜかAPIリファレンスに載っていませんでした。

class ExampleEventListener(EventListener):
    def on_new(self, view):
        pass
    def on_clone(self, view):
        pass
    def on_load(self, view):
        pass
    def on_close(self, view):
        pass
    def on_pre_save(self, view):
        pass
    def on_post_save(self, view):
        pass
    def on_modified(self, view):
        pass
    def on_selection_modified(self, view):
        pass
    def on_activated(self, view):
        pass
    def on_deactivated(self, view):
        pass
    def on_query_context(self, view, key, operator, operand, match_all):
        return None
    def on_query_completions(self, view, prefix, locations):
        return []

最後に

とりあえずプラグインを実装する最初のステップを書いてみました。実際にプラグインを作るには Sublime Text 2 の API を知らなければなりませんが、それはやる気が出れば続きを書こうと思います。

実は、現在の私の仕事のコードがShift-JISなので、私自身は Subilme Text 2 を実戦投入できていません。 この記事は仕事で使えない悲しみを糧にして書きました。誰かの参考になれば幸いです。

(補足: 現在の Sublime Text 2 は Shift-JIS のファイルを扱えません。)

Sublime Text 2 の自動補完プラグインの作成方法

Sublime Text 2 はデフォルトで自動補完する機能を持っていますが、その補完候補に独自の候補を追加する方法を簡単に書きます。

実装する方法は本当に簡単で、 EventListener を継承して on_query_completions で補完候補をリストで返すだけです。以下にサンプルコードを示します。

import sublime, sublime_plugin

class CompleteTest(sublime_plugin.EventListener):
    def on_query_completions(self, view, prefix, locations):
        return [
            ('neocomplecache', 'neocomplecache'),
            ('unite.vim', 'unite.vim'),
            ('vimshell', 'vimshell')
            ]

このコードを (データディレクトリ)/Packages/User/complete_example.py みたいなファイル名で保存し、適当なファイルで neo と入力すると、 "neocomplcache" が補完候補として表示されます。

on_query_completions で返すリストは、リストの中にタプルが入っている入れ子構造で、タプルは「ポップアップに表示する文字列」、「補完結果として挿入される文字列」の2つの要素からなります。次のような構造です。

[(候補1の表示文字列, 候補1の挿入文字列), (候補2の表示文字列, 候補2の挿入文字列), ...]

単純な単語補完では、表示文字列は挿入文字列と同じ文字列で問題ないでしょう。つまり、タプルの要素は2つとも同じ文字列となります。

ポップアップ表示の補完候補に説明を追加したい場合は、表示文字列に説明を追加すればよいです。