Sublime Text и Clojure: не соединяйте одиночные кавычки

Есть ли способ получить тип синтаксиса для определения сочетаний клавиш или для установки сочетания клавиш в зависимости от типа синтаксиса (возможно, под "context")?

Мои цитируемые списки '(1 2 3) вводятся следующим образом: '(1 2 3)', потому что Sublime применяет это полезное (но не в этом случае) поведение.

Вот соответствующий бит файла Default (OSX).sublime-keymap

// Auto-pair single quotes
{ "keys": ["'"], "command": "insert_snippet", "args": {"contents": "'$0'"}, "context":
    [
        { "key": "setting.auto_match_enabled", "operator": "equal", "operand": true },
        { "key": "selection_empty", "operator": "equal", "operand": true, "match_all": true },
        { "key": "following_text", "operator": "regex_contains", "operand": "^(?:\t| |\\)|]|\\}|>|$)", "match_all": true },
        { "key": "preceding_text", "operator": "not_regex_contains", "operand": "['a-zA-Z0-9_]$", "match_all": true },
        { "key": "eol_selector", "operator": "not_equal", "operand": "string.quoted.single", "match_all": true }
    ]
},
{ "keys": ["'"], "command": "insert_snippet", "args": {"contents": "'${0:$SELECTION}'"}, "context":
    [
        { "key": "setting.auto_match_enabled", "operator": "equal", "operand": true },
        { "key": "selection_empty", "operator": "equal", "operand": false, "match_all": true }
    ]
},
{ "keys": ["'"], "command": "move", "args": {"by": "characters", "forward": true}, "context":
    [
        { "key": "setting.auto_match_enabled", "operator": "equal", "operand": true },
        { "key": "selection_empty", "operator": "equal", "operand": true, "match_all": true },
        { "key": "following_text", "operator": "regex_contains", "operand": "^'", "match_all": true }
    ]
},

Ответы

Ответ 1

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

"auto_match_enabled": false

Затем добавьте следующие параметры.

"my_auto_match_enabled": false

Затем нам нужно добавить новый набор привязок. Я только сделал одно из того, что вы разместили, но я объясню, что я сделал, поскольку это может быть не очевидно.

{ "keys": ["'"], "command": "insert_snippet", "args": {"contents": "'${0:$SELECTION}'"}, "context":
    [
        { "key": "setting.my_auto_match_enabled", "operator": "equal", "operand": true },
        { "key": "selection_empty", "operator": "equal", "operand": false, "match_all": true },
        { "key": "selector", "operator": "not_equal", "operand": "source.clojure", "match_all": true }
    ]
}

Во-первых, обратите внимание, что я переключил первый контекстный ключ с setting.auto_match_enabled на setting.my_auto_match_enabled. Затем я добавил последнюю запись контекста, которая ограничит область. При этом сниппет будет запускаться только тогда, когда вы не находитесь в области source.clojure. Возможно, вам придется изменить это, так как я не знаю, что такое имя области в clojure, я просто догадался =). Вам нужно будет сделать это для всех ваших записей с одной кавычкой. Теперь, поскольку мы отключили встроенное автоматическое сопряжение, мы также должны прочитать все эти записи. В этих записях мы снова изменим setting.auto_match_enabled на setting.my_auto_match_enabled. После этого все должно работать. Заметьте, что на самом деле это не должно быть my_auto_match_enabled, это то, что я выбрал. Вы можете изменить его по своему усмотрению.

При всем том, что я сказал, я не полностью протестировал все это, так что комментарий, если вы столкнулись с проблемами.

Объяснение:

Итак, теперь вы можете спросить себя, почему мне нужно отключить встроенный код автосогласования? Ну вот ответ. Даже если мы заблокировали автоматическое заполнение в наших пользовательских настройках, используя аналогичное правило определения, оно все равно вернется к умолчанию, таким образом, введя автоматические парные кавычки, независимо от того, что мы делаем в папке пользователя. Теперь вы можете подумать, но что, если мы изменим файл настроек по умолчанию. Хотя мы могли бы это сделать, снова вставив тот же параметр контекста, мы должны были бы обязательно восстановить этот файл при любых последующих обновлениях. Поэтому я думаю, в конце концов, это зависит от вас. Если вы редактируете файл по умолчанию, просто имейте в виду, что если вам когда-нибудь понадобится вернуться, вам придется снова изменить файл.

Sublime Text 3:

В ST3 вы можете фактически изменить файл по умолчанию. Это связано с изменением того, как пакеты загружаются в ST3. Вместо того, чтобы быть извлеченным в папку Packages, плагины запускаются непосредственно из файлов .sublime-package (которые просто переименованы в zips). Кроме того, любой файл в каталоге Packages имеет приоритет над файлом .sublime-package. Итак, в ST3 вы создадите Packages/Default/Default (your os here).sublime-keymap и добавьте контекстную строку. Это безопасно от любых последующих обновлений, поскольку обновления больше не изменяют каталог Packages.

Ответ 2

Я сделал эту простую вещь:
Поместите этот:

// Singlequote for lisp
{ "keys": ["'"], "command": "insert_snippet", "args": {"contents": "'"}, "context":
    [
        { "key": "selector", "operator": "equal", "operand": "source.lisp"}
    ]
},

в пользовательских ключах-привязках.


Шаг за шагом:

В этом случае есть еще один необычный случай: '|' (pipe представляет каретку), после нажатия backspace он все равно удалит оба одиночных кавычки.


Чтобы исправить это, добавьте этот к ключевым словам пользователя:

{ "keys": ["backspace"], "command": "left_delete", "context":
    [
        { "key": "setting.auto_match_enabled", "operator": "equal", "operand": true },
        { "key": "selection_empty", "operator": "equal", "operand": true, "match_all": true },
        { "key": "preceding_text", "operator": "regex_contains", "operand": "'$", "match_all": true },
        { "key": "following_text", "operator": "regex_contains", "operand": "^'", "match_all": true },
        { "key": "selector", "operator": "equal", "operand": "source.lisp"}
    ]
},

ВАЖНОЕ ПРИМЕЧАНИЕ:

Как указано pickwick в комментариях, вы должны - конечно - изменить

"source.lisp"
для изображения "source.<lisp-of-your-choice>"
или, скорее, к "source.<name-of-syntax-of-your-choice>"
или даже скорее - er:
"source.<name-of-scope-the-syntax-you're-using-is-using>".


ScopeAlways - это плагин, который может показать вам правильное имя области, используемой вашим синтаксисом. Скорее всего, это будет что-то вроде "source.lisp" для CL, "source.clojure" для clojure, может быть "source.scheme", если вы пообщаетесь с классными детьми и т.д.