아아... 몇 년 동안 사용해 오면서 꽤 숙달되었다고 생각했었고, 텍스트 에디터 사용법을 알기 위해 비싼 책을 살 필요가 있나 싶었는데... 정말 쥐뿔도 모르고 사용해 왔었다는 것을 깨닫게 되었다... 팁이 보이는 대로 여기에 적어 두기로 함.
:split 또는 :new 현재편집중인화일이름
마우스로 붙여넣기를 할 때 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`)] - 이런 편한 플러그인이 생겼다. 그냥 붙여넣기 하면 알아서 된다.
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
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
au BufNewFile,BufRead *.pl \ set kp=perldoc\ -f
set complete=.,w,b,u,t
명령 모드에서 q /
하면 검색 히스토리가, q :
하면 명령 히스토리를 나타내는 버퍼가 생기고, 여기에서 yy등으로 복사가능. 윈도용 gvim에서는 블럭지정하여 Ctrl+C 등으로도 복사 가능
vim 홈페이지에 등록된 스크립트 중에 다음 것이 간단히 쓸만해 보인다.
다만 위 버전은 최소 Vim 7.0, 스크립트 최신 버전의 경우 7.2가 필요하고, 만일 구버전의 Vim을 사용하고 있다면 위 스크립트의 오리지날 버전인 다음 것을 사용하면 될 듯. (위의 것은 아래 스크립트가 더 이상 개발되지 않자 다른 사람이 이어받아 관리하는 것)
[스크린샷] - 오리지널 버전 페이지에 있던 것
:windo 명령
예를 들어 vsplit 으로 분리한 두 창에 동시에 scrollbind 를 하고 싶으면
:windo set scrollbind
(참고: [vim 분할 창의 내용이 한 파일에 대해 이어지게 볼 수 있나요? | KLDP])
응용으로, 두 파일을 vnew 로 나란히 띄운 상태에서 diff를 적용하여 보고 싶다면
:windo set diff scrollbind
일본어로 주석이 달린 Perl 스크립트를 조금 고쳐볼 일이 생겼는데, gvim으로 열었더니 주석이 전부 깨져서 보이질 않았다. 어차피 보여도 못 읽긴 하지만, 눈에 안 보이는 글자들이 있다는 게 꽤나 신경쓰이더라.
위 스크린샷에 상황이 잘 적혀 있지만, 다시 정리해보면
KLDP에 [질문글]을 올려서 위 6번 문제, 마지막 메시지 깨지는 문제를 해결:
그 다음은 5번 문제, "MS Mincho"글꼴은 일본어와 한글이 다 잘 나오지만 너무 보기 안 좋다는 건데...
윈도우에서는 fontlink란 걸 써서3, 어떤 베이스 폰트에서 표시할 수 없는 글자는 그 베이스 폰트에 링크된 대체 폰트에서 찾아서 표시를 해 준다고 한다4 따라서, '나눔고딕코딩'글꼴에 'MS Mincho'글꼴을 링크하면 나눔고딕코딩으로 표시할 수 없는 문자만 MS Mincho를 사용하여 표시하게 할 수 있다.
링크하는 방법5:
regedit
로 레지스트리 에디터를 연다
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\FontLink\SystemLink
로 이동
새로 만들기 - 다중 문자열 값
NanumGothicCoding
MSMINCHO.TTF,MS Mincho MSMINCHO.TTC,MS Mincho
다음과 같이 한글까지도 나눔고딕코딩으로 잘 나온다.
(그런데 첫번째 방법과 비교하면 일본어와 한자 글꼴이 다르다. 왜 다른지는 모르겠다)
앞 섹션에서 하단에 출력되는 gvim 메시지가 깨지는 문제를 해결했기 때문에, 이젠 맘 편하게 vimrc 파일에다 set encoding=utf-8
을 했더니만, 이번에는 상단의 메뉴의 글꼴이 깨졌다.
이것에 대해 검색해보니 다음 두 가지 방법이 보였음
set encoding=utf-8
이 라인을 vimrc 파일의 최상단에 두거나
게다가 명령 프롬프트 창에서 띄울 때는 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
[Vim 질문입니다. (반복작업 줄이기...) | KLDP]
q{레지스터이름}
로 레코드 시작
qq
로 레코드 종료
@{레지스터이름}
으로 실행
:help recording
참조
게시판에서 타인의 코드 같은 걸 복사해오면 들여쓰기가 엉망이 되어 있을 때가 있는데...
v
를 써서 전체를 블럭 잡고 =
를 누르거나
gg=G
로 첫 줄에서 마지막까지 =를 적용시키면 된다.
:help =
다른 파일에 있는 내용을 y
ank 하고 p
aste해서 붙여넣거나 했는데, 이 붙여넣은 부분의 들여쓰기 기준이 나머지 부분과 달라서 정렬해주고 싶다면 전체 정렬을 다시 돌려도 되겠지만,
p=']
로 붙여넣기 직후에 '방금 붙여넣은 영역의 마지막 글자(']
또는 `]
. 둘 다 동일)까지를 재정렬시킬 수 있음.
split 이나 new 등으로 vim 창 안에서 윈도우를 둘 이상으로 분할할 경우 각 윈도우 하단에 파일명이 적힌 상태표시줄이 나타나는데, 이걸 자신의 입맛에 맞게 설정할 수 있다.
" 상태표시줄에 출력할 내용들 set statusline=%F\ %m%h%r%<%=\ [%{&ff},%{&fenc}]\ [%Y]\ [%l,%v]\ [%L]\ [%p%%] " 윈도우가 하나 뿐일 때도 상태표시줄이 나타나도록 set laststatus=2
:help statusline
여러 윈도우들 중에 현재 편집 중인 윈도우의 상태표시줄에 대해 특별히 더 꾸며주고 싶다면, 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
윈도우용 gvim 에서는 마우스휠을 써서 버퍼의 내용을 위아래로 스크롤할 수 있었는데 PuTTY를 써서 리눅스 서버에 접속했을 때는 안 되어서 불편했다. mouse
옵션을 주면 된다.
set mouse=a
ScreenUtility를 띄우고 그 위에서 vim을 띄우는 경우는 다음 옵션까지 켜줘야 한다.[1]
set ttymouse=xterm2
저 색상이 맘에 들어서 적용해봤다. 다운받아서 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 은 아직 컬러스킴을 적용하지 않은 상태)을 띄워보면,
(왼쪽 위가 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일 때, 커서의 색상이 너무 옅어서 잘 안 보인다. 해결법은 모르겠음)
[vim 스크립트로 헥사뷰어기능 추가하기 | KLDP]
말로 설명하기 애매한데, 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.
출처: 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
뿐 아니라 y
ank와 같이 쓰는 것도 아주 쏠쏠하다. 어떤 태그로 둘러쌓인 부분(예를 들어 "<b>bold text</b>
") 안에 커서를 놓고 yat
하면 시작태그부터 끝태그까지의 내용이 복사되고 p
aste로 붙여넣을 수 있다. 마우스로 긁거나 SHIFT+커서키 조합으로 블락을 지정해서 복사하는 것보다 훨씬 편함.
윈도우(내 경우 윈도우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으로 수정할 때는 주의해야 하는 듯.
:mks
(:mksession)으로 현재 작업 중인 상태를 세션 파일로 저장
vim -S 세션파일이름
으로 복원. 파일이름이 "Session.vim"인 경우 생략 가능
j
나 k
는 실제 문서의 라인 단위로 이동한다.
어떤 라인이 매우 길고 set wrap
옵션이 되어 있어 여러 줄에 걸쳐 표시되고 있는 상태에서, 그 라인 내에서 상하로 이동하려면 gj
, gk
를 사용하면 된다.
커서키로 이동할 때도 마찬가지로 적용
" 노말 모드에서 스크린 기준으로 위아래로 이동 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
:help f
노말 모드에서 다음과 같이 커서를 이동시킬 수 있다.
f{문자} 커서 위치에서 오른쪽 방향에 있는 {문자}까지 이동 F{문자} 커서 위치에서 왼쪽 방향에 있는 {문자}까지 이동 t{문자} 커서 위치에서 오른쪽 방향에 있는 {문자}의 바로 직전까지 이동 T{문자} 커서 위치에서 왼쪽 방향에 있는 {문자}의 바로 직후까지 이동
앞에 숫자를 넣어서, 예를 들어 3fa
라고 하면 커서 위치에서 오른쪽 방향으로 가다가 세 번째로 a
가 나타나는 곳까지 이동한다.
단지 커서만 이동할 거면 그냥 /
를 써서 검색을 해도 되겠는데, 이게 삭제 등 다른 명령과 같이 쓰면 요긴하다.
$str = "very long long long long long"; ^ 커서가 여기 있을 때 dt" 를 입력하면 $str = "very long long"; ^ 따옴표 직전까지의 내용이 삭제된다.
예를 들어 file1
, file2
가 있을 때,
ls f
까지 타이핑하고 탭을 누르면 ls file
까지 완성되고 거기서 멈춘다. 다시 탭을 누르면 "file"로 시작하는 파일들의 목록이 보임
:e f
까지 타이핑하고 탭을 누르면 한번에 :e file1
까지 완성되고 탭을 누르면 "f"로 시작하는 파일들이 번갈아가며 완성된다.
vim에서 파일명 자동완성을 bash 스타일로 바꾸자.
set wildmode=longest,list,full set wildmenu
적용한 모습:
:e s
까지 입력한 상태에서
step
까지.
set wildmenu
는, full이 적용되는 순간에 하단에 매치되는 후보 파일들 목록이 따로 뜨고 그 중 현재 선택된, 즉 완성된 파일명이 하일라이트되어 표시된다. 이 상태에서 커서키나 Ctrl+P/Ctrl+N 으로 이전/이후 후보를 선택할 수 있음.
예를 들어 textwidth
값을 바꿔서 한 행에 들어갈 글자 수를 바꿨을 때, 현재 작성되어 있는 텍스트에 적용하려면 gq
를 사용한다. gq 뒤에 커서 이동을 하면 그 위치 방향에 있는 텍스트를 변경한다. 처음부터 끝까지 바꾸고 싶으면 gggqG
같은 식으로.
또는 비주얼 블락을 잡은 후에 gq
해서 선택 영역만 변경.
Perl/Mojolicious에서 사용하는 템플릿으로 Text::Xslate를 사용하는데, .tx
템플릿 파일을 편집할 때 신택스 하일라이트가 안 되어 불편하다:
syntax/xslate.vim
에다가, [% ... %]
형태를 추가해주니 그럭저럭 볼 만함
syntax region txBlock matchgroup=txDelim start=+\[%+ end=+%\]+ contains=txKeyword,txComment,@inlinePerl containedin=ALL keepend
그리고 템플릿을 만들다보면 불가피하게 계속 div 안에 div 안에 div 안에... 이런 식으로 만들게 되는데, (서툴러서 그런가...) 태그들이 제대로 열고 닫는 매치가 되고 있는지도 걱정되고, 여는 태그에 대응되는 닫는 태그 찾는 것도 일이라서 불편하다.
일단 vim의 기본 기능 중에 v
isual block을 응용하는 법이 있다.
vat
하면 해당 태그로 쌓인 부분이 블럭으로 지정되면서, 커서는 닫는 태그에 위치한다.
o
를 누르면 커서가 여는 태그와 닫는 태그 사이를 왕복한다.
이것만으로는 아무래도 불편하다.
(이미지는 저 홈페이지에서 가져왔음)
plugin/MatchTagAlways.vim
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 시퀀스 말고, %
를 누르면 (매치되는 괄호로 점프하듯이) 매치되는 태그로 점프하는 플러그인이 있다.
$VIMRUNTIME/macros/matchit.vim
이 존재한다.
.vimrc
에다가 다음 줄을 추가한다.
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>,' . \ '<\@
노멀 모드에서 내렸던 명령(dd
같은)을 반복할 때는 .
명령줄 모드에서 내렸던 명령(:tabnew
같은)을 반복할 때는? @:
별도의 문서에 파일명을 적을 때 일일이 다시 적어줄 필요없이 곧바로 복사 붙여넣기 하려면
" 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
파일에 저장한다.
,cs
: 파일명을 클립보드에 저장. 이 파일명은 현재 vim에서 열고 있는 기준이라서, 하위 디렉토리에 있는 경우는 dir/filename
형태로 복사되더라. (맥에서만 테스트한 상태)
,cl
: 전체 경로명을 클립보드에 저장
[Indenting source code - Vim Tips Wiki - Wikia]
매번 다음과 같이 슬래쉬 앞에 백슬래쉬를 붙여줄 필요 없이,
:s/\/usr\/local\//\/opt\//
구분자를 다른 것으로 바꿔 쓸 수 있다.
:s#/usr/local/#/opt/#
치환은 이렇게 할 수 있는데 그냥 검색만 할 때는 방법이 없어서 여지껏 늘 백슬래쉬를 붙이고 살았으나....
/
대신 ?
를 눌러 검색어를 입력할 때는 슬래쉬를 이스케이프하지 않아도 된다. -_-;;;; 아이고 세상에 이걸 몰랐네. 물론 검색 방향이 역방향이 되므로, 정방향으로 찾으려면 다시 /
한 번 엔터 한 번.
:%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>
:map ;;a :s/old1/new1/e<CR>:s/old2/new2/e<CR>
/e
플래그가 있으면 첫번째 치환이 실패해도 에러가 발생하지 않고 계속 다음 명령이 진행된다. 단 :help s_flags
의 도움말을 보면 몇몇 에러는 여전히 발생한다고 함.
:sh
로 쉘을 띄우면 LANG 환경 변수가 영어로 바뀌어버려서 한글 텍스트를 다룰 때 불편해진다. 로그인쉘로 띄우도록 함. (부작용이 있으려나?)
vim의 정규표현식은 Perl/정규표현식과 같은 개념을 좀 다르게 표기해서 헷갈린다.
:help pattern.txt
해서 나오는 [레퍼런스 문서 Pattern and search commands]에 있다.
이하의 내용은 주인장이 이래저래 쓰다가 알아낸 부분만 도움말에서 발췌해서 정리함:
검색 패턴 중에 어떤 문자는 문자 그 자체를 의미하고, 앞에 백슬래쉬를 붙이면 특수한 의미가 된다. 반면 어떤 문자는 백슬래쉬 없이 쓸 때 특수한 의미가 있고, 백슬래쉬를 붙이면 그제서야 문자 그 자체를 의미한다:
+
는 "+"문자 자체, \+
는 1개 이상의 반복
*
는 0개 이상의 반복, \*
는 "*"문자 자체
잘은 모르겠지만, 오리지널 vi에서와 최대한 호환성을 유지하기 위해 메타캐릭터를 기본적으로는 최소한의 것만 제공하고, 그 외에는 백슬래쉬를 붙여서 쓰도록 하는 느낌이다. Perl/정규표현식에서는 *
, +
, ()
, {}
등이 전부 특수한 의미를 가지고 있다. 그러다보니 vim을 쓸 때와 혼동되곤 한다.
어떤 문자가 문자 자체로 해석될지 특수한 의미로 해석될지 여부를 조절하는 데 magic
옵션을 쓸 수 있다. 또한, 검색 패턴 내에 \m
, \M
, \v
, \V
를 삽입하여 일시적으로 지정할 수도 있다.
\m
이후에 오는 패턴은, magic
옵션이 켜져 있을 때처럼 해석된다.
\M
이후에 오는 패턴은, nomagic
옵션을 썼을 때처럼 해석된다.
\v
이후에 오는 패턴은, '0'-'9', 'a'-'z', 'A'-'Z', '_'를 제외하곤 전부 특수한 의미로 해석된다. "very magic"
\V
이후에 오는 패턴은, 오직 백슬래쉬만이 특수한 의미로 해석된다. "very nomagic"
예:
지정: \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)
레퍼런스 문서의 [2장 패턴의 정의] 부분을 보다 발견한 것.
"or"에 해당하는 \|
에 대응되어서, "and"에 해당하는 \&
도 있다. 하나 이상의 concat8을 \&
로 연결할 경우, 이 패턴은 문자열의 한 위치에서 모든 concat이 다 매치할 때에 한해서, 마지막 concat에 매치된다. 이건 Perl에는 없고 vim에만 있는 기능이다.
String : ....... foobeep ....... current position : ^ concat 1 : foobeep concat 2 : ...
이건 결국 lookahead 검색과 동일하나, 아래 얘기할 lookahead에 비해 쓰기 간편하다.
Perl/정규표현식에 있는 lookahead와 lookbehind를 vim에서도 쓸 수 있는데 형태가 좀 다르다. 먼저 검색할 원소를 적은 후에 뒤에 다음 기호를 붙인다.
\@=
, \@!
: lookahead.
\@<=
, \@<!
: lookbehind.
예제를 보면:
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"
자세한 건 [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)
뉴라인 캐릭터를 처리할 때의 차이:
^
와 $
는 텍스트의 시작과 끝 부분에 매치
.
이 뉴라인에도 매치되게 할 수 있음
^
와 $
는 항상 중간에 삽입된 뉴라인에도 매치됨
\%^
와 \%$
는 텍스트의 시작과 끝에 매치
\_
를 .
또는 문자클래스 앞에 붙여서, 뉴라인을 포함하여 매치하게 할 수 있음
\s
는 뉴라인을 제외한 공백문자. \_s
는 뉴라인을 포함한 공백문자.
Perl에만 있는 것:
Vim에만 있는 것:
[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/'
(?!pattern)
등과 같이 쓸 경우 "!"를 vim이 먼저 해석해버리는지 perl이 제대로 수행되지 않고 에러가 반환되었다.
서버에 있는게 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
Undefined subroutine &ExtUtils::ParseXS::errors called at /home/gypark/perl5/perlbrew/perls/perl-5.14.2/lib/5.14.2/ExtUtils/xsubpp
에러가 난다. 포기.
---
현재 라인의 문자열을 바이그램으로 추출하기
:map ;b yyp:s/\([^ ]\)\([^ ]\)\@=/\1\2 /g<CR>kJ$D
set encoding=utf-8
해 주면 텍스트는 잘 보이는데 그 다음부터는 gvim의 메시지가 다 깨져보여서 불편:set
했을때 아예 나오지도 않더라. 윈도우용 gvim 7.2에서 확인