让 Sublime 在两个相似的构建系统中进行选择

Let Sublime choose among two similar build systems

我当前的设置是工具 > 构建系统 > 自动

我使用两个构建系统:Python.sublime-buildPython64.sublime-build

当且仅当 .py 文件以 #python64?

开头时,如何使 Sublime 使用后者

(这​​样我就不必在 Sublime 的工具 > 构建系统 > Python 64Sublime 的工具 > 构建系统之间手动切换> Python).

或者,如何制作:

(它们都应该在 Sublime 的底部构建输出面板中显示输出)。


# Python.sublime-build
{
    "cmd": ["python", "-u", "$file"],
    "file_regex": "^[ ]*File \"(...*?)\", line ([0-9]*)",
    "selector": "source.python"
}

# Python64.sublime-build
{
    "cmd": ["c:\python27-64\python", "-u", "$file"],
    "file_regex": "^[ ]*File \"(...*?)\", line ([0-9]*)"
}

PS:我使用 Windows,我需要 Python 的两个版本(32 和 64),原因不在此处。

一般来说,Sublime 会根据您正在编辑的文件类型(例如 python 源文件)自动 select 设置合适的构建系统。在 Sublime Text 3 中,也可以根据某个文件(例如名为 Makefile)的存在来激活构建系统。

对于此处介绍的用例,这些都不是可行的解决方案,第二个仅适用于 Sublime Text 3 而不是 Sublime Text 2。

有几种方法可以实现这一点。我在这里提供两组说明,一组用于 Sublime Text 2,一组用于 Sublime Text 3,因此这是一个更广泛有用的答案。

选项 #1 - 自定义构建目标

构建系统可以有一个名为 target 的可选参数,它指定 sublime 应该执行的命令以执行构建。未指定时,默认为 exec 命令。构建文件的大部分内容实际上只是直接传递给 exec 命令本身的参数。

通过指定自定义目标,您可以向构建命令添加额外的逻辑,以便能够分析当前文件并采取适当的行动。

这一部分的第一部分是提供将用于执行构建的自定义命令,这可以通过一些简单的插件代码来完成。这应该作为 python 文件(例如 Packages\User\python_build.py)保存在您的 User 包中。

第二部分是修改您正在使用的构建系统,以便利用新命令来执行我们希望它执行的操作。单个构建文件将以两种方式使用。您可以将其命名为 Python.sublime-build 并启用它作为 Packages\Python\Python.sublime-build 中现有构建的覆盖或在您的用户包中作为 Packages\User\Python.sublime-build.

Sublime Text 2 插件:

import sublime, sublime_plugin

class PythonBuildCommand(sublime_plugin.WindowCommand):
    def detect_version(self, filename, python32, python64):
        with open(filename, 'r') as handle:
            line = handle.readline ()
        return python64 if (line.startswith ("#") and "64" in line) else python32

    def execArgs(self, sourceArgs):
        current_file = self.window.active_view ().file_name ()
        args = dict (sourceArgs)

        python32 = args.pop ("python32", "python")
        python64 = args.pop ("python64", "python")
        selected = self.detect_version (current_file, python32, python64)

        if "cmd" in args:
            args["cmd"][0] = selected

        return args

    def run(self, **kwargs):
        self.window.run_command ("exec", self.execArgs (kwargs))

Sublime Text 2 构建文件:

{
    "target": "python_build",

    "python32": "python",
    "python64": "c:/python27-64/python",

    "cmd": ["python", "-u", "$file"],
    "file_regex": "^[ ]*File \"(...*?)\", line ([0-9]*)",
    "selector": "source.python"
}

Sublime Text 3 插件:

import sublime, sublime_plugin

class PythonBuildCommand(sublime_plugin.WindowCommand):
    def detect_version(self, filename, python32, python64):
        with open(filename, 'r') as handle:
            line = handle.readline ()
        return python64 if (line.startswith ("#") and "64" in line) else python32

    def execArgs(self, sourceArgs):
        current_file = self.window.active_view ().file_name ()
        args = dict (sourceArgs)

        python32 = args.pop ("python32", "python")
        python64 = args.pop ("python64", "python")
        selected = self.detect_version (current_file, python32, python64)

        if "shell_cmd" in args:
            args["shell_cmd"] = args["shell_cmd"].replace ("python", selected)

        return args

    def run(self, **kwargs):
        self.window.run_command ("exec", self.execArgs (kwargs))

Sublime Text 3 构建文件:

{
    "target": "python_build",

    "shell_cmd": "python -u \"$file\"",
    "file_regex": "^[ ]*File \"(...*?)\", line ([0-9]*)",
    "selector": "source.python",

    "python32": "python",
    "python64": "c:/python27-64/python",

    "env": {"PYTHONIOENCODING": "utf-8"},

    "variants":
    [
        {
            "name": "Syntax Check",
            "shell_cmd": "python -m py_compile \"${file}\"",
        }
    ]
}

请注意,插件代码在两个版本的代码中基本相同。 Sublime Text 3 支持 shell_cmd 以及 cmd 来指定可执行文件,每个版本中 Python 的默认构建系统都反映了这一点。如果需要,Sublime Text 2 版本也应该在 Sublime Text 3 中工作,只要您也使用适当的构建文件。

在任何一种情况下,自定义命令都会检查文件的第一行,以查看它应该执行 python 的两个版本中的哪一个,适当地修改构建系统中的命令,然后调用 exec 命令来执行构建。

构建文件本身需要指定在任何一种情况下使用哪个版本的 python 解释器,回退(由插件中的代码确定)都是 python 如果未指定。

如果您使用的是 Sublime Text 3 并将构建文件放在 User 包中,您的构建菜单将包含两次 Python 选项;一次用于内置版本,一次用于您自己的版本。在这种情况下,您可能需要确保正确的 selected.

选项 #2 - 使用键绑定

两个版本的 Sublime 中都没有可以 运行 构建并指定要使用的构建系统的命令(至少没有我能找到的文档)。这仍然可以在两个版本中使用键绑定,尽管在 Sublime Text 3 的情况下要容易一些。

Sublime Text 2 按键绑定:

对于 Sublime Text 2,命令 build 将使用当前 selected 构建系统执行构建,并且 set_build_system 可用于交换构建系统。

为了通过一次按键完成此操作,您需要安装 ChainOfCommand 插件,它允许您将多个命令链接在一起。安装该软件包后,您可以设置以下键绑定:

{
    "keys": ["ctrl+b"],
    "command": "chain", "args": {"commands": [
        ["set_build_system", {"file": "Packages/Python/Python.sublime-build"}],
        ["build"]
    ]}
},
{
    "keys": ["ctrl+shift+b"],
    "command": "chain", "args": {"commands": [
        ["set_build_system", {"file": "Packages/Python/Python64.sublime-build"}],
        ["build"]
    ]}
}

其中第一个将构建系统更改为 python,然后 运行s 构建,而第二个将其更改为 Python64。根据需要修改构建文件的路径(例如,如果您将一个或两个存储在 User 包中)。

这有点 sub-optimal 因为它使得 Ctrl+B 键总是尝试构建 python 即使那是不合适的。

我不积极使用 Sublime Text 2,所以我不确定您将如何使这些绑定仅特定于 python 文件。我尝试过的一些可以在 Sublime Text 2 中使用的东西在这里不起作用。

Sublime Text 3 按键绑定:

对于 Sublime Text 3,这要容易一些。此版本支持构建系统中的变体,可以告诉 build 命令执行当前 selected 构建的变体。

要使其正常工作,您需要一个类似于以下版本的单一构建系统。这是标准 Sublime Text 3 python 构建文件的修改版本,它删除了 Syntax Check 变体以支持 Python64 版本。这可能是模组根据需要填写。

{
    "shell_cmd": "python -u \"$file\"",
    "file_regex": "^[ ]*File \"(...*?)\", line ([0-9]*)",
    "selector": "source.python",

    "env": {"PYTHONIOENCODING": "utf-8"},

    "variants":
    [
        {
            "name": "Python64",
            "shell_cmd": "c:/python27-64/python -u \"$file\"",
        }
    ]
}

有了这个,添加以下键绑定:

{
    "keys": ["ctrl+shift+b"],
    "command": "build", "args": {"variant": "Python64"},
    "context": [
        { "key": "selector", "operator": "equal", "operand": "source.python"},
    ]
},

现在构建系统有一个变体,因此常规 Python 构建将使用 32 位版本,而 Python - Python64 将使用 64 位版本。

此处的键绑定设置为仅在 python 文件中操作,因为在 Sublime Text 3 中,此键序列用于提示您选择要使用的当前版本的变体。

对于一些初始设置,一旦启用此键绑定,您应该打开一个 python 文件并从菜单中打开 select Tools > Build > Build With...,然后 select Python 以便告诉 Sublime 你想使用 Python build.

从现在开始,当您编辑 python 文件时,Ctrl+B 将执行主构建,即 32 位 python, 和 Ctrl+Shift+B 将执行使用 64 位版本的变体。

除了 OdatNurd 的出色回答外,这是我使用的,使用键盘映射和 variants

  • CTRL+B : Python 32 (在 Sublime 中输出日志)
  • CTRL+SHIFT+B : Python 64 (输出日志在 Sublime 中)
  • ALT+SHIFT+B : Python 32(在一个新航站楼 window)
  • CTRL+SHIFT+ALT+B : Python 64(在新终端中 window)
  • CTRL+ALT+B : 杀死当前的 Python 脚本

默认(Windows)。sublime-keymap

[
{ "keys": ["ctrl+alt+b"], "command": "exec", "args": {"kill": true} },
{ "keys": ["alt+shift+b"], "command": "python_run" },
{ "keys": ["ctrl+shift+alt+b"], "command": "python64_run" }
]

注意:这里没有关于 CTRL+B(默认构建)和关于 CTRL+SHIFT+B(默认变体构建)。

python_run.py

import sublime
import sublime_plugin
import subprocess
class PythonRunCommand(sublime_plugin.WindowCommand):
    def run(self):
        command = 'cmd /k "C:\Python27\python.exe" %s' % sublime.active_window().active_view().file_name()
        subprocess.Popen(command)

python64_run.py

同上C:\Python27-64\python.exe

Python.sublime-build

{
    "cmd": ["python", "-u", "$file"],
    "file_regex": "^[ ]*File \"(...*?)\", line ([0-9]*)",
    "selector": "source.python",
    "variants": [ { 
          "name": "Run", 
          "file_regex": "^[ ]*File \"(...*?)\", line ([0-9]*)", 
          "cmd": ["C:\Python27-64\python.exe", "-u", "$file"] 
    } ] 
}