Метод run_command()
предназначен для выполнения внутренних команд Sublime (то есть того, что вы связываете с клавишей или триггером из меню), поэтому одна из причин, почему это не работает для вас, заключается в том, что вы пытаетесь чтобы заставить Sublime запустить команду вместо того, чтобы она выполняла внешнюю программу.
Система сборки обычно выполняется командой exec
; по сути это значение по умолчанию для клавиши target
, если вы не указали его в файле sublime-build
. exec
отвечает за использование аргументов, данных ему Sublime, для запуска внешнего процесса, захвата его вывода и отображения его на панели вывода в нижней части окна.
Для того, чтобы настроить то, что получает после выполнения, вам нужно реализовать свой собственный WindowCommand
и использовать клавишу target
, чтобы сообщить Sublime о его запуске, но затем эта команда отвечает за то, что будет делать exec
, включая запуск внешнего процесса и захват выходные данные.
В примере, приведенном в документации, для выполнения этой задачи используется subprocess.Popen()
, а также отслеживание выполнения задачи для ее закрытия и т. д. c.
An Самый простой способ сделать это - создать свою команду как подкласс команды, которую 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
файлом, но необходимо внести следующие изменения:
Вам необходимо использовать target
, чтобы указать, что наша команда должна выполнять
You следует (но не нужно) установить клавишу cancel
, чтобы сообщить Sublime, как отменить сборку, если вы выберете команду отмены сборки; эта команда сообщает Sublime выполнить ту же команду app_build
, которую она использовала для запуска сборки, но дает дополнительный аргумент, чтобы сказать, что сборка должна быть прекращена.
Везде, где вы хотите получить доступ к номеру версии по пути к файлу, используйте обозначение \\${version:DEFAULT}
.
Переменная должна указывать таким образом (т. е. с двумя \\
символами впереди), потому что Sublime автоматически попытается раскрыть любые переменные в системных ключах сборки, которые exec
распознает, прежде чем вызовет команду.
Поскольку во время вызова команды мы еще не установили значение переменной version
, это заставит Sublime предположить, что значение является пустой строкой, что удаляет его из строки и останавливает мы не можем обнаружить, что он там есть.
Чтобы Sublime оставил переменную в покое, вам нужно использовать обозначение \$
как указание на то, что это не должно рассматриваться как особый $
персонаж; Sublime преобразует \$
в $
и передает его нашей команде. В файле sublime-build
необходимо использовать \\$
, поскольку \$
не является допустимым экранированием JSON.
Часть :DEFAULT
является необязательной; это то, что будет использоваться в качестве расширенного текста, если переменная version
не установлена. В приведенном выше примере он установлен на 100
, но на практике вместо него вы должны установить что-то вроде 9
или 11
. Переменная не будет установлена, если команде не удалось определить версию для использования, поэтому вы можете использовать ее, чтобы установить версию по умолчанию, которая будет использоваться в этом случае (если это имеет смысл для вашего варианта использования).
Эта серия видеороликов о системах сборки в Sublime Text содержит больше общей информации о том, как работают системы сборки, включая несколько видео о пользовательских целях сборки и о том, как они работают, включая дополнительную информацию о расширенных пользовательских целях, которые подкласс ExecCommand
, как мы делаем здесь (отказ от ответственности: я автор).