SublimeText3 插件 - 监听应用程序或 Window 关闭事件

SublimeText3 Plugin - Listen on Application or Window close events

在为 SublimeText 开发插件时,我们可以通过扩展 EventListener or ViewEventListener 类.

来监听事件

使用 API,是否可以在应用程序关闭之前或 window 关闭之前执行操作?

我尝试使用 on_window_command(window, command_name, args) 查看所有已触发的 window 命令,但应用程序关闭时似乎没有涉及可拦截的 window 命令。

我也试过在 on_pre_close(view) 上收听。当应用程序为每个选项卡关闭一次时会触发此事件,但我无法通过该方法确定是仅关闭一个视图还是关闭整个 window.

我是否遗漏了一些明显的东西,或者无法听到应用程序或应用程序的关闭 window?

根据您希望在 window 关闭或 Sublime 退出之前采取行动,对您的问题的简短回答是不可能以可靠的方式进行。然而,有可能在事情发生后的某个时候知道这些事情中的任何一个,尽管对于 Sublime 退出的情况,这通常不那么有趣,因为当你能够知道的时候,你已经来不及了任何回应。

on_closeon_pre_close事件是view事件;也就是说,它们在关闭(或即将关闭)选项卡时触发。选项卡可能因各种原因而关闭,因此仅使用该事件来检测 window 何时关闭是不可行的。

特别是,当 hot_exit 设置打开时(默认情况下),退出 Sublime 或关闭具有关联的 sublime-project 或 [=16] 的 window =] 文件将导致所有 windows(或 project/workspace window,取决于您的操作)的状态在不关闭任何视图的情况下持久保存到 session 或工作区文件中.因此,从这个意义上说,您只会在有人实际关闭文件时才会收到这些事件。

确定 Sublime 即将关闭(或 window 即将关闭)的一种方法是使用 on_window_command 正如您在问题中指出的那样,但这并不可靠。

当您告诉 Sublime 终止时,exit 命令会被触发,因此您可以使用 on_window_command 拦截它以了解它何时发生,但仅限于某些情况。

例如,以下插件侦听 exit 命令并重写它以阻止 Sublime 终止:

import sublime
import sublime_plugin


class TestListener(sublime_plugin.EventListener):
    def on_window_command(self, window, command, args):
        if command == "exit":
            print("I think not!")
            return ("noop")

如果你绑定一个键到exit命令,那个键将退出Sublime并被插件拦截,但是选择File > ExitFile > Quit会终止Sublime而不触发插件.当您在 Linux 或 Windows 上关闭最后一个 window 时,它也不会触发任何东西(这会隐式退出 Sublime;在 MacOS 上 Sublime 保持 运行 即使没有 windows 现在)。所以总的来说,这不是一个靠谱的方法。

同样,您也可以监听 close_window 命令来检测 window 何时关闭。但是,在这种情况下,命令仅在您使用键绑定或菜单项时触发,但在您使用 window 标题中的按钮关闭 window 时不会触发(因为这实际上不会触发命令在 Sublime 中)。

因此,在这两种情况下,技术上都可以在任何一个事件发生之前捕捉到它,但仅限于某些特定情况,这对于您需要依赖的任何事情来说都不太理想。

也就是说,可以在这些项目发生后检测到它们中的任何一个,尽管它的潜在效用可能不是您想要的,特别是因为您有兴趣在这种情况下事先知道。

可以从 Sublime 外部观察 plugin_host 终止,这会让您知道 Sublime 何时终止。在 Linux 和 MacOS 上,您可以编写一个插件来分叉 plugin_host,然后观察 parent 何时消失。在 Windows 上,您需要生成某种外部进程,因为据我所知,在 windows 上的 Python 不支持 fork()

技术上也可以通过持续轮询来自 sublime.windows() 的 windows 列表来检测 window 何时关闭(事后)以查看大小列表的更改或 windows 之一的 window.id() 已更改(这表明 window 关闭并添加了一个新列表)。

这会让您知道 window 在关闭后消失了,但是您使用的轮询间隔将决定您发现它的时间;频繁的轮询间隔也可能存在性能问题。