on_pre_save 事件发生在文件缓冲区写入磁盘之前,它允许您在磁盘上的文件更改之前执行您可能想要执行的任何操作,例如对缓冲区的内容进行一些更改(例如“保存时重新格式化”)。
on_post_save 事件发生在文件缓冲区写入磁盘之后,允许您在保存操作后执行您可能想要采取的任何操作,例如检查缓冲区的“最终”内容(例如“lint on save”,如果通过外部工具完成,则需要将更改保存在磁盘上,而不仅仅是在内存中。
在任何一种情况下,文件的文件名在事件发生时都已被用户选择。对于一个新文件,这意味着on_pre_save 直到他们选择了文件的名称和位置之后才会发生。对于现有文件,save 只是使用相同的文件名重新保存。
要回答您的问题,您可以在on_pre_save 中执行您想要的大多数“任意”事情,以便在保存发生之前发生。如果您真的愿意,也可以在这种情况下更改文件名。
但是请注意,在不先询问用户的情况下从用户名下更改文件名绝对是糟糕的用户体验。此外,如果您将文件名更改为 on_pre_save 中已经存在的文件,sublime 会盲目地覆盖该文件而不会发出警告,这也是 Bad Mojo。
对于要更改文件在磁盘上的名称和位置的内容,更合适的方法是让用户必须明确调用一个命令来实现这一点,以便他们完全了解正在发生的事情.
根据评论中的要求并为了完整起见,这里有一个示例,可以满足您希望上面的示例代码执行的操作。
这里要注意的重要一点是,您必须非常小心触发此事件的情况。如上所述,您的插件将无法保存任何类型的文件,因为它会交换改为 python 文件。
在本例中,它被限制为仅对文本文件生效,将其转换为 python 文件。但是请注意,如果该位置已经有一个具有该名称的 python 文件,它将覆盖它而不会警告您它即将发生。
对这段代码要格外小心;很容易意外地阻止自己以正确的名称保存文件,例如,这可能会阻止您使用 Sublime 修复代码以及其他令人讨厌的问题。
import sublime_plugin
import os
class TestListener(sublime_plugin.EventListener):
def on_pre_save(self, view):
# This part is extremely important because as mentioned above it's
# entirely disconcerting for your save operation to gank your
# filename and make it suddenly be something else without any
# warning. If you're not careful you might destroy your ability to
# use sublime to fix your plugin, for example.
if not view.file_name().endswith(".txt"):
print("Doing nothing for: ", view.file_name())
return
# HUGE WARNING: This CAN and WILL willfully clobber over any file
# that already happens to exist without any warning to you
# whatsoever, and is most decidedly a Bad Idea(tm)
python_name = os.path.splitext(view.file_name())[0] + ".py"
view.retarget(python_name)