Case Study: Grep Operator, Part Three
우리가 만든 "grep operator"는 잘 작동하지만, 두가지를 더 추가하여 vim 생태계에서 잘 사용되게 해보자
Saving Registers
이전에 만들었던 명령어
nnoremap <leader>g :set operatorfunc=GrepOperator<cr>g@
vnoremap <leader>g :<c-u>call GrepOperator(visualmode())<cr>
function! GrepOperator(type)
if a:type ==# 'v'
normal! `<v`>y"
elseif a:type ==# 'char'
normal! `[y`]
else
return
endif
silent execute "grep! -R " . shellescape(@@) . " ."
copen
endfunction
이전에 만든 명령어에서 우리는 unnamed register를 사용하였다 - 이는 이전에 사용자가 사용하던 register를 제거해버리게 된다. 뿐만 아니라 visual select를 이용함으로서 가장 최근에 사용한 visual selection도 덮어씌워진다.
이는 사용자 입장에서는 좋지 않기 때문에 이를 방지해보자
nnoremap <leader>g :set operatorfunc=GrepOperator<cr>g@
vnoremap <leader>g :<c-u>call GrepOperator(visualmode())<cr>
function! GrepOperator(type)
let saved_unnamed_register = @@
if a:type ==# 'v'
normal! `<v`>y"
elseif a:type ==# 'char'
normal! `[y`]
else
return
endif
silent execute "grep! -R " . shellescape(@@) . " ."
copen
let @@ = saved_unnamed_register
endfunction
기존 명령어와 달라진 점은 시작과 끝에 let
을 사용하여 변수를 지정해 준 것 뿐이다. 처음에 우리는 @@
에 있는 내용을 saved_unnamed_register
변수에 할당한다.
그리고 if문에서 복사한 내용을 이후에 다시 기존 register로 덮어씌워준다
이제 기존에 복사한 텍스트를 <leader>g
명령어가 덮어씌우지 않는 것을 볼 수 있다.
혹시 os의 클립보드와 unnamed register를 공유하는 경우에는 위 내용이 적용되지 않는다. 나도 평소에
set clipboard=unnamed
를 추가하여 vim의 unnamed 레지스터를 clipboard로 사용하는데, 이럴 경우<leader>g
안에서 복사한 텍스트는 clipboard register에 적용되지 않기 때문으로 보인다. 기존과 같이:set clipboard="*
로 변경시킨 후 실행해보면 정상적으로 작동하는 것을 볼 수 있다. (:set clipbaord=unnamedplus
를 사용하고 있다면 문제가 없다)
Namespacing
우리가 만든 스크립트의 함수명인 GrepOperator
는 global namespace를 사용하고 있다. 별 일이 아닐 수도 있지만, vimscript를 작성할 때에는 최대한 안전하게 작성하는 것이 좋다.
코드에 몇 줄만 추가하여 이 문제를 해결할 수 있다.
nnoremap <leader>g :set operatorfunc=<SID>GrepOperator<cr>g@
vnoremap <leader>g :<c-u>call <SID>GrepOperator(visualmode())<cr>
function! s:GrepOperator(type)
let saved_unnamed_register = @@
if a:type ==# 'v'
normal! `<v`>y
elseif a:type ==# 'char'
normal! `[y`]
else
return
endif
silent execute "grep! -R " . shellescape(@@) . " ."
copen
let @@ = saved_unnamed_register
endfunction
처음 세 줄만이 변경된 것을 볼 수 있다.
함수명을 s:
와 함께 시작하여 현재 script의 namespace를 사용하게 하였다.
그리고 GrepOperator
함수를 부를 때 <SID>
를 사용하여 함수를 찾을 수 있게 하였다.
축하한다! 우리의 grep-operator.vim
이 드디어 완성되었다!
Excersize
- Read
:help <SID>
- Treat yourself to a snack. You deserve it!
맥주한잔하러간다
'tools > vim' 카테고리의 다른 글
Learn Vimscript The Hard Way - 36. Looping (0) | 2020.04.16 |
---|---|
Learn Vimscript The Hard Way - 35. List (0) | 2020.04.15 |
Learn Vimscript The Hard Way - 33. Case Study: Grep Operator, Part Two (0) | 2020.04.12 |
vim 자동완성의 끝판왕, coc.nvim (0) | 2020.04.11 |
Learn Vimscript The Hard Way - 32. Case Study: Grep Operator, Part One - 2/2 (0) | 2020.04.10 |