1. Новый маппинг для плагина Mark. Плагин Mark позволяет легко подсвечивать слова или паттерны, соответствующие регулярным выражениям. В отличие от встроенного механизма поиска и подсветки, Mark позволяет одновременно подсвечивать разными цветами несколько слов или паттернов. К сожалению, маппинг, принятый в Mark по умолчанию, на мой взгляд, требует изменения. Именно благодаря неудачному маппингу я некоторое время не пользовался этим плагином, хотя он и был установлен мною собственноручно.
Итак, маппинг по умолчанию: \m - подсветить слово, \n - снять подсветку, \r - ввести паттерн для подсветки. Этот маппинг ужасно тормозил (требовалось ждать около секунды, чтобы изменения вступили в силу), и я сначала думал, что это особенность реализации подсветки в Mark. Но проблема оказалась весьма тонкой. Выяснилось, что маппинг пересекается с маппингом плагина c.vim и еще одного установленного мною плагина. Так, в c.vim определено множество маппингов, начинающихся с \n и \r (\nc, \ns, \ni и т.д.). Таким образом, при вводе символов, соответствующих маппингу Mark, vim некоторое время ждал, а не введет пользователь еще один символ, который можно будет интерпретировать как маппинг из c.vim - это нормальное поведение vim.
Чтобы в следующий раз не наступать на грабли, можно посмотреть все маппинги, начинающиеся с определенного символа, скажем с \n (первый символ \ как таковой в маппинг не входит, так как является спецсимволом - так называемым лидером). Для этого нужно в командной строке vim ввести
:map \nВ новом маппинге я задействовал сочетание клавиш Ctrl-m:
nmap <C-m><C-m> <Plug>MarkSet nmap <C-m>n <Plug>MarkClear nmap <C-m>r <Plug>MarkRegex vmap <C-m><C-m> <Plug>MarkSet vmap <C-m>r <Plug>MarkRegex nmap <C-m>* <Plug>MarkSearchCurrentNext nmap <C-m># <Plug>MarkSearchCurrentPrev nmap <C-m>/ <Plug>MarkSearchAnyNext nmap <C-m>? <Plug>MarkSearchAnyPrev nmap <C-m>c <Plug>MarkAllClear nmap <C-m>t <Plug>MarkToggle nmap <C-m>s :MarkSave<CR> nmap <C-m>l :MarkLoad<CR>В принципе, тут все понятно: вместо \m нужно, удерживая клавишу Ctrl, два раза нажать m, вместо \n - нажать Ctrl-m, а затем n, вместо \r - Ctrl-m, а затем r. Кроме того, я добавил маппинг для переключения подсветки, которого нет по умолчанию: <Ctrl-m>t.
Update. По иронии судьбы Ctrl-m тоже плохой маппинг, так как это сочетание в vim полностью соответствует клавише Enter. Так что если оставить такой маппинг, то Enter в нормальном режиме будет так же тормозить, как раньше тормозил сам Mark. Клавиша Enter потенциально используется в vim достаточно часто, например в плагине taglist при переходе к метке под курсором. Поэтому в приведенных выше маппингах следует заменить все вхождения <C-m> на какое-нибудь другое, неиспользуемое сочетание клавиш, например на <C-k>.
2. Подсветка областей кода, не соответствующих принятому стандарту. Несмотря на грозное название, здесь имеется ввиду очень простая вещь. Допустим, вам требуется убедиться, что код, который вы в данный момент редактируете или только что открыли, не содержит знаков табуляции, все строки завершаются не пробельными символами и их длина не превышает 80 знаков. Для этого вам нужно иметь возможность подсвечивать паттерны регулярных выражений, соответствующих указанным требованиям. Сами паттерны не такие уж сложные, однако вы предпочитаете делать это простым нажатием пары клавиш и, кроме того, таким же простым нажатием убирать подсветку.
Здесь я покажу, как это сделать с помощью простого маппинга ,s (запятая - s), который будет включать или выключать соответствующую подсветку в зависимости от текущего состояния (т.е. реализует то, что в английском языке называется простым словом toggle).
Прежде всего объявим переменную g:RightBorder, которая будет содержать максимальную разрешенную длину строки (т.е. 80), и новую область подсветки FormatHints, с помощью которой мы будем подсвечивать код, не соответствующий стандарту:
let g:RightBorder = 80 highlight FormatHints term=standout ctermfg=250 ctermbg=229 \ guifg=Red guibg=WhiteОпределение FormatHints разделено на две строки как результат следования внутренней дисциплине и установленному правилу непревышения строкой 80 символов :) Здесь с помощью аргументов ctermfg и ctermbg определена подсветка для терминалов с поддержкой 256 цветов, которая, на мой взгляд, вполне подходит для темных цветовых схем (светло-серый текст на бледно-желтом фоне: в конце концов мы подсвечиваем "запрещенные" участки кода, поэтому светлое на светлом здесь вполне уместно). Поскольку я не использую GUI vim, значения для guibg и guifg выбраны произвольно.
Теперь определим функции для включения и выключения подсветки:
fun! <SID>formathints() if !exists("w:m1") || w:m1 == 0 let w:m1 = matchadd('FormatHints', '\%>'.g:RightBorder.'v.\+', -1) let w:m2 = matchadd('FormatHints', '[\t]', -1) let w:m3 = matchadd('FormatHints', '[\t \r]\+$', -1) endif endfun fun! <SID>formathints_hide() if exists("w:m1") && w:m1 > 0 silent! call matchdelete(w:m1) silent! call matchdelete(w:m2) silent! call matchdelete(w:m3) let w:m1 = 0 let w:m2 = 0 let w:m3 = 0 endif endfunС помощью переменных w:m1, w:m2 и w:m3 определяются паттерны, соответствующие областям кода, которые мы хотим подсвечивать. Приставка к переменной w: в vim означает, что будут созданы отдельные инстансы этой переменной в каждом отдельном окне vim, соответственно, наше переключение подсветки будет работать только в активном окне.
Теперь определим команды для включения и выключения подсветки:
command -bar ShowFormatHints call <SID>formathints() command -bar HideFormatHints call <SID>formathints_hide()Опция -bar нужна для использования команд в составе сложных выражений, содержащих элементы <Bar> в следующем итоговом маппинге:
nmap <silent> ,s :if !exists("w:m1") <Bar><Bar> w:m1 == 0 <Bar> \ ShowFormatHints <Bar> echo "Show format hints" <Bar> else <Bar> \ HideFormatHints <Bar> echo "Hide format hints" <Bar> endif<CR>Напомним, что элементы <Bar> в маппингах расширяются в символ |, следовательно, без учета echo "Show format hints" и echo "Hide format hints", этому маппингу будет соответствовать команда
:if !exists("w:m1") || w:m1 == 0 | ShowFormatHints | else | HideFormatHints | endifЕсли оставить этот маппинг без модификатора <silent> (и без дополнительных команд echo), то эта малоинформативная строка будет выводиться в командную строку vim каждый раз при нажатии ,s - добавление <silent> и команд echo делают использование этого маппинга намного более удобным за счет более информативных сообщений.
Итак, цель достигнута. Теперь при нажатии на клавиатуре комбинации ,s будет происходить переключение подсветки проблемных участков кода с выводом сопутствующей информации в командную строку vim.
3. Маппинг для переключения ограничительной колонки (colorcolumn). Цель почти такая же, как и в предыдущем пункте: создать маппинг для включения/выключения цветовой колонки, которая будет располагаться на 81-ом знаке и предупреждать пользователя о возможном нарушении стандарта кодирования, ограничивающего длину строк 80 знаками. Но реализовать эту задачу теперь проще:
nmap <silent> ,m :if &colorcolumn == 81 <Bar> set colorcolumn= <Bar> \ elseif !&colorcolumn <Bar> set colorcolumn=81 <Bar> endif<CR>Новый маппинг соответствует комбинации клавиш ,m. На этот раз нет смысла выводить сообщения на дисплей, поскольку наличие или отсутствие ограничительной колонки заметно и так.
4. Маппинг для переключения режима paste. Режим paste бывает полезен, когда нужно вставить из буфера обмена многострочный участок кода без дополнительного форматирования. Маппинг соответствует комбинации клавиш ,p и выглядит следующим образом:
nmap <silent> ,p :set paste! <Bar> set paste?<CR>Команда set paste! переключает (toggle) текущий режим paste, а команда set paste? выводит его значение на дисплей.
Спасибо за статью! Попробовал у себя добавить в .vimrc функцию из пункта два. Не хочет работать. Использую вызов через имя. Так как ваш мапинг у меня задействован другим плагином.
ОтветитьУдалитьТогда используйте другой маппинг вместо ',s', например ',h'. Кстати, сейчас я использую именно ',h' для этого. Маппинг ',s' я задействовал для переключения проверки правописания:
Удалитьnmap <silent> ,s :set spell! <Bar> set spell?<CR>
С маппингом разобрался. Выводит в статусною строку сообщение о включении и выключении функции, но визуально подсведки не вижу. Где может быть ошибка?
Удалить1. Вы используете GUI или терминал? (В зависимости от ответа будут различаться цвета подсветки).
Удалить2. Если терминал, то поддерживает ли ваш терминал 256 цветов? Для проверки введите в определении FormatHints вместо ctermfg=250 и ctermfg=229 какие-нибудь стандартные цвета, например ctermfg=Red ctermbg=White. Если цвета появились, то ваш терминал не поддерживает 256 цветов и вам стОит включить эту поддержку, так как гамма из 8 или 16 цветов выглядит скудно (ну здесь на вкус и цвет).
3. Если пункт 2 не сработал, то убедитесь, что в вашем тексте есть символы табуляции и строки длиннее 80 символов.
У меня gvim. цвета guibg=White guibg=Red должны быть хорошо видны в моей теме. Строки с символами больше 80 есть, но подсвечиватся.
УдалитьТакже попробовал в терминале и голой консоли. Результат негативный
УдалитьЯ не использую gvim, но решил проверить, сработает ли у меня. Работает. За исключением того, что я опечатался и оба раза определил guibg. Должно быть guibg=White guifg=Red (красный текст на белом фоне)
УдалитьПроблема все таки из подсведкой. При замене 'FormatHints' на 'ErrorMsg'. Получается отобразить. Спс за полезную функцию. Она работает.Пусть красным цветом. Я уже сам попытаюст разобраться что не так у моего вима с подсветкой.
УдалитьОтсюда: http://vim.wikia.com/wiki/Highlight_unwanted_spaces:
УдалитьHowever, be aware that future colorscheme commands may clear all user-defined highlight groups.
Возможно, это ваш случай и FormatHints затирается вашей цветовой схемой. Там же предлагают сделать так:
autocmd ColorScheme * highlight FormatHints guifg=Red guibg=White
(в общем то же определение для autocmd)
Спасибо за помощь. Теперь все получилось! Специально смотрел цветовую схему перед этим. Но не нашел там такой группы.
УдалитьФункию немного упростил. Буду теперь использовтаь только для подсветки "лишних" знаков.
А там и не может быть такой группы. Это пользовательская группа и она определена только в данном скрипте.
УдалитьСледствие показало, что пользовательские группы подсветки, такие как FormatHints, могут действительно удаляться при чтении цветовых схем, например это происходит, если использовать схему lucius. Выход из ситуации: в .vimrc определить не только цветовую группу, но и автокоманду для ее восстановления:
Удалитьhighlight FormatHints term=standout
\ ctermfg=250 ctermbg=229 guifg=Red guibg=White
" restore FormatHints after switching to a color scheme that may clear it off
autocmd ColorScheme * highlight FormatHints term=standout
\ ctermfg=250 ctermbg=229 guifg=Red guibg=White
Если в вашем .vimrc определение цветовой схемы (с помощью команды colorscheme) находится ниже по тексту, чем этот код, то достаточно определить только автокоманду.