Можно ли добавить глобальную привязку X11 через/в Sublime Text 3?

Я хотел бы добавить глобальную привязку X11, предпочтительно через конфигурацию ST3, которая при активации будет:

  • переместите фокус в окно ST3 и просмотрите,
  • это также потребует переключения на правильный виртуальный рабочий стол,
  • вызвать возвышенную команду (текстовую команду или другую).

Это возможно?

Я занимаюсь кодированием Xlib/EWMH и могу выполнить активацию и переключение рабочего стола вручную. Все, что мне нужно, это глобальная привязка X11, которая будет вызывать команду Sublime Text. Возможна ли такая привязка через конфигурацию Sublime? Если нет, то как выполнить вышеописанное?


person psprint    schedule 13.12.2020    source источник


Ответы (1)


Я не совсем уверен, что вы подразумеваете под глобальной привязкой X11, но я бы сказал, что то, чего вы хотите достичь, возможно с помощью Xlib и EWMH в сочетании с плагином Sublime Text, чтобы сфокусировать требуемое представление и вызвать команду ST.

Ниже приведен полностью работающий базовый макет необходимой логики, который использует сценарий Bash для фокусировки окна и переключения виртуальных рабочих столов, а затем для вызова плагина Sublime Text, который изменяет представление и запускает необходимую команду.

Сценарий использует wmctrl полезную утилиту, которая выдает команды X Window Manager, совместимым с EWMH/NetWM.

Сохраните этот файл как сценарий Bash и дайте ему разрешение на выполнение:

#!/bin/bash

# EWMH WM_CLASS for Sublime Text 3: "sublime_text.Sublime_text"
#
# EWMH WM_NAME examples: "~/Path/FileName.ext (Project Name) - Sublime Text"
#                        "~/Path/No Project.ext - Sublime Text"
#                        "untitled - Sublime Text"
#                        "~/Path/FileName.ext • (Project) - Sublime Text"
#
# Note: The project file name without the extension will be shown in brackets
# if there is a project file. '•' (see last example above) will be added if
# the file is unsaved and the suffix " - Sublime Text" is always added.

# Example: "~/Programming/Projects/MyProject.sublime-project" --> "MyProject"
target_project="MyProject"

# Example "wmctrl -lx" line:
# 0x02400003 0 sublime_text.Sublime_text host ~/File.ext (MyProject) - Sublime Text
# WinID   Desktop      WM_CLASS        hostname             WM_NAME
target_window=$(wmctrl -lx | grep ".*sublime_text.Sublime_text.*($target_project).*")
if [ "$target_window" = "" ]; then
    exit
fi

target_window_id=$(echo "$target_window" | grep -Eo '0x[0-9a-f]+')
if [ "$target_window_id" = "" ]; then
    exit
fi

# Switch focus to the window, wmctrl will switch virtual desktops if needed.
wmctrl -ia "$target_window_id"

# Call the Sublime Text window command:
# [This assumes Sublime Text is already running.]
subl --background --command "focus_view_invoke_cmd"

Сохраните этот файл где-нибудь в дереве каталогов ST3 config Packages с расширением .py. например ~/.config/sublime-text-3/Packages/User/FocusViewInvokeCommand.py:

import os.path
import sublime
import sublime_plugin

# Command created by ST for this class: focus_view_invoke_cmd
# How to set or find the command name of a Sublime Text plugin
# see this answer: https://stackoverflow.com/a/63979147/2102457

class FocusViewInvokeCmdCommand(sublime_plugin.WindowCommand):

    def run(self):

        # view_name_to_match is a file or unsaved buffer
        # name that the focus should be switched to. e.g.
        view_name_to_match = "MyToDoList"

        for view in self.window.views():
            if view_name_to_match in self.view_name(view):
                self.window.focus_view(view)
                self.run_command(view)
                break


    def view_name(self, view):

        # Return the file name (not full path) if the buffer is saved.
        if view.file_name():
            path = view.file_name()
            return os.path.basename(path)

        # Return the buffer name; i.e. the name the user has assigned,
        # or the buffer's 1st line auto. assigned by ST, or "untitled".
        else:
            # "untitled" is the default displayed name shown by ST
            # for all buffers which are both unsaved and unnamed,
            # but view.name() returns "" for "untitled" buffers.
            return view.name() if view.name() else "untitled"


    def run_command(self, view):

        command_to_run = "insert"
        command_args = {"characters": "This is a test! :)"}

        # In each of the run_command() methods the
        # command_args parameter may be omitted.

        # Use to run a *text command* on the view.
        view.run_command(command_to_run, command_args)

        # Use to run a *window command*.
        # self.window.run_command(command_to_run, command_args)

        # Use to run an *application command*.
        # sublime.run_command(command_to_run, command_args)
person mattst    schedule 14.12.2020