La solución de DJ McMayhem me inspiró a escribir la mía propia que se basa en ctags y matchit para hacer un análisis adecuado de los límites de las funciones.
La parte difícil ya ha sido realizada por lh-dev y lh-tags durante varios años:
- el archivo actual se analiza a través de etiquetas con las opciones correctas
- buscamos todas las definiciones de funciones en la base de datos de etiquetas que está restringida a las etiquetas obtenidas para el archivo actual
- Gracias a la base de datos, tenemos los números de línea de inicio para todas las funciones (bueno, las etiquetas pueden pasar por alto
template
y inline
parte)
- con una búsqueda iterativa simple (podría haberse realizado una búsqueda binaria, pero bueno, se supone que los archivos son "cortos"), se encuentra el comienzo de la función actual
- Y gracias al complemento matchit, su línea final también se encuentra: veo que ctags universales ofrece un
end
campo que se puede usar con C, C ++, Python y Vim que también se puede usar para encontrar el final de una función.
Tenga en cuenta que cualquier parte de este algoritmo podría anularse según el tipo de archivo. es decir, la detección de límites de las funciones de Python podría buscar def
y analizar la sangría, simplemente podríamos buscar function
en javascript, etc. hacer para Python)
Así que defino ahora dos nuevas asignaciones: una asignación de modo visual y una asignación de modo pendiente de operador:
onoremap <silent> if :<c-u>call lh#dev#_select_current_function()<cr>
xnoremap <silent> if :<c-u>call lh#dev#_select_current_function()<cr><esc>gv
Que se basan en:
function! lh#dev#_select_current_function() abort
let fn = lh#dev#find_function_boundaries(line('.'))
exe fn.lines[0]
normal! v
exe fn.lines[1]
endfunction
Te perdono los cientos de líneas de código de lh#dev#find_function_boundaries()
Y gracias al mapeo de DJ McMayhem
" Note that my vim settings requires two backslashes here instead of one
vnoremap / <esc>/\\%V
podemos hacer una vif/pattern
búsqueda pattern
en la función actual.
También podemos eliminar funciones con dif
, tirarlas con yif
, etc.
Así es como se ve cuando se aplica en una función realista de C ++ (es decir, no tiene sangría de 0):
lh#dev#find_function_boundaries
de lh-dev