it-swarm.com.de

Vim: Erstellen von übergeordneten Verzeichnissen beim Speichern

Wenn ich vim foo/bar/somefile aber foo/bar gibt es noch nicht, Vim weigert sich zu speichern.

Ich weiß, ich könnte zu einer Shell wechseln oder :!mkdir foo/bar von Vim, aber ich bin faul :) Gibt es eine Möglichkeit, Vim dazu zu bringen, dies automatisch zu tun, wenn der Puffer gespeichert wird?

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

Beachten Sie die folgenden Bedingungen: expand("<afile>")!~#'^\w\+:/' verhindert, dass vim Verzeichnisse für Dateien wie ftp://* Und !isdirectory Erstellt. Dies verhindert teure mkdir-Aufrufe.

pdate: etwas bessere Lösung, die auch nach nicht leeren Buftypen sucht und mkdir() verwendet:

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
86
ZyX

Basierend auf den Vorschlägen zu meiner Frage, hier ist, was ich am Ende mit:

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

Dies definiert die :W Befehl. Idealerweise hätte ich gerne alle :w!, :wq, :wq!, :wall etc funktionieren genauso, aber ich bin mir nicht sicher, ob dies möglich ist, ohne sie alle mit benutzerdefinierten Funktionen neu zu implementieren.

18
Damien Pollet

Ich habe dies zu meinem ~/.vimrc hinzugefügt

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

Wenn ich das Verzeichnis erstellen muss, in dem ich mich befinde, tippe ich :mk. und es ersetzt dies durch "! mkdir -p/path/to/my/file /" und ermöglicht mir, den Befehl zu überprüfen, bevor ich ihn aufrufe.

6
Asa Ayers

Ich machte :saveas! Erstellen Sie das Verzeichnis, falls es fehlt: https://github.com/henrik/dotfiles/commit/54cc9474b345332cf54cf25b51ddb8a9bd00a0bb

3
Henrik N

Dieser Code fordert Sie auf, das Verzeichnis mit :w Zu erstellen, oder tun Sie es einfach mit :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
3
Tom Hale

Ich glaube, ich habe es in drei Zeilen geschafft, das zu kombinieren, was andere zu dieser Antwort sagen.

Dies scheint den Trick zu tun:

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

Es wird versucht, den Ordner beim Speichern eines Puffers automatisch zu erstellen. Wenn etwas Schlimmes passiert (d. H. Berechtigungsprobleme), wird es einfach heruntergefahren und das Schreiben der Datei schlägt fehl.

Wenn jemand offensichtliche Mängel sieht, schreibe bitte einen Kommentar. Ich bin nicht sehr vertraut mit Vimscript.

EDIT: Notizen dank ZyX

  • Dies funktioniert nicht, wenn Ihre Ordner Leerzeichen enthalten (anscheinend sind sie nicht richtig geschützt oder so).
  • Oder wenn Sie Pseudodateien machen.
  • Oder wenn Sie Ihr vimrc beschaffen.
  • Aber mein Sohn, es ist kurz.
1
kikito