Vim:保存時に親ディレクトリを作成する


122

呼び出してvim foo/bar/somefilefoo/barまだ存在していない、Vimは、保存することを拒否します。

シェルに切り替えたり:!mkdir foo/barVimから実行したりできることは知っていますが、怠惰です:) Vimがバッファーを保存するときに自動的にそれを実行する方法はありますか?


13
mkdir -p %:hネストされた存在しないパスに対して機能し、パスが既に存在し、%:h現在のファイルの完全パスである場合にエラーを発生させないため、より優れています。ただし、これを自動的に呼び出す方法はわかりません。通常、これはautomcommandsで行われますが、BufWritePreイベントはここでは機能しないようです。
Konrad Rudolph

ファイルが存在するかどうかをチェックし、組み込みwriteを呼び出し、それ以外の場合はシステムを呼び出す関数を定義mkdir -pdirnameます。マップしWます...構文を検索して回答として投稿するのが
面倒

1
私はあなたの提案とエイリアスの両方を組み合わせることができ推測:wmkdir -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コールを防ぐことができます。

更新:空ではない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
おかげで、私がハッキングしたものよりもずっときれいに見えます:)
Damien Pollet

11
call mkdir(expand('%:h'), 'p')よりポータブルになるかもしれません。
Marius Gedminas

1
@MariusGedminasその変更を含む完全なコードを見たいのですが。回答として投稿してください/どこかにアップロードしてください。
kikito 2012

@kikito私の答えを見てください。そのコメントの数時間後に編集されました。
ZyX 2012

@Zyxありがとう!私は少し短いことをやった(私の答えは現在最後のものです)が、うまくトリックを行うようです。
kikito 2012

20

私の質問への提案に基づいて、これが私が結局終わったものです:

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

これは:Wコマンドを定義します。理想的には、私はすべてを持っているしたいのですが:w!:wq:wq!:wallなどが同じように動作しますが、それは基本的にすべてのカスタム関数でそれらを再実装することなく可能だ場合、私はわかりません。


2
私はこれと同じコマンドを試しましたが:W、を使用するたびに、画面がほとんど空白になります。以前のオプションを削除して、フィードバックします。
moebius_eye 2016

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

私はこれを3行で行うことができたと思います。他の人がこの答えで言っていることを組み合わせて。

これはトリックを行うようです:

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

バッファを保存するときに、自動的にフォルダを作成しようとします。何か悪いことが起こった場合(つまり、権限の問題)、シャットダウンしてファイルの書き込みを失敗させます。

明らかな欠陥を見つけた場合は、コメントを投稿してください。私はvimscriptに精通していません。

編集:ZyXのおかげでメモ

  • フォルダにスペースがある場合、これは機能しません(どうやら、適切にエスケープされていないなど)。
  • または、疑似ファイルを実行している場合。
  • または、vimrcを調達している場合。
  • しかし、息子、それは短いです。

1
%このようなスクリプトでは使用しないでください。たとえば、あなたが名前のファイル編集している場合:Vimは特別な記号をエスケープするつもりはない/mnt/windows/Documents and Settings/User/_vimrc:あなたは4つの新しいディレクトリを持つことになりますが/mnt/windows/Documents./and./Settings./Settings/User。ちなみに、:executeここでは必要ありません。
ZyX 2012

1
system()完全に無音のシェル呼び出し用の関数がありますが、:executeand は必要ありません%:p:h。::silent !mkdir -p %:p:hは記述したとおりに機能しますが(:redraw!最後に必要になる場合もありますが、この場合:executeは便利です)、を使用することをお勧めしますcall system('mkdir -p '.shellescape(expand('%:p:h')))。の:execute '!command' shellescape(arg, 1)代わりにbangを使用する必要がある場合は、(shellescapeの2番目の引数と共に)を使用してくださいsystem()。エスケープされた引数に改行が含まれる場合は、前髪を使用してください。
ZyX 2012

起動シェルごとのvimrcは(あなたが実行してのvimrcのアップデートで引っ張る想定調達後にもう1回:そして、あなたは私が私の最初のコードスニペットで回避しています他のトラブルを回避していない:source ~/.vimrc(これは何ですか)augroupautocmd!、シェルを起動した後に廃棄ビューをするためのものであるが)コマンド(つまりredraw!)、疑似ファイルを使用する場合にガベージディレクトリを作成(最初のコードでは、ファイル名をパターンと照合することによってのみチェックされますが、2番目のコードでもチェックします&buftype)、およびケースディレクトリでの無用なシェル呼び出しあり(isdirectory()状態)。
ZyX 2012

1
@ZyXご意見ありがとうございます。自分が抱えていない問題を解決したくない。私はフォルダで特別な文字(つまりスペース)を使用したことがないので、%:p:hで十分です。私はvimrcをソースすることはなく(代わりにvimを強制終了して再度開きます)、疑似ファイルが何であるかもわかりません。再描画!私には何もしないようです。しかし、私はすべてを短くするために実行を削除するというあなたの提案が好きです。乾杯!
kikito 2012

1
特殊文字を持っているかどうかは関係ありませんが、気にする必要があります。%拡張に関する問題が多すぎて、だれにもそれを使用することを提案できません。疑似ファイルは、多数のプラグイン(たとえば、逃亡者や私のオーラム)で使用されているため、注意する価値があります。vimrcのリソーシングも一般的な方法です。vimrcには何でも入れることができますが、答えとして提案しないでください。:silent! call mkdir(expand('%:p:h'), 'p')バリアントを使用すると、私が言及した2つのポイントと、3つ目は言及しなかった3つのポイントが解決さ!mkdirれます。ウィンドウでは機能しません。
ZyX
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.