Vim automatyczne generowanie ctags
W tej chwili mam w moim .vimrc
:
au BufWritePost *.c,*.cpp,*.h !ctags -R
Jest z tym kilka problemów:
- jest powolny -- regeneruje znaczniki dla plików, które nie zmieniły się od ostatniej generacji znaczników.
- muszę ponownie nacisnąć przycisk enter Po zapisaniu pliku z powodu nieuniknionego "naciśnij Enter lub wpisz polecenie, aby kontynuować".
Gdy połączysz te dwa problemy, za wcześnie naciskam dodatkowe enter( zanim ctags -R
się skończy), a następnie zobacz irytujący komunikat o błędzie i ponownie naciśnij enter.
Wiem, że to nie brzmi jak wielka sprawa, ale z ilością plików, które piszę w danym dniu, zwykle robi się to naprawdę denerwujące. Musi być na to lepszy sposób!
12 answers
au BufWritePost *.c,*.cpp,*.h silent! !ctags -R &
Minusem jest to, że nie będziesz miał przydatnego pliku tagów, dopóki nie zostanie ukończony. Tak długo, jak jesteś na systemie *nix, powinno być ok, aby zrobić wiele zapisów przed poprzedni ctags został zakończony, ale powinieneś to przetestować. W systemie Windows nie będzie go umieszczać w tle i będzie narzekać, że plik jest zablokowany do czasu zakończenia pierwszych ctags (co nie powinno powodować problemów w Vimie, ale skończysz z nieco przestarzałym plikiem tags).
Uwaga, możesz użyć --append
opcja jak sugeruje tonylo, ale wtedy będziesz musiał wyłączyć tagbsearch
, co może oznaczać, że wyszukiwanie tagów trwa znacznie dłużej, w zależności od rozmiaru pliku tagów.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-10-01 00:07:22
Edit : rozwiązanie bardzo podobne do poniższych zostało opublikowane jako AutoTag skrypt vim. Zauważ, że skrypt potrzebuje Vima z obsługą Pythona.
Moje rozwiązanie zamiast tego działa na awk, więc powinno działać na wielu innych systemach.
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
Zauważ, że możesz to napisać tylko w ten sposób w skrypcie, w przeciwnym razie musi to iść w jednej linii.
Dużo się dzieje w tam:
To automatyczne polecenie uruchamia się po wykryciu pliku jako C lub C++ i dodaje z kolei automatyczne polecenie bufora lokalnego, które jest wyzwalane przez zdarzenie
BufWritePost
.Używa symbolu zastępczego
%
, który jest zastępowany przez nazwę pliku bufora w czasie wykonywania, wraz z modyfikatorem:gs
używanym do Shell-quote nazwy pliku (zamieniając dowolne osadzone pojedyncze cudzysłowy w quote-escape-quote-quote).W ten sposób uruchamia polecenie powłoki sprawdza, czy istnieje plik
tags
, w którym to przypadku jego zawartość jest drukowana z wyjątkiem linii, które odnoszą się do właśnie zapisanego pliku, tymczasemctags
jest wywoływany tylko na właśnie zapisanym pliku, a wynikiem jestsort
ed i wstawiany z powrotem na miejsce.
Caveat implementor: zakłada to, że wszystko znajduje się w tym samym katalogu i że jest to również bufor-lokalny katalog bieżący. Nie zastanawiałam się nad tym.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-01-29 19:24:01
Napisałem easytags.vim aby to zrobić: automatycznie aktualizuj i podświetl tagi. Wtyczka może być skonfigurowana tak, aby aktualizować tylko edytowany plik lub wszystkie pliki w katalogu edytowanego pliku (rekurencyjnie). Może używać globalnego pliku tagów, plików tagów specyficznych dla typu pliku i plików tagów specyficznych dla projektu.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-06-19 17:52:50
Zauważyłem jednak, że jest to stary wątek... Użyj incron w * Nix podobnych środowiskach wspierających inotify. Zawsze będzie uruchamiać polecenia za każdym razem, gdy zmienią się pliki w katalogu. tzn.,
/home/me/Code/c/that_program IN_DELETE,IN_CLOSE_WRITE ctags --sort=yes *.c
To wszystko.Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-11-30 05:46:46
Być może użyj argumentu append do ctags, jak pokazano przez:
Http://vim.wikia.com/wiki/Autocmd_to_update_ctags_file
Nie mogę za to ręczyć, ponieważ zazwyczaj używam Source insight do przeglądania kodu, ale używam Vima jako edytora... pomyśl.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-30 23:01:38
A może ctags będzie uruchamiany przez crontab? Jeśli twoje drzewo projektu jest dość stabilne w swojej strukturze, powinno to być wykonalne?
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-30 22:55:34
Aby wyłączyć monit "naciśnij enter", użyj : silent .
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-30 23:03:15
Na OSX to polecenie nie będzie działać po wyjęciu z pudełka, przynajmniej nie dla mnie.
au BufWritePost *.c,*.cpp,*.h silent! !ctags -R &
Znalazłem post , który wyjaśnia jak uzyskać standardową wersję ctags zawierającą opcję-R. To samo nie zadziałało. Musiałem dodać /usr / local / bin do zmiennej PATH w .bash_profile w celu pobrania kosza, w którym Homebrew instaluje programy.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-09-01 10:45:09
W moim opninion, Plugin Indexer jest lepszy.
Http://www.vim.org/scripts/script.php?script_id=3221
Może Być:
1) dodatek do projektu.smoła.gz
2) niezależny plugin
- generowanie znaczników tła (nie trzeba czekać na działanie ctags)
- obsługiwane wiele projektów
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-05-13 05:37:29
Istnieje wtyczka vim o nazwie AutoTag , która działa naprawdę dobrze.
Jeśli masz zainstalowaną listę tagów, zaktualizuje ją również dla Ciebie.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-01-27 17:07:10
Opcja --append
jest rzeczywiście droga do zrobienia. Używany z grep -v
, możemy zaktualizować tylko jeden oznaczony Plik. Na przykład, oto fragment unpolished plugin , który rozwiązuje ten problem. (Uwaga: będzie to wymagało" zewnętrznego " pluginu biblioteki )
" 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
Ten kod definiuje:
-
^Xta
aby wymusić aktualizację bazy tagów dla wszystkich plików w bieżącym projekcie; -
^Xtc
Aby wymusić aktualizację bazy tagów dla bieżącego (niezapisanego) plik; - autocommand, który aktualizuje bazę tagów za każdym razem, gdy plik jest zapisywany ; i obsługuje i wiele opcji, aby wyłączyć automatyczną aktualizację tam, gdzie jej nie chcemy, aby dostroić wywołania ctags w zależności od typów plików, ... To nie jest tylko wskazówka, ale mały fragment wtyczki.
HTH,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-03-16 17:34:09
Auto Tag jest wtyczką vim, która aktualizuje istniejące pliki tagów podczas zapisywania.
Używam go od lat bez problemów, z wyjątkiem tego, że wymusza maksymalny rozmiar plików tagów. Jeśli nie masz naprawdę dużego zestawu kodu indeksowanego w tym samym pliku tags, nie powinieneś jednak przekraczać tego limitu.
Zauważ, że Auto Tag wymaga obsługi Pythona w Vimie.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-10-26 22:15:27