Question

À l'heure actuelle, j'ai les éléments suivants dans mon .vimrc :

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

Il y a quelques problèmes avec ceci:

  1. C’est lent - régénère les balises des fichiers qui n’ont pas changé depuis la dernière génération de balises.
  2. Je dois appuyer à nouveau sur le bouton d'entrée après après avoir écrit le fichier, en raison de l'inévitable "appuyez sur la touche Entrée ou tapez la commande pour continuer".

Lorsque vous combinez ces deux problèmes, je finis par pousser trop tôt l'entrée supplémentaire (avant que ctags -R ne soit terminé), puis je vois le message d'erreur gênant et je dois appuyer à nouveau sur entrée.

Je sais que cela ne semble pas très grave, mais avec la quantité d’écritures de fichiers que je fais un jour donné, cela a tendance à être vraiment agaçant. Il doit y avoir une meilleure façon de le faire!

Était-ce utile?

La solution

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

L'inconvénient est que vous ne disposerez pas d'un fichier de balises utile avant la fin. Tant que vous êtes sur un système * nix, il devrait être correct de faire plusieurs écritures avant la fin de la précédente ctags, mais vous devriez le tester. Sur un système Windows, il ne le mettra pas en arrière-plan et se plaindra que le fichier est verrouillé jusqu'à la fin des premières balises (ce qui ne devrait pas causer de problèmes dans vim, mais vous obtiendrez un fichier de balises légèrement obsolète. ).

Notez que vous pouvez utiliser l'option - append comme le suggère tonylo, mais vous devrez ensuite désactiver tagbsearch , ce qui pourrait signifier que les recherches de tags prennent beaucoup plus de temps. , en fonction de la taille de votre fichier de balise.

Autres conseils

Modifier : une solution très semblable au suivant a été publiée sous le nom de AutoTag script vim . Notez que le script nécessite un vim prenant en charge Python , cependant.

Ma solution doit plutôt faire place à awk. Elle devrait donc fonctionner sur de nombreux autres systèmes.

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

Notez que vous ne pouvez l'écrire que de cette façon dans un script, sinon il doit se faire sur une seule ligne.

Il se passe beaucoup de choses là-bas:

  1. Cette commande automatique se déclenche lorsqu'un fichier a été détecté comme étant C ou C ++ et ajoute à son tour une commande automatique tampon-locale déclenchée par l'événement BufWritePost .

  2. Il utilise l’espace réservé % qui est remplacé par le nom de fichier du tampon au moment de l’exécution, ainsi que le modificateur : gs utilisé pour citez le nom du fichier (en transformant les guillemets simples incorporés en quote-escape-quote-quote).

  3. De cette façon, il exécute une commande shell qui vérifie si un fichier tags existe, auquel cas son contenu est imprimé, à l'exception des lignes qui font référence au fichier que vous venez de sauvegarder. < code> ctags est appelé uniquement sur le fichier que vous venez de sauvegarder et le résultat est alors sort édité et remis en place.

Mise en œuvre: nous supposons que tout se trouve dans le même répertoire et qu’il s’agit également du répertoire courant du tampon local. Je n'ai pas réfléchi au chemin qui traîne.

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

Notez que vous ne pouvez l'écrire que de cette façon dans un script, sinon il doit se faire sur une seule ligne.

Il se passe beaucoup de choses là-bas:

  1. Cette commande automatique se déclenche lorsqu'un fichier a été détecté comme étant C ou C ++ et ajoute à son tour une commande automatique tampon-locale déclenchée par l'événement BufWritePost .

  2. Il utilise l’espace réservé % qui est remplacé par le nom de fichier du tampon au moment de l’exécution, ainsi que le modificateur : gs utilisé pour citez le nom du fichier (en transformant les guillemets simples incorporés en quote-escape-quote-quote).

  3. De cette façon, il exécute une commande shell qui vérifie si un fichier tags existe, auquel cas son contenu est imprimé, à l'exception des lignes qui font référence au fichier que vous venez de sauvegarder. < code> ctags est appelé uniquement sur le fichier que vous venez de sauvegarder et le résultat est alors sort édité et remis en place.

Mise en œuvre: nous supposons que tout se trouve dans le même répertoire et qu’il s’agit également du répertoire courant du tampon local. Je n'ai pas réfléchi au chemin qui traîne.

J'ai écrit easytags.vim pour ce faire: mettre à jour automatiquement et surlignez les tags. Le plug-in peut être configuré pour ne mettre à jour que le fichier en cours d'édition ou tous les fichiers du répertoire du fichier en cours d'édition (de manière récursive). Il peut utiliser un fichier de balises globales, des fichiers de balises spécifiques au type de fichier et des fichiers de balises spécifiques au projet.

J'ai remarqué que c'était un vieux fil, cependant ... Utilisez incron dans * nix, comme les environnements prenant en charge inotify. Il lancera toujours des commandes chaque fois que les fichiers d'un répertoire changent. c'est-à-dire

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

C'est tout.

Utilisez peut-être l'argument add to ctags comme indiqué par:

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

Je ne peux pas vraiment en garantir le contenu, car j'utilise généralement l'insight sur les sources pour naviguer dans le code, mais j'utilise vim en tant qu'éditeur ... allez comprendre.

Pourquoi ne pas programmer les balises ctags avec crontab? Si votre arborescence de projet est assez stable dans sa structure, cela devrait être faisable?

Pour supprimer le " appuyez sur Entrée " invite, utilisez : silencieux .

Sous OSX, cette commande ne fonctionnera pas, du moins pour moi.

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

J'ai trouvé un post , qui explique comment obtenir la version standard de ctags contenant l'option -R. Cela seul n'a pas fonctionné pour moi. J'ai dû ajouter / usr / local / bin à la variable PATH dans .bash_profile afin de sélectionner le bac dans lequel Homebrew installe les programmes.

À mon avis, le plugin Indexer est meilleur.

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

Cela peut être:

1) un add-on pour project.tar.gz

2) un plugin indépendant

  • génération de balises d'arrière-plan (vous n'avez pas attendu que ctags fonctionne)
  • projets multiples pris en charge

Il existe un plug-in vim appelé la balise automatique qui fonctionne vraiment. bien.

Si vous avez installé la liste de balises, elle la mettra également à jour pour vous.

L’option - append est vraiment la voie à suivre. Utilisé avec un grep -v , nous ne pouvons mettre à jour qu'un seul fichier balisé . Par exemple, voici un extrait d'un plug-in non poli traitant de ce problème. (Remarque: il faudra un plug-in de bibliothèque externe

.

" 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, '

Ce code définit:

  • ^ Xta pour forcer la mise à jour de la base de balises pour tous les fichiers du projet en cours;
  • ^ Xtc pour forcer la mise à jour de la base de balises pour le fichier actuel (non enregistré);
  • une autocommande qui met à jour la base de balises chaque fois qu'un fichier est enregistré; et il prend en charge de nombreuses options pour désactiver la mise à jour automatique là où nous ne le voulons pas, pour ajuster les appels ctags en fonction des types de fichiers, ... Ce n’est pas seulement un conseil, mais un petit extrait d’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

Ce code définit:

  • ^ Xta pour forcer la mise à jour de la base de balises pour tous les fichiers du projet en cours;
  • ^ Xtc pour forcer la mise à jour de la base de balises pour le fichier actuel (non enregistré);
  • une autocommande qui met à jour la base de balises chaque fois qu'un fichier est enregistré; et il prend en charge de nombreuses options pour désactiver la mise à jour automatique là où nous ne le voulons pas, pour ajuster les appels ctags en fonction des types de fichiers, ... Ce n’est pas seulement un conseil, mais un petit extrait d’un plugin.

HTH,

Auto Tag est un plug-in vim qui met à jour les fichiers de balises existants lors de l'enregistrement.

Je l'utilise depuis des années sans problèmes, à l'exception du fait qu'il impose une taille maximale aux fichiers de balises. Sauf si vous avez un très grand ensemble de codes indexés dans le même fichier de balises, vous ne devriez pas atteindre cette limite, cependant.

Notez que Auto Tag requiert la prise en charge de Python dans vim.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top