Domanda

In questo momento ho il seguente nel mio .vimrc :

au BufWritePost *.c,*.cpp,*.h !ctags -R

Ci sono alcuni problemi con questo:

  1. È lento: rigenera i tag per i file che non sono stati modificati dall'ultima generazione di tag.
  2. Devo premere di nuovo il pulsante Invio di nuovo dopo aver scritto il file a causa di un inevitabile "quot", premi Invio o digita il comando per continuare " ;.

Quando combini questi due problemi, finisco per inviare l'ulteriore invio troppo presto (prima che ctags -R sia terminato), quindi vedo il fastidioso messaggio di errore e devo premere di nuovo Invio.

So che non sembra un grosso problema, ma con la quantità di scritture di file che faccio in un dato giorno, tende a diventare davvero fastidioso. Deve esserci un modo migliore per farlo!

È stato utile?

Soluzione

au BufWritePost * .c, *. cpp, *. h silent! ! ctags -R & amp;

Il rovescio della medaglia è che non avrai un utile file tag fino al suo completamento. Finché sei su un sistema * nix dovrebbe essere ok fare più scritture prima che i tag precedenti siano stati completati, ma dovresti testarlo. Su un sistema Windows non lo metterà in background e si lamenterà che il file è bloccato fino al termine dei primi tag (il che non dovrebbe causare problemi in VIM, ma finirai con un file tag leggermente obsoleto ).

Nota, potresti usare l'opzione --append come suggerisce tonylo, ma poi dovrai disabilitare tagbsearch il che potrebbe significare che le ricerche di tag impiegano molto più tempo , a seconda della dimensione del file tag.

Altri suggerimenti

Modifica : una soluzione molto simile a quanto segue è stata pubblicata come the AutoTag vim script . Nota che lo script ha bisogno di un vim con supporto Python , tuttavia.

La mia soluzione si esegue invece su awk, quindi dovrebbe funzionare su molti più sistemi.


au FileType {c,cpp} au BufWritePost <buffer> silent ! [ -e tags ] &&
    \ ( awk -F'\t' '$2\!="%:gs/'/'\''/"{print}' tags ; ctags -f- '%:gs/'/'\''/' )
    \ | sort -t

Nota che puoi scrivere in questo modo solo in uno script, altrimenti deve andare su una sola riga.

Ci sono molte cose in corso lì dentro:

  1. Questo comando automatico si attiva quando un file è stato rilevato come C o C ++ e aggiunge a sua volta un comando automatico locale buffer che viene attivato dall'evento BufWritePost .

  2. Utilizza il segnaposto % che viene sostituito dal nome file del buffer al momento dell'esecuzione, insieme al modificatore : gs usato per shell- citare il nome del file (trasformando le virgolette singole incorporate in quote-escape-quote-quote).

  3. In questo modo esegue un comando di shell che controlla se esiste un file tags , nel qual caso il suo contenuto viene stampato ad eccezione delle righe che si riferiscono al file appena salvato, nel frattempo < code> ctags viene invocato solo sul file appena salvato e il risultato viene quindi sort ed ed è rimesso a posto.

Implementatore Caveat: questo presuppone che tutto sia nella stessa directory e che sia anche la directory corrente buffer-local. Non ho pensato a un percorso di demolizione.

\t' -k1,1 -o tags.new && mv tags.new tags

Nota che puoi scrivere in questo modo solo in uno script, altrimenti deve andare su una sola riga.

Ci sono molte cose in corso lì dentro:

  1. Questo comando automatico si attiva quando un file è stato rilevato come C o C ++ e aggiunge a sua volta un comando automatico locale buffer che viene attivato dall'evento BufWritePost .

  2. Utilizza il segnaposto % che viene sostituito dal nome file del buffer al momento dell'esecuzione, insieme al modificatore : gs usato per shell- citare il nome del file (trasformando le virgolette singole incorporate in quote-escape-quote-quote).

  3. In questo modo esegue un comando di shell che controlla se esiste un file tags , nel qual caso il suo contenuto viene stampato ad eccezione delle righe che si riferiscono al file appena salvato, nel frattempo < code> ctags viene invocato solo sul file appena salvato e il risultato viene quindi sort ed ed è rimesso a posto.

Implementatore Caveat: questo presuppone che tutto sia nella stessa directory e che sia anche la directory corrente buffer-local. Non ho pensato a un percorso di demolizione.

Ho scritto easytags.vim per fare proprio questo: aggiorna automaticamente ed evidenziare i tag. Il plug-in può essere configurato per aggiornare solo il file in fase di modifica o tutti i file nella directory del file in fase di modifica (ricorsivamente). Può utilizzare un file di tag globale, file di tag specifici per tipo di file e file di tag specifici del progetto.

Ho notato che questo è un vecchio thread, tuttavia ... Usa incron in * nix come ambienti che supportano inotify. Avvierà sempre i comandi ogni volta che cambiano i file in una directory. cioè.,

/home/me/Code/c/that_program IN_DELETE,IN_CLOSE_WRITE ctags --sort=yes *.c

Questo è tutto.

Forse usa l'argomento append per ctags come dimostrato da:

http://vim.wikia.com/wiki/Autocmd_to_update_ctags_file

Non posso davvero garantirlo, dato che generalmente utilizzo informazioni sul codice sorgente per la navigazione del codice, ma uso vim come editor ... vai a capire.

Che ne dici di avere pianificato l'esecuzione dei tag tramite crontab? Se l'albero del progetto è abbastanza stabile nella sua struttura, dovrebbe essere fattibile?

Per eliminare " premi Invio " prompt, usa : silent .

Su OSX questo comando non funzionerà immediatamente, almeno non per me.

au BufWritePost *.c,*.cpp,*.h silent! !ctags -R &

Ho trovato un post , che spiega come ottenere la versione standard di ctags che contiene l'opzione -R. Questo da solo non ha funzionato per me. Ho dovuto aggiungere / usr / local / bin alla variabile PATH in .bash_profile per raccogliere il cestino in cui Homebrew installa i programmi.

A mio avviso, il plug-in Indexer è migliore.

http://www.vim.org/scripts/script.php? script_id = 3221

Può essere:

1) un componente aggiuntivo per project.tar.gz

2) un plugin indipendente

  • generazione di tag in background (non hai aspettato che ctags funzioni)
  • progetti multipli supportati

Esiste un plugin vim chiamato AutoTag per questo che funziona davvero bene.

Se hai installato la taglist, aggiornerà anche quella per te.

L'opzione --append è davvero la strada da percorrere. Utilizzato con un grep -v , possiamo aggiornare solo un file taggato . Ad esempio, ecco un estratto di un plugin non lucidato che risolve questo problema. (NB: richiederà un " external " plugin della libreria )

" Options {{{1
let g:tags_options_cpp = '--c++-kinds=+p --fields=+imaS --extra=+q'

function! s:CtagsExecutable()
  let tags_executable = lh#option#Get('tags_executable', s:tags_executable, 'bg')
  return tags_executable
endfunction

function! s:CtagsOptions()
  let ctags_options = lh#option#Get('tags_options_'.&ft, '')
  let ctags_options .= ' '.lh#option#Get('tags_options', '', 'wbg')
  return ctags_options
endfunction

function! s:CtagsDirname()
  let ctags_dirname = lh#option#Get('tags_dirname', '', 'b').'/'
  return ctags_dirname
endfunction

function! s:CtagsFilename()
  let ctags_filename = lh#option#Get('tags_filename', 'tags', 'bg')
  return ctags_filename
endfunction

function! s:CtagsCmdLine(ctags_pathname)
  let cmd_line = s:CtagsExecutable().' '.s:CtagsOptions().' -f '.a:ctags_pathname
  return cmd_line
endfunction


" ######################################################################
" Tag generating functions {{{1
" ======================================================================
" Interface {{{2
" ======================================================================
" Mappings {{{3
" inoremap <expr> ; <sid>Run('UpdateTags_for_ModifiedFile',';')

nnoremap <silent> <Plug>CTagsUpdateCurrent :call <sid>UpdateCurrent()<cr>
if !hasmapto('<Plug>CTagsUpdateCurrent', 'n')
  nmap <silent> <c-x>tc  <Plug>CTagsUpdateCurrent
endif

nnoremap <silent> <Plug>CTagsUpdateAll     :call <sid>UpdateAll()<cr>
if !hasmapto('<Plug>CTagsUpdateAll', 'n')
  nmap <silent> <c-x>ta  <Plug>CTagsUpdateAll
endif


" ======================================================================
" Auto command for automatically tagging a file when saved {{{3
augroup LH_TAGS
  au!
  autocmd BufWritePost,FileWritePost * if ! lh#option#Get('LHT_no_auto', 0) | call s:Run('UpdateTags_for_SavedFile') | endif
aug END

" ======================================================================
" Internal functions {{{2
" ======================================================================
" generate tags on-the-fly {{{3
function! UpdateTags_for_ModifiedFile(ctags_pathname)
  let source_name    = expand('%')
  let temp_name      = tempname()
  let temp_tags      = tempname()

  " 1- purge old references to the source name
  if filereadable(a:ctags_pathname)
    " it exists => must be changed
    call system('grep -v "  '.source_name.' " '.a:ctags_pathname.' > '.temp_tags.
      \ ' && mv -f '.temp_tags.' '.a:ctags_pathname)
  endif

  " 2- save the unsaved contents of the current file
  call writefile(getline(1, '

Questo codice definisce:

  • ^ Xta per forzare l'aggiornamento della base di tag per tutti i file nel progetto corrente;
  • ^ Xtc per forzare l'aggiornamento della base di tag per il file corrente (non salvato);
  • un comando automatico che aggiorna la base dei tag ogni volta che viene salvato un file; e supporta e molte opzioni per disabilitare l'aggiornamento automatico dove non lo vogliamo, per ottimizzare le chiamate ctags a seconda dei tipi di file, ... Non è solo un suggerimento, ma un piccolo estratto di un plugin.

HTH,

), temp_name, 'b') " 3- call ctags, and replace references to the temporary source file to the " real source file let cmd_line = s:CtagsCmdLine(a:ctags_pathname).' '.source_name.' --append' let cmd_line .= ' && sed "s#\t'.temp_name.'\t#\t'.source_name.'\t#" > '.temp_tags let cmd_line .= ' && mv -f '.temp_tags.' '.a:ctags_pathname call system(cmd_line) call delete(temp_name) return ';' endfunction " ====================================================================== " generate tags for all files {{{3 function! s:UpdateTags_for_All(ctags_pathname) call delete(a:ctags_pathname) let cmd_line = 'cd '.s:CtagsDirname() " todo => use project directory " let cmd_line .= ' && '.s:CtagsCmdLine(a:ctags_pathname).' -R' echo cmd_line call system(cmd_line) endfunction " ====================================================================== " generate tags for the current saved file {{{3 function! s:UpdateTags_for_SavedFile(ctags_pathname) let source_name = expand('%') let temp_tags = tempname() if filereadable(a:ctags_pathname) " it exists => must be changed call system('grep -v " '.source_name.' " '.a:ctags_pathname.' > '.temp_tags.' && mv -f '.temp_tags.' '.a:ctags_pathname) endif let cmd_line = 'cd '.s:CtagsDirname() let cmd_line .= ' && ' . s:CtagsCmdLine(a:ctags_pathname).' --append '.source_name " echo cmd_line call system(cmd_line) endfunction " ====================================================================== " (public) Run a tag generating function {{{3 function! LHTagsRun(tag_function) call s:Run(a:tag_function) endfunction " ====================================================================== " (private) Run a tag generating function {{{3 " See this function as a /template method/. function! s:Run(tag_function) try let ctags_dirname = s:CtagsDirname() if strlen(ctags_dirname)==1 throw "tags-error: empty dirname" endif let ctags_filename = s:CtagsFilename() let ctags_pathname = ctags_dirname.ctags_filename if !filewritable(ctags_dirname) && !filewritable(ctags_pathname) throw "tags-error: ".ctags_pathname." cannot be modified" endif let Fn = function("s:".a:tag_function) call Fn(ctags_pathname) catch /tags-error:/ " call lh#common#ErrorMsg(v:exception) return 0 finally endtry echo ctags_pathname . ' updated.' return 1 endfunction function! s:Irun(tag_function, res) call s:Run(a:tag_function) return a:res endfunction " ====================================================================== " Main function for updating all tags {{{3 function! s:UpdateAll() let done = s:Run('UpdateTags_for_All') endfunction " Main function for updating the tags from one file {{{3 " @note the file may be saved or "modified". function! s:UpdateCurrent() if &modified let done = s:Run('UpdateTags_for_ModifiedFile') else let done = s:Run('UpdateTags_for_SavedFile') endif endfunction

Questo codice definisce:

  • ^ Xta per forzare l'aggiornamento della base di tag per tutti i file nel progetto corrente;
  • ^ Xtc per forzare l'aggiornamento della base di tag per il file corrente (non salvato);
  • un comando automatico che aggiorna la base dei tag ogni volta che viene salvato un file; e supporta e molte opzioni per disabilitare l'aggiornamento automatico dove non lo vogliamo, per ottimizzare le chiamate ctags a seconda dei tipi di file, ... Non è solo un suggerimento, ma un piccolo estratto di un plugin.

HTH,

Auto Tag è un plugin vim che aggiorna i file tag esistenti al momento del salvataggio.

Lo uso da anni senza problemi, con l'eccezione che applica una dimensione massima ai file dei tag. A meno che tu non abbia un set molto grande di codice tutti indicizzati nello stesso file di tag, non dovresti raggiungere questo limite.

Nota che Auto Tag richiede il supporto Python in vim.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top