1

API から情報を取得し、それらにアクセスできるコンテキスト メニューを作成する Python スクリプトを作成しています。API への 1 回の呼び出しで実行が少し遅くなるため、スレッド化を使用したいと考えていますが、自分のコードでスレッド化を実装する方法がわかりません。私はこのサイトをスレッド参照に使用しています: http://www.ibm.com/developerworks/aix/library/au-threadingpython/ コードのロジックを理解しています すべてのメソッドに対してスレッドクラスを書きたくないだけですねじ込みたい。

これは、コンテキスト メニューを作成し、返された json を解析するクラスです。run コマンドの for ループに追加する必要があると思います。どんな助けでも大歓迎です。

class SyncsnippetsCommand(sublime_plugin.TextCommand):

  def __init__(self, queue):
      threading.Thread.__init__(self)
      self.queue = queue

  def buildLexerDict(self,snippets):
      lexers = snippets[0]['user']['lexers']
      lexer_dict = {}
      for lexer in lexers:
          lexer_dict[lexer] = []
      return lexer_dict

  def buildsnippetsContextDict(self,snippets,lexer_dict):
      snippets_dict = lexer_dict
      for snippet in snippets:
          snippets_dict[snippet['lexer']].append({"id":str(snippet['id']),
                                         "title":snippet['title']})
      return snippets_dict

  def run(self, edit):
      snippet_url = buildsnippetURL()
      snippets_count = 1;
      snippets = getsnippets(snippet_url)
      context_menu = '['
      context_menu += '\n\t{ "caption": "snippets", "id": "file", "children":'
      context_menu += '\n\t\t['
      if snippets == None:
          {"caption":"No snippets available"}
      else:
          snippets = snippets['objects']
          lexers = self.buildLexerDict(snippets)
          snippets_dict = self.buildsnippetsContextDict(snippets, lexers)
          for j,key in reversed(list(enumerate(reversed(snippets_dict.keys())))):
              ... loop through JSON and create menu ...
              if j == 0:
                  context_menu += ''
              else:
                  context_menu += ',' 
      context_menu += '\n\t\t]'
      context_menu += '\n\t}'
      context_menu += '\n]'
      f = open(sublime.packages_path() + '\snippetSync\\Context.sublime-menu', 'w')
      f.write(context_menu)
      f.close
      self.view.set_status('snippet', 'snippet Sync: Added ' + str(snippets_count) + ' snippets from your account.')
      sublime.set_timeout(lambda: self.view.erase_status('snippet'), 3000)
      return
4

1 に答える 1

2

これは、スレッド化された単純な Sublime Text 2 プラグインです。Hello World!3 秒後に挿入します。この 3 秒間はカーソルを移動できることに気付くでしょう。

あなたの場合、API から一連のスニペットを取得し、返されたデータからコンテキスト メニューを作成するだけでよいようです。次に、追加されたスニペットの数を示す通知が下部に表示されます。私は間違っているかもしれませんが、このコードを変更してプラグインを機能させることができるはずです。

import threading
import time
import sublime
import sublime_plugin

"""
The command just creates and runs a thread.
The thread will do all the work in the background.

Note that in your Thread constructor, you will need to pass in an 
instance of your Command class to work with in your thread.
"""
class ExampleCommand(sublime_plugin.TextCommand):

    def run(self, edit):

        exampleThread = ExampleThread(self, edit)
        exampleThread.start()

"""
Extend the Thread class and add your functionality in 
the run method below.

One thing to remember when moving your code over is 
you need to use self.cmd instead of self.
"""
class ExampleThread(threading.Thread):

    """
    Remember to pass in the parameters you need
    in this thread constructor.
    """
    def __init__(self, cmd, edit):
        threading.Thread.__init__(self)
        self.cmd = cmd
        self.edit = edit

    """
    Add your functionality here.

    If you need to access the main thread, you need to
    use sublime.set_timeout(self.callback, 1).

    In my example here, you can't call insert text into the editor
    unless you are in the main thread.

    Luckily that is fast operation.

    Basically, time.sleep(3) is a slow operation and will block, hence it
    is run in this separate thread.
    """
    def run(self):
        time.sleep(3)
        sublime.set_timeout(self.callback, 1)

    """
    This is the callback function that will be called to 
    insert HelloWorld. 

    You will probably need to use this to set your status message at 
    the end. I'm pretty sure that requires that you be on main thread 
    to work.
    """
    def callback(self):
        self.cmd.view.insert(self.edit, 0, "Hello, World!")

アップデート

上記で概説したアプローチを使用して、上記のコードスニペットを統合することがあることがわかりました。まだいくつかの空白を埋める必要がありますが、うまくいけば、これでコードを配置する場所がわかります。この例では、コンテキスト メニューを作成しているセクションがコメント アウトされているのはそのためです。

import threading
import time
import sublime
import sublime_plugin


def buildsnippetURL():
    return ""

def getsnippets(snippet_url):
    time.sleep(3)
    return ""

class SyncsnippetsCommand(sublime_plugin.TextCommand):
    def run(self, edit):
        syncsnippetsThread = SyncsnippetsThread(self, edit)
        syncsnippetsThread.start()


class SyncsnippetsThread(threading.Thread):
    def __init__(self, cmd, edit):
        threading.Thread.__init__(self)
        self.cmd = cmd
        self.edit = edit

    def buildLexerDict(self,snippets):
        lexers = snippets[0]['user']['lexers']
        lexer_dict = {}
        for lexer in lexers:
            lexer_dict[lexer] = []
        return lexer_dict

    def buildsnippetsContextDict(self,snippets,lexer_dict):
        snippets_dict = lexer_dict
        for snippet in snippets:
            snippets_dict[snippet['lexer']].append({"id":str(snippet['id']),
                                         "title":snippet['title']})
        return snippets_dict

    def run(self): 
        snippet_url = buildsnippetURL()
        snippets_count = 1;
        snippets = getsnippets(snippet_url)

        """
        context_menu = '['
        context_menu += '\n\t{ "caption": "snippets", "id": "file", "children":'
        context_menu += '\n\t\t['
        if snippets == None:
            {"caption":"No snippets available"}
        else:
            snippets = snippets['objects']
            lexers = self.buildLexerDict(snippets)
            snippets_dict = self.buildsnippetsContextDict(snippets, lexers)
            for j,key in reversed(list(enumerate(reversed(snippets_dict.keys())))):
                ... loop through JSON and create menu ...
                if j == 0:
                    context_menu += ''
                else:
                    context_menu += ',' 
        context_menu += '\n\t\t]'
        context_menu += '\n\t}'
        context_menu += '\n]'
        f = open(sublime.packages_path() + '\snippetSync\\Context.sublime-menu', 'w')
        f.write(context_menu)
        f.close
        """

        sublime.set_timeout(lambda: self.callback(snippets_count), 1)

    def callback(self, snippets_count):
        self.cmd.view.set_status('snippet', 'snippet Sync: Added ' + str(snippets_count)  + ' snippets from your account.')
        sublime.set_timeout(lambda: self.cmd.view.erase_status('snippet'), 3000)
于 2013-02-23T04:57:42.807 に答える