विम: सेव पर पैरेंट डायरेक्टरी बनाना


122

अगर मैं आह्वान करता हूं, vim foo/bar/somefileलेकिन foo/barपहले से मौजूद नहीं है, तो विम ने बचाने से इनकार कर दिया।

मुझे पता है कि मैं एक खोल पर स्विच कर सकता हूं या :!mkdir foo/barविम से कर सकता हूं, लेकिन मैं आलसी हूं :) क्या विम को बनाने का एक तरीका है कि स्वचालित रूप से जब यह बफर बचाता है?


13
mkdir -p %:hबेहतर है क्योंकि यह नेस्टेड नॉन-मौजूदा रास्तों के लिए काम करता है, जब कोई रास्ता पहले से मौजूद है, तो कोई त्रुटि नहीं करता है और %:hवर्तमान फ़ाइल का पूर्ण पथ है। हालाँकि, मुझे नहीं पता कि यह स्वचालित रूप से कैसे लागू किया जाए। आम तौर पर, यह आटोमोटिव्स के साथ किया जाता है, लेकिन यह BufWritePreकार्यक्रम यहां काम नहीं करता है।
कोनराड रुडोल्फ

एक समारोह जो जांच करता है कि फ़ाइल मौजूद है और निर्मित कॉल को परिभाषित करें writeऔर करने के लिए सिस्टम को कॉल mkdir -pपर dirnameअन्यथा, से मैप W... मैं वाक्य रचना के लिए खोज करने के लिए और एक जवाब के रूप में पोस्ट करने के लिए बहुत आलसी हूँ ... क्षमा करें
Khachik

1
मुझे लगता है मैं दोनों अपने सुझाव और उर्फ जोड़ सकता :wकरने के लिए mkdir -p %:hbuilting द्वारा पीछा किया:write
डेमियन Pollet

जवाबों:


91
augroup BWCCreateDir
    autocmd!
    autocmd BufWritePre * if expand("<afile>")!~#'^\w\+:/' && !isdirectory(expand("%:h")) | execute "silent! !mkdir -p ".shellescape(expand('%:h'), 1) | redraw! | endif
augroup END

शर्तों पर ध्यान दें: expand("<afile>")!~#'^\w\+:/'जैसे फाइलों के लिए निर्देशिका बनाने से vim को रोका जा सकेगा ftp://*और !isdirectoryमहंगी mkdir कॉल को रोका जा सकेगा।

अद्यतन : sligtly बेहतर समाधान जो गैर-रिक्त buftype और उपयोगों के लिए भी जाँच करता है mkdir():

function s:MkNonExDir(file, buf)
    if empty(getbufvar(a:buf, '&buftype')) && a:file!~#'\v^\w+\:\/'
        let dir=fnamemodify(a:file, ':h')
        if !isdirectory(dir)
            call mkdir(dir, 'p')
        endif
    endif
endfunction
augroup BWCCreateDir
    autocmd!
    autocmd BufWritePre * :call s:MkNonExDir(expand('<afile>'), +expand('<abuf>'))
augroup END

1
धन्यवाद, मुझे लगता है कि हैक की तुलना में बहुत साफ लगता है :)
डेमियन पोललेट

11
call mkdir(expand('%:h'), 'p')अधिक पोर्टेबल हो सकता है।
मारियस गेडमिनस

1
@MariusGedminas मैं उस बदलाव के साथ पूरा कोड देखना चाहूंगा। क्या आप इसे उत्तर के रूप में पोस्ट कर सकते हैं / कहीं अपलोड कर सकते हैं?
किक्टो सेप

@kikito मेरा जवाब देखें। उस टिप्पणी के कुछ घंटों बाद इसे संपादित किया गया था।
ज़ीएक्स

@Zyx धन्यवाद! मैं कुछ छोटा कर रहा था (मेरा जवाब वर्तमान में अंतिम है) लेकिन यह अच्छी तरह से चाल करने के लिए लगता है।
किकेटो सेप

20

मेरे प्रश्न के सुझावों के आधार पर, यहाँ मैंने क्या किया:

function WriteCreatingDirs()
    execute ':silent !mkdir -p %:h'
    write
endfunction
command W call WriteCreatingDirs()

यह :Wकमांड को परिभाषित करता है । आदर्श रूप में, मैं के सभी करना चाहते हैं :w!, :wq, :wq!, :wallएक ही काम करते हैं आदि, लेकिन मुझे यकीन है कि अगर यह मूल रूप से उन्हें सभी कस्टम कार्यों के साथ reimplementing बिना संभव है नहीं कर रहा हूँ।


2
मैंने इसी कमांड की कोशिश की है और हर बार जब मैं उपयोग करता हूं :W, तो मेरी स्क्रीन लगभग खाली हो जाती है। मैं कोशिश करूंगा और अपने पिछले विकल्पों को हटाकर प्रतिक्रिया दूंगा।
moebius_eye

6

मैंने इसे अपने ~ / .vimrc में जोड़ा

cnoremap mk. !mkdir -p <c-r>=expand("%:h")<cr>/

अगर मुझे निर्देशिका बनाने की आवश्यकता है जो मैं टाइप कर रहा हूं :mk.और यह "mkdir -p / path / to / my / file /" के साथ बदल देता है और मुझे इसे लागू करने से पहले कमांड की समीक्षा करने की अनुमति देता है।



3

यह कोड आपको निर्देशिका बनाने :w, या बस इसके साथ करने के लिए संकेत देगा :w!:

augroup vimrc-auto-mkdir
  autocmd!
  autocmd BufWritePre * call s:auto_mkdir(expand('<afile>:p:h'), v:cmdbang)
  function! s:auto_mkdir(dir, force)
    if !isdirectory(a:dir)
          \   && (a:force
          \       || input("'" . a:dir . "' does not exist. Create? [y/N]") =~? '^y\%[es]$')
      call mkdir(iconv(a:dir, &encoding, &termencoding), 'p')
    endif
  endfunction
augroup END

1

मुझे लगता है कि मैं तीन पंक्तियों में ऐसा करने में कामयाब रहा, जो इस उत्तर पर अन्य कह रहे हैं।

यह चाल करने के लिए लगता है:

if has("autocmd")
  autocmd BufWritePre * :silent !mkdir -p %:p:h
end

यह बफर को सहेजते समय फ़ोल्डर को स्वचालित रूप से बनाने का प्रयास करता है। अगर कुछ भी बुरा होता है (यानी अनुमति जारी करता है) तो यह बस बंद हो जाएगा और फ़ाइल को विफल होने दें।

यदि किसी को कोई स्पष्ट दोष दिखाई देता है, तो कृपया एक टिप्पणी पोस्ट करें। मैं विम्सस्क्रिप्ट में बहुत पारंगत नहीं हूं।

संपादित करें: नोट्स ZyX के लिए धन्यवाद

  • यह तब काम नहीं करेगा जब आपके फ़ोल्डर में जगह होगी (जाहिर है कि वे ठीक से बच नहीं रहे हैं या कुछ और)
  • या अगर आप छद्म फाइलें कर रहे हैं।
  • या अगर आप अपने vimrc सोर्स कर रहे हैं।
  • लेकिन बेटा, यह छोटा है।

1
%इस तरह की लिपियों में कभी प्रयोग न करें । उदाहरण के लिए, आप नाम की एक फ़ाइल संपादन कर रहे हैं, तो: विम किसी विशेष प्रतीकों से बचने के लिए नहीं जा रहा है /mnt/windows/Documents and Settings/User/_vimrcआप चार नए निर्देशिका होने खत्म हो जाएगा: /mnt/windows/Documents, ./and, ./Settingsऔर ./Settings/User। और, वैसे, आपको :executeयहाँ की आवश्यकता नहीं है।
ज़ीएक्स

1
नहीं है system()पूरी तरह से चुप खोल कॉल के लिए समारोह, लेकिन आप दोनों की जरूरत नहीं है :executeऔर %:p:h: :silent !mkdir -p %:p:h(हालांकि आप की आवश्यकता हो सकती है कि तुम क्या लिखा है के रूप में वास्तव में काम करता है :redraw!, अंत में इस मामले में :executeकाम आता है), लेकिन यह उपयोग करने के लिए बेहतर है call system('mkdir -p '.shellescape(expand('%:p:h')))। उपयोग करते हैं :execute '!command' shellescape(arg, 1)(shellescape को दूसरा तर्क के साथ) आप के बजाय बैंग्स उपयोग करने के लिए है, तो system()। बैंग का उपयोग करें यदि बच तर्क में newlines शामिल हैं।
ज़ीएक्स

और आप अन्य परेशानियों से नहीं बचते हैं, मैं अपने पहले कोड स्निपेट में टाल रहा हूं: प्रत्येक vimrc सोर्सिंग के बाद शेल को एक अतिरिक्त समय में लॉन्च करना (ऐसा करने से आप vimrc अपडेट में खींचते हैं :source ~/.vimrc) (यह वही है augroupऔर autocmd!इसके लिए हैं), शेल को खोलने के बाद स्क्रैप किया गया दृश्य कमांड (जो कि redraw!इसके लिए है), छद्म फाइलों का उपयोग करने के मामले में कचरा निर्देशिकाओं का निर्माण कर रहा है (पहले कोड में छीन लिया गया यह केवल एक पैटर्न के खिलाफ फ़ाइल नाम से मेल खाता है, लेकिन दूसरे में मैं भी जांचता हूं &buftype) और मामले निर्देशिका में बेकार शेल कॉल मौजूद ( isdirectory()स्थिति)।
ज़ीएक्स

1
@ZyX आपकी प्रतिक्रिया के लिए धन्यवाद। मैं उन समस्याओं को हल नहीं करना चाहता जो मेरे पास नहीं हैं। मैं अपने फ़ोल्डरों पर कभी भी विशेष वर्ण (यानी रिक्त स्थान) का उपयोग नहीं करता, इसलिए%: p: h मेरे लिए ठीक है। मैं कभी भी विमिंस का स्रोत नहीं होता (मैं इसके बजाय विम को मारता हूं और फिर से खोल देता हूं) और मुझे यह भी नहीं पता है कि स्यूडोफाइल्स क्या हैं। पुनः बनाने! मुझे कुछ भी करने के लिए प्रतीत नहीं होता है। लेकिन मुझे सब कुछ छोटा करने के लिए अमल को हटाने का आपका सुझाव पसंद है। चीयर्स!
किक्टो सेप

1
इससे कोई फर्क नहीं पड़ता कि आपके पास विशेष पात्र हैं या नहीं, यह वह चीज है जिसके बारे में आपको ध्यान रखना चाहिए। किसी को भी %इसका उपयोग करने का सुझाव देने के लिए विस्तार के साथ बहुत अधिक समस्याएं हैं । छद्म फ़ाइलों का उपयोग प्लगइन्स के एक बड़े समूह में किया जाता है (जैसे भगोड़ा या मेरे aurum), इस प्रकार वे देखभाल करने के लायक हैं। Vimrc को रीसर्च करना भी एक आम बात है। आपके पास vimrc में जो कुछ भी आप चाहते हैं, बस एक उत्तर के रूप में सुझाव नहीं दे सकते हैं। :silent! call mkdir(expand('%:p:h'), 'p')मेरे द्वारा उल्लेख किए गए दो बिंदुओं के भिन्न प्रकारों का उपयोग करते हुए और तीसरा जिसका मैंने उल्लेख नहीं किया है: !mkdirखिड़कियों पर काम करने वाला नहीं है।
ZyX
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.