Eсть не знаю, как я могу связать ключ с большим классом ключей одновременно, поэтому для того, чтобы делать то, что вы хотите, вам нужно было бы создать индивидуальное сопоставление для каждого из ключей по одному, что довольно громоздко и, скорее всего, не очень хорошая идея.
[править] Существует на самом деле способ сделать это; Я добавил больше информации к концу моего ответа [/ править]
С некоторого простого тестирования, казалось бы, что ключи, которые вы заинтересованы в (этот входной текст) непосредственно обрабатываются Sublime core, если вы не предоставили для них сопоставление. То есть они разрушают нормальный командный механизм, а это означает, что вы не можете просто ловить всякий раз, когда текст вставлен и переформатирован.
Один из способов сделать это, как предложено MattDMO, использовать обработчик on_modified
для отслеживания изменения буфера, а затем запускать перегруппировку таким образом.
Пример плагин, который может сделать что-то вроде этого является следующее:
import sublime
import sublime_plugin
import re
class TableFormatEventListener(sublime_plugin.EventListener):
def __init__(self):
self._views = dict()
self.regex = re.compile(r"\s*\|")
def on_modified(self, view):
# Only for views with table editing enabled that are not already being
# modified
if (view.settings().get("enable_table_editor", False) and
self._views.get(view.id(), False) is False):
for s in view.sel():
line = view.substr(view.line(s.begin()))
prior = view.substr(s.begin() - 1) if s.begin() > 0 else ""
# Only if all cursors are inside of a table row and the
# character prior to the cursor is not a space
if self.regex.match(line) is None or prior == " ":
return
# Perform the realignment
self._views[view.id()] = True
view.run_command("table_editor_align")
self._views[view.id()] = False
def on_text_command(self, view, cmd, args):
# Don't trigger reformatting while an undo is happening
if cmd == "undo":
self._views[view.id()] = True
def on_post_text_command(self, view, cmd, args):
# Undo is complete; resume reformat handling
if cmd == "undo":
self._views[view.id()] = False
Это реализует слушатель событий, который вызывает каждый раз, когда вид модифицируется. Это означает, что текст был добавлен или удален, а также охватывает такие вещи, как пасты (буквально все, что изменяет буфер, а больше на секунду).
Плагин выполняет такой же контекст, что и привязка ключа, чтобы гарантировать, что все доступные кадры находятся внутри строки таблицы, как если бы вы вызывали команду для выравнивания таблицы в противном случае, она выбрасывает ошибка.
Кроме того, также проверяется, был ли добавлен последний добавленный символ. Это связано с тем, что переформатирование, по-видимому, устраняет конечные пробелы, что фактически блокирует вас от возможности ввода пространства в любом месте таблицы.
Предполагая, что все курсоры находятся в строках таблицы и не просто вставляют пробел, команда для выравнивания таблицы выполняется в текущем представлении.
Вещь, которую следует отслеживать здесь, заключается в том, что перегруппировка таблицы вызывает изменение содержимого буфера, которое затем снова запускает прослушиватель плагинов, который снова и снова перенастраивает таблицу снова и снова в цикле до тех пор, пока не произойдет сбой плагина ,
Чтобы прекратить это, мы сохраняем дорожку представлений, которые должны были проигнорировать событие on_modified
, добавив текущее представление в список до изменения таблицы, а затем удалив его, как только мы закончим.
Побочный эффект от того, что делает плагин, заключается в том, что любые изменения, внесенные вами в таблицу, приводят к двум изменениям; сделанное вами изменение и изменение, которое перенастраивает таблицу (даже если оно не изменяется). Это означает, что для отмены изменений в таблице вам иногда приходится отжимать Undo больше, чем вы могли бы подумать.
Это вызывает потенциальные проблемы. Например, если вы должны были вернуться в начале строки таблицы, эта строка и предыдущая строка будут в одной строке. Модификация вызывает функцию перегруппировки, которая формально делает две строки одной.
Теперь у вас немного рассол, потому что вы не можете отменить изменение; когда вы один раз отжимаете отменить, он отменяет перегруппировку, но при этом он модифицирует буфер, который вызывает повторную замену.
Чтобы решить эту проблему, прослушиватель событий также прослушивает, когда произойдет команда undo
, и убедитесь, что, пока происходит отмена, обработчик модификации не будет перестраивать таблицу.
Поскольку я не использую этот конкретный плагин, могут быть аналогичные краевые случаи для других сценариев, которые необходимо будет обрабатывать таким образом.
Производительность может или не может пострадать в зависимости от того, насколько велика таблица, которую вы редактируете. В моем (чрезвычайно упрощенном) тестировании производительность на небольших таблицах была незначительной на моей машине. Ваш пробег может отличаться, поэтому потенциально может быть хорошей идеей иметь дополнительную проверку кода, которая останавливает его при запуске, если текущий файл находится над некоторым пороговым значением или чем-то рядом с этими строками.
[править]
Как это происходит, то на самом деле это способ сделать что-то подобное тому, что вы изначально просили. Можно назначить привязку клавиш, которая будет запускаться для любого вставленного символа, хотя вам все равно нужно немного кода плагина для склеивания, чтобы связать все вместе (а также несколько вопросов удобства использования относятся к тому, как плагин таблицы выполняет переформатирование).
Необходимый код плагина - это команда, которая будет принимать символ и вставлять текст, как обычно, а затем также запускать команду выравнивания таблицы.
import sublime
import sublime_plugin
class TextAndAlignTableCommand(sublime_plugin.TextCommand):
def run(self, edit, character):
self.view.run_command("insert", {"characters": character})
if character != " ":
self.view.run_command("table_editor_align")
Это определяет команду, которая принимает один аргумент character
, который будет вставить в буфер путь характер, как правило, вводятся. Затем, если символ не является пространством, он также вызывает команду для выравнивания таблицы.
При этом в месте, ключ привязки для создания является:
{ "keys": ["<character>"], "command": "text_and_align_table", "context":
[
{ "key": "setting.enable_table_editor", "operator": "equal", "operand": true, "match_all": true },
{ "key": "preceding_text", "operator": "regex_contains", "operand": "^\\s*\\|", "match_all": true },
{ "key": "following_text", "operator": "regex_match", "operand": "\\s*\\|.*$", "match_all": true }
]
},
В основном это ключ привязки, который вы упомянули выше (который по умолчанию для базовой таблицы плагин для запуска переформатировать) с некоторыми небольшие изменения.
Во-первых, ключ привязан к ключу <character>
, что делает его потенциально триггером для любого символа, который иначе был бы вставлен в буфер.
Во-вторых, он использует нашу специальную команду сверху, которая сначала вставляет текст, а затем переформатирует таблицу.
В-третьих, контекст following_text
изменен таким образом, что он запускается только тогда, когда он находится в конце столбца в таблице, так что можно вставить текст в середину столбца, не указав позицию курсора, конец столбца.
При привязке этого способа привязка будет вызываться для любого отдельного символа и вызовет команду, предоставленную с аргументом, который сообщает вам, что это за символ. Сама привязка не может иметь на ней модификатора (например, ctrl
, shift
и т. Д.), Но персонаж, который вы получаете, является тем, который в противном случае был бы напечатан.
Это намного чище и не имеет такой же проблемы, как и код выше w/касается отмены, потому что все предпринятые действия являются частью одной и той же операции редактирования.
Кроме того, наличие привязки не является триггером внутри тела столбца, устраняет проблему с возможностью вставки текста в середине столбца, поскольку перестановка таблицы сдвигает местоположение курсора. Это приводит к тому, что таблица не выравнивается, но существующая привязка ключей может использоваться в этой ситуации для устранения проблемы.
С другой стороны, по-прежнему невозможно иметь пробелы в конце значения столбца (после переформатирования), потому что tableformat хочет удалить их. Чтобы не допустить этого, базовый плагин должен быть изменен, чтобы этого не делать, но похоже, что он несколько скомпрометировал форматирование таблицы.
Вам было бы намного лучше написать подкласс подкастов ['sublime_plugin.EventListener'] (http://www.sublimetext.com/docs/3/api_reference.html#sublime_plugin.EventListener) и использовать его' on_modified() '. – MattDMo
@MattDMo плагин в настоящее время является подклассом sublime_plugin.TextCommand, и я считаю, что это необходимо для его работы. Плагин, который я пытаюсь изменить, - https://github.com/vkocubinsky/SublimeTableEditor. – Basj