क्या यह <बफर> का उपयोग सही है?
मुझे लगता है कि यह सही है, लेकिन आपको इसे केवल एक एग्रुप के अंदर लपेटने की जरूरत है, और बाद को साफ़ करना होगा, यह सुनिश्चित करने के लिए कि जब भी आप उसी कमांड को निष्पादित करते हैं, जो एक ही बफर को फिर से लोड करता है, तो हर बार ऑटोकैम को डुप्लिकेट नहीं किया जाएगा।
जैसा कि आपने समझाया, विशेष पैटर्न <buffer>
आपको फ़ाइल के अंदर कार्यान्वित बिल्ट-इन फ़िलाटाइप पहचान तंत्र पर भरोसा करने की अनुमति देता है $VIMRUNTIME/filetype.vim
।
इस फ़ाइल में, आप विम के बिल्ट-इन ऑटोकैड्स पा सकते हैं, जो किसी भी बफर के लिए सही फाइलाइप सेट करने के लिए जिम्मेदार हैं। उदाहरण के लिए, मार्कडाउन के लिए:
" Markdown
au BufNewFile,BufRead *.markdown,*.mdown,*.mkd,*.mkdn,*.mdwn,*.md setf markdown
अपने फ़ाइल प्रकार प्लग इन के अंदर, आप अपने द्वारा इंस्टॉल किए गए प्रत्येक ऑटोकैड के लिए समान पैटर्न कॉपी कर सकते हैं। उदाहरण के लिए, अपने कर्सर को कुछ सेकंड के दौरान स्थानांतरित नहीं होने पर स्वचालित रूप से बफर को बचाने के लिए:
au CursorHold *.markdown,*.mdown,*.mkd,*.mkdn,*.mdwn,*.md update
लेकिन <buffer>
रास्ता कम क्रिया है:
au CursorHold <buffer> update
इसके अलावा, अगर किसी दिन एक और एक्सटेंशन वैध है, और $VIMRUNTIME/filetype.vim
इसे शामिल करने के लिए अपडेट किया गया है, तो आपके ऑटोकैम को सूचित नहीं किया जाएगा। और आपको अपने सभी प्रकार के पैटर्न को अपने फाइलपेट प्लगइन्स के अंदर अपडेट करना होगा।
क्या चीजें गड़बड़ हो जाएंगी अगर मैं एक बफर मिटा दूंगा और दूसरा खोल दूंगा (उम्मीद है कि संख्या टकराएगी नहीं, लेकिन ...)?
मुझे यकीन नहीं है, लेकिन मुझे नहीं लगता कि विम एक मिटाए गए बफर के बफर नंबर का फिर से उपयोग कर सकता है। मुझे मदद से संबंधित अनुभाग नहीं मिला, लेकिन मुझे यह अनुच्छेद vim.wikia.com से मिला :
नहीं। विम एक नए बफर के लिए हटाए गए बफर के बफर नंबर का फिर से उपयोग नहीं करेगा। विम हमेशा एक नए बफर के लिए अगले अनुक्रमिक संख्या असाइन करेगा।
इसके अलावा, जैसा @ @ Tumbler41 ने समझाया, जब आप एक बफर मिटाते हैं, तो इसके ऑटोकैड्स हटा दिए जाते हैं। से :h autocmd-buflocal
:
जब एक बफर को मिटा दिया जाता है तो उसके बफर-लोकल ऑटोकॉमैंड भी चले जाते हैं।
यदि आप अपने आप को जांचना चाहते हैं, तो आप विम के वर्बोसिटी स्तर को बढ़ाकर 6. कर सकते हैं। आप इसे अस्थायी रूप से, केवल एक कमांड के लिए, :verbose
संशोधक का उपयोग करके कर सकते हैं। इसलिए, अपने मार्कडाउन बफर के अंदर, आप निष्पादित कर सकते हैं:
:6verbose bwipe
फिर, यदि आप विम के संदेशों की जाँच करते हैं:
:messages
आपको इस तरह दिखने वाली एक लाइन देखनी चाहिए:
auto-removing autocommand: CursorHold <buffer=42>
42
आपके मार्कडाउन बफर की संख्या कहां थी।
क्या कोई नुकसान है जिसकी मुझे जानकारी होनी चाहिए?
ऐसी 3 स्थितियां हैं, जिन्हें मैं नुकसान के रूप में मानता हूं और जिनमें विशेष पैटर्न शामिल है <buffer>
। उनमें से दो में, <buffer>
एक मुद्दा हो सकता है, दूसरे में यह एक समाधान है।
गड्ढा 1
सबसे पहले, आपको अपने बफर-स्थानीय ऑटोकैड्स के संवर्गों को साफ करने के तरीके से सावधान रहना चाहिए। आपको इस स्निपेट से परिचित होना चाहिए:
augroup your_group_name
autocmd!
autocmd Event pattern command
augroup END
तो, आप अपने बफर-स्थानीय ऑटोकैड्स के लिए इसका उपयोग करने के लिए लुभा सकते हैं, इस तरह से अनमॉडिफाइड:
augroup my_markdown
autocmd!
autocmd CursorHold <buffer> update
augroup END
लेकिन इसका अवांछित प्रभाव पड़ेगा। पहली बार जब आप A
मार्कडाउन बफर को लोड करते हैं, तो इसे कॉल करते हैं , इसका ऑटोकैम सही ढंग से इंस्टॉल हो जाएगा। फिर, जब आप पुनः लोड करेंगे A
, तो स्वतः पूर्ण हटा दिया जाएगा (क्योंकि autocmd!
), और पुनः स्थापित। तो, ऑग्रुप सही ढंग से ऑटोकैड के दोहराव को रोक देगा।
अब, मान लीजिए कि आप एक 2 मार्कडाउन बफर को लोड करते हैं, तो इसे B
2 विंडो में कॉल करें । ऑग्रुप के सभी ऑटोकैड्म को साफ कर दिया जाएगा: जो कि आटोकार्ड A
और इन में से एक है B
। फिर, के लिए एक SINGLE ऑटोकैम स्थापित किया जाएगा B
।
इसलिए, जब आप कुछ बदलाव करते हैं B
, और कुछ सेकंड रुकने के CursorHold
लिए निकाल दिया जाता है, तो यह स्वचालित रूप से सहेजा जाएगा। लेकिन अगर आप वापस जाते हैं A
और वही काम करते हैं, तो बफर सेव नहीं होगा। ऐसा इसलिए है क्योंकि पिछली बार जब आपने मार्कडाउन बफर लोड किया था, तो आपके द्वारा हटाए गए और आपने जो जोड़ा था, उसके बीच असंतुलन था। आपने जो जोड़ा उससे अधिक आपने निकाल दिया।
समाधान सभी ऑटोकैमड्स को हटाने के लिए नहीं है, लेकिन केवल वर्तमान बफर के विशेष पैटर्न <buffer>
को पास करके :autocmd!
:
augroup my_markdown
autocmd! CursorHold <buffer>
autocmd CursorHold <buffer> update
augroup END
ध्यान दें कि आप CursorHold
पंक्ति में किसी भी घटना से मेल खाने के लिए एक स्टार के साथ बदल सकते हैं जो ऑटोकैड्स को हटाता है:
augroup my_markdown
autocmd! * <buffer>
autocmd CursorHold <buffer> update
augroup END
इस तरह, आपको उन सभी घटनाओं को निर्दिष्ट करने की आवश्यकता नहीं है जिनके लिए आपका ऑटोकैड सुन रहा है जब आप समूह को साफ़ करना चाहते हैं।
पिटने की क्रिया २
एक और नुकसान है, लेकिन इस बार <buffer>
यह मुद्दा नहीं है, यह समाधान है।
जब आप किसी फ़ाइल विकल्प प्लगइन में एक स्थानीय विकल्प शामिल करते हैं, तो आप शायद इसे इस तरह से करते हैं:
setlocal option1=value
setlocal option2
यह बफर-लोकल ऑप्शंस के लिए उम्मीद के मुताबिक काम करेगा, लेकिन हमेशा विंडो-लोकल के लिए नहीं। समस्या का वर्णन करने के लिए, आप निम्नलिखित प्रयोग आज़मा सकते हैं। फ़ाइल बनाएँ ~/.vim/after/ftdetect/potion.vim
, और इसके अंदर लिखें:
autocmd BufNewFile,BufRead *.pn setfiletype potion
यह फ़ाइल स्वचालित रूप से potion
किसी भी फ़ाइल के लिए फ़िलाटाइप सेट करेगी जिसका एक्सटेंशन है .pn
। आपको इसे एक एग्रुप के अंदर लपेटने की आवश्यकता नहीं है, क्योंकि इस विशेष प्रकार की फ़ाइल के लिए, विम इसे स्वचालित रूप से करेगा (देखें :h ftdetect
)।
यदि मध्यवर्ती निर्देशिका आपके सिस्टम पर मौजूद नहीं हैं, तो आप उन्हें बना सकते हैं।
अगला, फ़िलेपाइप प्लगइन बनाएं ~/.vim/after/ftplugin/potion.vim
, और इसके अंदर लिखें:
setlocal list
डिफ़ॉल्ट रूप से, किसी potion
फ़ाइल में, यह सेटिंग टैब वर्णों के रूप में ^I
और लाइनों के अंत के रूप में प्रदर्शित होगी $
।
अब, एक न्यूनतम बनाएँ vimrc
; अंदर /tmp/vimrc
लिखें:
filetype plugin on
... फ़िलाटाइप प्लग इन को सक्षम करने के लिए।
इसके अलावा, एक पोशन फ़ाइल /tmp/pn.pn
, और एक यादृच्छिक फ़ाइल बनाएँ /tmp/file
। पोशन फ़ाइल में, कुछ लिखें:
foo
bar
baz
रैंडम फाइल में, पोशन फाइल के लिए रास्ता लिखें /tmp/pn.pn
:
/tmp/pn.pn
अब, कम से कम आरंभीकरण के साथ विम शुरू करें, बस सोर्सिंग करें vimrc
, और ऊर्ध्वाधर व्यूपोर्ट में दोनों फाइलें खोलें:
$ vim -Nu /tmp/vimrc -O /tmp/pn.pn /tmp/file
आपको 2 ऊर्ध्वाधर व्यूपोर्ट देखने चाहिए। बाईं ओर पोशन फ़ाइल डॉलर के संकेतों के साथ लाइनों के अंत को प्रदर्शित करती है, दाईं ओर यादृच्छिक फ़ाइल उन्हें बिल्कुल भी प्रदर्शित नहीं करती है।
रैंडम फ़ाइल पर फ़ोकस दें, और gf
पॉज़िशन फ़ाइल दिखाने के लिए दबाएँ जिसका पथ कर्सर के नीचे है। अब आप सही व्यूपोर्ट में एक ही पोशन बफर देखते हैं, लेकिन इस बार, डॉलर के अंत में डॉलर के संकेत प्रदर्शित नहीं होते हैं। और यदि आप टाइप करते हैं :setlocal list?
, तो विम को जवाब देना चाहिए nolist
:
घटनाओं की पूरी श्रृंखला:
BufRead event → set 'filetype' option → load filetype plugins
... ऐसा नहीं हुआ, क्योंकि उनमें से पहला BufRead
, जब आपने दबाया था, तब नहीं हुआ था gf
। बफ़र पहले से ही लोड था।
यह अप्रत्याशित लग सकता है, क्योंकि जब आप setlocal list
अपने पॉशन फ़िलाटाइप प्लगइन के अंदर जुड़ते हैं, तो आपने सोचा होगा कि यह 'list'
किसी भी विंडो में विकल्प को पॉशन बफर प्रदर्शित करने में सक्षम करेगा ।
यह मुद्दा इस नए potion
फ़ाइल-प्रकार के लिए विशिष्ट नहीं है । आप इसे एक markdown
फ़ाइल के साथ भी अनुभव कर सकते हैं।
यह 'list'
विकल्प के लिए भी विशिष्ट नहीं है । आप अन्य विंडो-स्थानीय सेटिंग्स के साथ यह अनुभव कर सकते हैं, जैसे 'conceallevel'
, 'foldmethod'
, 'foldexpr'
, 'foldtitle'
, ...
यह gf
कमांड के लिए विशिष्ट नहीं है । आप इसे अन्य आदेशों के साथ अनुभव कर सकते हैं जो वर्तमान विंडो में प्रदर्शित बफर को बदल सकते हैं: वैश्विक चिह्न, C-o
(विंडो-लोकल जंपलिस्ट में पीछे हटो) :b {buffer_number}
,, ...
संक्षेप में, विंडो-स्थानीय विकल्प सही ढंग से सेट किए जाएंगे, यदि और केवल यदि:
- वर्तमान विम सत्र के दौरान फ़ाइल को पढ़ा नहीं गया है (क्योंकि
BufRead
निकाल दिया जाएगा)
- फ़ाइल को एक विंडो में प्रदर्शित किया जा रहा है, जहां विंडो-स्थानीय विकल्प पहले से ही सही ढंग से सेट थे
- नई विंडो एक कमांड के साथ बनाई गई है, जैसे
:split
(इस मामले में, यह विंडो से स्थानीय-स्थानीय विकल्पों को इनहेरिट करना चाहिए जहां विंडो निष्पादित की गई थी)
अन्यथा, विंडो-स्थानीय विकल्प सही तरीके से सेट नहीं हो सकते हैं।
एक संभव समाधान यह होगा कि उन्हें सीधे एक फ़िलाटाइप प्लगइन से नहीं, बल्कि उत्तरार्द्ध में स्थापित एक ऑटोकैमड से सेट किया जाए, जिसे वह सुनेंगे BufWinEnter
। इस घटना को हर बार एक विंडो में एक बफर प्रदर्शित होने पर निकाल दिया जाना चाहिए।
इसलिए, उदाहरण के लिए, यह लिखने के बजाय:
setlocal list
आप इसे लिखेंगे:
augroup my_potion
au! * <buffer>
au BufWinEnter <buffer> setlocal list
augroup END
और यहां, आप फिर से विशेष पैटर्न पाते हैं <buffer>
।
पिटने की अवस्था ३
यदि आप अपने बफर के फिलाटाइप को बदलते हैं, तो ऑटोकैड्स बने रहेंगे। यदि आप उन्हें निकालना चाहते हैं, तो आपको कॉन्फ़िगर करने b:undo_ftplugin
(देखने :h undo_ftplugin
) की आवश्यकता है, और इसमें यह कमांड शामिल करें:
exe 'au! my_markdown * <buffer>'
हालांकि, खुद को एग्रुप हटाने की कोशिश न करें, क्योंकि अभी भी कुछ मार्कडाउन बफ़र्स हो सकते हैं, जिनके अंदर ऑटोकैम हैं।
FWIW, यह UltiSnips स्निपेट है जिसे मैं सेट करने के लिए उपयोग कर रहा हूं b:undo_ftplugin
:
snippet undo "undo ftplugin settings" bm
" teardown {{{1
let b:undo_ftplugin = get(b:, 'undo_ftplugin', '')
\ .(empty(get(b:, 'undo_ftplugin', '')) ? '' : '|')
\ ."${1:
\ setl ${2:option}<}${3:
\ | exe '${4:n}unmap <buffer> ${5:lhs}'}${6:
\ | exe 'au! ${7:group_name} * <buffer>'}${8:
\ | unlet! b:${9:variable}}${10:
\ | delcommand ${11:Cmd}}
\ "
$0
endsnippet
और यहाँ मूल्य का एक उदाहरण है जो मेरे पास है ~/.vim/after/ftplugin/awk.vim
:
let b:undo_ftplugin = get(b:, 'undo_ftplugin', '')
\ .(empty(get(b:, 'undo_ftplugin', '')) ? '' : '|')
\ ."
\ setl cms< cocu< cole< fdm< fdt< tw<
\| exe 'nunmap <buffer> K'
\| exe 'au! my_awk * <buffer>'
\| exe 'au! my_awk_format * <buffer>'
\ "
एक साइड नोट के रूप में, मैं समझता हूं कि आपने सवाल क्यों पूछा, क्योंकि जब मैंने उन सभी लाइनों की तलाश की जहां <buffer>
विम के डिफ़ॉल्ट फाइलों में विशेष पैटर्न का उपयोग किया गया था:
:vim /au\%[tocmd!].\{-}<buffer>/ $VIMRUNTIME/**/*
मुझे केवल 9 मैच मिले (आप कम या ज्यादा पा सकते हैं, मैं विम संस्करण 8.0 का उपयोग कर रहा हूं, पैच के साथ 134
)। और 9 मैचों में से 7 दस्तावेज में हैं, केवल 2 वास्तव में खट्टे हैं। आपको उन्हें $ VIMRUNTIME / syntax / dircolors.vim में ढूंढना चाहिए :
autocmd CursorMoved,CursorMovedI <buffer> call s:preview_color('.')
autocmd CursorHold,CursorHoldI <buffer> call s:reset_colors()
मैं अगर यह एक मुद्दा पैदा कर सकता है पता नहीं है, लेकिन वे एक augroup है, जो हर बार जब आप एक बफर जिसका फ़ाइल प्रकार है फिर से लोड का मतलब है के भीतर नहीं हैं dircolors
(ऐसा होता है अगर आप नाम के एक फ़ाइल को संपादित .dircolors
, .dir_colors
या जिनकी साथ पथ समाप्त होता है /etc/DIR_COLORS
), वाक्यविन्यास प्लगइन एक नया बफर-स्थानीय ऑटोकैम जोड़ देगा।
आप इसे इस तरह से देख सकते हैं:
$ vim ~/.dir_colors
:au * <buffer>
अंतिम कमांड को यह प्रदर्शित करना चाहिए:
CursorHold
<buffer=1>
call s:reset_colors()
CursorHoldI
<buffer=1>
call s:reset_colors()
CursorMoved
<buffer=1>
call s:preview_color('.')
CursorMovedI
<buffer=1>
call s:preview_color('.')
अब, बफर को फिर से लोड करें, और फिर से पूछें कि वर्तमान बफर के लिए बफर-स्थानीय ऑटोकैम क्या हैं:
:e
:au * <buffer>
इस बार, आप देखेंगे:
CursorHold
<buffer=1>
call s:reset_colors()
call s:reset_colors()
CursorHoldI
<buffer=1>
call s:reset_colors()
call s:reset_colors()
CursorMoved
<buffer=1>
call s:preview_color('.')
call s:preview_color('.')
CursorMovedI
<buffer=1>
call s:preview_color('.')
call s:preview_color('.')
फ़ाइल के हर पुन: लोड के बाद, s:reset_colors()
और s:preview_color('.')
एक अतिरिक्त समय कहा जाता है, को घटना की हर बार एक CursorHold
, CursorHoldI
, CursorMoved
, CursorMovedI
निकाल दिया जाता है।
यह शायद एक बड़ा मुद्दा नहीं है, क्योंकि dircolors
कई बार किसी फ़ाइल को पुनः लोड करने के बाद भी , मुझे विम से ध्यान देने योग्य मंदी या अप्रत्याशित व्यवहार नहीं दिखाई दिया।
यदि यह आपके लिए एक समस्या है, तो आप सिंटैक्स प्लगइन के अनुरक्षक से संपर्क कर सकते हैं, लेकिन इस बीच, यदि आप ऑटोकैड्स के दोहराव को रोकना चाहते थे, तो आप dircolors
फ़ाइल का उपयोग करके फ़ाइलों के लिए अपना सिंटैक्स प्लगइन बना सकते हैं ~/.vim/syntax/dircolors.vim
। इसके अंदर आप मूल सिंटैक्स प्लगइन की सामग्री आयात करेंगे:
$ vim ~/.vim/syntax/dircolors.vim
:r $VIMRUNTIME/syntax/dircolors.vim
फिर, उत्तरार्द्ध में, आप बस ऑटोकैड्स को एक एग्रुप के अंदर लपेटेंगे जिसे आप स्पष्ट करेंगे। तो, आप इन पंक्तियों को प्रतिस्थापित करेंगे:
autocmd CursorMoved,CursorMovedI <buffer> call s:preview_color('.')
autocmd CursorHold,CursorHoldI <buffer> call s:reset_colors()
... इन लोगों के साथ:
augroup my_dircolors_syntax
autocmd! * <buffer>
autocmd CursorMoved,CursorMovedI <buffer> call s:preview_color('.')
autocmd CursorHold,CursorHoldI <buffer> call s:reset_colors()
augroup END
ध्यान दें कि यदि आपने dircolors
फ़ाइल के साथ अपना सिंटैक्स प्लगइन बनाया है ~/.vim/after/syntax/dircolors.vim
, तो यह काम नहीं करेगा, क्योंकि डिफ़ॉल्ट सिंटैक्स प्लगइन को पहले खट्टा किया जाएगा। का उपयोग करके ~/.vim/syntax/dircolors.vim
, आपके सिंटैक्स प्लगइन को डिफ़ॉल्ट एक से पहले खट्टा किया जाएगा, और यह बफर-लोकल वैरिएबल को सेट करेगा b:current_syntax
, जो डिफ़ॉल्ट सिंटैक्स प्लगइन को खट्टा होने से रोकेगा क्योंकि इसमें यह गार्ड है:
if exists("b:current_syntax")
finish
endif
सामान्य नियम ऐसा प्रतीत होता है: कस्टम फ़ाइलटाइप / सिंटैक्स प्लगइन बनाने के लिए निर्देशिकाओं का उपयोग करें ~/.vim/ftplugin
और ~/.vim/syntax
रनटाइम पथ में अगले प्लगइन (उसी फ़िलाटाइप के लिए) को रोका जा सकता है जिसमें (डिफ़ॉल्ट वाले सहित)। और उपयोग करें ~/.vim/after/ftplugin
, ~/.vim/after/syntax
अन्य प्लगइन्स को खट्टा होने से रोकने के लिए नहीं, बल्कि कुछ सेटिंग्स के मूल्य पर अंतिम शब्द के लिए।