【问题标题】:SublimeText 3 Build System based on file pathSublime Text 3 基于文件路径构建系统
【发布时间】:2020-02-03 15:16:05
【问题描述】:

我需要运行不同的编译器,具体取决于正在编辑的文件将用于哪个版本的应用程序。

源文件始终存储在包含版本号的路径中。

so 文件 %APPDATA%\App\9\Settings\Source.file 需要运行

%ProgramFiles%\App\9\Compiler.exe "%APPDATA%\App\9\Settings\Source.file"


%APPDATA%\App\11\Settings\Source.file 需要运行

%ProgramFiles%\App\11\Compiler.exe "%APPDATA%\App\11\Settings\Source.file"

我已尝试按照此处的高级示例进行操作: https://www.sublimetext.com/docs/3/build_systems.html#advanced_example

但是 python 真的不是我的东西,我似乎无法运行任何东西

基本有效,但我无法指定版本:

    {
        "cmd": ["c:\\Program Files\\App\\10\\compile.exe", "$file"],
        "selector": "source.app",
        "file_patterns": "*.ext"
    }

但这不是:

        {
        "target": "app_build", 
        "selector": "source.app",
        "file_patterns": "*.ext"
    }

.py 文件

    import sublime
    import sublime_plugin

    class AppBuildCommand(sublime_plugin.WindowCommand):

        def run (self):

            vars = self.window.extract_variables()
            compiler = vars['file_path']

            compiler = compiler.split("\\")

            compiler_path = "c:\\Program Files\\App\\" + compiler[compiler.index("App")+1] + "\\Compiler.exe"

            file = vars['file']

            self.window.run_command (compiler + " \"" + file + "\"")

也试过没有成功:

    args = []
    args.append(compiler)
    args.append(file)

    self.window.run_command("cmd", args)

【问题讨论】:

    标签: python sublimetext3 build-system


    【解决方案1】:

    run_command() 方法用于执行内部 Sublime 命令(即您将绑定到键或从菜单触发的东西),所以这对您不起作用的部分原因是您正在尝试让 Sublime 运行命令而不是让它执行外部程序。

    构建系统通常由exec 命令执行;如果您没有在 sublime-build 文件中提供它,这本质上是 target 键的默认值。 exec 负责使用 Sublime 给它的参数来启动一个外部进程,捕获它的输出并将其显示在窗口底部的输出面板中。

    为了自定义要执行的内容,您需要实现自己的WindowCommand 并使用target 键告诉Sublime 运行它,但是该命令随后负责执行exec 会执行的操作,这包括启动外部进程和捕获输出。

    文档中列出的示例使用subprocess.Popen() 执行此任务,并且必须跟踪任务是否正在运行以关闭它等。

    实现这一点的一种简单方法是将您的命令创建为 Sublime 通常用于运行构建的命令的子类,以便您可以自定义构建的启动方式,但让现有代码处理所有细节.

    此类命令的示例如下所示:

    import sublime
    import sublime_plugin
    
    import os
    
    from Default.exec import ExecCommand
    
    
    class AppBuildCommand(ExecCommand):
        def run(self, **kwargs):
            # Get the list of variables known to build systems
            variables = self.window.extract_variables()
    
            # Is there a file path? There won't be if the file hasn't been saved
            # yet.
            if "file_path" in variables:
                # Pull out the file path, split it into parts, and use the segment
                # after the "App" segment as the value of a new variable named
                # version.
                file_path = variables["file_path"].upper().split(os.sep)
                if "APP" in file_path:
                    variables["version"] = file_path[file_path.index("APP") + 1]
    
            # Expand any remaining variables in our arguments and then execute the
            # build.
            kwargs = sublime.expand_variables(kwargs, variables)
            super().run(**kwargs)
    

    使用此命令进行构建的sublime-build 文件示例如下:

    {
        "target": "app_build",
        "cancel": {"kill": true},
    
        "cmd": ["c:\\Program Files\\App\\\\${version:100}\\compile.exe", "$file"],
    
        "selector": "source.app",
        "file_patterns": ["*.ext"]
    }
    

    命令本身检查App 段后面的段的当前文件的路径(这里不区分大小写以防万一),并使用它来创建一个名为version 的新构建系统变量。如果该文件尚未保存(因此在磁盘上没有名称)或者如果其中没有名为 App 的路径段,则不会创建该变量。

    最后两行展开所有尚未展开的变量,然后告诉exec 命令执行构建。

    sublime-build 文件在任何方面都可以是普通的sublime-build 文件,但您需要进行的更改是:

    1. 您需要使用target 表示我们的命令应该是要执行的命令

    2. 如果您选择取消构建命令,您应该(但不需要)设置cancel 键来告诉 Sublime 如何取消您的构建;这个命令告诉 Sublime 执行与启动构建相同的app_build 命令,但给它一个额外的参数来说明应该终止构建。

    3. 如果您想从文件路径访问版本号,请使用符号\\${version:DEFAULT}

    需要以这种方式指定变量(即前面有两个 \\ 字符),因为 Sublime 会在调用命令之前自动尝试扩展 exec 识别的构建系统键中的任何变量。

    由于在调用命令时我们还没有设置 version 变量的值,这将使 Sublime 假定该值是空字符串,这会将其从字符串中删除并阻止我们能够检测到它的存在。

    为了让 Sublime 不考虑变量,您需要使用 \$ 表示法来指示不应将其视为特殊的 $ 字符; Sublime 会将\$ 转换为$ 并将其传递给我们的命令。在sublime-build 文件中,您需要使用\\$,因为\$ 不是有效的JSON 字符转义。

    :DEFAULT 部分是可选的;如果未设置 version 变量,这将用作扩展文本。在上面的示例中,它设置为100,但实际上您会将其设置为911 之类的东西。如果命令无法确定要使用的版本,则不会设置该变量,因此您可以使用它来设置在这种情况下使用的默认版本(如果这对您的用例有意义)。

    build systems in Sublime Text 上的这个视频系列有更多关于构建系统如何工作的一般信息,其中包括几个关于自定义构建目标及其工作方式的视频,包括更多关于高级自定义目标的更多信息,这些目标是我们的 ExecCommand 的子类在这里做(免责声明:我是作者)。

    【讨论】:

    • 太棒了,谢谢。由于某种我无法理解的原因,该变量未包含在命令中,但由于我已经知道完整路径,因此无论如何我都可以在运行之前覆盖完整的命令。
    猜你喜欢
    • 1970-01-01
    • 2014-10-21
    • 2015-03-01
    • 2013-10-14
    • 1970-01-01
    • 2018-04-27
    • 2015-02-04
    • 1970-01-01
    相关资源
    最近更新 更多