Case Study: Grep Operator, Part One
해당 장은 case study part one - 1/2에서 이어지는 글이다.
Escaping Shell Command Arguments
앞 장에서 사용한 방법 (작은따옴표로 quoting하는 방법)에도 문제가 있다. 검색하려는 string에 작은따옴표가 포함된 경우이다. that's
에 커서를 두고 매핑된 grep을 실행시켜보자.
만약 새로운 window라면
:nnoremap <leader>g :grep -R '<cWORD>' .<cr>
명령어로 매핑을 추가하고 예시를 진행해보자.
that's
이를 해결하기 위해서 shellescape
함수를 사용할 수 있다. :help escape()
와 :help shellescape()
를 읽어서 어떻게 동작하는지 살펴보자. (꽤 쉽다)
shellescape()
명령어는 vim string에서 작동하기 때문에 명령어를 execute
를 사용하여 동적으로 빌드해 주어야 한다. 우선 :grep
매핑을 :execute "..."
형태로 변경해보자.
:nnoremap <leader>g :execute "grep -R '<cWORD>' ."<cr>
위 명령어가 이전과 동일하게 작동하는지 확인해보자.
그리고 shellescape
를 사용하게 명령어를 수정해보자.
:nnoremap <leader>g :execute "grep -R " . shellescape("<cWORD>") . " ."<cr>
해당 명령어가 아까와 동일하게 작동하는지 foo
와 같은 일반 단어에 적용해보자.
잘 작동한다면 that's
에 적용해보자. 여전히 작동하지 않는 것을 볼 수 있다. 왜 그런것일까?
그 이유는 vim이 <cWORD>
같은 special string을 해석하기 전에 shellescape()
함수를 호출해서이다. 그래서 shellescape
는 커서 아래 있는 단어가 아니라 "<cWORD>"
를 문자 그대로 해석한다.
아래 명령어로 이 동작을 실제로 확인해볼 수 있다.
:echom shellescape("<cWORD>")
'<cWORD>'
이를 해결하기 위해 expand()
함수를 사용하여 shellescape
함수가 실행되기 이전에 <cWORD>
를 커서 아래에 있는 스트링으로 해석하게 할 것이다.
that's 에 커서를 올리고 아래 명령어를 실행해보자
:echom expand("<cWORD>")
that's
이를 shellescape
에 추가해보자.
:echom shellescape(expand("<cWORD>"))
'that'\''s'
'that'\''s'
가 반환되는 것을 볼 수 있다. 조금 이상해 보이고 해석하기 어렵지만, 일단 vim이 이를 제대로 escape 했다고 믿어보자.
이제 <leader>g
매핑에 이를 적용해보자.
:nnoremap <leader>g :execute "grep -R " . shellescape(expand("<cWORD>")) . " ."<cr>
이제 that's
에 커서를 올리고 <leader>g
를 실행시키면 잘 작동하는 것을 볼 수 있다!
Cleanup
매핑을 마무리하기 전에 몇가지 살펴보아야 할 것이 남았다. 지금은 처음 검색 결과로 바로 넘어가버리는데, 이를 방지하기 위해 grep
대신 grep!
을 사용하면 된다.
:nnoremap <leader>g :execute "grep! -R " . shellescape(expand("<cWORD>")) . " ."<cr>
vim은 quickfix window를 채우지만, 이를 열지는 않는다. quickfix window를 열게 명령어를 수정해보자.
:nnoremap <leader>g :execute "grep! -R " . shellescape(expand("<cWORD")) . " ."<cr>:copen<cr>
이제 quickfix window가 열리는 것을 볼 수 있다!
이제 마지막으로 grep output이 나오는 것을 없애고 바로 quickfix window가 뜨게 해보자. silent
명령어는 해당 명령어를 실행시켜서 나오는 메세지를 숨겨주는 역할을 한다.
:nnoremap <leader>g :silent execute "grep! -R " . shellescape(expand("<cWORD>")) . " ."<cr>:copen<cr>
Exercise
Add the mapping we just created to your ~/.vimrc file.
Read :help :grep if you didn't read it before.
Read :help cword.
<cword> is replaced with the word under the cursor (like |star|)
<cWORD> is replaced with the WORD under the cursor (see |WORD|)
Read :help cnext and :help cprevious. Try them out after using your new grep mapping.
Set up mappings for :cnext and :cprevious to make it easier to quickly run through matches.
나는 딱히 추가하지는 않았다. :cn
, :cp
(:cN
)로 사용 가능하기 때문. 아래와 같이 추가하면 된다.
nnoremap <leader>cn :cnext<cr>
nnoremap <leader>cp :cprevious<cr>
Read :help expand.
(읽어도 잘 모르겠다..)Read :help copen.
Add a height to the :copen command in the mapping we created to make sure the quickfix window is opened to whatever height you prefer.
Read :help silent.
'tools > vim' 카테고리의 다른 글
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 - 1/2 (0) | 2020.04.09 |
Learn The Vimscript The Hard Way - 31. Basic Regular Expressions (0) | 2020.04.08 |
Learn Vimscript The Hard Way - 30. Execute Normal! (0) | 2020.04.07 |