GVim 파일 탭 열기
gvim 설정에서 cursor 밑에 있는 파일을 새 탭으로 여는 함수 작성해줘. 이 때 파일 경로가 상대경로일 경우 현재 열려있는 파일로부터 상대 경로로 찾아야 해. 그리고 만약 파일이 없으면 input() 으로 새로 해당 파일을 만들지 질문하고 y로 답할 경우 만들고 열어줘.
아래는 gvim에서 사용할 수 있는 Vimscript 함수입니다. 커서 아래 있는 단어(파일 경로로 간주)를 새 탭으로 열되, 상대경로일
경우 현재 열려 있는 파일 기준으로 처리하고, 해당 파일이 존재하지 않으면 생성 여부를 묻는 기능을 포함하고 있습니다.
vim
function! OpenFileUnderCursorInTab()
" 커서 아래 단어 가져오기
let l:filename = expand('<cfile>')
" 현재 버퍼의 디렉토리 기준으로 상대경로 처리
let l:current_dir = expand('%:p:h')
let l:fullpath = fnamemodify(l:filename, ':p')
if !isdirectory(fnamemodify(l:filename, ':h'))
let l:fullpath = resolve(l:current_dir . '/' . l:filename)
endif
" 파일 존재 여부 확인
if filereadable(l:fullpath)
" 새 탭으로 열기
execute 'tabedit ' . fnameescape(l:fullpath)
else
" 파일 생성 여부 확인
let l:answer = input("File does not exist. Create it? (y/N): ")
if l:answer ==? 'y'
" 디렉토리 없으면 생성
call mkdir(fnamemodify(l:fullpath, ':h'), 'p')
" 새 탭으로 열기 (파일 생성 포함)
execute 'tabedit ' . fnameescape(l:fullpath)
else
echo "Aborted."
endif
endif
endfunction
" 매핑 예시 (원하는 키로 변경 가능)
nnoremap <Leader>ot :call OpenFileUnderCursorInTab()<CR>
요점 정리:
-
expand('<cfile>')을 사용하여 커서 아래 파일명 추출. -
expand('%:p:h')로 현재 파일 기준 경로 가져와서 상대경로 처리. -
filereadable()로 존재 여부 확인 후tabedit로 새 탭에서 열기. -
없을 경우
input()으로 사용자에게 파일 생성 여부 묻기.
참고 사항:
-
상대경로 처리에서 Vim이
:p로 풀지 못하는 경우가 있어resolve()와 디렉토리 접합을 함께 사용함. -
mkdir(..., 'p')는 상위 디렉토리까지 포함해 생성함.
테스트 후 의도대로 작동하지 않는 부분이 있으면 알려주세요. 삽질 없이 바로 고칠 수 있도록 도와드리겠습니다.
만들지 물을 때 절대 경로를 보여주고 물어주면 좋겠어.
아래는 요청하신 대로 파일이 없을 때 절대 경로를 보여주고 생성 여부를 묻도록 수정한 버전입니다:
vim
function! OpenFileUnderCursorInTab()
" 커서 아래 단어 가져오기
let l:filename = expand('<cfile>')
" 현재 파일 기준 디렉토리에서 상대경로 처리
let l:current_dir = expand('%:p:h')
let l:fullpath = resolve(fnamemodify(l:current_dir . '/' . l:filename, ':p'))
" 파일 존재 확인
if filereadable(l:fullpath)
execute 'tabedit ' . fnameescape(l:fullpath)
else
" 경고 및 절대 경로 출력
let l:answer = input("File does not exist: " . l:fullpath . "\nCreate it? (y/N): ")
if l:answer ==? 'y'
" 디렉토리 없으면 생성
call mkdir(fnamemodify(l:fullpath, ':h'), 'p')
execute 'tabedit ' . fnameescape(l:fullpath)
else
echo "Aborted."
endif
endif
endfunction
" 예시 키 매핑
nnoremap <Leader>ot :call OpenFileUnderCursorInTab()<CR>
변경 사항 요약:
input()메시지에l:fullpath(절대 경로)를 출력함으로써 사용자가 어떤 경로에 파일을 만들게 되는지 명확하게 보여줌.
이제 실수로 엉뚱한 위치에 파일을 만드는 일은 줄어들 겁니다. 더 개선하고 싶은 점 있으시면 말씀해 주세요.
질문에 색깔을 넣을 수도 있어?
네, GVim이나 터미널 Vim에서 색깔을 넣는 건 제한적 입니다.
하지만 GVim , 특히 GUI 환경에서는 :echohl을 활용하면 색상 강조 를 넣을 수 있습니다. 단,
input() 자체는 하이라이팅을 직접 지원하지 않아서 질문 전체를 색상 있게 출력하고, 입력은 따로 받는 방식 으로 우회해야
합니다.
예시 코드는 다음과 같습니다:
vim
function! OpenFileUnderCursorInTab()
let l:filename = expand('<cfile>')
let l:current_dir = expand('%:p:h')
let l:fullpath = resolve(fnamemodify(l:current_dir . '/' . l:filename, ':p'))
if filereadable(l:fullpath)
execute 'tabedit ' . fnameescape(l:fullpath)
else
" 강조된 질문 메시지 출력
echohl Question
echon "File does not exist: "
echohl Directory
echon l:fullpath
echohl Question
echon "\nCreate it? (y/N): "
echohl None
" 입력은 따로 처리
let l:answer = nr2char(getchar())
if l:answer ==? 'y'
call mkdir(fnamemodify(l:fullpath, ':h'), 'p')
execute 'tabedit ' . fnameescape(l:fullpath)
else
echo "Aborted."
endif
endif
endfunction
설명:
-
echohl은 특정 하이라이트 그룹으로 색상을 바꿉니다. -
Question,Directory같은 기본 하이라이트 그룹을 사용했지만,:highlight로 사용자 지정도 가능함. -
echon은 개행 없이 출력합니다.getchar()로 입력을 따로 받아야input()없이 색상 출력이 가능합니다.
참고:
-
터미널 Vim에서는 색이 보이지 않거나 제한될 수 있습니다. GVim이나 색상 지원 터미널에서 확인하세요.
-
원하는 색감이 아니면
:highlight Question등의 명령어로 색상 조정 가능합니다.
필요하시면 사용자 정의 색상까지 설정하는 방법도 알려드릴게요.
파일 경로가 /로 시작하면 절대 경로니깐 상대 경로로 찾지 말아줘
네, 그게 맞습니다. 파일 경로가 /로 시작하면 이미 절대 경로이므로, 상대 경로 계산을 피해야 합니다. 이를 반영한 전체 코드를 아래에
정리해 드리겠습니다:
vim
function! OpenFileUnderCursorInTab()
let l:filename = expand('<cfile>')
" 절대 경로 여부 확인
if fnamemodify(l:filename, ':p') ==# l:filename
let l:fullpath = resolve(l:filename)
else
let l:current_dir = expand('%:p:h')
let l:fullpath = resolve(fnamemodify(l:current_dir . '/' . l:filename, ':p'))
endif
" 파일 존재 여부 확인
if filereadable(l:fullpath)
execute 'tabedit ' . fnameescape(l:fullpath)
else
" 강조된 메시지 출력 (GVim 또는 컬러 터미널에서 유효)
echohl Question
echon "File does not exist: "
echohl Directory
echon l:fullpath
echohl Question
echon "\nCreate it? (y/N): "
echohl None
let l:answer = nr2char(getchar())
if l:answer ==? 'y'
call mkdir(fnamemodify(l:fullpath, ':h'), 'p')
execute 'tabedit ' . fnameescape(l:fullpath)
else
echo "Aborted."
endif
endif
endfunction
" 키 매핑 예시
nnoremap <Leader>ot :call OpenFileUnderCursorInTab()<CR>
핵심 변경 사항:
-
fnamemodify(..., ':p') ==# ...비교로 절대 경로 여부를 판단함. -
절대 경로일 경우 상대 경로 붙이지 않고 그대로
resolve()만 적용. -
상대 경로일 경우에만 현재 버퍼 기준으로 조합.
-
질문 메시지는 하이라이트(
echohl)로 컬러 출력하며getchar()로 직접 입력 받음.
이제 절대 경로와 상대 경로 모두 정확히 처리됩니다.
필요하면 하이라이트 색상도 커스터마이즈해서 시각적으로 더 분명하게 만들 수 있습니다.
절대 경로 여부 판단 원리가 뭐야? "./abcd"라고하면 상대경로로 인식해야할 것 같은데 절대 경로로 인식하는 것 같음
좋은 지적입니다. Vim의 fnamemodify({fname}, ':p')는 상대 경로를 절대 경로로 변환 해주기 때문에, 아래와
같은 판단:
vim
if fnamemodify(l:filename, ':p') ==# l:filename
은 사실 절대 경로 판별로는 부정확합니다. 예를 들어:
-
"./abcd"→fnamemodify(..., ':p')결과는/현재경로/abcd→ 절대 경로처럼 보임 -
"abcd"→ 마찬가지로 절대 경로로 변환됨 -
"/etc/passwd"→ 애초에 절대 경로임
결국 위 조건은 "./abcd" 같은 상대 경로도 절대 경로로 인식해버리는 문제가 있습니다.
정확한 절대 경로 판단 방법은?
Vim에서는 파일 이름이 루트(/)로 시작하는지 직접 판단하는 것이 더 정확합니다:
vim
if l:filename =~ '^/'
" 절대 경로
else
" 상대 경로
endif
수정된 코드 (절대 경로 판별 정확하게 반영):
vim
function! OpenFileUnderCursorInTab()
let l:filename = expand('<cfile>')
" 절대 경로 여부: 슬래시로 시작하면 절대 경로
if l:filename =~ '^/'
let l:fullpath = resolve(l:filename)
else
let l:current_dir = expand('%:p:h')
let l:fullpath = resolve(fnamemodify(l:current_dir . '/' . l:filename, ':p'))
endif
if filereadable(l:fullpath)
execute 'tabedit ' . fnameescape(l:fullpath)
else
echohl Question
echon "File does not exist: "
echohl Directory
echon l:fullpath
echohl Question
echon "\nCreate it? (y/N): "
echohl None
let l:answer = nr2char(getchar())
if l:answer ==? 'y'
call mkdir(fnamemodify(l:fullpath, ':h'), 'p')
execute 'tabedit ' . fnameescape(l:fullpath)
else
echo "Aborted."
endif
endif
endfunction
결론:
-
fnamemodify(..., ':p') == ...는 절대 경로 판별용으로 틀림. -
파일 경로가
/로 시작하는지를 직접 정규식(^/)으로 검사하는 게 정확하고 신뢰할 수 있는 방법 입니다.
의심을 잘 하셨습니다. 이 부분에서 실수하는 경우 많습니다.