Se eu chamar, vim foo/bar/somefile
mas foo/bar
ainda não existir, o Vim se recusará a salvar.
Eu sei que poderia mudar para um shell ou fazer a :!mkdir foo/bar
partir do Vim, mas sou preguiçoso :) Existe uma maneira de fazer o Vim fazer isso automaticamente quando ele salva o buffer?
mkdir -p %:h
é melhor porque funciona para caminhos não existentes aninhados, não gera um erro quando o caminho já existe e%:h
é o caminho completo do arquivo atual. No entanto, não sei como invocar isso automaticamente. Normalmente, isso é feito com comandos automáticos, mas oBufWritePre
evento parece não funcionar aqui.write
e chama o sistemamkdir -p
emdirname
caso contrário, mapeá-lo paraW
... Eu sou muito preguiçoso para procurar a sintaxe e postá-lo como uma resposta ... Desculpe:w
paramkdir -p %:h
segui-las:write
Respostas:
Observe as condições:
expand("<afile>")!~#'^\w\+:/'
impedirá o vim de criar diretórios para arquivos comoftp://*
e!isdirectory
evitará chamadas caras do mkdir.Atualização : solução ligeiramente melhor que também verifica buftype não vazio e usa
mkdir()
:fonte
call mkdir(expand('%:h'), 'p')
pode ser mais portátil.Com base nas sugestões para minha pergunta, eis o que acabei fazendo:
Isso define o
:W
comando. Idealmente, eu gostaria de ter todos:w!
,:wq
,:wq!
,:wall
etc funcionam da mesma forma, mas não tenho certeza se é possível sem basicamente reimplementar todos eles com funções personalizadas.fonte
:W
, minha tela fica quase em branco. Vou tentar remover minhas opções anteriores e dar feedback.Adicionei isso ao meu ~ / .vimrc
cnoremap mk. !mkdir -p <c-r>=expand("%:h")<cr>/
Se eu precisar criar o diretório em que estou, digite
:mk.
e o substitua por "! Mkdir -p / caminho / para / meu / arquivo /" e me permita revisar o comando antes de invocá-lo.fonte
I fez
:saveas!
criar o diretório se ausente: https://github.com/henrik/dotfiles/commit/54cc9474b345332cf54cf25b51ddb8a9bd00a0bbfonte
Este código solicitará que você crie o diretório
:w
ou faça-o apenas com:w!
:fonte
Acho que consegui fazer isso em três linhas, combinando o que os outros estão dizendo nesta resposta.
Isso parece fazer o truque:
Ele tenta criar a pasta automaticamente ao salvar um buffer. Se algo de ruim acontecer (por exemplo, problemas de permissão), ele simplesmente se cala e deixa a gravação do arquivo falhar.
Se alguém vir alguma falha óbvia, por favor poste um comentário. Eu não sou muito versado em vimscript.
EDIT: Notas graças ao ZyX
fonte
%
em tais scripts. Vim não vai escapar quaisquer símbolos especiais: por exemplo, se você estiver editando um arquivo chamado/mnt/windows/Documents and Settings/User/_vimrc
você vai acabar tendo quatro novos diretórios:/mnt/windows/Documents
,./and
,./Settings
e./Settings/User
. E, a propósito, você não precisa:execute
aqui.system()
função para chamadas de shell completamente silenciosas, mas você não precisa de ambas:execute
e%:p:h
::silent !mkdir -p %:p:h
funciona exatamente como o que você escreveu (embora você possa precisar:redraw!
no final, neste caso,:execute
é útil), mas é melhor usá-locall system('mkdir -p '.shellescape(expand('%:p:h')))
. Use:execute '!command' shellescape(arg, 1)
(com o segundo argumento para shellescape) se você precisar usar franja em vez desystem()
. Use bangs se o argumento de escape contiver novas linhas.:source ~/.vimrc
) (isto é o queaugroup
eautocmd!
são para), vista desmantelada após o lançamento shell comandos (redraw!
é para isso), criação de diretórios de lixo no caso de usar pseudo-arquivos (no primeiro código cortado, ele é verificado apenas combinando o nome do arquivo com um padrão, mas no segundo eu também verifico&buftype
) e chamada de shell inútil no diretório do caso existe (isdirectory()
condição).%
expansão para sugerir o uso para qualquer pessoa. Os pseudo arquivos são usados em vários plugins (por exemplo, fugitivo ou meu aurum), portanto vale a pena se preocupar. O recurso ao vimrc também é uma prática comum. Você pode ter o que quiser no vimrc, mas não o sugira como resposta. O uso da:silent! call mkdir(expand('%:p:h'), 'p')
variante resolve dois dos pontos que mencionei e o terceiro não mencionei:!mkdir
não vai funcionar no Windows.