¿Es posible asignar un signo al grupo "Todo"?

9

¿Es posible agregar un signo para que se muestre en la columna de signos siempre que la línea tenga un grupo de tareas pendientes (ToDo, FIXME ...).

Al ajustar mi esquema de colores, cambié el punto culminante del grupo Todo, pero me gustaría tener un indicador en la columna de signos, como Errores y advertencias fantásticos.


fuente

Respuestas:

9

Prueba esta función:

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

Ahora llame a la función en la línea de comando:

:call SignKeyword()

O agregue un mapeo en su ~/.vimrcpara llamarlo:

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

O agregue un autocmd. Por ejemplo, si desea que se llame automáticamente a la función al abrir un archivo cuyo tipo de archivo es markdown:

autocmd FileType markdown call SignKeyword()

La primera línea de la función silent! sign undefine todoelimina el signo todo si ya existe, de modo que si sus signos están fuera de lugar después de eliminar o agregar una línea, puede recuperar la función para corregirlos de inmediato.


La segunda línea define un signo cuyo nombre es todo, cuyo texto es >>(puede cambiarlo según sus preferencias) y que utiliza el grupo de resaltado Buscar (lo mismo).


La tercera línea usa el comando global:

:g/pattern/command

El comando global ejecuta un comando en cada línea que coincide con un patrón.

Aquí el patrón es \v\C(<TODO>|<FIXME>), lo que significa cualquier línea que contenga la palabra TODO o FIXME .
La expresión regular incluye el átomo \Cpara que la búsqueda respete el caso (no importa cuál sea su opción 'ignorecase'). Si desea que la búsqueda no respete el caso, cámbielo a \c.

Cada vez que se encuentra dicha línea, la función ejecuta la siguiente línea:

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

Ejecuta (con el :executecomando) el contenido de la siguiente cadena:

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

La cadena incluye dos funciones integradas de vim: line()y bufnr().
line('.')devuelve el número de la línea actual cuando el comando global encuentra una coincidencia y bufnr('.')devuelve el número del búfer actual.

Entonces, por ejemplo, si el comando global encuentra una coincidencia en la línea 10 en el búfer 5, dará:

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

Los puntos concatenan las cadenas, por lo que finalmente se evaluará para:

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

Cuál es el :signcomando que coloca un signo en la línea 10 en el búfer 5.
9999 es una identificación aleatoria elegida para el signo (puede elegir otro).


La cuarta línea de la función :nohlsearchdesactiva el resaltado de los patrones coincidentes.

Editar: arreglé la expresión regular, el original estaba equivocado. Escribí ^[TODO|FIXME]pero en cambio creo que debería ser \v\C(<TODO>|<FIXME>). Disculpe las molestias, todavía estoy aprendiendo vimscript.

Saginaw
fuente
1
¿Cómo eliminar el signo una vez que TODOse ha eliminado el comentario?
1
eso no es lo que esperaba, ya que eliminan todas las todoseñales, pero sin embargo he dado cuenta de que la eliminación de la línea se elimina el signo, por lo que está bien
1
Ok, he añadido esta línea al principio de la función: silent! sign undefine todo. Elimina el signo todo si ya existe, de modo que si sus signos están fuera de lugar después de eliminar una línea que contiene la palabra clave TODO o FIXME, puede recuperar la función para corregirlos de inmediato.
Saginaw
2
La expresión regular estaba mal, escribí ^[TODO|FIXME]pero en su lugar debería haberlo estado \v(TODO|FIXME). La nueva expresión regular coincidirá con una línea que contenga una de las palabras clave, pero no con el comienzo de la línea, ya que supongo que una línea podría contener algún código antes de un comentario, por ejemplo, como este some code # FIXME this line needs to be fixed. La expresión regular anterior estaba completamente equivocada, disculpen las molestias, todavía estoy aprendiendo vimscript ...
saginaw
1
El problema con este enfoque es que se sincronizará rápidamente si modifica el búfer, por ejemplo, agregue otra línea por encima de una línea TODO.
Christian Brabandt
6

Puedes usar mi complemento DynamicSigns . Esto permite los llamados "SignExpression", que son similares a la expresión de pliegue.

Entonces puedes simplemente hacer :SignExpression getline(v:lnum)=~'TODO'?'Warning':0

Lea la ayuda para obtener más ejemplos de lo que es posible.

La ventaja de usar mi complemento es que rastrea los cambios del búfer y ajusta los signos en consecuencia.

Christian Brabandt
fuente