Выберите первый символ до первого символа, отличного от camelCase или не верхнего регистра, или до первого символа змеи _ в vim - PullRequest
1 голос
/ 03 февраля 2020

Я использовал эту карту:

map ,w v/\([^ a-z0-9]\|[^ A-Z0-9]\)*<cr>h

идея состоит в том, чтобы выбрать

в словах

mysuperTest
MYSUPER_TEST
mysuper_test

, чтобы всегда выбирать часть, которая говорит mysuper

, но это не работает, не знаю почему

1 Ответ

3 голосов
/ 03 февраля 2020

Я бы использовал что-то вроде следующего:

nnoremap ,w v/\C\%#.\([a-z]\+\<bar>[A-Z]\+\)\zs<cr>h

Следует отметить, что при отображении вам необходимо использовать <bar> (или экранировать | с дополнительным backsla sh) поскольку в противном случае | распознается как разделитель команд (см. :help map-bar.)

Еще одно замечание: вы хотите, чтобы совпадение было start с первого символа за пределами слова ( так что в конце слова вы попадете с h). Визуальный выбор расширится до начала совпадения в поиске. Я предлагаю использовать \zs для явной установки начала матча (см. :help /\zs.)

Наконец, остерегайтесь настроек 'ignorecase' или 'smartcase'. Используйте \C, чтобы явно запросить совпадение с учетом регистра (см. :help /\C.)

Мне также нравится идея использовать более сильный якорь для начала матча, поэтому я использую \%# чтобы соответствовать текущей позиции курсора (см. :help /\%#), поэтому вы всегда должны соответствовать только текущему слову и не заканчивать тем, что бродили по буферу.

Соберите все вместе:

\C         Case-sensitive search
\%#        From cursor position
.          Skip first character
\(         Either one of:
  [a-z]\+  One or more lowercase letters
  \|       (\<bar>) Or:
  [A-Z]\+  One or more uppercase letters
\)         End group
\zs        Set match position here

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

Я сохранил вашу первоначальную идею поиска первый символ после слова, затем с помощью h до go назад на один слева. Но это может быть проблемой, если, например, слово находится в конце строки.

Вместо этого вы можете сопоставить последний символ слова с чем-то вроде [a-z]\+\zs[a-z], что установит начало совпадения на последнем символе в нижнем регистре. Вы можете сделать это для обеих сторон группы (у вас может быть более одного \zs в вашем паттерне, последние победы.) Если вы структурируете свой матч таким образом, вам не понадобятся финальные h до go назад.

Я не обрабатывал числа, я оставлю их в качестве упражнения для читателя.

Наконец, рассмотрим довольно много угловых случаев, которые могут сделать такое отображение вполне сложно получить права. Вместо того, чтобы придумывать свои собственные, почему бы не взглянуть на плагины, которые добавляют поддержку обработки слов CamelCase, которые были проверены в бою, и будут охватывать варианты использования намного более продвинутые, чем простое выражение, которое вы здесь используете?

Существует превосходное vim-scripts / camelcasemotion от In go Karkat, которое устанавливает отображение ,w для перехода к началу следующего слова CamelCase, а также i,w для выбора текущий. Вы можете использовать мощные комбинации, такие как v3i,w, чтобы визуально выбрать текущее и следующие два слова CamelCase.

Вы также можете проверить tpope / vim-aboli Тима Поупа sh, которые, среди другие функции, определяет набор cr отображений для приведения из camelCase в MixedCase, snake_case, UPPER_CASE и т. д. c. (Не напрямую о выборе, но все же связано, и вы можете найти это полезным.)

...