更新时间:2023-12-06 08:34:40
一般来说,如果不使用某种插件代码将该信息传达给应用程序,就无法执行命令并向其提供当前活动文件的名称命令.
正如在键绑定、菜单等中定义的那样,您需要为预定义的命令提供参数,这意味着命令中的某些内容需要能够根据您提供的参数知道当前文件,或者该命令需要隐式地只处理当前文件,而不会被告知这样做.
做这样的事情最方便的方法是创建一个 sublime-build
文件来运行你想要运行的命令,然后使用 $file
cmd
条目中的 variable表示当前文件,然后将您的菜单命令绑定到 build
命令,以便触发构建.
这里的缺点是这会妨碍将构建用于其他用途;build
命令仅执行当前选定的构建,因此它要求您在开始使用菜单之前先设置构建系统,或者将构建系统设置为 Automatic
以便Sublime 将在正确的时间执行正确的构建.无论哪种方式都可能会或可能不会妨碍您将构建用于其他目的而无需在中间采取手动步骤.
另一种方法是创建一个插件来实现 exec
命令的一个版本,该命令将扩展变量本身,而不是要求 build
命令将它们扩展为
此类插件的示例如下(如果您不熟悉使用,请参阅此视频自定义插件):
import sublime导入 sublime_plugin从 Default.exec 导入 ExecCommand类 MenuExecCommand(ExecCommand):def run(self, **kwargs):变量 = self.window.extract_variables()键入(cmd"、shell_cmd"、working_dir"):如果输入 kwargs:kwargs[key] = sublime.expand_variables(kwargs[key], variables)super().run(**kwargs)
这实现了一个名为 menu_exec
的命令,它与 exec
在调用时完全一样,除了 cmd
、 中的变量shell_cmd
和 working_dir
参数的扩展方式与它们在 sublime-build
文件中的方式相同.
使用该插件,您的 sublime-menu
条目会将 exec
交换为 menu_exec
并使用 $file
表示当前文件:
注意:如果您的文件名包含空格,您应该用双引号将变量括起来;"P:\\decoder.exe \"$file\""
例如;否则外部命令可能无法获得正确的文件名.
I have created a tab context menu to decode some data. Now, I need to take current file(Tab context menu) as 1st argument to decode this file using exec
.
Currently I'm using hardcoded path. How can I pass the name of the current file instead?
[
{ "command": "exec", "args": {"cmd": "P:\\decoder.exe P:\\in.txt"}, "caption": "DecodeJ" },
]
Generally speaking there's no way to execute a command and provide to it the name of the currently active file without using some sort of plugin code to convey that information to the command.
As defined in key bindings, menus and so on you need to provide arguments to commands that are predefined, which means that something in the command needs to be able to know based on the argument that you provided that you meant the current file, or the command needs to implicitly just work on the current file without being told to do so.
The most expedient way to do something like this would be to create a sublime-build
file that runs the command that you want to run, and then use the $file
variable in the cmd
entry to represent the current file, followed by binding your menu command to the build
command instead so that it triggers a build.
The downsides here are that this can get in the way of using builds for other uses; the build
command only executes the currently selected build so it requires that you first set the build system before you start using the menu, or that you set the build system to Automatic
so that Sublime will execute the correct build at the correct time. Either way may or may not get in the way of your ability to use builds for other purposes without having to take manual steps in the middle.
An alternative to this would be to create a plugin that implements a version of the exec
command that will expand variables itself instead of requiring that the build
command expand them for it.
An example of such a plugin would be the following (see this video if you're unfamiliar with using custom plugins):
import sublime
import sublime_plugin
from Default.exec import ExecCommand
class MenuExecCommand(ExecCommand):
def run(self, **kwargs):
variables = self.window.extract_variables()
for key in ("cmd", "shell_cmd", "working_dir"):
if key in kwargs:
kwargs[key] = sublime.expand_variables(kwargs[key], variables)
super().run(**kwargs)
This implements a command named menu_exec
that does exactly what exec
would do when invoked, except that variables in the cmd
, shell_cmd
and working_dir
arguments will be expanded the same way as they are in sublime-build
files.
With that plugin your sublime-menu
entry would swap exec
for menu_exec
and use $file
to represent the current file:
[
{
"caption": "DecodeJ",
"command": "menu_exec",
"args": {
"cmd": "P:\\decoder.exe $file"
}
},
]
Note: If your file names contain spaces, you should wrap the variable in double quotes;
"P:\\decoder.exe \"$file\""
for example; otherwise the external command might not get the right filename.