Можно ли присвоить знак группе «Тодо»?

9

Можно ли добавить знак для отображения в столбце знаков, если в строке есть группа ToDo (ToDo, FIXME ...).

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


источник

Ответы:

9

Попробуйте эту функцию:

function! SignKeyword()

    silent! sign undefine todo

    sign define todo text=>> texthl=Search

    g/\v\C(<TODO>|<FIXME>)/execute "sign place 9999 line=" . line('.')
    \ . " name=todo buffer=" . bufnr('')

    nohlsearch

endfunction

Теперь вызовите функцию в командной строке:

:call SignKeyword()

Или добавьте отображение в вашем, ~/.vimrcчтобы назвать это:

nnoremap <your mapping> :call SignKeyword()<cr>

Или добавьте autocmd. Например, если вы хотите, чтобы функция вызывалась автоматически при открытии файла, тип файла которого имеет разметку:

autocmd FileType markdown call SignKeyword()

Первая строка функции silent! sign undefine todoудаляет знак todo, если он уже существует, так что, если ваши знаки смещены после удаления или добавления строки, вы можете вызвать функцию, чтобы исправить их немедленно.


Вторая строка определяет знак, имя которого todo, текст которого >>(вы можете изменить его в соответствии со своими предпочтениями) и который использует группу подсветки поиска (тоже самое).


Третья строка использует глобальную команду:

:g/pattern/command

Глобальная команда выполняет команду в каждой строке, которая соответствует шаблону.

Здесь шаблон \v\C(<TODO>|<FIXME>), который означает любую строку, содержащую либо слово TODO, либо FIXME .
Регулярное выражение включает атом, \Cтак что поиск учитывает регистр (независимо от того, какая у вас опция «ignorecase»). Если вы хотите, чтобы поиск не соответствовал случаю, измените его на \c.

Всякий раз, когда такая строка найдена, функция выполняет следующую строку:

execute "sign place 9999 line=" . line('.')
    \ . " name=todo buffer=" . bufnr('')

Он выполняет (с помощью :executeкоманды) содержимое следующей строки:

"sign place 9999 line=" . line('.') . " name=todo buffer=" . bufnr('')

Строка включает две встроенные функции vim: line()и bufnr().
line('.')возвращает номер текущей строки, когда глобальная команда находит совпадение, и bufnr('.')возвращает номер текущего буфера.

Так, например, если глобальная команда находит совпадение в строке 10 в буфере 5, она выдаст:

"sign place 9999 line=" . 10 . " name=todo buffer=" . 5

Точки объединяют строки, и, в конечном итоге, они будут оцениваться следующим образом:

"sign place 9999 line=10 name=todo buffer=5"

Это :signкоманда размещения знака в строке 10 в буфере 5.
9999 - это случайный идентификатор, выбранный для знака (вы можете выбрать другой).


Четвертая строка функции :nohlsearchотключает подсветку совпавших шаблонов.

Изменить: я исправил регулярное выражение, оригинал был неправ. Я написал, ^[TODO|FIXME]но вместо этого я думаю, что это должно быть \v\C(<TODO>|<FIXME>). Извините за неудобства, я все еще изучаю vimscript.

Сагино
источник
1
как убрать подпись после удаления TODOкомментария?
1
это не то, что я ожидал, потому что это удаляет все todoзнаки, но, тем не менее, только что заметил, что при удалении строки знак удаляется, так что все в порядке
1
Хорошо, я добавил эту строку в начале функции: silent! sign undefine todo. Он удаляет знак todo, если он уже существует, поэтому, если после удаления строки, содержащей ключевое слово TODO или FIXME, ваши знаки будут смещены, вы можете вызвать функцию, чтобы исправить их немедленно.
saginaw
2
Регулярное выражение было неправильно, я напечатал, ^[TODO|FIXME]но вместо этого должно было быть \v(TODO|FIXME). Новое регулярное выражение будет соответствовать строке, содержащей одно из ключевых слов, но не начало строки, так как я предполагаю, что строка может содержать некоторый код перед комментарием, например, как этот some code # FIXME this line needs to be fixed. Предыдущее регулярное выражение было полностью неверным, извините за неудобства, я все еще изучаю vimscript ...
saginaw
1
Проблема с этим подходом состоит в том, что он будет быстро не синхронизирован, если вы измените буфер, например добавите еще одну строку над строкой TODO.
Кристиан Брабандт
6

Вы можете использовать мой плагин DynamicSigns . Это позволяет использовать так называемое SignExpression, которое похоже на выражение сгиба.

Так что вы можете просто сделать :SignExpression getline(v:lnum)=~'TODO'?'Warning':0

Прочитайте справку для большего количества примеров того, что возможно.

Преимущество использования моего плагина в том, что он отслеживает изменения в буфере и соответствующим образом корректирует знаки.

Кристиан Брабандт
источник