2014年10月7日火曜日

sublime text3用のプラグイン作成において、WindowCommandでbegin_edit()が出来ないので要注意的なお話

  • このエントリーをはてなブックマークに追加

sublime text3用のプラグインを作っている際に、処理中とか何を処理したとかそういった表示をしたいことがある。
で、そんなときはoutput_panelっていうのを作ってあげればよかったりする。
ここのブログの記事が作成方法でわかりやすかったりするけど、
実はsublime text3から仕様が厳密になったみたいで、エラーとなって諸々問題が出てきてしまった。

ということは今日はその解説をば。

■sublime text3になったことでTextCommandでしかeditクラスは使用できない

begin_edit()とend_edit()がTextCommandでしか使用できないので、下記のように書かないとダメ。

class ExampleCommand(sublime_plugin.TextCommand):
  def run(self,edit):
    window = self.view.window()
    output_view = window.get_output_panel("textarea")
    window.run_command("show_panel",{"panel": "output.textarea"})
    output_view.set_read_only(False)
    #edit = output_view.begin_edit()
    output_view.insert(edit, output_view.size(),"test")
    output_view.end_edit(edit)
    output_view.set_read_only(True)
こんな感じでやればoutput_panelにtestって入力される。
ちなみに#edit = output_view.begin_edit()としているのは、
TypeError: begin_edit() missing 2 required positional arguments: 'edit_token' and 'cmd'
というエラーが出て来て、うまくoutput_panelに出力されないためにコメントアウトしている。

上記のようなエラーが出てしまう原因としてはsublime text2用までは、
WindowCommandでもoutput_viewを出すにはeditクラスを生成?してあげるためだったんじゃないかと。
けどsublime text3からはTextCommandで引数に入ってくるeditを使用するしかないらしいとのこと。

公式の記事

ってなわけでsublime text3用のプラグインというかパッケージで、
output_panelを使いたかったらTextCommandを使いましょう的な。


■WindowCommandでもedit使いたい場合はどうすればよいのか

例えばサイドバーに表示されているファイルを右クリックして、
そこにコマンドを割り当ててうんちゃらして、その処理過程をoutput_panelで表示したい場合はどうすればよいのか。
そういった場合はちょっと強引な手法になるけど下記のような感じでやれば大丈夫。

class Example2Command(sublime_plugin.WindowCommand):
  def run(self,paths = []):
    self.window.active_view().run_command("example")
こんな感じで現在のactive_viewに対してrun_command()で先ほどのoutput_panelを出すクラスを呼び出してあげればよい。
こうすれば右クリックで割り当てたメニューにcommand内で、output_panelを呼び出せる。


■output_panelに引数を与えて文字を表示させたい

WindowCommandで強引にoutput_panelを出す方法だと、特定の文字列しか出来ないように思えるけど、
引数を渡してその引数の文字列を表示させたいなみたいなことがあると思う。
ってなわけでそれに対応した記述は下記のような感じ。

class ExampleCommand(sublime_plugin.TextCommand):
  def run(self,edit,*args,**kwargs):
    window = self.view.window()
    output_view = window.get_output_panel("textarea")
    window.run_command("show_panel",{"panel": "output.textarea"})
    output_view.set_read_only(False)
    #edit = output_view.begin_edit()
    if "s" in kwargs:
      output_view.insert(edit, output_view.size(),**kwargs["s"] + "\n")
    output_view.end_edit(edit)
    output_view.set_read_only(True)

class Example2Command(sublime_plugin.WindowCommand):
  def run(self,paths = []):
    self.window.active_view().run_command("example",{"s":"test"})
def run(self,edit,*args,**kwargs)とすることで、
run_command("example",{"s":"test"})のキーワード付きの引数を受け取る事が出来るようになる。

なので何をどう処理したとかは引数で渡してあげればうまく表示することが出来るよって感じ。


ってな感じで強引ではあるけど、こうやって処理をすればoutput_panelをWindowCommandでも呼び出す事が出来る。
もちろんコンソール上でview.run_commnad()みたいにやったらoutput_panelが出ちゃうけどそれはしょうがないかと。
何かでうまく処理してあげればそこらへんは解決出来るんじゃないかなと。

sublimeのAPIについて解説してるのはまだまだ少なかったりするし、
書いてあってもsublime text2用だったりで3で使ってみるとエラーが出てしまうとかあったりするので、
しっかりと調べたものを実行してみるのって大事だよね的なみたいな。

Adsense