아직 존재하지 않는 디렉토리에 파일을 어떻게 저장합니까?


35

아직 생성되지 않은 디렉토리에서 새 파일을 편집하기 위해 Vim을 시작한다고 가정합니다.

vim nonExisitingDirectory/newFile.txt

Vim은 빈 버퍼를 행복하게 보여줄 것이며 새 파일 작성을 시작할 수 있습니다. 그러나 파일을 디스크에 쓰려고하면이 오류가 발생합니다.

E212: Can't Open file for writing.

디렉토리가 아직 존재하지 않기 때문이라고 생각합니다. Vim이 나를 위해 디렉토리를 만들도록하는 방법이 있습니까?

답변:


37

내가 아는 한이 설정이나 설정이 없습니다. 그러나 모든 것을 잃어버린 것은 아니며 BufWritePre자동 명령을 사용할 수도 있습니다 .
버퍼가 디스크에 기록되기 전에 실행됩니다. 디렉토리가 존재하지 않는 경우 디렉토리를 작성할 수 있습니다.

예를 들면 다음과 같습니다.

augroup Mkdir
  autocmd!
  autocmd BufWritePre *
    \ if !isdirectory(expand("<afile>:p:h")) |
        \ call mkdir(expand("<afile>:p:h"), "p") |
    \ endif
augroup END
  • 먼저 디렉토리가로 존재하는지 확인 isdirectory하고 그렇지 않으면 mkdir오류가 발생합니다.
  • <afile>저장하려는 파일을 나타냅니다. :p는 상대 경로가 아닌 전체 경로 이름으로 확장 :h하고 마지막 경로 구성 요소 (파일)를 제거 하는 수정 자 입니다.
  • 그런 다음 mkdir()필요한 경우 전화 합니다. 모든 부모 디렉토리를 만들 려면 p플래그 가 필요합니다 mkdir()(예 :의 경우) nonexistent/more_nonexisting/file.

물론 mkdir()Vim 명령 줄에서 명령을 실행 하거나 키 바인드에 바인딩 할 수도 있습니다.

nnoremap <Leader>m :call mkdir(expand("%:p:h"), "p")<CR>

여기서는 autocommand 내에서만 유효하기 때문에 %대신에 사용 했습니다 <afile>( 예를 들어 %작동하지 않는 현재 활성 버퍼 참조, autocmd를 트리거하는 버퍼의 파일 이름 참조).:wa<afile>

원하는 경우 디렉토리를 작성하기 전에 확인을 요청할 수도 있습니다. 자세한 내용은이 질문을 참조하십시오. BufWritePre 자동 명령에서 Vim이 파일을 쓰지 못하게하려면 어떻게해야합니까?


위의 스 니펫은 첫 번째 쓰기 ( :w) 에 디렉토리를 만듭니다 . 원하는 경우, 대신 autocmd를 vim ...사용하여 디렉토리를 처음 열 때 (예 : 입력 직후 ) 디렉토리를 만들 수도 있습니다 .BufNewFileBufWritePre


auto_mkdir 이라는 플러그인도 있는데 위와 사실상 동일합니다.

이 페이지 에는 약간 확장 된 스 니펫 (snippet)이 있는데,이 디렉토리는 먼저 디렉토리를 생성 할 것인지 묻습니다. 또한 쓰기 전에 인코딩의 파일 이름을 변환합니다.

call mkdir(iconv(expand("%:p:h"), &encoding, &termencoding), 'p')

이것이 실제로 필요한지 확실하지 않지만 인코딩을 많이 혼합하고 이상한 파일 이름을 얻는다면 시도해 볼 수 있습니다.


더 쉬운 설치를 위해 위의 모든 것을 auto_mkdir2.vim플러그인 에 넣었습니다 .


3

Vim을 사용 하여 UNIX / Linux에서 작업 할 때 매우 유용한 명령을 정의하는 vim-eunuch 라는 팀 포프의 vim 플러그인을 추천 할 수 있습니다 ( 기능 확인 !).

vim을 열어서이 vim this/is/a/test디렉토리가 존재하지 않았다고 가정 해 봅시다 . 그냥 실행 :Mkdir!<CR>하고 vim-eunuch가 당신을 위해 그것들을 생성 mkdir -p하므로 이제 파일을로 저장할 수 있습니다 :w<CR>.


2

:W파일 및 상위 디렉토리를 작성하는 데 사용하십시오 .

function! s:WriteCreatingDirs()
  let l:file=expand("%")
  if empty(getbufvar(bufname("%"), '&buftype')) && l:file !~# '\v^\w+\:\/'
    let dir=fnamemodify(l:file, ':h')
    if !isdirectory(dir)
      call mkdir(dir, 'p')
    endif
  endif
  write
endfunction
command! W call s:WriteCreatingDirs()

(에 추가하십시오 vimrc. Zyx의 답변Damien Pollet의 답변 조합을 기반으로 함 ).


1

바닐라 Vim을 사용하는 다른 방법 (추가 conf 또는 플러그인 없음). Vim에서 :

:!mkdir -p /folder/you/want/
:w  #save file

또는

$ vim /folder/you/want/myfile.conf
$ ctrl+z # switch to the terminal then create the folders
$ mkdir -p /folder/you/want/
$ fg # return to Vim
$ :w  #save file

1

위의 답변을 토대로 한 버전을 제공하여 워크 플로우를 훨씬 더 간소화합니다. 나는 종종 광범위한 프로젝트 구조 내에서 새 파일을 만들고 있습니다. 이 조정은 시간을 절약 해줍니다.

내가 생각할 수 있는 두 가지 종속성 이 있습니다.

  1. 수입 명세서 autochdir와 어떻게 작동하는지 설정 했습니다 <C-x><C-f>.
  2. saveas"뒤에 잎"(만약 당신) 상기의 숨겨진 버퍼 버퍼 목록. 모든 vim / nvim 인스턴스가 즐기는 상태 동작인지 확실하지 않습니다.
  3. 다른 참고 사항 : Mac OS에서 NVIM을 사용합니다.

    " Auto magically Mkdir
    " ====================
    
    autocmd BufWritePre * call MkDir()
    
    function! MkDir()
       if !isdirectory(expand("<afile>:p:h"))
          let confirmation=confirm("Create a new directory?", "&Yes\n&No")
          if confirmation == 1
             call mkdir(expand("<afile>:p:h"), "p")
             lcd %:p:h
             saveas %:t
             echom "Created a new directory:" expand("<afile>:p:h")
             let buf_del = bufnr("$")
             exe "bd" . buf_del
          endif
          redraw
       endif
    endfunction
    
    " Conditionaly create the parent directory when writing to disk
    " <afile> refers to the file we are saving
    " :p is a modifier that expands to full filename
    " :h is a modifier that removes the file from full filename
    " :t is a modifier that generates the filename with extension
    " "p" is the flag that will create all the parent directories
    
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.