2008-09-30 11 views
52

फ़िलहाल मेरी .vimrc में निम्नलिखित है:विम को स्वत: जनरेट ctags

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

इस के साथ कुछ समस्याएं हैं:

  1. यह धीमी है - फ़ाइलें जो हेवन 'के लिए टैग पुन: बनाता है अंतिम टैग पीढ़ी के बाद से बदल नहीं है।
  2. मुझे अपरिहार्य "एंटर दबाएं या जारी रखने के लिए कमांड टाइप करें" के कारण फ़ाइल लिखने के बाद एंटर बटन फिर से दबाएं।

जब आप इन दो मुद्दों मैं अंत (पहले ctags -R समाप्त हो गया है) अतिरिक्त बहुत जल्दी प्रवेश धक्का गठबंधन है, तो कष्टप्रद त्रुटि संदेश देखते हैं, और पुश करने के लिए फिर से दर्ज की है।

मुझे पता है कि यह एक बड़े सौदे की तरह नहीं लगता है, लेकिन फाइल लिखने की मात्रा के साथ मैं किसी दिए गए दिन पर करता हूं, यह वास्तव में परेशान होता है। ऐसा करने का एक बेहतर तरीका होना चाहिए!

उत्तर

41

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

नकारात्मक पक्ष यह है कि आप एक उपयोगी टैग फ़ाइल जब तक यह पूरा नहीं होगा है। जब तक आप * निक्स सिस्टम पर हों, तब तक पिछले सीटीएजी पूरा होने से पहले कई लिखना ठीक होना चाहिए, लेकिन आपको इसका परीक्षण करना चाहिए। विंडोज सिस्टम पर यह इसे पृष्ठभूमि में नहीं रखेगा और यह शिकायत करेगा कि फाइल को तब तक लॉक किया जाता है जब तक कि पहले सीटीएजी खत्म नहीं हो जाते (जो कि विम में समस्याएं नहीं पैदा कर सकता है, लेकिन आप थोड़ी पुरानी टैग फ़ाइल के साथ समाप्त हो जाएंगे)।

नोट, आप --append विकल्प का उपयोग कर सकते हैं क्योंकि टोनीलो सुझाव देता है, लेकिन फिर आपको tagbsearch अक्षम करना होगा जिसका अर्थ यह हो सकता है कि आपकी टैग फ़ाइल के आकार के आधार पर टैग खोजों को बहुत अधिक समय लगता है।

+0

आह ... अच्छा समाधान। मैं चुपचाप इस्तेमाल कर रहा था! ctags -R और समझ में नहीं आया क्यों कुछ भी नहीं हो रहा था ... मुझे लगता है कि आपको उस दूसरी धमाके की जरूरत है। – cdleary

+2

विंडोज़ पर आप हमेशा 'ctags -R शुरू करें' का उपयोग कर सकते हैं। यह बैकग्राउड में सीटीएजी शुरू करेगा। – devemouse

+2

मुझे इस समाधान के साथ समस्याएं थीं जब फाइलें उन चेतावनियों के बाद सीटीएजी चेतावनियां उत्पन्न करती थीं तो फिर विम में प्रदर्शित होती हैं और स्क्रीन को गड़बड़ कर देती हैं (पूर्व 'ctags: चेतावनी: सार्वजनिक/jquery.form.js में शून्य टैग को अनदेखा करना)। मैंने बस stderr को/dev/null पर रीडायरेक्ट किया है और यह इसे ठीक करता है, लेकिन इसका मतलब है कि मुझे टैग के साथ समस्याओं के बारे में पता नहीं चलेगा। 'autocmd BufWritePost *। आरबी, * जेएस चुप! !/usr/local/bin/ctags -R 2>/dev/null और ' – mmrobins

2

crontab के माध्यम से चलाने के लिए निर्धारित ctags के बारे में कैसे? यदि आपकी परियोजना का पेड़ इसकी संरचना में काफी स्थिर है, तो यह करने योग्य होना चाहिए?

+0

+1, KISS। यहां एक cronjob का एक उदाहरण दिया गया है जिसे मैंने हर दिन 2:10 बजे चलाने के लिए स्थापित किया था। जाहिर है, आप जितना चाहें उतने हो सकते हैं। मेरे ctags विकल्प drupal के लिए हैं, जो शायद आपको चाहिए की तुलना में अधिक है। 10 2 * * * सीडी/var/www/yoursite/&&/usr/bin/ctags --langmap = php: .engine.inc.module.theme.install.php --php-type = cdf --languages ​​= php --recurse – roberttstephens

3

शायद के रूप में द्वारा प्रदर्शन ctags के लिए संलग्न तर्क का उपयोग करें:

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

मैं वास्तव में इस समर्थन नहीं कर सकता के रूप में मैं आम तौर पर कोड ब्राउज़िंग के लिए स्रोत अंतर्दृष्टि उपयोग करें, लेकिन एक संपादक के रूप vim का उपयोग .. । जाओ पता लगाओ।

2

"एंटर दबाएं" प्रॉम्प्ट को दबाने के लिए, :silent का उपयोग करें।

1

--append विकल्प वास्तव में जाने का तरीका है। grep -v के साथ प्रयुक्त, हम केवल टैग की गईं फ़ाइल अपडेट कर सकते हैं। उदाहरण के लिए, यहां unpolished plugin का एक अंश है जो इस समस्या को संबोधित करता है।(ध्यान दें: यह एक "बाहरी" की आवश्यकता होगी library plugin)

" 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 

इस कोड को परिभाषित करता है:

  • ^Xta वर्तमान प्रोजेक्ट में सभी फ़ाइलों के लिए टैग के आधार के अद्यतन के लिए मजबूर करने के लिए;
  • ^Xtc वर्तमान (सहेजे गए) फ़ाइल के टैग बेस के अद्यतन को मजबूर करने के लिए;
  • एक ऑटोकॉन्मंड जो प्रत्येक फ़ाइल को सहेजने पर टैग बेस अपडेट करता है; और यह स्वत: अद्यतन को अक्षम करने के लिए कई विकल्प का समर्थन करता है जहां हम इसे नहीं चाहते हैं, फ़ाइल प्रकारों के आधार पर ctags कॉल को ट्यून करने के लिए ... यह सिर्फ एक टिप नहीं है, बल्कि प्लगइन का एक छोटा सा अंश है।

HTH,

13

संपादित: बहुत निम्न AutoTag vim स्क्रिप्ट के रूप में नियुक्त किया गया है, की तर्ज पर एक समाधान। ध्यान दें कि स्क्रिप्ट को पाइथन समर्थन के साथ एक विम की आवश्यकता है।

मेरा समाधान इसके बदले अजीब हो जाता है, इसलिए इसे कई और प्रणालियों पर काम करना चाहिए।


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 

ध्यान दें कि आप केवल एक स्क्रिप्ट में इस तरह से लिख सकते हैं, अन्यथा यह एक पंक्ति पर जाना पड़ता है।

वहाँ बहुत वहाँ में चल रहा है:

  1. यह ऑटो आदेश से चलाता है जब किसी फ़ाइल सी या सी ++ होने की पहचान की गई है, और बदले में कहते हैं एक बफर-स्थानीय ऑटो आदेश से शुरू हो रहा BufWritePost घटना।

  2. यह % प्लेसहोल्डर जो निष्पादन समय पर बफर के फ़ाइल नाम की जगह एक साथ उपयोग करता है, (उद्धरण-एस्केप बोली-बोली में किसी भी एम्बेडेड एकल उद्धरण बदल कर) खोल-उद्धरण फ़ाइल नाम के लिए इस्तेमाल किया :gs संशोधक के साथ ।

  3. इस तरह यह एक शेल कमांड कि जाँच करता है अगर एक tags फ़ाइल मौजूद है चलाता है, जो मामले में अपनी सामग्री लाइनों कि अभी-सहेजी गई फ़ाइल का उल्लेख के अलावा छपा है, इस बीच ctags बस अभी-बचाया पर शुरू हो जाती है फ़ाइल, और परिणाम sort एड है और जगह में वापस डाल दिया।

चेतावनी कार्यान्वयनकर्ता: यह मानता है कि सब कुछ एक ही निर्देशिका में है और यह भी बफर-स्थानीय वर्तमान निर्देशिका है। मैंने पथ उलझन में कोई विचार नहीं दिया है।

7

मैंने देखा है कि यह एक पुराना धागा है, हालांकि ... incron * निक्स में इनोटिफ़ाई का समर्थन करने वाले वातावरण जैसे निक्स का उपयोग करें। निर्देशिका में फ़ाइलों को बदलने पर यह हमेशा आदेश लॉन्च करेगा। यानी,

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

यही है।

1

इस के लिए AutoTag नामक एक विम प्लगइन है जो वास्तव में अच्छी तरह से काम करता है।

यदि आपके पास टैगलिस्ट स्थापित है तो यह आपके लिए भी अपडेट करेगा।

1

मेरे opininion में, प्लगइन सूचकांक बेहतर है।

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

यह हो सकता है:

1) एक ऐड-ऑन project.tar.gz

2) एक स्वतंत्र प्लगइन

  • पृष्ठभूमि टैग पीढ़ी के लिए (यदि आपके पास प्रतीक्षा करें जबकि ctags काम करता है)
  • एकाधिक परियोजनाओं का समर्थन
2

ओएसएक्स पर यह आदेश बॉक्स के बाहर काम नहीं करेगा, कम से कम मेरे लिए नहीं।

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

मैं एक post पाया है, जो बताते हैं कि कैसे है कि आर विकल्प होता है मानक ctags संस्करण प्राप्त करने के। यह अकेला मेरे लिए काम नहीं करता था। होमब्री प्रोग्राम्स इंस्टॉल करता है, जहां बिन को चुनने के लिए मुझे .bash_profile में PATH चर में/usr/local/bin जोड़ना था।

0

ऑटो टैग एक vim प्लगइन है जो सहेजने पर मौजूदा टैग फ़ाइलों को अपडेट करता है।

मैं समस्याओं के बिना वर्षों तक इसका उपयोग कर रहा हूं, अपवाद के साथ कि यह टैग फ़ाइलों पर अधिकतम आकार लागू करता है। जब तक आपके पास एक ही टैग फ़ाइल में अनुक्रमित कोड का वास्तव में बड़ा सेट न हो, तब तक आपको उस सीमा को हिट नहीं करना चाहिए।

ध्यान दें कि ऑटो टैग को विम में पायथन समर्थन की आवश्यकता है।

10

मैंने यह करने के लिए easytags.vim लिखा था: स्वचालित रूप से टैग अपडेट करें और हाइलाइट करें। प्लग-इन को संपादित की जा रही फ़ाइल या फ़ाइल की निर्देशिका में सभी फ़ाइलों को संपादित करने के लिए कॉन्फ़िगर किया जा सकता है (रिकर्सिव)। यह एक वैश्विक टैग फ़ाइल, फ़ाइल प्रकार विशिष्ट टैग फ़ाइलों और परियोजना विशिष्ट टैग फ़ाइलों का उपयोग कर सकते हैं।

+1

easytags अच्छा और ठंडा है, लेकिन डिफ़ॉल्ट विम घटना ट्रिगर समय बहुत उत्सुक है .. कष्टप्रद स्टालों को रोकने के लिए इसे अपने f.e में जोड़ें।/Etc/vim/vimrc।स्थानीय: 'अपडेटटाइम = 30000 सेट करें "4 सेकंड के बाद उपयोगकर्ता निष्क्रियता के आधा मिनट के बाद ऑटोकॉर्ड्स ट्रिगर करें ↵' सेट swapsync = "" उपयोगकर्ता निष्क्रियता ट्रिगर पर स्वैप फ़ाइल सिंक अक्षम करें – eMPee584

+1

@ eMPee584: मैं मानता हूं कि यह प्राप्त कर सकता है कई बार बहुत परेशान (उपयोगकर्ता के वर्कफ़्लो में बाधा डालना)। मैं वर्तमान में [एक शाखा पर काम कर रहा हूं जहां एक्सबेरेंट सीटैग को एसिंक्रोनस सबप्रोसेस में निष्पादित किया जाता है] (https://github.com/xolox/vim-easytags/pull/49)। एक बार यह सभी प्लेटफार्मों पर बॉक्स से विश्वसनीय रूप से काम करता है, तो शायद मैं इसे डिफ़ॉल्ट बना दूंगा। – xolox

संबंधित मुद्दे