先日から開発環境の見直しを考えてまして、前回のGrunt導入に続いてエディタをSublime Text3にしてみようかと思い試してみました。
本体の多機能さと豊富なプラグインのおかげで特に手をかけなくても相当に強力な開発環境となるのですが、大人(お仕事)の事情でオリジナルのプラグインが作れないとメインエディタにはできません。
そこで実際に簡単なプラグインを作ってみました。
プラグインとして動作するものをGithubで公開していますので、よかったら参考にしてみてください。
Sublime Text3を使用した例ですので、2では動かないコードもあります。ご注意ください。
ADs
作成するプラグインの名称を「newPlugin」ということにして話を進めます。
C:\Users\ユーザー名\AppData\Roaming\Sublime Text 3\Packages\
内に「newPlugin」という名前のフォルダを作成し、更にその中に「newPlugin.py」というファイルを作成します。
このnewPlugin.pyに処理を書いていきます。
メニューの「ツール」→「プラグイン追加」とすると新規ドキュメントが開き、以下の内容が表示されるかと思います。
入力しているテキストを操作するタイプのプラグインは以下の記述がベースとなります。
1 2 3 4 5 |
import sublime, sublime_plugin #必ず必要 class ExampleCommand(sublime_plugin.TextCommand): #関数定義 def run(self, edit): #プラグインが実行された時の処理 self.view.insert(edit, 0, "Hello, World!") #ここからが本体 |
プラグイン内の1つの機能が1つのクラスとなるため、単一ファイル内に複数のクラスを記述することも可能です。
Pythonは名前ぐらいしか知らなかったので簡単な処理でもずいぶん手間取ってしまいました…。
PHPやJavascriptの{}の代わりにインデントを使う、というふうに見れば分かりやすいかもしれません。
のちほどメニューやコマンドパレットから実行する際に名前が必要となります。
名前のルールとして最後は必ず「Command」で終わり、複数の単語の場合はキャメルケースにする必要があります。
プラグイン本体であるnewPlugin.pyファイルに記述する内容をいくつか書いてみました。
いずれもテキストを操作する単純な例なので、プラグイン開発の基本的な流れが分かりやすいのではないかと思います。
たとえば、「おにぎり」という単語を選択してプラグインを実行すれば全部<strong></strong>で囲ってくれるという処理は以下のようになります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
<p> おいしいおにぎりが食べたいな~。<br /> 今日のランチはファミマにしよう。そういえばおにぎりが20円引きだったな。<br /> おにぎりワッショイ!おにぎりワッショイ! </p> ↓ 「おにぎり」を選択して <p> おいしい<strong>おにぎり</strong>が食べたいな~。<br /> 今日のランチはファミマにしよう。そういえば<strong>おにぎり</strong>が20円引きだったな。<br /> <strong>おにぎり</strong>ワッショイ!<strong>おにぎり</strong>ワッショイ! </p> こうしたい!みたいな |
具体的な処理の流れとしては
・選択範囲の取得
・前後にテキストを足して選択範囲を置き換える
となります。
1 2 3 4 5 6 7 8 9 |
class txtWrapCommand(sublime_plugin.TextCommand): def run(self, edit): start = "<strong>" end = "</strong>" #ST3は複数箇所の選択ができるので、forになります for region in self.view.sel(): if not region.empty(): self.view.replace(edit, region, start + self.view.substr(region) + end) |
この例そのままだと「Emmetでええやん…」という程度のものですが、選択範囲のテキストによって条件分岐したりテキストの内容を元にstart/endを定義したりするなど、応用すればいろいろと使えます。
たとえば、カーソル位置に<br />を入れる処理は以下のようになります。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
<p> 「ではみなさんは、そういうふうに川だと云いわれたり、乳の流れたあとだと云われたりしていたこのぼんやりと白いものがほんとうは何かご承知ですか。」 </p> ↓ 改行を入れたいところにカーソルを置いて <p> 「ではみなさんは、そういうふうに川だと云いわれたり、<br /> 乳の流れたあとだと云われたりしていたこのぼんやりと白いものが<br /> ほんとうは何かご承知ですか。」 </p> こうしたい! |
1 2 3 4 5 |
class txtInsertCommand(sublime_plugin.TextCommand): def run(self, edit): for region in self.view.sel(): #選択している場所ではないのでinsertになります self.view.insert(edit, region.a, '<br />'+"\n") |
定型文の挿入などに使えそうです。
上記の例では固定文言を挿入したり差替えたりというものでしたが、プロンプトみたいなものを出してその入力内容を反映して処理を行いたい、という場合もあると思います。
たとえば、画像サイズを入力すればそのサイズを適用したimgを生成する、といった処理は以下のようになります。
1 2 3 4 5 6 |
コンソールでwidth/heightを入力してもらったら <img src="https://placehold.jp/300x200.png" alt=""> と生成される、みたいな。 ※http://placehold.jp/ を利用させていただきました。 |
文字入力を行う場合はこれまでの処理と異なり、以下の2つのクラスが必要となります。
・コンソールを表示させ、文字入力後の処理へ引き継ぐクラス
・実際に処理を行うクラス
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
#コンソールを表示させるクラス class imageSettingCommand(sublime_plugin.TextCommand): def on_done(self,arr): size = arr.split('x') w = size[0] h = size[1] self.view.run_command('insert_image', {'arr': [w,h]}) def run(self, edit): self.view.window().show_input_panel('サイズを「幅x高さ」で入力(例:600x300)', '600x300', self.on_done, None, None) #実際に行われる処理 class insertImage(sublime_plugin.TextCommand): def run(self,edit,arr): w = arr[0] h = arr[1] img = '<img src="https://placehold.jp/WIDTHxHEIGHT.png" width="WIDTH" height="HEIGHT" alt="">' img = img.replace('WIDTH',w) img = img.replace('HEIGHT',h) for region in self.view.sel(): self.view.insert(edit, region.a, img) |
これで3つの処理を含んだプラグインが出来上がったわけですが、このままでは実行することが出来ません。
※コンソールからなら実行できますが。
そこでコマンドパレット(ctrl+shift+p で出てくるやつ)の一覧に表示されるようにします。
newPluginフォルダ内に「Default.sublime-commands」というファイルを作成し、以下のように記述します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
[ { "caption": "newPlugin: strongタグで囲う", "command": "txt_wrap" }, { "caption": "newPlugin: 改行を挿入", "command": "txt_insert" }, { "caption": "newPlugin: 画像挿入", "command": "image_setting" } ] |
Default.sublime-commandsというファイルがプラグインフォルダ内にあれば、コマンドパレットの一覧に表示されます。
そこで該当のプラグインを選択すれば、実際にこれまで書いた処理が実行されます。
利用頻度が高いプラグインであればあるほどショートカットで呼び出したいことも多いと思います。
その場合は「Default (Windows).sublime-keymap」というキーマップファイルを作成し、ショートカットの定義を行います。
Windowsの場合は「Default (Windows).sublime-keymap」というファイルを作成し、以下の内容を記述します。
ショートカットキーと.sublime-commandsファイルでも使用したコマンド名を入力します。
1 2 3 4 5 6 7 8 9 10 11 |
[ { "keys": ["ctrl+f1"], "command": "txt_wrap" }, { "keys": ["ctrl+f2"], "command": "txt_insert" }, { "keys": ["ctrl+f3"], "command": "image_setting" } ] |
Default (OSX).sublime-keymap
Default (Linux).sublime-keymap
となります。
指定するキー名はSublime Textのデフォルトの設定を見るといいでしょう。
SublimeText3のPackageフォルダ内に「NewPlugin」というフォルダをつくり、その中に上記アーカイブの中の「newPlugin.py」「Default.sublime-commands」「Default (Windows).sublime-keymap」の3つのファイルをコピーすればプラグインとして動作します。
コマンドパレットより「newPlugin」という単語で探すか、Ctrl+f1/f2/f3のショートカットを試してみてください。
Sublime Text3もPythonも全然使ったことなかったですが、いろいろなサイトの情報のおかげで何とかなりました。
ありがとうございました。
Sublime Text 2 Plugin Tips
SublimeTextのpluginの作り方
Sublime Text 2 のプラグインを作る
Pythonでの文字列置換をマスターする
テキストで.pyファイルや設定ファイルを書いて指定フォルダに置くだけでプラグインとして動作するというのはとても手軽です。
過去にDreamweaverとEmEditorでプラグイン(というかマクロ)を作成したことがありますが、プラグインとして認識させるためにはコンパイルが必要でした。その面倒さと比べると自宅と職場の環境の共有や移行なども簡単にできそうです。
Pythonというのが大きな壁なのですが、慣れてくれば簡潔で見通しのいい言語と思える日がくるかもしれません。
でもプラグインをJavascriptで書けたらいいのに…とは思わざるをえない…。
ADs