Linux SublimeText 3 で自作プラグイン

  • 23
    いいね
  • 0
    コメント

最初に

 こちらの記事がわかりやすかった。
 こちらはAPIの邦訳。

HelloWorld プラグイン

 編集中のファイルに「Hello, World!」を出力するだけの HelloWorld プラグインを作成。プラグインのコマンドは TextCommand ベースの HelloWorldCommand のみ(以下のベースクラスを参照)。

ディレクトリ構成

 SublimeText3(ST3)を起動して

$ subl

 ST3 上部のメニューバーから「Preferences」→「Browse Packages」を開く。パスなら「/home/user-name/.config/sublime-text-3/Packages」ディレクトリ。「Packages」ディレクトリ直下に「HelloWorld」ディレクトリを作成。ここに必要なファイルを作成。
 最終的にこんなツリーに。

HelloWorld
$ tree
HelloWorld/
|-- HelloWorld.sublime-settings
|-- Context.sublime-menu
|-- HelloWorld.py
|-- Main.sublime-menu
`-- Side Bar.sublime-menu

プラグイン用のベースクラスの選択

 参照によると用途によって各コマンドのベースクラスが異なる。

WindowCommand: self.windowでカレントウィンドウにアクセスできる
TextCommand: self.viewで編集中のファイルにアクセスできる
EventListener: ファイルの保存などイベントをフックして実行できる
ApplicationCommand: ウィンドウやファイルにアクセス出来ない

HelloWorld.py の作成

 ST3 上部のメニューバーから「Tool」→「Developer」→「New Plugin」と選択して、Pluginのひな形を作成。そして「HelloWorld」ディレクトリ内に「HelloWorld.py」で保存。

HelloWorld.py
import sublime, sublime_plugin

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

 クラス名を「HelloWorldCommand」に変更。このコマンドは TextCommand ベースのコマンド。

HelloWorld.py
class HelloWorldCommand(sublime_plugin.TextCommand):

 ここからデバッグが必要になるので、ST3 上部のメニューバーから「View」→「Show Console」と選択してコンソールを開く。コンソールのコマンド実行欄に

ST3_Console
view.run_command('hello_world')

 と入力して「hello_world」コマンドを実行。現在開いているファイルの先頭に「Hello, World!」が挿入された。
 view.run_command にはコマンド名を渡す。しかし、このコマンド名をタイプした覚えがない(゚Д゚)?。これはクラス名から由来するらしい。クラス名が

 class HelloWorldCommand

 であれば、コマンド名は「hello_world」に。クラス名が

 class ExampleCommand

 であれば、コマンド名は「example」に暗黙的に変換される。参照によるとスネークケースに変換されるらしい。

hello_world コマンドをショートカットキーから呼ぶ

 「Preferences」→「Key Bindings - User」から追加。

[
    { "keys": ["super+shift+h"], "command": "hello_world" },
]

hello_world コマンドをメニューから呼ぶ

 「Main.sublime-menu」を作成して「HelloWorld」ディレクトリ直下に保存。

Main.sublime-menu
[
    {
        "id": "HelloWorld",
        "caption": "Hello, World!",
        "children":
        [
            {
                "caption": "run",
                "command": "hello_world",
            }
        ],
    }
]

 ST3 上部のメニューバーに「Hello, World!」アイテムが出現。クリックして「run」で「hello_world」コマンドが実行された。

hello_world コマンドを右クリックメニューから呼ぶ

 「Context.sublime-menu」を作成して「HelloWorld」ディレクトリ直下に保存。

Context.sublime-menu
[
    {
        "id": "HelloWorld",
        "caption": "Hello, World!",
        "command": "hello_world"
    }
]

 編集領域内での右クリックメニューに「Hello, World!」アイテムが出現する。クリックで「hello_world」コマンドが実行された。

hello_world コマンドをプロジェクトサイドバー上の右クリックメニューから呼ぶ

 「Side Bar.sublime-menu」を作成して「HelloWorld」ディレクトリ直下に保存。

[
    {
        "id": "HelloWorld",
        "caption": "Hello, World!",
        "command": "hello_world"
    }
]

 プロジェクトを開くと ST3 左部にサイドバーが現れる。そこで右クリックすると「Hello, World!」が出現。クリックで「hello_world」コマンドが(ry

プラグインの設定

 プラグインは独自の設定ファイルを持つことが出来る。「HelloWorld」ディレクトリ直下に JSON で「HelloWorld.sublime-settings」を保存。

HelloWorld.sublime-settings
{
    "message": "HelloWorld plugin as free plugin."
}

 プラグインから設定ファイル内の設定値を参照するには、最初に設定ファイルのロードを行う。その後、各設定にアクセスできる。

ShowSettingsCommand
import sublime, sublime_plugin

class ShowSettingsCommand(sublime_plugin.TextCommand):
    def run(self, edit):
        # プラグインの設定ファイルを読み込み
        settings = sublime.load_settings('HelloWorld.sublime-settings')

        # 設定値を取得してコンソールに出力
        message = settings.get('message')
        print(message)

自作プラグインに自作モジュールを読み込む

 プラグインが肥大化し、モジュールで分割する必要が出てきた場合などは API の sublime.packages_path() を使ってパッケージまでのパスを作成し、システムに追加。
 でもsublime.packages_path()はたまに空文字列を返す。原因は不明。__file__を使う方法もあって、そちらは今のところ正常に動作。それからパッケージ名とプラグイン名が被ると正常に動作しない?いろいろと謎が多い部分(´・ω・)(・ω・`)ネー

directorys
myplugin/ # <- プラグインのルート
    myplugin.py # <- プラグイン本体
    mypackage/ # <- パッケージ
        __init__.py
        mymodule.py # <- モジュール

sublime.packages_path()を使う場合。

myplugin.py
import sublime, sublime_plugin
import os, sys

sys.path.append(os.path.join(sublime.packages_path(), 'mypackage')) # <- 'mypackage' は パッケージ名
from mypackage import mymodule
from mypackage.mymodule import myfunc

__file__を使う場合。

myplugin.py
import sublime, sublime_plugin
import os, sys

sys.path.append(os.path.dirname(os.path.abspath(__file__)))
from mypackage import mymodule
from mypackage.mymodule import myfunc

API の使い方

 ST3 のプラグイン開発では ST3 提供の API を使用して開発する。その API の詳細は Sublime Text 3 Documentation - API Reference から参照可能だけど、「プラグイン開発者がやりたいこと」と「そのやりたいことを実現する API」のリンクで難儀したので試してみた結果を以下に履歴。

TextCommand

ReplaceToReimuCommand

 現在開いているファイルのテキスト全てをAAに置き換え。参照元のコードではペ○○スに置き換えていた。

HelloWorld.py
import sublime, sublime_plugin

class ReplaceToReimuCommand(sublime_plugin.TextCommand):
    def run(self, edit):
        allContent = sublime.Region(0, self.view.size())
        self.view.replace(edit, allContent, '    , -、\n   _ ,ノ\n / :;;/" 、⌒ヽ,\n | :: ( △::;;;::△:;|\n ヽ,,::、WWW;/\n  くi Lノノハノ)」\n   λ.[i ゚ ヮ゚ノi! Trick or Treat!(お賽銭をくれなきゃいたずらするわよ)\n   レ\',ヘ.i`ム\'」つ\n   ,く_,//T.iλ\n   "ーr_,t_ァ\'"\n')

カーソルが置かれている行を取得してコンソールに文字列を表示

参照: http://stackoverflow.com/questions/30115649/get-current-line-in-sublime-text-3-plugin

ShowCurLineCommand
import sublime, sublime_plugin

class ShowCurLineCommand(sublime_plugin.TextCommand):
    def run(self, edit):
        vw = self.view

        # Selection オブジェクトを取得
        sel = vw.sel()

        # Selection から Region オブジェクトを取得
        reg = sel[0]

        # line() で Region を行単位に拡大する
        # line() は full_line() のエイリアス
        reg = vw.line(reg)

        # Region を String オブジェクトに変換
        curln = vw.substr(reg)

        # ST3 のコンソールに出力
        print(curln)

カーソルが置かれている行を文字列で置き換え

ReplaceCurLineCommand
import sublime, sublime_plugin

class ReplaceCurLineCommand(sublime_plugin.TextCommand):
    def run(self, edit):
        vw = self.view

        # Selection オブジェクトを取得
        sel = vw.sel()

        # Selection から Region オブジェクトを取得
        reg = sel[0]

        # line() で Region を行単位に拡大する
        # line() は full_line() のエイリアス
        reg = vw.line(reg)

        # カーソルが置かれている行を置き換え
        vw.replace(edit, reg, 'REPLACE!')

自作プラグインのサンプル

UrlToLinks

 カーソル行に入力されたパスを <a> タグで階層化して出力する。
 https://github.com/narupo/UrlToLinks

Image

参照

Sublime Text 3 Documentation
Sublime Text 3 Documentation - API Reference
How to Create a Sublime Text 2 Plugin
Creating Sublime Text 3 Plugins – Part 1
Creating Sublime Text 3 Plugins – Part 2
Plugins — Sublime Text Unofficial Documentation
SublimeTextのプラグイン作成方法