2017-10-26 11 views
2

編集中のファイルに関連付けられた.logファイルを開くプラグインを作成しようとしています。私はファイルを開くことができましたが、ファイルがすでに開いているときにコードを再実行しない限り、カーソルをファイルの最後に移動することはできませんでした。eofでファイルを開くプラグイン

import sublime 
import sublime_plugin 

class OpenlogCommand(sublime_plugin.TextCommand): 
    def run(self, edit): 
     if os.path.isfile(self.view.file_name()[:-3]+"log"): 
      a=sublime.active_window().open_file(self.view.file_name()[:-3]+"log") 
     a.run_command("move_to", {"to": "eof"}) 

誰かがそれを行う方法を知っていますか?

答えて

1

ファイルが既に開いていないとこれが機能しないのは、ファイルのロードが非同期であるためです。ファイルを開くコマンドがすぐに返され、ファイルがまだ開いていなければバックグラウンドで読み込まれます。

move_toコマンドは、初めて空のバッファの最後にあるため何も実行しませんが、ファイルがすでにロードされている場合は、期待どおりに処理されます。それを回避するために

、あなたはファイルがまだロードし、それが終了しています後まで、ファイルの最後にジャンプするための呼び出しを延期されたかどうかを検出する必要があります。その一例は以下の通りである。これの既存のバージョンと

import sublime 
import sublime_plugin 
import os 

class OpenLogCommand(sublime_plugin.TextCommand): 
    def run(self, edit): 
     log_name = self.view.file_name()[:-3] + "log" 
     log_view = self.view.window().open_file(log_name) 

     if log_view.is_loading(): 
      log_view.settings().set("_goto_eol", True) 
     else: 
      log_view.run_command("move_to", {"to": "eof"}) 

    def is_enabled(self): 
     fname = self.view.file_name() 
     if fname is not None and not fname.endswith(".log"): 
      return os.path.isfile(fname[:-3] + "log") 

     return False 

class OpenLogListener(sublime_plugin.EventListener): 
    def on_load(self, view): 
     if view.settings().get("_goto_eol", False): 
      view.settings().erase("_goto_eol") 
      view.run_command("move_to", {"to": "eof"}) 

問題は、ファイルがまだディスクに保存されていない場合file_name()方法はNoneを返すということです。したがって、保存されていないファイルに対してこのコマンドを実行すると、コンソールにエラーが生成されます。これは無害ですが、あなたが他の問題を抱えていて、コンソールでそのエラーが発生した場合は、赤いニシンかもしれないので、少し汚れています。

このような問題を防ぐためにファイルが保存されている場合にのみ、このコマンドが有効になります。ログファイルがまだ存在しない場合(それは冗長なので)、関連するログファイルが実際に存在する場合にのみ有効になります。

コマンドを無効にすると、実行できません。つまり、コマンドパレットにも表示されず、メニューにグレー表示されます(どちらか一方に追加した場合)。このコマンドを実行すると

は、それが最初に関連するログファイルを開くにはopen_fileを呼び出し、次にビュー「あなたはまだロードしているの?」尋ねます。ビューにNOと表示されている場合は、ファイルがすでに開いていることを意味し、すぐにファイルの最後にジャンプできます。

ビューにこの質問がYESと表示されている場合は、ビューの一時的な設定を行い、このビューの内容が終了したらバッファの最後にジャンプしたいと考えています。

イベントリスナーは、この設定が設定されている場合、すべてのビューに読み込みが完了すると尋ねます。設定が完了すると、設定を削除してファイルの最後にジャンプします。以下のコメントで述べたように


[編集]

は、move_toコマンドは、すでにだけ読み込みが完了したファイルに対して開いているファイルに対して多少異なる動作をします。

私は完全にはわかりませんが、ファイルコンテンツがロードされているがまだ表示されていないか、またはこれに沿って何かが届いているという通知とon_loadの間に微妙な相互作用があると思われます。ちょうど推測です。

class OpenLogListener(sublime_plugin.EventListener): 
    def on_load(self, view): 
     if view.settings().get("_goto_eol", False): 
      view.settings().erase("_goto_eol") 
      sublime.set_timeout(lambda: view.run_command("move_to", {"to": "eof"}), 1) 

ように、これは少し物事を変更します。いずれの場合で

、最も都合の修正ではなく、これに上記のコードの一部を置き換えることにより、イベントリスナーへのわずかな修正を加えることであろうmove_toコマンドの呼び出しは、すべてのイベント処理が完了した後で効果的に実行されます。それは少なくとも私のテストマシンで問題を解決するようです。

+0

偉大な説明をありがとう!私はeofコマンドへの移行に少し問題があります。任意のバッファでCtrl + endを押すと、最後の行にカーソルが置かれ、最後の行はページの最下部にとどまり、画面上のテキストの量が最大になります。このコードでは、.logファイルがすでに開いている場合にこの方法で動作します。それがまだ開いていない場合は、テキストの最後の行を画面の最初の行に置きます。テキストはまったく表示されません。上にスクロールしてテキストを表示する必要があります。私はこれまでGoogleで多くの検索を成功させました。あなたはこれを解決する方法を知っていますか? – Emerson

+0

興味深いことになぜそれが起こっているのか分かりませんが、疑わしいようです。私は可能な回避策を提供するために答えを編集しました。それがあなたのために働くかどうか私に教えてください。 – OdatNurd

+0

パーフェクト!ありがとうございました! – Emerson