【问题标题】:Run a sync sequence of commands in sublime plugin在 sublime 插件中运行同步命令序列
【发布时间】:2016-07-04 15:35:23
【问题描述】:

我一直在尝试为 Sublime Text (3) 编写一个非常简单的插件,但是对于这个主题来说是新手,要么我遗漏了某些东西,要么某些东西没有按预期工作。

我想创建一个命令,将当前选项卡移动到指定组(例如组 0 以进行简化)。在那之后,我想专注于该组:

import sublime
import sublime_plugin

class MoveAndFocusToGroupCommand(sublime_plugin.WindowCommand):

    def run(self):
        self.window.run_command("move_to_group",{"group": 0})
        self.window.run_command("focus_group", {"group": 0})

之前的 sn-p 确实工作。将执行第一个命令,但不会执行第二个命令。
如果我注释第一个命令,则执行第二个命令。

也许这些命令是在不同的线程上执行的,或者正在发生一些异步操作。

我还尝试在事件处理程序中运行第二个命令:

class MoveAndFocusToGroupCommand(sublime_plugin.WindowCommand):

    def run(self):
        self.window.run_command("move_to_group",{"group": 0})

class MovedToGroupEventListener(sublime_plugin.EventListener):
    def on_post_window_command(self, window, name, args):
        if name == 'move_to_group' and args is not None:
            window.run_command("focus_group", args)

但没有任何变化,焦点永远不会设置在第 0 组上。

我在这里错过了什么?

【问题讨论】:

  • 第一个命令也应该将焦点设置到组。如果该组在移动后是空的,它似乎会创建一个视图,该视图会在您执行命令后抓住焦点。

标签: python sublimetext3 sublimetext sublime-text-plugin


【解决方案1】:

您的初始代码对我来说运行良好,直到我在第二组中的最后一个视图上尝试了它。

正如 cmets 中提到的r-stein,似乎 SublimeText 在空组中创建的空白视图干扰了您的命令序列的时序。

以下代码使用set_timeout_async 重新排序命令的顺序。我省略了可选的delay 参数,因为没有它似乎也能正常工作。


import sublime
import sublime_plugin

class MoveAndFocusToGroupCommand( sublime_plugin.WindowCommand ):

    def run( self ):
        self.window.run_command( "move_to_group", { "group": 0 } )
        sublime.set_timeout_async( lambda: self.window.focus_group( 0 ) )

【讨论】:

  • 为什么在对set_timeout_async() 的调用中使用了lambda:?这对我来说似乎没有必要,没有它插件也能正常工作,但我是否遗漏了一些使用它的微妙原因?在 Python 中创建 匿名函数 时,我只使用了 lambda 函数,例如map(lambda x: x**2, num_list) 使用 lambda 函数 而不是预定义函数,例如map(calc_square, num_list) 和我之前没有看到 lambda: 与预定义函数一起使用,也没有至少一个参数。
  • @mattst 我想如果没有参数我们可以省略 lambda 并只传递 self.focus 但在我的情况下它很有用,因为我将参数传递给 self.focus 所以它充当包装器
  • @Leonardo @Enteleform 在 Enteleform 的插件中,以下所有功能都可以正常工作:set_timeout_async(self.focus)set_timeout_async(self.focus, 200)set_timeout_async(self.focus(group_num))set_timeout_async(self.focus(group_num), 200) 假设 focus() 被定义为采用组号参数,即def focus(self, group_num) 需要时。所以包装器不是必需的。我很想知道 Enteleform 是否有其他原因使用 lambda 函数
  • @mattst:我对使用线程和 lambdas 还是很陌生;所以我还不完全理解它们是如何工作的。 Keith Hall 之前用His AnswerThis Question 帮助过我,但看起来我在这个答案的初稿中误用了他的方法。再次查看他的解释后,我直接在self.window.focus_group 上实现了他的方法,并删除了额外的WindowCommand 函数。
  • @mattst:根据我对 Keith 的解释、回调和set_timeout 函数的理解; set_timeout 的第一个参数应该是functionName 格式的回调,而不是functionName()。如果使用后一种变体,该函数将立即执行而不是回调。由于focus_group 需要一个参数,所以它必须包含在lambda 中(or partial)。这是related answer 使用带参数的回调。
猜你喜欢
  • 2013-11-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-03-11
  • 1970-01-01
  • 1970-01-01
  • 2021-01-29
  • 1970-01-01
相关资源
最近更新 更多