É possível atribuir um sinal ao grupo "Todo"?

9

É possível adicionar um sinal a ser exibido na coluna de sinais sempre que a linha tiver um grupo ToDo (ToDo, FIXME ...).

Ajustando meu esquema de cores, mudei o destaque do grupo Todo, mas gostaria de ter um indicador na coluna de sinais, como erros e avisos do Syntastic.


fonte

Respostas:

9

Tente esta função:

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

Agora chame a função na linha de comando:

:call SignKeyword()

Ou adicione um mapeamento ~/.vimrcpara chamá-lo:

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

Ou adicione um autocmd. Por exemplo, se você deseja que a função seja chamada automaticamente ao abrir um arquivo cujo tipo de arquivo é remarcado:

autocmd FileType markdown call SignKeyword()

A primeira linha da função silent! sign undefine todoexclui o conjunto de sinais, se ele já existir, para que, se seus sinais forem extraviados após a exclusão ou adição de uma linha, você possa recuperar a função para corrigi-los imediatamente.


A segunda linha define um sinal cujo nome é todo, cujo texto é >>(você pode alterá-lo para se adequar às suas preferências) e que usa o grupo de destaque Pesquisa (a mesma coisa).


A terceira linha usa o comando global:

:g/pattern/command

O comando global executa um comando em todas as linhas que correspondem a um padrão.

Aqui está o padrão \v\C(<TODO>|<FIXME>), o que significa qualquer linha que contenha a palavra TODO ou FIXME .
O regex inclui o átomo \Cpara que a pesquisa respeite o caso (não importa qual seja a sua opção 'caso ignorado'). Se você deseja que a pesquisa não respeite o caso, altere-a para \c.

Sempre que uma linha é encontrada, a seguinte linha é executada pela função:

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

Ele executa (com o :executecomando) o conteúdo da seguinte string:

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

A sequência inclui duas funções internas do vim: line()e bufnr().
line('.')retorna o número da linha atual quando uma correspondência é encontrada pelo comando global e bufnr('.')retorna o número do buffer atual.

Por exemplo, se o comando global encontrar uma correspondência na linha 10 no buffer 5, ele fornecerá:

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

Os pontos concatenam as strings e, por fim, avaliarão:

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

Qual é o :signcomando que coloca um sinal na linha 10 no buffer 5.
9999 é um ID aleatório escolhido para o sinal (você pode escolher outro).


A quarta linha da função :nohlsearchdesativa o realce dos padrões correspondentes.

Edit: Corrigi a regex, o original estava errado. Eu escrevi, ^[TODO|FIXME]mas acho que deveria ser \v\C(<TODO>|<FIXME>). Desculpe pelo transtorno, ainda estou aprendendo vimscript.

saginaw
fonte
11
como remover o sinal depois que o TODOcomentário foi removido?
11
isso não é o que eu esperava, porque isso remove todos os todosinais, mas no entanto só notei que a remoção da linha o sinal é removido, de modo que é ok
11
Ok, eu adicionei esta linha no início da função: silent! sign undefine todo. Exclui o sinal de todo, se ele já existir, para que, se seus sinais forem extraviados após a exclusão de uma linha que contenha a palavra-chave TODO ou FIXME, você poderá recuperar a função para corrigi-los imediatamente.
Saginaw
2
O regex estava errado, digitei, ^[TODO|FIXME]mas deveria estar \v(TODO|FIXME). O novo regex corresponderá a uma linha que contém uma das palavras-chave, mas não o início da linha, pois suponho que uma linha possa conter algum código antes de um comentário, por exemplo, como este some code # FIXME this line needs to be fixed. A regex anterior era completamente errado, muito pelo inconveniente, eu ainda estou aprendendo vimscript ...
Saginaw
11
O problema com essa abordagem é que ela ficará completamente fora de sincronia, se você modificar o buffer, por exemplo, adicione outra linha acima da linha TODO.
Christian Brabandt
6

Você pode usar meu plug-in DynamicSigns . Isso permite o chamado "SignExpression", que é semelhante à expressão da dobra.

Então você pode simplesmente fazer :SignExpression getline(v:lnum)=~'TODO'?'Warning':0

Leia a ajuda para mais exemplos do que é possível.

A vantagem de usar meu plug-in é que ele rastreia as alterações do buffer e ajusta os sinais de acordo.

Christian Brabandt
fonte