मैं किसी निर्देशिका में किसी फ़ाइल को कैसे सहेज सकता हूं जो अभी तक मौजूद नहीं है?


35

मान लीजिए कि मैं एक निर्देशिका में एक नई फ़ाइल को संपादित करने के लिए विम शुरू करता हूं जो अभी तक नहीं बनाई गई है:

vim nonExisitingDirectory/newFile.txt

विम मुझे खुशी से एक खाली बफर दिखाएगा और मैं अपनी नई फ़ाइल लिखना शुरू कर सकता हूं। लेकिन जब मैं फ़ाइल को डिस्क पर लिखना चाहता हूं तो मुझे यह त्रुटि मिलती है:

E212: Can't Open file for writing.

मुझे लगता है कि यह है क्योंकि निर्देशिका अभी तक मौजूद नहीं है। क्या मेरे लिए निर्देशिका बनाने में विम को मजबूर करने का एक तरीका है?

जवाबों:


37

जहां तक ​​मुझे पता है कि ऐसा करने के लिए कोई सेटिंग या कुछ ऐसा नहीं है। लेकिन सभी खो नहीं है, हम निश्चित रूप से BufWritePreऑटोकॉमैंड का उपयोग कर सकते हैं ।
डिस्क पर बफ़र लिखे जाने से पहले इसे निष्पादित किया जाता है। तो अगर हम अभी तक मौजूद नहीं हैं तो हम वहां निर्देशिका बना सकते हैं।

उदाहरण के लिए:

augroup Mkdir
  autocmd!
  autocmd BufWritePre *
    \ if !isdirectory(expand("<afile>:p:h")) |
        \ call mkdir(expand("<afile>:p:h"), "p") |
    \ endif
augroup END
  • हम पहले जाँचते हैं कि क्या निर्देशिका मौजूद है isdirectory, अन्यथा mkdirकोई त्रुटि देता है।
  • <afile>उस फ़ाइल को संदर्भित करता है जिसे हम सहेजने की कोशिश कर रहे हैं; :pपूर्ण पथनाम (सापेक्ष के बजाय) में इसका विस्तार करने के लिए एक संशोधक है, और :hअंतिम पथ घटक (फ़ाइल) को निकालता है।
  • mkdir()यदि आवश्यक हो तो हम फिर फोन करते हैं । सभी माता-पिता निर्देशिका (यानी के मामले में) बनाने के pलिए हमें ध्वज की आवश्यकता mkdir()है nonexistent/more_nonexisting/file

आप निश्चित रूप mkdir()से, विम कमांडलाइन से कमांड चला सकते हैं , या इसे कीबाइंड पर बाँध सकते हैं, अर्थात:

nnoremap <Leader>m :call mkdir(expand("%:p:h"), "p")<CR>

यहाँ मैंने %इसके बजाय प्रयोग किया है <afile>, क्योंकि यह केवल एक ऑटोकॉमैंड के भीतर से मान्य है ( %वर्तमान में सक्रिय बफ़र को संदर्भित करता है, जो :waउदाहरण के साथ नहीं होगा । <afile>बफ़र के फ़ाइलनाम को संदर्भित करता है जो ऑटोकैम को चलाता है)।

यदि आप चाहें तो एक निर्देशिका लिखने से पहले आप इसकी पुष्टि भी कर सकते हैं। अधिक विवरण के लिए यह प्रश्न देखें: मैं BufWritePre ऑटोकेमैंड में फ़ाइल लिखने से विम को कैसे रोक सकता हूं?


उपरोक्त स्निपेट पहले लिखने पर निर्देशिका बनाएगा ( :w)। यदि आप चाहते थे, तो निर्देशिका को तब भी बना सकते हैं जब आप पहली बार इसे खोलते हैं (यानी टाइप करने के बाद vim ...) BufNewFileइसके बजाय ऑटोकैम का उपयोग करके BufWritePre


इसमें auto_mkdir नाम का एक प्लगइन भी है जो प्रभावी रूप से ऊपर वाला ही है।

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

call mkdir(iconv(expand("%:p:h"), &encoding, &termencoding), 'p')

मुझे यकीन नहीं है कि यह वास्तव में आवश्यक है, लेकिन यदि आप एन्कोडिंग को बहुत मिलाते हैं और अजीब फ़ाइल नाम प्राप्त करते हैं, तो आप इसे आज़मा सकते हैं।


मैं आसान स्थापना के लिए एक auto_mkdir2.vimप्लगइन में उपरोक्त सभी डाल दिया ।


3

मैं टिम पोप से एक विम प्लगइन की सिफारिश कर सकता हूं जिसे विम-यूनुच कहा जाता है जो कई बेहद उपयोगी आदेशों को परिभाषित करता है जब विम के साथ यूनिक्स / लिनक्स पर आपका काम ( इसकी विशेषताओं की जांच करें !)।

मान लीजिए कि आप के साथ विम खोलते हैं vim this/is/a/testऔर इनमें से कोई भी निर्देशिका पहले मौजूद नहीं है। बस चलाएं :Mkdir!<CR>और vim-eunuch उन्हें आपके लिए (साथ mkdir -p) बनाता है , जिससे आप अब अपनी फ़ाइल को सहेज सकते हैं :w<CR>


2

:Wफ़ाइल और उसकी मूल निर्देशिका बनाने के लिए उपयोग करें :

function! s:WriteCreatingDirs()
  let l:file=expand("%")
  if empty(getbufvar(bufname("%"), '&buftype')) && l:file !~# '\v^\w+\:\/'
    let dir=fnamemodify(l:file, ':h')
    if !isdirectory(dir)
      call mkdir(dir, 'p')
    endif
  endif
  write
endfunction
command! W call s:WriteCreatingDirs()

(अपने को जोड़ें vimrcZyx के उत्तर और डेमियन पोललेट के उत्तरों के संयोजन के आधार पर )।


1

वेनिला विम (अतिरिक्त आत्मविश्वास या प्लगइन्स के बिना) के साथ एक और तरीका। विम में:

:!mkdir -p /folder/you/want/
:w  #save file

या

$ vim /folder/you/want/myfile.conf
$ ctrl+z # switch to the terminal then create the folders
$ mkdir -p /folder/you/want/
$ fg # return to Vim
$ :w  #save file

1

मुझे लगता है कि वर्कफ़्लो को व्यवस्थित करने के लिए उपरोक्त उत्तरों पर बनने वाले संस्करण को योगदान देने की उम्मीद है, बस इतना ही। मैं अक्सर प्रोजेक्ट संरचनाओं की एक विस्तृत श्रृंखला के भीतर नई फाइलें बना रहा हूं। यह ट्विक मुझे समय की एक ठोस राशि बचाएगा।

दो निर्भरताएं हैं जो मैं सोच सकता हूं:

  1. मैं यह निर्धारित autochdirकरता <C-x><C-f>हूं कि यह मेरे आयात विवरणों के साथ कैसे काम करता है ।
  2. saveas"पीछे छोड़ देता है" (यदि आप) में छिपा बफर अंत बफर सूची की। मुझे यकीन नहीं है कि अगर यह राज्य व्यवहार है कि सभी vim / nvim उदाहरणों का आनंद लें।
  3. अन्य FYI करें: मैं एक मैक ओएस पर NVIM का उपयोग करता हूं

    " Auto magically Mkdir
    " ====================
    
    autocmd BufWritePre * call MkDir()
    
    function! MkDir()
       if !isdirectory(expand("<afile>:p:h"))
          let confirmation=confirm("Create a new directory?", "&Yes\n&No")
          if confirmation == 1
             call mkdir(expand("<afile>:p:h"), "p")
             lcd %:p:h
             saveas %:t
             echom "Created a new directory:" expand("<afile>:p:h")
             let buf_del = bufnr("$")
             exe "bd" . buf_del
          endif
          redraw
       endif
    endfunction
    
    " Conditionaly create the parent directory when writing to disk
    " <afile> refers to the file we are saving
    " :p is a modifier that expands to full filename
    " :h is a modifier that removes the file from full filename
    " :t is a modifier that generates the filename with extension
    " "p" is the flag that will create all the parent directories
    
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.