Vim: создание родительских каталогов при сохранении
Если я вызываю vim foo/bar/somefile
, но foo/bar
еще не существует, Vim отказывается сохранять.
Я знаю, что могу переключиться на оболочку или сделать :!mkdir foo/bar
у Vim, но я ленивый:)
Есть ли способ заставить Vim делать это автоматически, когда он сохраняет буфер?
Ответы
Ответ 1
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
Ответ 2
Основываясь на предложениях по моему вопросу, вот что я закончил с:
function WriteCreatingDirs()
execute ':silent !mkdir -p %:h'
write
endfunction
command W call WriteCreatingDirs()
Это определяет команду :W
. В идеале, я бы хотел, чтобы все теги :w!
, :wq
, :wq!
, :wall
и т.д. Работали одинаково, но я не уверен, что это возможно, не переосмысливая их полностью пользовательскими функциями.
Ответ 3
Я добавил это к своему ~/.vimrc
cnoremap mk. !mkdir -p <c-r>=expand("%:h")<cr>/
Если мне нужно создать каталог, в котором я есть, введите :mk.
, и он заменит это на "! mkdir -p/path/to/my/file/" и позволяет мне просмотреть команду, прежде чем я ее вызову.
Ответ 4
Я создал :saveas!
создать каталог, если отсутствует: https://github.com/henrik/dotfiles/commit/54cc9474b345332cf54cf25b51ddb8a9bd00a0bb
Ответ 5
Этот код предложит вам создать каталог с :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
Ответ 6
Я думаю, мне удалось сделать это в трех строках, объединив то, что другие говорят об этом ответе.
Это похоже на трюк:
if has("autocmd")
autocmd BufWritePre * :silent !mkdir -p %:p:h
end
Он пытается создать папку автоматически при сохранении буфера. Если что-то плохое происходит (например, проблемы с разрешениями), оно просто заткнется и позволит файлу сбой записи.
Если кто-либо видит какие-либо очевидные недостатки, отправьте комментарий. Я не очень разбираюсь в vimscript.
EDIT: Заметки благодаря ZyX
- Это не будет работать, если в ваших папках есть пробелы (видимо, они не экранированы или что-то не так)
- Или если вы делаете псевдофайлы.
- Или, если вы используете ваш vimrc.
- Но сын, это коротко.