Pergunta

Agora eu tenho o seguinte no meu .vimrc:

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

Existem alguns problemas com isso:

  1. É lento -. Regenera etiquetas para arquivos que não foram alterados desde a última geração tag
  2. Eu tenho que apertar o botão de entrar novamente após gravar o arquivo por causa de uma inevitável "pressione Enter ou digite o comando para continuar".

Quando você combina essas duas questões que acabam empurrando o adicional entrar muito cedo (antes ctags -R tem terminado), em seguida, a mensagem de erro irritante, e tem que empurrar entrar novamente.

Eu sei que não soa como um grande negócio, mas com a quantidade de arquivos grava I fazer em um determinado dia ele tende a ficar muito chato. Tem que haver uma maneira melhor de fazê-lo!

Foi útil?

Solução

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

A desvantagem é que você não vai ter um arquivo de tags úteis até completar. Enquanto você está em um sistema * nix que deve ser ok fazer várias gravações antes dos ctags anteriores foi concluída, mas você deve testar isso. Em um sistema Windows que não vai colocá-lo no fundo e ele vai se queixam de que o arquivo está bloqueado até que os primeiros CTags acabamentos (que não deve causar problemas no vim, mas você vai acabar com um arquivo de tags ligeiramente ultrapassada ).

Note, você pode usar a opção --append como tonylo sugere, mas, em seguida, você terá que desativar tagbsearch que poderia significar que pesquisas tag levar muito mais tempo, dependendo do tamanho do seu arquivo de tag.

Outras dicas

Editar : Uma solução muito ao longo das linhas da seguinte já foi registada como o o marca de formatação automática vim roteiro . Note que o script precisa de um vim com suporte Python , no entanto.

A minha solução conchas fora de awk vez, assim que deve funcionar em muitos mais sistemas.


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

Note que você só pode escrever desta maneira em um script, caso contrário, ele tem que ir em uma única linha.

Há muita coisa acontecendo lá:

  1. Este auto-comando gatilhos quando um arquivo foi detectado a ser C ou C ++, e acrescenta, por sua vez um auto-comando tampão-local que é disparada pelo evento BufWritePost.

  2. Ele usa o espaço reservado % que é substituído pelo nome do arquivo do tampão em tempo de execução, juntamente com o modificador :gs usado para shell de citar o nome do arquivo (rodando qualquer aspas simples incorporados Citação-escape-apóstrofo-apóstrofo ).

  3. Dessa forma, ele executa um comando shell que verifica se existe um arquivo tags, caso em que o seu conteúdo é impresso exceto para as linhas que se referem ao arquivo recém-salvo, entretanto ctags é invocado apenas na só- arquivo salvo, eo resultado é então sorted e colocar de volta no lugar.

Caveat implementador: isso pressupõe que tudo está no mesmo diretório e que esse também é o diretório atual buffer local. Eu não dei qualquer pensamento para mangling caminho.

Eu escrevi easytags.vim para fazer exatamente isso: atualização automaticamente e as marcas de destaque. O plug-in pode ser configurado para atualizar apenas o arquivo que está sendo editado ou todos os arquivos no diretório do arquivo que está sendo editado (de forma recursiva). Ele pode usar um arquivo de tags global, tipo de arquivo arquivos de tags específicas e arquivos de tags específicas do projeto.

Tenho notado esta é uma discussão antiga, no entanto ... Use incron no * nix como ambientes de apoio inotify. Será sempre lançar comandos sempre que os arquivos em uma mudança de diretório. i.,

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

É isso.

Talvez use o argumento de acréscimo para ctags como demonstrado por:

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

Eu realmente não posso atestar isso como eu geralmente uso visão fonte para navegação de código, mas o uso vim como uma figura editor ... ir.

Que tal ter ctags programadas para serem executadas via crontab? Se a sua árvore do projeto é bastante estável em sua estrutura, que deve ser factível?

Para suprimir o "enter" prompt, use : silencioso.

No OSX este comando não vai funcionar fora da caixa, pelo menos não para mim.

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

Eu encontrei um pós , que explica como obter a versão ctags padrão que contém a opção -R. Isso por si só não funcionou para mim. Eu tive que adicionar / usr / / bin local para a variável PATH no .bash_profile, a fim de pegar o bin onde Homebrew instala programas.

Na minha opninion, plugins indexador é melhor.

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

Pode ser:

1) um add-on para project.tar.gz

2) um independente plug-in

  • geração de etiquetas de fundo (você não esperar enquanto CTags obras)
  • vários projetos apoiados

Há uma vim plugin chamado marca de formatação automática para este que funciona realmente bem.

Se você tem taglist instalado, ele também irá atualizar isso para você.

A opção --append é realmente o caminho a percorrer. Usado com um grep -v, podemos atualizar apenas um com a tag arquivo. Por exemplo, aqui está um trecho de um unpolished plug-in que resolve esse problema. (NB: Isso irá requerer um "externo" biblioteca de plug-in )

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

Este código define:

  • ^Xta para forçar a atualização da base de etiquetas para todos os arquivos no projeto atual;
  • ^Xtc para forçar a atualização da base de etiquetas para o arquivo atual (não salvos);
  • um autocommand que atualiza as tags basear cada vez que um arquivo é salvo; e suporta e muitas opções para desativar a atualização automática, onde nós não queremos isso, para chamadas CTags ajustar dependendo tipos de arquivos, ... Não é apenas uma ponta, mas um pequeno trecho de um plugin.

HTH,

Tag Auto é um vim plugin que atualizações de arquivos de marca existente em Salvar.

Eu tenho usado por anos sem problemas, com a ressalva de que ele impõe um tamanho máximo dos arquivos etiquetas. A menos que você tem realmente um grande conjunto de código tudo indexado no mesmo arquivo tags, você não deve bater esse limite, no entanto.

Note que Tag Auto requer suporte Python no vim.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top