2017-10-26 1 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로 표시되면 파일이 이미 열려 있음을 의미하므로 즉시 파일의 끝으로 이동할 수 있습니다.

보기에이 질문에 예라고 표시되면 우리는이보기의 내용이 완료되면 버퍼의 끝으로 건너 뛰고 싶다는 것을 알 수 있도록보기에서 임시 설정을 설정합니다.

이벤트 수신기는이 설정이있는 경우로드가 완료 될 때마다 모든보기를 요청하고 설정이 완료되면 설정을 제거한 다음 파일의 끝으로 이동합니다.


는 [편집] 아래의 설명에서 언급 한 바와 같이

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 파일이 이미 열려 있으면이 방법으로 작동합니다. 아직 열리지 않았다면 화면의 첫 번째 줄에 텍스트의 마지막 줄을 놓고 텍스트가 전혀 표시되지 않고 위로 스크롤해야 텍스트를 볼 수 있습니다. 나는 구글에서 지금까지 아무런 성공없이 많은 검색을했다. 이 문제를 해결하는 방법을 알고 있습니까? – Emerson

+0

재미 있습니다. 그게 왜 일어나는 지 모르겠지만 의심스러운 것 같습니다. 나는 가능한 해결책을 제공하기 위해 해답을 편집했다. 저것이 너를 위해 또는 아닙니다 작동하면 나는 알린다. – OdatNurd

+0

완벽! 고맙습니다! – Emerson