La soluzione di DJ McMayhem mi ha ispirato a scrivere il mio che si basa su tag e matchit per fare una corretta analisi dei confini delle funzioni.
La parte difficile è già stata fatta da lh-dev e lh-tag da diversi anni:
- il file corrente viene analizzato tramite tag con le giuste opzioni
- cerchiamo tutte le definizioni delle funzioni nel database dei tag che è limitato ai tag ottenuti per il file corrente
- grazie al DB, abbiamo i numeri della linea di partenza per tutte le funzioni (beh, la parte
templatee inlinepuò essere mancata dai tag)
- con una semplice ricerca iterativa (avrebbe potuto essere eseguita una ricerca binaria, ma si suppone che i file siano "brevi"), si trova l'inizio della funzione corrente
- E grazie al plug-in matchit, viene trovata anche la sua riga finale - vedo che ctags universali offre un
endcampo che può essere usato con C, C ++, Python e Vim che potrebbe anche essere usato per trovare la fine di una funzione.
Si noti che qualsiasi parte di questo algoritmo potrebbe essere sovrascritta in base al tipo di file. cioè il rilevamento dei limiti delle funzioni di Python potrebbe cercare defe analizzare il rientro, potremmo semplicemente cercare functionin javascript e così via - In altre parole, la versione corrente funziona anche con Java, Vim e alcune altre lingue (ho ancora del lavoro fare per Python)
Quindi definisco ora due nuovi mapping: un mapping in modalità visiva e un mapping in modalità operatore in sospeso:
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
Che si basano su:
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
Ti risparmio le diverse centinaia di righe di codice di lh#dev#find_function_boundaries()
E grazie alla mappatura di DJ McMayhem
" Note that my vim settings requires two backslashes here instead of one
vnoremap / <esc>/\\%V
possiamo fare un vif/patternper cercare patternnella funzione corrente.
Possiamo anche eliminare le funzioni con dif, strapparle con yif, ecc.
Ecco come appare se applicato su una funzione C ++ realistica (ovvero non indentata):
lh#dev#find_function_boundariesdi lh-dev