Esiste un modo per cercare una stringa in un file sorgente C/C++ mentre si saltano le righe commentate?Ricerca Vim nelle righe di codice C/C++
risposta
Questa è una domanda intrigante.
Penso che @sixtyfootersdude abbia l'idea giusta - lascia che l'evidenziazione della sintassi di Vim ti dica cos'è un commento e cosa no, quindi cerca le corrispondenze all'interno dei non-commenti.
Cominciamo con una funzione che imita Vim di built-in search()
di routine, ma fornisce anche un "saltare" il parametro di lasciar ignorare alcuni incontri:
function! SearchWithSkip(pattern, flags, stopline, timeout, skip)
"
" Returns true if a match is found for {pattern}, but ignores matches
" where {skip} evaluates to false. This allows you to do nifty things
" like, say, only matching outside comments, only on odd-numbered lines,
" or whatever else you like.
"
" Mimics the built-in search() function, but adds a {skip} expression
" like that available in searchpair() and searchpairpos().
" (See the Vim help on search() for details of the other parameters.)
"
" Note the current position, so that if there are no unskipped
" matches, the cursor can be restored to this location.
"
let l:matchpos = getpos('.')
" Loop as long as {pattern} continues to be found.
"
while search(a:pattern, a:flags, a:stopline, a:timeout) > 0
" If {skip} is true, ignore this match and continue searching.
"
if eval(a:skip)
continue
endif
" If we get here, {pattern} was found and {skip} is false,
" so this is a match we don't want to ignore. Update the
" match position and stop searching.
"
let l:matchpos = getpos('.')
break
endwhile
" Jump to the position of the unskipped match, or to the original
" position if there wasn't one.
"
call setpos('.', l:matchpos)
endfunction
Ecco un paio di funzioni che costruire su SearchWithSkip()
per implementare le ricerche di sintassi sensibili:
function! SearchOutside(synName, pattern)
"
" Searches for the specified pattern, but skips matches that
" exist within the specified syntax region.
"
call SearchWithSkip(a:pattern, '', '', '',
\ 'synIDattr(synID(line("."), col("."), 0), "name") =~? "' . a:synName . '"')
endfunction
function! SearchInside(synName, pattern)
"
" Searches for the specified pattern, but skips matches that don't
" exist within the specified syntax region.
"
call SearchWithSkip(a:pattern, '', '', '',
\ 'synIDattr(synID(line("."), col("."), 0), "name") !~? "' . a:synName . '"')
endfunction
Qui sono comandi che rendono le sintassi sensibili funzioni di ricerca più facile da usare:
command! -nargs=+ -complete=command SearchOutside call SearchOutside(<f-args>)
command! -nargs=+ -complete=command SearchInside call SearchInside(<f-args>)
E 'stata una lunga strada da percorrere, ma ora siamo in grado di fare cose come questa:
:SearchInside String hello
che cerca hello
, ma solo all'interno del testo che Vim considera una stringa.
E (! Finalmente) Questo cerca double
ovunque tranne commenti:
:SearchOutside Comment double
Per ripetere una ricerca, utilizzare la macro @:
per eseguire lo stesso comando più volte, come premendo n
per ripetere una ricerca.
(Grazie per questa domanda, tra l'altro. Ora che ho costruito queste routine, mi aspetto di utilizzare loro un sacco.)
Ecco come vorrei procedere:
- Cancella Commenti Tutto C/C++ (utilizzando il sostituire comando
%s
) - Procedere alla ricerca utilizzando ricerca normale comando
/
- Set a mark nella posizione che utilizza
m a
(per impostare il segno "a") - annullare l'eliminazione dei commenti utilizzando
u
- Vai al marchio "a" utilizzando `` a`
- eliminazione Alla fine il marchio utilizzando
delm a
(sarebbe sovrascritto nel caso in cui non elimina, in modo che nessun grosso affare)
Naturalmente è possibile farlo in un'unica grande operazione/funzione. Non ho padronanza degli script di Vim abbastanza da dare un esempio di ciò.
Ammetto che la mia soluzione è un po '"pigra" (e probabilmente lo puoi fare modo meglio) ma questo è tutto quello che ho trovato.
Spero che aiuti.
Spero che ci sia un modo più adatto, ma meglio che niente .. :-) –
Piuttosto pericoloso se me lo chiedi. –
@Ken Bloom: una vita senza pericolo deve essere piuttosto noiosa no ?! ;) – ereOn
Questo modello cerca una stringa che non sia preceduta dalle due convenzioni di commento C++. Ho anche escluso "*" come il primo carattere non di spazio bianco, poiché si tratta di una convenzione comune per i commenti su più righe.
/\(\(\/\*\|\/\/\|^\s*\*[^/]\).*\)\@<!foo
Solo il primo e il quarto foo sono abbinati.
foo
/* foo
* baz foo
*/ foo
// bar baz foo
Mettere \ v all'inizio del modello elimina un gruppo di backslash:
/\v((\/\*|\/\/|^\s*\*[^/]).*)@<!foo
È possibile associare un tasto di scelta rapida a questo modello mettendo questo nel vostro .vimrc
"ctrl+s to search uncommented code
noremap <c-s> <c-o>/\v((\/\*\|\/\/\|^\s*\*[^/]).*)@<!
Intelligente, bello e semplice. – ereOn
Funziona anche con 'hlsearch' –
non funziona con alcuni commenti/* */commenti senza una stella all'inizio della riga. –
Non so se questo è utile ma whe n digiti :syn
ha tutta la formattazione usata nel tuo tipo di file. Forse puoi riferirti in qualche modo. Potresti dire qualcosa come:
map n betterN
function betterN{
n keystroke
while currentLine matches comment class
do another n keystroke
}
- 1. Ricerca e sostituzione Vim: confinare su alcune righe
- 2. Ricerca incrementale Vim
- 3. Ricerca e sostituzione VIM
- 4. Completamento del codice Vim
- 5. Vim: evidenzia le righe modificate
- 6. Ricerca di variabili inutilizzate nelle viste CakePHP
- 7. vim phpdoc righe commento autoindent
- 8. vim: ricerca e sostituzione per "&"
- 9. Vim ricerca incrementale risultato successivo
- 10. Vim - Rientro di più righe con scheda
- 11. Come eliminare le righe attorno a un modello di ricerca in vim?
- 12. Testo di ricerca Vim nella cartella
- 13. Vim di ricerca e sostituzione efficienza
- 14. Ricerca di righe comuni in R
- 15. Come inserire il codice in più righe in un codice di più righe?
- 16. Utilizzo delle barre rovesciate nelle abbreviazioni vim
- 17. Ricerca di righe duplicate in excel
- 18. Copia righe in modalità visiva in vim
- 19. Funzionamento CC-Tray
- 20. Ricerca offset di simboli locali nelle librerie condivise a livello di codice su OS X
- 21. PHP Mail, CC Field
- 22. Correzione di righe di commento troppo lunghe in Vim
- 23. indentazione di un gruppo di righe in VIM
- 24. Come concatenare rapidamente due righe in Vim?
- 25. Taglia e incolla più righe in vim
- 26. VIM .. Yank più righe basate su regex
- 27. Gruppo T-SQL righe nelle colonne
- 28. Salva i dati modificati nelle righe
- 29. Come eliminare l'evidenziazione della ricerca in Vim
- 30. In Emacs come operare (cioè ricerca) solo nelle regioni di codice?
Grazie per la tua * ottima * risposta. Mi aspetto di usarli molto :-) –
Questo è fantastico! C'è un piccolo problema, però. Se la stringa di ricerca si trova nel file, ma solo in luoghi che vengono saltati, si ottiene un ciclo infinito. Puoi sistemarlo mettendo una guardia in posizione. Sopra il ciclo: 'let l: guard = []'. Quindi nel ciclo: 'if l: guard == [] | let l: guard = getpos ('.') | elseif l: guard == getpos ('.') | pausa | endif'. –
Questo è davvero fantastico. Nota che puoi escludere più SynNames con 'SearchOutside Comment \\\\ | String double', yes hai bisogno di quattro backslash per uscire dalla pipe. – Drasill