Bir dosyayı henüz bulunmayan bir dizine nasıl kaydederim?


35

Diyelim ki henüz oluşturulmamış bir dizindeki yeni bir dosyayı düzenlemek için Vim'i başlattım:

vim nonExisitingDirectory/newFile.txt

Vim bana mutlu bir şekilde boş bir tampon gösterecek ve yeni dosyamı yazmaya başlayacağım. Ancak dosyayı diske yazmak istediğimde bu hatayı alıyorum:

E212: Can't Open file for writing.

Sanırım, dizin henüz mevcut değil. Vim'i benim için dizini oluşturmaya zorlamanın bir yolu var mı?

Yanıtlar:


37

Bildiğim kadarıyla, bunu yapacak herhangi bir ayar veya bazı yoktur. Fakat hepsi kaybolmaz, elbette BufWritePreotomatik komutu kullanabiliriz .
Bu, arabellek diske yazılmadan önce yürütülür. Böylece henüz mevcut değilse, oradaki dizini oluşturabiliriz.

Örneğin:

augroup Mkdir
  autocmd!
  autocmd BufWritePre *
    \ if !isdirectory(expand("<afile>:p:h")) |
        \ call mkdir(expand("<afile>:p:h"), "p") |
    \ endif
augroup END
  • İlk önce dizinin var olup olmadığını kontrol ederiz isdirectory, aksi halde mkdirhata verir.
  • <afile>kaydetmeye çalıştığımız dosyayı ifade eder; :ptam yol adına genişletmek için bir değiştiricidir (göreceli değil) ve :hson yol bileşenini (dosya) kaldırır.
  • mkdir()Gerekirse arayacağız . Tüm ebeveyn dizinlerini yapmak için pbayrağa ihtiyacımız var mkdir()(yani nonexistent/more_nonexisting/file.

Elbette, mkdir()Vim komut satırından da komutu çalıştırabilir veya bir tuşa bağlayabilirsiniz, yani:

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

Burada , %bunun yerine <afile>sadece bir otokomun içinden geçerli olduğu %için kullandım (şu anda aktif olan arabelleğe başvuruyor, :waörneğin çalışmayan ; <afile>otocmd'yi tetikleyen arabelleğin dosya adını ifade ediyor).

İsterseniz bir dizin yazmadan önce onay isteyebilirsiniz. Daha fazla ayrıntı için bu soruya bakın: Vim'in BufWritePre otomatik komutunda bir dosya yazmasını nasıl durdurabilirim?


Yukarıdaki kod parçası, ilk write ( :w) dizinini oluşturur . İsterseniz, ilk açtığınızda (yani sadece yazdıktan hemen sonra vim ...) BufNewFileyerine autocmd'yi kullanarak da dizin oluşturabilirsiniz BufWritePre.


Ayrıca auto_mkdir adında bir eklenti var ve bu da yukarıdakilerle aynı.

Bu sayfada , ilk önce dizini oluşturmak isteyip istemediğinizi soran, bazılarının yararlı olabileceğini düşünen hafifçe genişletilmiş bir snippet var. Ayrıca, yazmadan önce kodlamanın dosya adını da dönüştürür:

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

Gerçekte bunun gerekli olup olmadığından emin değilim, ama kodlamaları çok karıştırırsanız ve garip dosya isimleri alırsanız, deneyebilirsiniz.


Kolay kurulum için yukarıdakilerin tümünü bir auto_mkdir2.vimeklentiye yerleştirdim.


3

Tim Pope'den vim-eunuch adında bir VIM eklentisi önerebilirim. Bu , UNIX / Linux üzerinde Vim ile çalışmanız durumunda birçok yararlı komutu tanımlar ( özelliklerini inceleyin !).

Vim ile açtığınızı vim this/is/a/testve bu dizinlerden hiçbirinin daha önce bulunmadığını varsayalım . Sadece çalıştırın :Mkdir!<CR>ve vim-eunuch sizin için yaratır (ile mkdir -p), böylece artık dosyanızı kaydedebilirsiniz :w<CR>.


2

:WBir dosya ve onun ana dizinlerini oluşturmak için kullanın :

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()

(Size ekleyin vimrc. Zyx'in cevabı ve Damien Pollet'in cevaplarının bir kombinasyonuna dayanarak ).


1

Vanilya Vim ile başka bir yol (fazladan conf veya eklentileri olmadan). Vim'de:

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

veya

$ 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

İş akışını daha da kolaylaştırmak için yukarıdaki cevaplara dayanan bir versiyona katkıda bulunmayı umuyorum. Genellikle çok çeşitli proje yapıları içinde yeni dosyalar oluşturuyorum. Bu ince ayar bana sağlam bir zaman kazandıracak.

Aklıma gelen iki bağımlılık var:

  1. İçe aktarma ifadelerimin autochdirnasıl çalıştığı nedeniyle ayarladım <C-x><C-f>.
  2. saveas"arkasında yapraklar" (eğer olacak) bir gizli tampon sonunda tampon listesinin. Tüm vim / nvim örneklerinin zevk aldığı durum davranışı olup olmadığından emin değilim.
  3. Diğer FYI: Mac OS'ta NVIM kullanıyorum

    " 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
    
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.