Vim: Kaydederken ana dizinler oluşturma


122

Çağırırsam vim foo/bar/somefileama foo/barhalihazırda var olmazsam, Vim kaydetmeyi reddediyor.

Bir kabuğa geçebileceğimi veya :!mkdir foo/barVim'den yapabileceğimi biliyorum ama tembelim :) Arabelleği kaydettiğinde Vim'in bunu otomatik olarak yapmasını sağlamanın bir yolu var mı?


13
mkdir -p %:hdaha iyidir çünkü iç içe geçmiş olmayan yollar için çalışır, yol zaten var olduğunda bir hata %:holuşturmaz ve geçerli dosyanın tam yolu budur. Ancak, bunu otomatik olarak nasıl çalıştıracağımı bilmiyorum. Normalde bu otomatik komutlarla yapılır, ancak BufWritePreolay burada çalışmıyor gibi görünüyor.
Konrad Rudolph

Dosya kontrolleri varsa ve yerleşiğini çağıran bir fonksiyon tanımlanır writeve sistemin çağırır mkdir -püzerinde dirnameaksi halde, eşlemek W... Ben sözdizimi aramak ve bir cevap olarak göndermek için çok tembelim ... Üzgünüm
Khaçik

1
Ben önerilerinizi ve takma hem birleştirmek sanırım :whiç mkdir -p %:hbuilting ardından:write
Damien POLLET

Yanıtlar:


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

Koşullara dikkat edin: expand("<afile>")!~#'^\w\+:/'vim'in pahalı mkdir çağrısı gibi dosyalar için dizin oluşturmasını engelleyecek ftp://*ve !isdirectoryönleyecektir.

Güncelleme : Boş olmayan buftype'ı da kontrol eden ve aşağıdakileri kullanan biraz daha iyi bir çözüm 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
Teşekkürler, tahmin ettiğimden çok daha temiz görünüyor :)
Damien Pollet

11
call mkdir(expand('%:h'), 'p')daha taşınabilir olabilir.
Marius Gedminas

1
@MariusGedminas Bu değişiklikle birlikte kodun tamamını görmek istiyorum. Lütfen cevap olarak gönderebilir / bir yere yükleyebilir misiniz?
kikito

@kikito Cevabımı gör. Bu yorumdan birkaç saat sonra düzenlendi.
ZyX

@Zyx teşekkürler! Biraz daha kısa bir şey yaptım (cevabım şu anda sonuncusu) ama işi güzelce yapıyor gibi görünüyor.
kikito

20

Soruma verilen önerilere dayanarak, işte şunu buldum:

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

Bu, :Wkomutu tanımlar . İdeal olarak, ben hepsine sahip istiyorum :w!, :wq, :wq!, :wallaynı işe vs, ama temelde özel fonksiyonları ile hepsini reimplementing olmadan mümkün olup olmadığından emin değilim.


2
Aynı komutu denedim ve her kullandığımda :Wekranım neredeyse boş oluyor. Önceki seçeneklerimi kaldırmaya çalışacağım ve geri bildirimde bulunacağım.
moebius_eye

6

Bunu ~ / .vimrc dosyama ekledim

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

Bulunduğum dizini oluşturmam gerekirse, yazıyorum :mk.ve bu dizini "! Mkdir -p / yol / / / dosyam /" ile değiştiriyor ve komutu çalıştırmadan önce gözden geçirmeme izin veriyor.



3

Bu kod sizden dizini oluşturmanızı :wveya sadece şununla yapmanızı ister :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

Sanırım bunu, başkalarının bu cevapta söylediklerini birleştirerek üç satırda yapmayı başardım.

Bu hile yapıyor gibi görünüyor:

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

Bir arabelleği kaydederken klasörü otomatik olarak oluşturmaya çalışır. Kötü bir şey olursa (örneğin izin sorunları), sadece kapanır ve dosya yazma işleminin başarısız olmasına izin verir.

Herhangi biri bariz bir kusur görürse, lütfen bir yorum gönderin. Vimscript konusunda pek bilgili değilim.

DÜZENLEME: ZyX sayesinde notlar

  • Klasörlerinizde boşluklar varsa bu işe yaramayacaktır (görünüşe göre bunlar düzgün şekilde önlenmemiş veya başka bir şey)
  • Ya da sözde dosyalar yapıyorsanız.
  • Ya da vimrc'nizi tedarik ediyorsanız.
  • Ama oğlum, bu kısa.

1
Asla %bu tür komut dosyalarında kullanmayın . Örneğin, adlı bir dosya düzenleme ise: Vim özel simgeleri kaçmaya gitmiyor /mnt/windows/Documents and Settings/User/_vimrc: Eğer dört yeni dizinleri sahip sona erecek /mnt/windows/Documents, ./and, ./Settingsve ./Settings/User. Ve bu arada, :executeburaya ihtiyacın yok.
ZyX

1
system()Tamamen sessiz kabuk çağrıları için bir işlev vardır , ancak her ikisine de ihtiyacınız yoktur :executeve %:p:h: :silent !mkdir -p %:p:htam olarak yazdığınız gibi çalışır ( :redraw!sonunda ihtiyacınız olsa da , bu durumda :executeişe yarar), ancak kullanmak daha iyidir call system('mkdir -p '.shellescape(expand('%:p:h'))). Bunun :execute '!command' shellescape(arg, 1)yerine patlama kullanmak zorunda kalırsanız (shellescape için ikinci argümanla) kullanın system(). Kaçan bağımsız değişken yeni satırlar içeriyorsa patlama kullanın.
ZyX

Ve ilk kod parçamda kaçındığım diğer sorunlardan da kaçınmıyorsunuz: kabuğu her vimrc kaynağından sonra bir kez daha başlatmak (vimrc güncellemelerini yaparak bunu yaptığınızı varsayarak :source ~/.vimrc) (bu ne augroupve ne autocmd!içindir), kabuğu başlattıktan sonra hurda görünüm komutlar (bunun redraw!için), sözde dosyalar kullanılması durumunda çöp dizinleri oluşturma (ilk kodda, yalnızca bir kalıpla eşleşen dosya adıyla kontrol edilir, ancak ikincisinde de kontrol ederim &buftype) ve case dizininde işe yaramaz kabuk çağrısı var ( isdirectory()durum).
ZyX

1
@ZyX Geri bildiriminiz için teşekkürler. Sahip olmadığım sorunları çözmek istemiyorum. Klasörlerimde asla özel karakterler (yani boşluklar) kullanmıyorum, bu yüzden%: p: h benim için yeterli. Asla vimrc kaynağı oluşturmam (onun yerine vim'i öldürüp yeniden açıyorum) ve sahte dosyaların ne olduğunu bile bilmiyorum. yeniden çizme! bana hiç bir şey yapmıyor gibi görünüyor. Ama her şeyi kısaltmak için execute'u kaldırma önerinizi beğendim. Şerefe!
kikito

1
Özel karakterinizin olup olmadığı önemli değil, önemsemeniz gereken şey bu. %Genişlemeyle ilgili herhangi birine kullanmayı öneremeyecek kadar çok sorun var . Sözde dosyalar çok sayıda eklentide kullanılır (örn. Kaçak veya benim aurum), bu yüzden önemsemeye değer. Vimrc'ye kaynak sağlamak da yaygın bir uygulamadır. Vimrc'de istediğiniz her şeye sahip olabilirsiniz, sadece cevap olarak önermeyin. :silent! call mkdir(expand('%:p:h'), 'p')Değişken kullanmak , bahsettiğim ve üçüncüsü bahsetmediğim noktalardan ikisini çözer: !mkdirpencerelerde çalışmayacak.
ZyX
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.