1

我正在创建一个 python 脚本,它从 API 中获取信息并创建一个上下文菜单,让您可以访问它们。我想使用线程,因为它在一次调用 API 时运行速度有点慢,但我不确定如何使用我的代码实现线程。我正在使用此站点进行线程参考:http ://www.ibm.com/developerworks/aix/library/au-threadingpython/ 我了解代码中的逻辑我只是不想为每个方法编写线程类我想要穿线。

这是创建上下文菜单然后解析返回的json的类,我想我应该将它添加到运行命令中的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 秒后插入。您会注意到,在这三秒钟内您仍然可以移动光标。

在您的情况下,您似乎只需要从 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 回答