(Vim 페이지로부터 자동으로 이동)

[첫화면으로]ViEditor

마지막으로 [b]

Vi (Vim) Editor

http://www.vim.org

아아... 몇 년 동안 사용해 오면서 꽤 숙달되었다고 생각했었고, 텍스트 에디터 사용법을 알기 위해 비싼 책을 살 필요가 있나 싶었는데... 정말 쥐뿔도 모르고 사용해 왔었다는 것을 깨닫게 되었다... 팁이 보이는 대로 여기에 적어 두기로 함.

1. Tips
1.1. 한 화일의 두 곳을 동시에 편집
1.2. Folding
1.3. Copy&Paste 할 때 들여쓰기 금지
1.4. InternetExplorer 의 html 소스 보기를 vim 으로 띄우기
1.5. 소스 코딩시의 탭 설정
1.6. keywordprg 기능
1.7. 자동완성 범위
1.8. 사용한 검색 표현식을 복사하는 방법
1.9. 여러 단어를 서로 다른 색으로 하이라이트
1.10. 하나의 명령을 여러 창에 한꺼번에 적용하기
1.11. 일본어, 한국어가 동시에 들어간 문서를 편집할 때 글꼴 설정
1.12. encoding을 utf-8로 했을때 메뉴가 깨지는 문제
1.13. 레코딩
1.14. 들여쓰기 정리
1.15. 'p'로 붙여넣은 영역에 대해서만 들여쓰기 정리
1.16. 상태 표시줄 설정
1.17. 터미널에서 띄웠을 때 마우스휠로 스크롤하기
1.18. solarized 컬러테마 적용
1.19. 헥사에디팅
1.20. 주석문이 들여쓰기가 적용되지 않을 때
1.21. 따옴표(괄호, 부등호 등) 안의 내용을 통채로 지우기 - Text object selection
1.22. 윈도우에서 심볼릭링크가 깨지는 문제
1.23. 세션 저장 및 사용
1.24. word-wrap된 긴 줄 내에서의 상하 이동
1.25. 라인 내에서 글자를 찾아 이동하기
1.26. 파일명 자동 완성 방식 변경
1.27. 텍스트 포맷 일괄 변경
1.28. Xslate 와 TTerse, 신택스 하일라이트, 매치되는 태그 찾기 등
1.29. command line 모드의 명령 반복
1.30. 현재 편집 중인 파일의 파일명을 클립보드로 복사하기
1.31. autoindent, smartindent, cindent ?
1.32. 마크다운 파일 실시간 프리뷰
1.33. 검색, 치환할 때 슬래쉬를 이스케이프하지 않고 편하게 찾기
1.34. 패턴이 일치하는 개수만 세기
1.35. 자동 저장
1.36. map 에서 치환이 실패해도 계속 진행하도록
1.37. 치환하며 일련번호 붙이기
2. 유용한 옵션들
3. 검색과 치환, 정규표현식
3.1. magic, nomagic
3.2. branch 와 concat
3.3. lookahead, lookbehind
3.4. Perl과 비교
3.5. 아예 Perl을 써서 치환
4. 관련 링크
5. 기타 & Comments

1. Tips

1.1. 한 화일의 두 곳을 동시에 편집

 :split                     또는
 :new 현재편집중인화일이름
으로 화일을 열면, 하나의 화일을 분할된 두 창에서 동시에 편집할 수 있다. 한쪽 창에서 수정한 내용은 다른쪽 창에도 실시간으로 반영된다. 힘들게 화일의 이곳 저곳을 왔다갔다하느라 애쓸 필요가 없다.

1.2. Folding

1.3. Copy&Paste 할 때 들여쓰기 금지

출처: [KLDP BBS 게시물]

마우스로 붙여넣기를 할 때 autoindent 나 textwidth 등이 작동해 버려서 원하지 않는 들여쓰기가 되는 것을 막으려면:
:set paste
한 후에 붙여넣기를 하고
:set nopaste
를 하여 계속 작업하면 된다.

한 술 더 떠서,
:set pastetoggle=<Ins>
로 설정하면, Ins 를 누를 때마다 paste 와 nopaste 상태가 전환된다. (명령 모드, 입력 모드 둘 다에서 사용 가능하다) 와우~

추가

[ConradIrwin/vim-bracketed-paste: Handles bracketed-paste-mode in vim (aka. automatic `:set paste`)] - 이런 편한 플러그인이 생겼다. 그냥 붙여넣기 하면 알아서 된다.

1.4. InternetExplorer 의 html 소스 보기를 vim 으로 띄우기

HKEY_LOCAL_MACHINE 
|- Software 
   |- Microsoft 
      |- Internet Explorer 
         |- View Source Editor 
            |- Editor Name       (Default) = D:\Local\vim\vim62\gvim.exe (gvim.exe 의 경로)
위 레지스트리에서 gvim.exe 대신에 gvimweb.bat 으로 바꾸고
gvimweb.bat 의 내용은
start D:\Local\vim\vim62\gvim.exe -c "set ft=html" %1

1.5. 소스 코딩시의 탭 설정

출처: [KLDP BBS의 게시물] 중 nohmad 님의 글
set tabstop=8      "진짜 탭은 8칸으로
set softtabstop=4  "탭 키를 누르면 스페이스 4개 삽입
set shiftwidth=4   "<, >키로 줄을 밀거나 당길때
set backspace=2    "백스페이스를 누르면 sts값만큼 움직임
set expandtab      "탭을 항상 스페이스로 변환 noexpandtab 은 스페이스가 tabstop 값만큼 되면 탭으로 변환

au BufNewFile,BufReadPre *.java
    \ set tabstop=8 softtabstop=3 shiftwidth=3 backspace=2 expandtab

기존 코드에 탭 문자가 섞여 있을때 일괄적으로 스페이스로 변환하고 싶으면 :retab

1.6. keywordprg 기능

어떤 단어 위에서 "K"를 누르면 "man 단어"가 실행된다. Perl 파일을 편집할 때는 man 대신에 "perldoc -f 단어"를 띄우고 싶다면
au BufNewFile,BufRead *.pl
    \ set kp=perldoc\ -f

1.7. 자동완성 범위

gvim 7.1을 깔고 Perl파일을 편집할때, Ctrl+N, Ctrl+P를 눌러서 단어 자동완성을 하려 했더니만 ActivePerl 디렉토리의 파일들 전부를 검색하더라. 다른 파일들을 검색하지 않게 하려고 complete 옵션에서 i를 제거했다.
set complete=.,w,b,u,t

1.8. 사용한 검색 표현식을 복사하는 방법

명령 모드에서 q / 하면 검색 히스토리가, q : 하면 명령 히스토리를 나타내는 버퍼가 생기고, 여기에서 yy등으로 복사가능. 윈도용 gvim에서는 블럭지정하여 Ctrl+C 등으로도 복사 가능

1.9. 여러 단어를 서로 다른 색으로 하이라이트

vim 홈페이지에 등록된 스크립트 중에 다음 것이 간단히 쓸만해 보인다.

다만 위 버전은 최소 Vim 7.0, 스크립트 최신 버전의 경우 7.2가 필요하고, 만일 구버전의 Vim을 사용하고 있다면 위 스크립트의 오리지날 버전인 다음 것을 사용하면 될 듯. (위의 것은 아래 스크립트가 더 이상 개발되지 않자 다른 사람이 이어받아 관리하는 것)

[스크린샷] - 오리지널 버전 페이지에 있던 것

1.10. 하나의 명령을 여러 창에 한꺼번에 적용하기

:windo 명령

예를 들어 vsplit 으로 분리한 두 창에 동시에 scrollbind 를 하고 싶으면
:windo set scrollbind

(참고: [vim 분할 창의 내용이 한 파일에 대해 이어지게 볼 수 있나요? | KLDP])

응용으로, 두 파일을 vnew 로 나란히 띄운 상태에서 diff를 적용하여 보고 싶다면
:windo set diff scrollbind

1.11. 일본어, 한국어가 동시에 들어간 문서를 편집할 때 글꼴 설정

일본어로 주석이 달린 Perl 스크립트를 조금 고쳐볼 일이 생겼는데, gvim으로 열었더니 주석이 전부 깨져서 보이질 않았다. 어차피 보여도 못 읽긴 하지만, 눈에 안 보이는 글자들이 있다는 게 꽤나 신경쓰이더라.

위 스크린샷에 상황이 잘 적혀 있지만, 다시 정리해보면
  1. 메모장에서는 "나눔고딕코딩" 글꼴로도 잘 보이는데,
  2. 분명히 UTF-8로 저장을 했음에도 gvim으로 열어보면 fileencoding 이 cp949 로 잡혀 있음. 이것도 미스테리. fenc 값을 뒤늦게 utf-8로 바꾼다해도 화면에 보이는 데 차이가 있진 않고
  3. 윈도우용 gvim의 encoding 옵션이 cp949인데, 이걸 utf-8로 바꾸면 그때부터 보이긴 하는데
  4. 나눔고딕코딩 글꼴에서는 한글만 보이고, 굴림체에서는 한자까지는 보이는데 일본어 가나 중 일부가 깨지고
  5. MS Mincho로 설정하니 드디어 가나와 한글 둘 다 제대로 보이긴 하는데 글꼴이 너무 안 예쁘고
  6. 또한 gvim의 encoding=utf-8인 상태에서는 gvim자체의 메시지("저장했습니다", "새 파일" 등등 아랫줄에 뜨는 것들)가 죄다 깨져나와서 불편2

KLDP에 [질문글]을 올려서 위 6번 문제, 마지막 메시지 깨지는 문제를 해결:

그 다음은 5번 문제, "MS Mincho"글꼴은 일본어와 한글이 다 잘 나오지만 너무 보기 안 좋다는 건데...

윈도우에서는 Google:fontlink란 걸 써서3, 어떤 베이스 폰트에서 표시할 수 없는 글자는 그 베이스 폰트에 링크된 대체 폰트에서 찾아서 표시를 해 준다고 한다4 따라서, '나눔고딕코딩'글꼴에 'MS Mincho'글꼴을 링크하면 나눔고딕코딩으로 표시할 수 없는 문자만 MS Mincho를 사용하여 표시하게 할 수 있다.

링크하는 방법5:
NanumGothicCoding
MSMINCHO.TTF,MS Mincho
MSMINCHO.TTC,MS Mincho

다음과 같이 한글까지도 나눔고딕코딩으로 잘 나온다.
Upload:gvim_font3.png

(그런데 첫번째 방법과 비교하면 일본어와 한자 글꼴이 다르다. 왜 다른지는 모르겠다)

1.12. encoding을 utf-8로 했을때 메뉴가 깨지는 문제

앞 섹션에서 하단에 출력되는 gvim 메시지가 깨지는 문제를 해결했기 때문에, 이젠 맘 편하게 vimrc 파일에다 set encoding=utf-8을 했더니만, 이번에는 상단의 메뉴의 글꼴이 깨졌다.

이것에 대해 검색해보니 다음 두 가지 방법이 보였음

게다가 명령 프롬프트 창에서 띄울 때는 encoding이 cp949일 수밖에 없는터라6 최종적으로 아래와 같이 vimrc에 적어 주었음

" gvim일 때만
if has("gui_running")
        set lines=50

        set encoding=utf-8
        " 메뉴와 메시지창 한글 깨짐 문제 해결
        source $VIMRUNTIME/delmenu.vim
        set langmenu=ko.UTF-8
        source $VIMRUNTIME/menu.vim
endif

1.13. 레코딩

[Vim 질문입니다. (반복작업 줄이기...) | KLDP]

1.14. 들여쓰기 정리

게시판에서 타인의 코드 같은 걸 복사해오면 들여쓰기가 엉망이 되어 있을 때가 있는데...

1.15. 'p'로 붙여넣은 영역에 대해서만 들여쓰기 정리

다른 파일에 있는 내용을 yank 하고 paste해서 붙여넣거나 했는데, 이 붙여넣은 부분의 들여쓰기 기준이 나머지 부분과 달라서 정렬해주고 싶다면 전체 정렬을 다시 돌려도 되겠지만,

p='] 로 붙여넣기 직후에 '방금 붙여넣은 영역의 마지막 글자('] 또는 `]. 둘 다 동일)까지를 재정렬시킬 수 있음.

1.16. 상태 표시줄 설정

split 이나 new 등으로 vim 창 안에서 윈도우를 둘 이상으로 분할할 경우 각 윈도우 하단에 파일명이 적힌 상태표시줄이 나타나는데, 이걸 자신의 입맛에 맞게 설정할 수 있다.

" 상태표시줄에 출력할 내용들
set statusline=%F\ %m%h%r%<%=\ [%{&ff},%{&fenc}]\ [%Y]\ [%l,%v]\ [%L]\ [%p%%]

" 윈도우가 하나 뿐일 때도 상태표시줄이 나타나도록
set laststatus=2

여러 윈도우들 중에 현재 편집 중인 윈도우의 상태표시줄에 대해 특별히 더 꾸며주고 싶다면, highlight 명령으로 StatusLine 항목에 정의해주면 된다.
hi StatusLine term=bold,reverse cterm=bold,reverse gui=bold,reverse ctermfg=Blue guifg=Blue

입력 모드일 때와 명령 모드일 때 상태표시줄의 색상을 또 다르게 바꿔줄 수 있다.
" 입력 모드로 들어갈 때는 녹색으로, 입력 모드를 빠져나올 때는 파란색으로
au InsertEnter * hi StatusLine ctermfg=DarkGreen guifg=DarkGreen
au InsertLeave * hi StatusLine ctermfg=Blue guifg=Blue

창을 여러 번 분할해서 상태표시줄 길이가 짧아질 경우 내용이 잘리는데, 상태표시줄을 두 줄 이상 나오게 할 설정법은 없는 듯

리눅스 서버에 접속해서 작업할 때는 vi를 띄워 작업하다가 종료를 할 때 저 상태표시줄이 그대로 남아 있으니까 헷갈린다. 종료할 때는 표시줄을 없애고 종료하도록 고치자. 다른 옵션들을 보면서 다음과 같이 했더니 잘 되었음.
" 종료할 때 StatusLine 지워주기
au VimLeave * set laststatus=0
au VimLeave * redraw

1.17. 터미널에서 띄웠을 때 마우스휠로 스크롤하기

윈도우용 gvim 에서는 마우스휠을 써서 버퍼의 내용을 위아래로 스크롤할 수 있었는데 PuTTY를 써서 리눅스 서버에 접속했을 때는 안 되어서 불편했다. mouse 옵션을 주면 된다.
set mouse=a

ScreenUtility를 띄우고 그 위에서 vim을 띄우는 경우는 다음 옵션까지 켜줘야 한다.[1]
set ttymouse=xterm2

1.18. solarized 컬러테마 적용

저 색상이 맘에 들어서 적용해봤다. 다운받아서 vimfiles 폴더 아래에 colors, autoload, doc 디렉토리 안에 각각 파일을 복사해주고.

윈도우 gvim 설정:
" solarized
set background=light
call togglebg#map("")        " 이 라인을 넣어줘야, 이후에 <F5>를 눌러 배경색 토글을 할 수 있다.
let g:solarized_italic=0     " 이건 주석 라인이 이탤릭체로 나오는게 싫어서
colorscheme solarized

그런데 PuTTY로 리눅스 서버에 접속해서도 마찬가지로 적용하고 싶어서 시도했다가 좀 헤맸다.

putty에 설정하는 내용은 PuTTY#solarized 참고

그러면 일단 putty 로 접속하는 것 자체에 저 색상이 적용되긴 하는데... 막상 vim(vim 은 아직 컬러스킴을 적용하지 않은 상태)을 띄워보면,

Upload:solarized.png
(왼쪽 위가 putty+vim, 오른쪽 아래가 gvim)

배경은 똑같은데 키워드들의 하일라이트 색상이 다르다. 뭐 큰 지장이 있는 건 아닌데 그래도 맘에 안 든다. 그래서 이 상태에서 다시 vim 설정에도 위와 같이 solarized 를 설치하고 .vimrc 에 똑같이 적어줬더만 이번엔 배경색이 미묘하게 달라져버리고, 글자들도 일부 키워드에만 따로 배경색이 적용되어서 정말 흉하게 나왔다.

(반대로, putty에는 적용하지 않고 vim에만 적용하면... 역시 흉하게 나온다. colors/solarized.vim 파일을 열어보니, gvim에서는 일일이 색상값을 할당하지만, GUI모드가 아닌 vim에서는 터미널의 디폴트 색상을 사용하여 적용하고, 실제 색이 바뀌는 건 터미널 에뮬레이터의 팔레트를 조절하는 식으로 되어 있는 듯 하다)

뒤져보니 http://stackoverflow.com/a/5561823/1150133 에 이 컬러스킴 제작자가 친히 리플을 달았더라.
set t_Co=16          " 이 값이 원래는 8이었는데, 16으로 바꿔줌
...
colorscheme solarized
위와 같이 t_Co 값을 16으로 해주니, 이젠 완전히 동일하게 나온다. (딱 한가지, 배경이 light일 때, 커서의 색상이 너무 옅어서 잘 안 보인다. 해결법은 모르겠음)

1.19. 헥사에디팅

[vim 스크립트로 헥사뷰어기능 추가하기 | KLDP]

1.20. 주석문이 들여쓰기가 적용되지 않을 때

말로 설명하기 애매한데, Perl 스크립트 코딩을 하다보면 주석을 넣기 위해 "#"을 입력할 때 이게 무조건 첫 컬럼에 찍혀버린다.
# Do something       <-- 이렇게
  $x = $x + 1;
  if ($y) {
# Do something else  <-- 여기도
    $y = $y + $z;
  }

내가 원하는 건 현재 들여쓰기 레벨에 맞춰지는 것
  # Do something
  $x = $x + 1;
  if ($y) {
    # Do something else
    $y = $y + $z;
  }

희한한 건 윈도우용 gvim에서는 잘 되는데 리눅스용 vim에서만 저 문제가 발생한다는 건데, 암튼 뒤져보니 역시나 누가 질문글을 올렸었다.(위의 예제 코드도 이 글에서 퍼왔음)

.vimrc 파일에
filetype plugin indent on
syntax enable

두 줄을 추가하여 해결함.

저 링크 글에 보면 smartindent 옵션이 적용될 때 문제 같은데, 저 글에 다른 답변글에서도 언급하고 있지만 :help smartindent해 보면
        When typing '#' as the first character in a new line, the indent for
        that line is removed, the '#' is put in the first column.  The indent
        is restored for the next line.  If you don't want this, use this
        mapping: ":inoremap # X^H#", where ^H is entered with CTRL-V CTRL-H.
이렇게 정확히 해당 문제와(애초에 이게 문제가 아니라 의도된 기능인 듯?) 그 해결법도 나와 있긴 한데, 막상 해봐도 제대로 안 되더라.

1.21. 따옴표(괄호, 부등호 등) 안의 내용을 통채로 지우기 - Text object selection

출처: https://twitter.com/vimtips/statuses/270934644202041344

[motion.txt] 도움말을 보면 커서를 이동시키는 수많은(정말 수많은) 명령어들이 있다. 그 중 [6장]에 보면 "Text object selection" 항목이 있는데, 비주얼 모드에 들어가 있거나 c(change), d(delete), y(yank) 등의 명령어 뒤에서 쓰일 수 있는 이동 명령어들이다. 초반에는 단어 단위, 문장 단위, 단락 단위로 커서를 움직일 수 있는 방법이 나오고, 그 다음 나오는 것들이 쏠쏠하다.

a 뒤에
  ] 또는 [ - [ ] 블럭
  ) 또는 ( - ( ) 블럭
  > 또는 < - < > 블럭
  } 또는 { - { } 블럭
  "        - " " 블럭
  '        - ' ' 블럭
  `        - ` ` 블럭
  t        - <aaa>...</aaa> 태그 블럭

i 뒤에
  위와 마찬가지인데, 블럭 경계기호는 제외한 그 안의 것

즉, 현재 커서가 있는 위치를 둘러싸고 있는 블럭을 찾아서 그 블럭의 내용을 통채로 삭제하거나 복사하거나 할 수 있다. 특히나 블럭이 중첩되어 있을 때, 블럭의 좌우 괄호의 갯수를 손으로 세어가며 찾을 필요가 없음

예를 들어보면, 먼저 a를 쓰는 경우
y = (1+(2+(3+(4+func()))));
                 ^ 커서가 여기 있을 때 da( 순, 또는 da) 순으로 누르면 "delete a () block"
y = (1+(2+(3+          )));
                 이렇게 괄호까지 포함하여 지워지고
y = (1+(2+(3+)));
             ^ 커서 위치

이번에는 d(delete) 대신에 c(change)를, a 대신에 i 를 썼을 때:
y = (1+(2+(3+(4+func()))));
         ^ 커서가 여기 있을 때 ci( 순으로 누르면 "change inner () block"
y = (1+(                ));
         이렇게 괄호는 남아 있고 그 안의 내용만 지워지고
y = (1+());
        ^ 커서 위치는 이 )괄호 앞에서 입력 모드로 깜박거림

앞에 카운트를 넣어서 단계도 조절할 수 있다.
y = (1+(2+(3+(4+func()))));
                 ^ 커서가 여기 있을 때 c2i( 순으로 누르면
y = (1+(2+(            )));
                 2단계 중첩된 괄호 안의 내용이 지워지고,
                 (커서 위치에서 좌측으로 2번째 만나는 여는괄호를 찾고, 거기에 대응되는 닫는괄호까지 매치됨)
y = (1+(2+()));
           ^ 커서 위치는 이 괄호 앞에서 입력 모드

() 블락 뿐 아니라 암튼 좌우에 기호를 넣어 표시하는 웬만한 블럭은 다 된다. 심지어 html,xml 태그도 가능:
<b><i>long long long <s>long</s> long text</i></b>
           ^ 커서가 여기 있을 때 cit 순으로 누르면
<b><i></i></b>
      ^ <i>..</i>태그 안의 텍스트는 다 지워지고 여기서 입력 모드

사용하다보니 c뿐 아니라 yank와 같이 쓰는 것도 아주 쏠쏠하다. 어떤 태그로 둘러쌓인 부분(예를 들어 "<b>bold text</b>") 안에 커서를 놓고 yat하면 시작태그부터 끝태그까지의 내용이 복사되고 paste로 붙여넣을 수 있다. 마우스로 긁거나 SHIFT+커서키 조합으로 블락을 지정해서 복사하는 것보다 훨씬 편함.

1.22. 윈도우에서 심볼릭링크가 깨지는 문제

윈도우(내 경우 윈도우7)에서 mklink를 써서 심볼릭 링크를 만들었다고 했을 때.
mklink  link.txt  c:\somewhere\original.txt

gvim 으로 link.txt 를 열어서 수정하고 저장하는 순간, link.txt가 심볼릭 링크가 아니라 일반 파일로 바뀌어버린다.

이것은 기존 파일을 저장할 때 백업파일을 만드는 방식이, 기존 파일의 이름을 바꾸고 그 자리에 새 파일을 만드는 형태를 택했을 때 발생하는데, backupcopy 옵션값을 가지고 바꿀 수 있다.
set backupcopy=yes   - 원본 파일의 사본을 만들어 백업본으로 저장하고, 원본 파일을 덮어씀
              =no    - 원본 파일의 이름을 바꾸어 백업본으로 저장하고, 새 파일을 생성함
              =auto  - 디폴트. 두 방식 중 적절한 것을 사용

기본값이 auto인데, 윈도우에서 이게 no로 작동을 하는지, 새 파일이 생성되면서 symlink 속성이 날아가 버린다는 것.

(여기까지는 [vim - gVIM breaks symlinks on windows? - Super User] 참고)

그래서 일단 이 옵션을 yes 로 바꿔주면 당장은 해결되는 것처럼 보이는데... 처음 저장하는 순간 link.txt 가 읽기 전용 속성이 되면서 그 다음부터는 저장이 안된다... 저장하려고 :w!하면 그 때 일반 파일로 또 바뀌어버린다.

[vim - Symlink to .vimrc on windows makes file readonly upon write. Why? - Super User] 이 질문글에서 그에 대한 해답도 언급이 되어 있는데, 뭔가 귀찮아 보인다.

아뭏든 윈도우에서 심볼릭 링크(많이 쓰이지도 않겠지만)된 것을 gvim으로 수정할 때는 주의해야 하는 듯.

1.23. 세션 저장 및 사용

[Vim, 마지막 작업으로 열기? | KLDP]

1.24. word-wrap된 긴 줄 내에서의 상하 이동

jk는 실제 문서의 라인 단위로 이동한다.

어떤 라인이 매우 길고 set wrap 옵션이 되어 있어 여러 줄에 걸쳐 표시되고 있는 상태에서, 그 라인 내에서 상하로 이동하려면 gj, gk를 사용하면 된다.

Upload:vim_longline.png

커서키로 이동할 때도 마찬가지로 적용
" 노말 모드에서 스크린 기준으로 위아래로 이동
nnoremap <Up>       gk
nnoremap <Down>     gj
" 삽입 모드에서
inoremap <Up>       <C-O>gk
inoremap <Down>     <C-O>gj
" 삽입 모드에서 Shift 키와 같이 눌러서 블록 지정하며 이동할 때
inoremap <S-Up>     <C-O>vgk<C-G>
inoremap <S-Down>   <C-O>vgj<C-G>
" 선택 모드에서도 마찬가지
snoremap <S-Up>     <C-O>gk
snoremap <S-Down>   <C-O>gj

1.25. 라인 내에서 글자를 찾아 이동하기

:help f

노말 모드에서 다음과 같이 커서를 이동시킬 수 있다.
f{문자}  커서 위치에서 오른쪽 방향에 있는 {문자}까지 이동
F{문자}  커서 위치에서 왼쪽 방향에 있는 {문자}까지 이동
t{문자}  커서 위치에서 오른쪽 방향에 있는 {문자}의 바로 직전까지 이동
T{문자}  커서 위치에서 왼쪽 방향에 있는 {문자}의 바로 직후까지 이동

앞에 숫자를 넣어서, 예를 들어 3fa라고 하면 커서 위치에서 오른쪽 방향으로 가다가 세 번째로 a가 나타나는 곳까지 이동한다.

단지 커서만 이동할 거면 그냥 /를 써서 검색을 해도 되겠는데, 이게 삭제 등 다른 명령과 같이 쓰면 요긴하다.
$str = "very long long long long long";
                      ^ 커서가 여기 있을 때 dt" 를 입력하면
$str = "very long long";
                      ^ 따옴표 직전까지의 내용이 삭제된다.

1.26. 파일명 자동 완성 방식 변경

예를 들어 file1, file2가 있을 때, 장단점이 있기는 한데, 후보군의 파일 갯수가 적으면 한번에 바로 완성되는 게 편한데, 해당되는 파일이 수십개 있고 내가 원하는 파일이 순서 상 뒷부분이라면 탭을 하염없이 눌러야 하니 안 좋다.

vim에서 파일명 자동완성을 bash 스타일로 바꾸자.

set wildmode=longest,list,full
set wildmenu

적용한 모습:

Upload:vim_completion.png

1.27. 텍스트 포맷 일괄 변경

예를 들어 textwidth 값을 바꿔서 한 행에 들어갈 글자 수를 바꿨을 때, 현재 작성되어 있는 텍스트에 적용하려면 gq를 사용한다. gq 뒤에 커서 이동을 하면 그 위치 방향에 있는 텍스트를 변경한다. 처음부터 끝까지 바꾸고 싶으면 gggqG 같은 식으로.

또는 비주얼 블락을 잡은 후에 gq해서 선택 영역만 변경.

1.28. Xslate 와 TTerse, 신택스 하일라이트, 매치되는 태그 찾기 등

Perl/Mojolicious에서 사용하는 템플릿으로 Cpan:Text::Xslate를 사용하는데, .tx 템플릿 파일을 편집할 때 신택스 하일라이트가 안 되어 불편하다:
syntax region txBlock   matchgroup=txDelim start=+\[%+ end=+%\]+ contains=txKeyword,txComment,@inlinePerl containedin=ALL keepend

그리고 템플릿을 만들다보면 불가피하게 계속 div 안에 div 안에 div 안에... 이런 식으로 만들게 되는데, (서툴러서 그런가...) 태그들이 제대로 열고 닫는 매치가 되고 있는지도 걱정되고, 여는 태그에 대응되는 닫는 태그 찾는 것도 일이라서 불편하다.

일단 vim의 기본 기능 중에 visual block을 응용하는 법이 있다.

이것만으로는 아무래도 불편하다.

Upload:matchtagalways.gif
(이미지는 저 홈페이지에서 가져왔음)

let g:mta_filetypes =
      \ get( g:, 'mta_filetypes', {
      \ 'html' : 1,
      \ 'xhtml' : 1,
      \ 'xml' : 1,
      \ 'jinja' : 1,
      \ 'eruby' : 1,
      \ 'htmldjango' : 1,
      \ 'django' : 1,
      \ 'xslate' : 1,   " 추가
      \} )

태그 안의 내용이 길어서 한 화면에 안 나오거나, 설령 나온다 해도 어쨌거나 반대편 태그로 한번에 이동하는 게 쉽지 않다. 위에서 본 vat 시퀀스 말고, %를 누르면 (매치되는 괄호로 점프하듯이) 매치되는 태그로 점프하는 플러그인이 있다.

runtime macros/matchit.vim
runtime! syntax/html.vim
...
runtime! ftplugin/html.vim
runtime! syntax/html.vim
...
" HTML:  thanks to Johannes Zellner and Benji Fisher.
if exists("loaded_matchit")
    let b:match_ignorecase = 1
    let b:match_words = '<:>,' .
    \ '<\@<=[ou]l\>[^>]*\%(>\|$\):<\@<=li\>:<\@<=/[ou]l>,' .
    \ '<\@<=dl\>[^>]*\%(>\|$\):<\@<=d[td]\>:<\@<=/dl>,' .
    \ '<\@

1.29. command line 모드의 명령 반복

노멀 모드에서 내렸던 명령(dd 같은)을 반복할 때는 .

명령줄 모드에서 내렸던 명령(:tabnew 같은)을 반복할 때는? @:

1.30. 현재 편집 중인 파일의 파일명을 클립보드로 복사하기

별도의 문서에 파일명을 적을 때 일일이 다시 적어줄 필요없이 곧바로 복사 붙여넣기 하려면

" Convert slashes to backslashes for Windows.
if has('win32')
  nmap ,cs :let @*=substitute(expand("%"), "/", "\\", "g")<CR>
  nmap ,cl :let @*=substitute(expand("%:p"), "/", "\\", "g")<CR>

  " This will copy the path in 8.3 short format, for DOS and Windows 9x
  nmap ,c8 :let @*=substitute(expand("%:p:8"), "/", "\\", "g")<CR>
else
  nmap ,cs :let @*=expand("%")<CR>
  nmap ,cl :let @*=expand("%:p")<CR>
endif

위의 키매핑 설정을 .vimrc 파일에 저장한다.

1.31. autoindent, smartindent, cindent ?

[Indenting source code - Vim Tips Wiki - Wikia]

1.32. 마크다운 파일 실시간 프리뷰

/마크다운프리뷰

1.33. 검색, 치환할 때 슬래쉬를 이스케이프하지 않고 편하게 찾기

매번 다음과 같이 슬래쉬 앞에 백슬래쉬를 붙여줄 필요 없이,

:s/\/usr\/local\//\/opt\//

구분자를 다른 것으로 바꿔 쓸 수 있다.

:s#/usr/local/#/opt/#

치환은 이렇게 할 수 있는데 그냥 검색만 할 때는 방법이 없어서 여지껏 늘 백슬래쉬를 붙이고 살았으나....

/ 대신 ?를 눌러 검색어를 입력할 때는 슬래쉬를 이스케이프하지 않아도 된다. -_-;;;; 아이고 세상에 이걸 몰랐네. 물론 검색 방향이 역방향이 되므로, 정방향으로 찾으려면 다시 / 한 번 엔터 한 번.

1.34. 패턴이 일치하는 개수만 세기

:%s/pattern//gn

" Omit g to display the number of lines where the pattern matches:
:%s/pattern//n

" To restrict the count to a region of the text, specify a range instead of % (% means all lines).
" For example, the following counts the number of occurrences in lines 10 to 50 inclusive:
:10,50s/pattern//gn

" The following counts the number of occurrences in the lines in the most recent visual selection.
:'<,'>s/pattern//gn

" Word under cursorEdit
" To count the number of occurrences of the last used search pattern, you can leave out the pattern entirely:
:%s///gn

" To access this quickly, define a shortcut command like
map ,* *<C-O>:%s///gn<CR>

1.35. 자동 저장

1.36. map 에서 치환이 실패해도 계속 진행하도록

:map ;;a :s/old1/new1/e<CR>:s/old2/new2/e<CR>

/e 플래그가 있으면 첫번째 치환이 실패해도 에러가 발생하지 않고 계속 다음 명령이 진행된다. 단 :help s_flags의 도움말을 보면 몇몇 에러는 여전히 발생한다고 함.

1.37. 치환하며 일련번호 붙이기

삼국전투기 화차 페이지를 만들 때, 아래와 같이 화차 번호만 적어둔 후

150
151
152
153
154

다음과 같이 치환하면

:let i = 1 | g/\v^(\d+)/exec 'let i = i + 1 | s//=== # ('.i.') \1===/'

이렇게 앞에 일련번호를 붙여서 짠

=== # (1) 150화 ===
=== # (2) 151화 ===
=== # (3) 152화 ===
=== # (4) 153화 ===
=== # (5) 154화 ===

2. 유용한 옵션들

3. 검색과 치환, 정규표현식

vim의 정규표현식은 Perl/정규표현식과 같은 개념을 좀 다르게 표기해서 헷갈린다.

이하의 내용은 주인장이 이래저래 쓰다가 알아낸 부분만 도움말에서 발췌해서 정리함:

3.1. magic, nomagic

검색 패턴 중에 어떤 문자는 문자 그 자체를 의미하고, 앞에 백슬래쉬를 붙이면 특수한 의미가 된다. 반면 어떤 문자는 백슬래쉬 없이 쓸 때 특수한 의미가 있고, 백슬래쉬를 붙이면 그제서야 문자 그 자체를 의미한다:

잘은 모르겠지만, 오리지널 vi에서와 최대한 호환성을 유지하기 위해 메타캐릭터를 기본적으로는 최소한의 것만 제공하고, 그 외에는 백슬래쉬를 붙여서 쓰도록 하는 느낌이다. Perl/정규표현식에서는 *, +, (), {} 등이 전부 특수한 의미를 가지고 있다. 그러다보니 vim을 쓸 때와 혼동되곤 한다.

어떤 문자가 문자 자체로 해석될지 특수한 의미로 해석될지 여부를 조절하는 데 magic 옵션을 쓸 수 있다. 또한, 검색 패턴 내에 \m, \M, \v, \V를 삽입하여 일시적으로 지정할 수도 있다.

예:
지정:     \v       \m       \M       \V         매치되는 것
                'magic' 'nomagic'
          $        $        $        \$         라인의 끝
          .        .        \.       \.         임의의 문자
          *        *        \*       \*         직전 원소의 0번 이상의 반복
          ()       \(\)     \(\)     \(\)       그룹
          |        \|       \|       \|         얼터너티브
          \a       \a       \a       \a         알파벳 문자
          \\       \\       \\       \\         백슬래쉬 자체
          \.       \.       .        .          마침표 자체
          \{       {        {        {          '{' 자체
          a        a        a        a          'a' 자체

따로 지정하지 않을 경우 set magic 상태가 기본이며7, 문서에서는 호환성 문제를 없애기 위해 이 상태로 사용하는 것을 권장하고 있다.

Perl 정규표현식과 그나마 최대한 비슷하게 사용하려면 \v를 사용한다:
\(a\|b\)  이걸 아래처럼
\v(a|b)

3.2. branch 와 concat

레퍼런스 문서의 [2장 패턴의 정의] 부분을 보다 발견한 것.

"or"에 해당하는 \|에 대응되어서, "and"에 해당하는 \&도 있다. 하나 이상의 concat8\&로 연결할 경우, 이 패턴은 문자열의 한 위치에서 모든 concat이 다 매치할 때에 한해서, 마지막 concat에 매치된다. 이건 Perl에는 없고 vim에만 있는 기능이다.
String           : ....... foobeep .......
current position :         ^
concat 1         :         foobeep
concat 2         :         ...

이건 결국 lookahead 검색과 동일하나, 아래 얘기할 lookahead에 비해 쓰기 간편하다.

3.3. lookahead, lookbehind

Perl/정규표현식에 있는 lookahead와 lookbehind를 vim에서도 쓸 수 있는데 형태가 좀 다르다. 먼저 검색할 원소를 적은 후에 뒤에 다음 기호를 붙인다.

예제를 보면:
        Example                 matches ~
        foo\(bar\)\@=           "foobar"의 "foo"
        foo\(bar\)\@=foo        이건 절대 매치되지 않는다

        foo\(bar\)\@!           바로 뒤에 "bar"가 오지 않는 "foo"
        a.\{-}p\@!              "a", "ap", "app", 등. 더 이상 p가 오지 않을 때까지.
        if \(\(then\)\@!.\)*$   뒤쪽에 "then"이 오지 않는 "if "

        \(an\_s\+\)\@<=file     "an" 뒤에 공백 또는 라인의 끝 뒤에 오는 "file"

        \(foo\)\@<!bar          "foobar"의 경우만 제외한 "bar"
        \(\/\/.*\)\@<!in        앞쪽에 "//"가 나오지 않는 경우의 "in"

3.4. Perl과 비교

자세한 건 [perl-patterns] 부분 참조.

Perl과 vim의 정규표현식의 주요 차이점 비교:

Capability                      in Vimspeak     in Perlspeak ~
----------------------------------------------------------------
force case insensitivity        \c              (?i)
force case sensitivity          \C              (?-i)
backref-less grouping           \%(atom\)       (?:atom)
conservative quantifiers        \{-n,m}         *?, +?, ??, {}?
0-width match                   atom\@=         (?=atom)
0-width non-match               atom\@!         (?!atom)
0-width preceding match         atom\@<=        (?<=atom)
0-width preceding non-match     atom\@<!        (?<!atom)
match without retry             atom\@>         (?>atom)

뉴라인 캐릭터를 처리할 때의 차이:

Perl에만 있는 것:

Vim에만 있는 것:

3.5. 아예 Perl을 써서 치환

[Perl compatible regular expressions - Vim Tips Wiki] 참고

vim을 컴파일할 때 perl을 지원하게 했다면, (:ver 했을 때 +perl 또는 +perl/dyn이 있으면 됨) :perldo s/searchme/replaceme/g 이런 식으로 쓸 수 있음.

윈도우 gvim 의 경우는 perldo 명령을 실행했을 때 perl**.dll 이 없다고 에러가 날 수 있는데, [strawberry perl]의 해당 버전의 압축파일을 받아서 dll 만 vim이 있는 곳에 넣어 주면 된다. 그런데 perl58.dll이 필요하다고 할 때 perl-5.8.*.* 여러 버전 중에 어떤 건 vim이 죽어버리고 어떤 건 괜찮았으니 확인이 필요.

PC에 Perl이 설치되어 있는 경우는 perl 인터프리터를 직접 호출하는 식으로도 쓸 수 있긴 하다:
:%!perl -pi -e 's/<text>/\n/'

4. 관련 링크

5. 기타 & Comments

서버에 있는게 7.0인데, 7.3을 써보고 싶어서 직접 컴파일하려니... 도대체 그 수많은 옵션 중 뭐를 켜줘야 무난한지 모르겠다. 일단은
./configure --prefix=/home/gypark/local/
# 이름 겹치지 말라고
--with-vim-name=vim73 --with-ex-name=ex73 --with-view-name=view73
# 이건 아래 features 항목을 big으로 하면 안 해도 되는 것 같긴 한데
--enable-multibyte --enable-hangulinput
--with-features=huge
# 펄 인터프리터를 추가하는 건 실패했다
--enable-perlinterp=yes

---

현재 라인의 문자열을 바이그램으로 추출하기

:map ;b yyp:s/\([^ ]\)\([^ ]\)\@=/\1\2 /g<CR>kJ$D

이름:  
Homepage:
내용:
 


컴퓨터분류
각주:
1. [commentstrnig], [fold-create-marker] 참조
2. 이 문제는 다른 문서를 읽을 때도 종종 겪던 문제. 텍스트 문서가 UTF-8로 인코딩되어 있어도 보통은 gvim이 iconv를 써서 변환을 하면서 제대로 보여주는데, 상황에 따라 그 변환이 제대로 되지 않아 한글이 깨져나오는 경우가 있다. 이 경우 강제로 set encoding=utf-8 해 주면 텍스트는 잘 보이는데 그 다음부터는 gvim의 메시지가 다 깨져보여서 불편
3. Twitter:rashper님께서 알려주셨음. 감사합니다
4. font link를 통해 찾지 못할 경우는 font fallback을 사용하여 시스템에 있는 폰트를 검색하여 쓴다고도 하는데, 그래서 메모장에서는 제대로 보였는데 gvim은 안 되는 이유는 모르겠음
5. [하늘빛 공방 » 맑은 고딕 쓸 때 한자도 클리어 타입으로 보기], [Globalization Step-by-Step: Fonts]를 참고
6. encoding을 utf-8로 놓고, termencoding을 cp949로 해봤는데, 출력은 상관 없는데 한글을 입력할 때 문제가 생김
7. :set 했을때 아예 나오지도 않더라. 윈도우용 gvim 7.2에서 확인
8. 뭐라 번역해야 할지...

마지막 편집일: 2024-8-6 11:39 pm (변경사항 [d])
14064 hits | Permalink | 변경내역 보기 [h] | 페이지 소스 보기