Сублиметекстовая интеграция с подсистемой Windows для Linux (WSL, bash) - PullRequest
0 голосов
/ 11 декабря 2018

Есть ли способ выполнения команд bash из сублиметекста?

Во многих проектах просто лучше разрабатывать инструменты linux через подсистему Windows для Linux (WSL, bash), так как большинство инструментов построено для linux.

В Windows вы можете запускать команды bash в консоли Windows следующим образом:

bash -c "echo \"my bash command here\""

Допустим, я хочу запустить очень специфический скрипт сборки, подобный этому:

bash -c "prettier mypath/ && eslint mypath/ --fix"

или как это:

bash -c "my_very_specific_build_script.sh"

или, что еще лучше, иметь ловушку, выполняющую линтера через ловушку с: https://packagecontrol.io/packages/Hooks

bash -c "my_linting_script.sh"

и затем вызывать скрипт наКаждое «сохранение», подобное этому:

"on_post_save_user":
    [
        {
            "command": "bash_execute",
            "args": {
              "command": "my_linting_script.sh",
            }
        }
    ],

Это изменит правила игры для всех нас, разработчиков без Mac

MY ADVANCE SO FAR

В Keybindings это работает (создает журнал при нажатии Ctrl + Alt + B)

{
  "keys": ["ctrl+alt+b"], 
  "command": "exec", 
  "args": {
    "cmd": "bash -c \"cd ~ && echo ok >> log.txt\"",
  } 
}

И это работает в настройках, запускаемых при каждом «сохранении» с помощью плагина «hooks»:

"on_post_save_user": [
    {
        "command": "exec", 
        "args": {
          "cmd": "bash -c \"cd ~ && echo ok >> log.txt\"",
        },
            "scope": "window"

    }
],

Это лучший способ?

Попытка создания плагина

Я сделал простойПлагин, который успешно запускает "top" с bash в Windows с WSL.

https://github.com/eduardoarandah/sublime-bash-execute

Просто скопируйте BashCommand.py в Packages / User и запустите в консоли:

view.run_command('bash_exec')

Я никогда не делал великолепный плагин, любая помощь будет зачислена, оценена и т. Д.

1 Ответ

0 голосов
/ 13 декабря 2018

Внутренняя команда exec может запускать любую произвольную команду, которую вы выберете, поэтому вы можете использовать ее напрямую, если хотите, с помощью этой команды.

Следует отметить, чтокоманде exec можно присвоить либо cmd как ["list", "of", "strings"], либо shell_cmd как "a single string".При использовании cmd первый элемент в списке вызывается напрямую, а все остальное передается в качестве аргументов, тогда как во втором случае строка передается непосредственно в оболочку как есть.

Обычно для таких элементов, какВы упоминаете здесь, вы хотите использовать shell_cmd;поскольку он передается непосредственно в оболочку для выполнения, он может содержать такие вещи, как команды перенаправления и цепочки.

Как отмечалось в приведенных выше примерах, вы можете использовать shell_cmd и добавлять префикс к любой команде, которую вы хотите выполнить с помощьюbash -c, завершая остальную часть команды в двойные кавычки, и команда exec запустит bash и передаст ей указанную вами команду.

Также можно создать простую команду в Sublime.который ведет себя так же, как exec, и в то же время автоматически вводит соответствующий элемент, чтобы заставить bash выполнить команду за вас.

Такой плагин может выглядеть следующим образом:

import sublime
import sublime_plugin

from Default.exec import ExecCommand


class BashExecCommand(ExecCommand):
    """
    A drop in replacement for the internal exec command that will run the
    given command directly in bash. Use of "shell_cmd" is recommended, but
    some care is taken to convert "cmd" to the appropriate "shell_cmd"
    equivalent.

    For use in key bindings, replace `exec` with `bash_exec` and you're good
    to go. For use in a build system, include the following lines to your
    build to tell Sublime to use this command to execute the build as well as
    how to kill it:

        "target": "bash_exec",
        "cancel": {"kill": True}
    """
    def run(self, **kwargs):
        # If we're being told to kill a running build, short circuit everything
        # and just do it directly. Not really needed, but it's a nice reminder
        # that custom builds need to handle this sort of thing in general.
        if kwargs.get("kill", False):
            return super().run(kill=True)

        # If there is a "cmd" argument, grab it out and convert it into a
        # string. Items in cmd that contain spaces are double quoted so that
        # they're considered a single argument, and all items are joined
        # together.
        cmd = kwargs.pop("cmd", None)
        if cmd is not None:
            cmd = " ".join(["\"%s\"" % s if " " in s else s for s in cmd])

        # If there is a "shell_cmd" argument, then modify it to include the
        # correct prefix to run the command via bash as well as to quote all
        # double quote characters so the shell sees them.
        #
        # This will fall back to the string we just gathered for "cmd" if no
        # shell_cmd is given.
        shell_cmd = kwargs.pop("shell_cmd", cmd)
        if shell_cmd is not None:
            kwargs["shell_cmd"] = "bash -c \"{0}\"".format(
                shell_cmd.replace("\"", "\\\""))

        # Defer to the built in exec command to run the command
        super().run(**kwargs)

Если вы отредактируете комментарии, объясняющие, что они делают, изменение составит ~ 20 строк или около того.Что он делает, так это использует внутреннюю команду exec, чтобы выполнить всю тяжелую работу за нас.Таким образом, мы можем просто изменить аргументы команды автоматически и позволить Sublime позаботиться о деталях.

Как видно из кода, если предоставляется аргумент cmd, он преобразуется в строку, объединяя всеаргументы вместе с пробелами.По ходу дела любой аргумент, содержащий пробел, автоматически заключается в двойные кавычки, чтобы он правильно передавался в оболочку.

Если указан shell_cmd, он аналогичным образом извлекается и преобразуется в строку с префиксом bash -c;по ходу дела любые двойные кавычки, которые появляются в команде, заключаются в кавычки, чтобы они правильно передавались в оболочку.

Кроме того, преобразованное значение cmd используется в качестве значения по умолчанию, если не указано shell_cmd;таким образом, если вы укажете shell_cmd, это всегда то, что выполняется, и если вы используете cmd, то оно преобразуется в соответствующий аргумент shell_cmd напрямую.

Используемая команда, которая реализует это: bash_exec, идолжна быть замена для использования exec в местах, где вы вызываете его напрямую, таких как привязки клавиш, пункты меню, записи палитры команд, другие команды и т. д.

Кроме того,Вы можете добавить следующие две строки непосредственно в файл sublime-build, чтобы использовать эту команду для выполнения построений, выполненных таким образом;первая строка указывает Sublime использовать эту команду вместо exec для выполнения сборки, а вторая сообщает ей, какие аргументы передать команде, чтобы она отменила текущую сборку.

"target": "bash_exec",
"cancel": {"kill": True},

Caveats

Это действительно только для использования в Windows;в Linux и MacOS Sublime уже использует bash для выполнения shell_cmd без необходимости делать что-то особенное.Используя sublime.platform(), команда может определить, выполняется ли она в Windows, и только переписать команды в этой ОС, а также, при желании, оставить все как есть.

Обратите внимание, что я лично не использую WSL в моей Windowsмашины, так что это не проверено в этой среде (но это работает, как и ожидалось, на моем компьютере с Linux);таким образом, здесь все еще могут быть сделаны некоторые изменения, например, если bash не находится непосредственно на пути, или вы хотите, чтобы он был настраиваемым.

Последнее, что следует упомянуть, это то, что кодпреобразование shell_cmd и cmd в командную строку bash может потребовать дополнительных умственных или тонких настроек в зависимости от того, что вы пытаетесь осуществить.Если что-то не работает так, как вы ожидаете, консоль Sublime отображает, какая команда exec выполняется, что может пролить некоторый свет на вещи.

...