Как изменить цвет определенного номера строки в Vim

Я давно хотел это сделать, иногда, когда у меня открыт файл, я хочу иметь возможность выделить определенные номера строк другим цветом. Например, предположим, что мой LineNr синий, а мой Current LineNr красный. Скажем, я нахожусь в строке 25, могу ли я изменить цвет LineNr строк 28-30 на зеленый, НЕ выходя из моей текущей строки?


person Community    schedule 12.08.2019    source источник


Ответы (1)


В качестве быстрого ответа, если вы не возражаете против выделения только группами не более 8 строк одновременно, вы можете использовать функцию matchaddpos({group}, {pos}) и создать команду для применения группы highlight к диапазону строк.

command! -range -nargs=1 -complete=highlight HiLine call matchaddpos(<f-args>, range(<line1>,<line2>))

Что вы можете использовать, например, чтобы выделить как 'cursorline' :

:28,30HiLine CursorLine

Обратите внимание, что завершение применяется к аргументу для групп выделения.

Чтобы удалить группу (группы) ранее выделенных строк, вы можете удалить те, которые содержат определенную строку. Я не могу найти более простой способ, чем пройтись по всем getmatches() диктовкам и matchdelete({id}) тем, которые содержат строку на одном из их 'posX' ключей:

function! s:RemoveMatchOnLine(line) abort
  for l:match in getmatches()
    let l:matchlines = values(filter(copy(l:match), 'v:key =~# ''pos\d\+'''))
    if index(l:matchlines, [a:line]) >= 0
      call matchdelete(l:match['id'])
    endif
  endfor
endfunction
command! -nargs=? LoLine call <SID>RemoveMatchOnLine(<q-args> ? <q-args> : line('.'))

Теперь вы можете :LoLine отменить выделение строк рядом с текущей строкой или указать аргумент, чтобы указать другую строку, чтобы вам не приходилось перемещать туда курсор: :LoLine 28.

Наконец, вы можете установить сопоставления:

nnoremap <leader>hi :HiLine CursorLine<CR>
xnoremap <leader>hi :HiLine CursorLine<CR>
nnoremap <leader>hc :<c-u>execute 'LoLine ' . v:count<CR>

При вводе [count]<leader>hi в обычном режиме будет выделено count строк от курсора. А [count]<leader>hc удалит выделение группы строк count.

Приложение

Мы могли бы работать с большими диапазонами, используя matchadd({group}, {pattern}), используя \%xl для соответствия строке x. Замените call matchaddpos(... на

execute 'call matchadd(<f-args>, ''\%'.<line1>.'l\(.*\n\)\+\%'.(<line2>+1).'l'')'

и строки 2 и 3 функции на

let l:a = matchlist(get(l:match,'pattern',''), '^\\%\(\d\+\)l.*\\%\(\d\+\)l$')
if !empty(l:a) && l:a[1] <= a:line && a:line <= l:a[2]

Но для меня это ломается на больших диапазонах, я бы предпочел первое решение, которое кажется более надежным.

person perelo    schedule 12.08.2019
comment
Возможно, вы захотите показать использование с диапазоном для OP - person D. Ben Knoble; 13.08.2019
comment
@D.BenKnoble правильно, отредактировано. Знаете ли вы, почему совпадения регулярных выражений плохо работают на больших расстояниях? например, :%HiLine ... плохо работает в середине буфера или вверху, он выделяет текущий вид, но движется вниз, ничего не выделяется и т. д. - person perelo; 13.08.2019
comment
вероятно, снова недостатки использования регулярных выражений для выделения - person D. Ben Knoble; 13.08.2019