컬러스킴을 전환하기

vim에서 컬러 스킴을 변경하고 싶을 때에 :colorscheme 명령을 사용한다. (줄여서 :color로 쓸 수 있다.) 이 명령으로 컬러 스킴을 변경할 때에는 테마 이름을 알아야 하는데, 사실 몰라도 상관없다. :color<space> 한 후에 탭 키를 누르면 테마 이름은 자동완성되기 때문이다. 근데 이것보다도 키 하나만 눌러서 다른 테마로 적용되는 것을 보면서 전환하도록 하는 것이 더 편리할 것 같다. 이 기능을 vim 안에서 어떻게 만들면 좋을지 알아보자.

컬러스킴을 전환하기 더보기

jump 관련 명령 정리 – vim

vim에서 h,j,k,l 명령에만 익숙해지는 것도 사실 쉽지 않고, 일단 익숙해지면 이 키들을 연타하는 식으로 커서를 움직이는데, 특정한 위치로 바로 이동할 수 있는 jump관련 명령이 손에 익으면 그만큼 편리할 수가 없더라. jump와 관련된 명령들을 한 번은 정리하고 가자.

마커

m을 이용해서 현재 위치를 특정한 마커로 지정할 수 있고, 백팃 ` 이나 '작은 따옴표를 이용해서 그 위치로 되돌아 갈 수 있다. 보통 마크는 a-z, A-Z, 0-9 와 몇 가지 특수문자가 적용되는데, 특수문자들은 특별한 의미를 가지는 것들이다. 다음은 vim에서 사용되는 마커의 특징이다. 이 중에서 사용자가 임의로 설정할 수 있는 마커는 0-9,a-z,A-Z 이며, 이 각각은 문자의 종류에 따라 또 의미가 조금씩 다르다. 그 외에 편집/선택과 관련하여 특징적인 마커가 있으니 살펴봐두자.

  • a-z 영어 소문자는 일반적인 마크. 파일마다 따로 관리된다.
  • A-Z는 여러 파일간에 유지된다.
  • 0-9는 역시 여러 파일간에 유지되는데 … .viminfo 파일 내에 저장된다고 한다. 따라서 vim을 종료/재시작한 후에도 위치를 기억할 수 있다. (실제로 이는 vim을 빠져나갔을 때 위치를 기억한다고 한다.)
  • < > 는 이전 선택 영역의 처음과 끝을 가리킨다.
  • " 는 최종적으로 수정한 위치를 가리킨다.
  • ' 는 점프하기 이전 위치로 돌아간다.
  • ^는 삽입모드가 최종적으로 종료된 위치로 돌아간다.
  • .은 최종 변경이 시작된 위치이다.
  • [ ] 는 최종적으로 수정한 영역의 처음과 끝을 가리킨다.

:marks를 사용하면 현재 이동할 수 있는 마크들을 보여준다. jump 관련 명령 정리 – vim 더보기

스크립트에서 파일명 확장 – vim

vim 명령줄 모드에서 %는 보통 현재 파일의 전체 범위1현재 파일 이름의 의미가 된다. 예를 들어 C 파일을 작성하던 중에 현재 파일을 컴파일하고 싶다면 :!gcc -c % 라고 할 수 있다. 그렇다면 함수와 같은 스크립트 문맥에서는 어떨까? 스크립트 문맥에서는 파일명확장이 이루어지지 않고, 대신에 expand()함수를 써서 수동으로 처리해야 한다.

let current_file_name = expand('%')
let current_file_prefix = expand('%<')

그외 몇 가지 옵션이 있는데 이는 :h expand()로 찾아보면 된다.

  • % : 현재 파일이름
  • # : 대체 이름 (아마 이전 파일?)
  • #n : 대체이름 (n번째 이전 파일)
  • <cfile>: 커서가 있는 위치의 파일 이름
  • <cword> : 커서가 있는 위치의 단어
  • <cWORD> : 커서가 있는 위치의 단어를 대문자로

그외에 확장자가 붙어서 이를 변환할 수 있다. 그 중 일부만 소개하면 아래와 같다. (전체 목록은 도움말 내용을 확인하자.)

  • :p : full path로 확장한다.
  • :h : 헤드 (마지막 패스 요소를 제거한다.)
  • :t: 꼬리 (첫 패스 요소를 제거한다.)

  1. %s/ ... // 등에서 범위로 사용될 때는 전체 범위를 의미한다. 

SCSS 파일을 자동으로 컴파일하게 하기 – vim

scss 파일을 저장할 때 자동으로 컴파일 해주는 기능을 만들어보자. 이런 종류의 기능은 보통 vim의 autocmd나 키맵 등을 설정하여 만들 수 있다. 오토 커맨드로 등록하는 경우, 특정한 패턴의 파일을 열거나, 파일을 새로 만들거나, 저장하는 전후 등의 시점에 자동으로 수행될 수 있다.

SCSS 컴파일은 외부 컴파일러에 의존하고 있다. 따라서 vim 내에서 실행하면 해당 프로그램이 실행되는 동안 vim은 해당 프로세스가 종료되기를 기다리면서 동작을 멈추게 된다. 비록 짧은 시간이기는 하지만 이 과정이 제법 신경쓰일 수 있다.

그런데 vim8부터는 비동기로 이런 작업을 처리할 수 있는 기능이 제공된다. (따라서 vim7 이하버전에서는 실행되지 않는데, 이를 위한 처리를 통합했다.) 여기서 컴파일은 pysassc에 의존하며 이는 파이썬 pip를 이용해서 libsass를 설치하면 얻을 수 있다.


이제 vim 내에서 어떤식으로 비동기 명령을 실행하는지 알아보자.

  1. job_start() 함수를 사용하면 특정한 외부 명령을 비동기로 실행할 수 있다. 이 함수가 실행되면 자식 프로세스로 주어진 명령이 시작되고, 해당 명령과 연결되는 job 객체가 생긴다.
  2. vim 과 해당 프로세스는 채널을 통해 연결되고 job 은 시작시의 job_start() 의 옵션으로 몇 가지 이벤트에 대한 핸들러함수를 지정받을 수 있다.
  3. "close_cb" 옵션으로 지정한 함수는 해당 job의 채널을 인자로 받게된다. 따라서 채널을 통해 외부 프로세스의 표준 출력 혹은 표준 에러를 읽어올 수 있다.

먼저 SCSSCompile1 이라는 함수를 작성한다. 이 함수는 비동기 작업이 지원될 때 호출될 함수이다. 그런 다음 SCSSCompile0 함수는 비동기 지원이 되지 않는 상황에 호출될 함수로 작성한다.

SCSSCompile1 함수에서는 pysassc 를 호출하여 현재 파일을 css 파일로 컴파일하도록 한다. 그리고 채널이 닫힐 때 SCSSCompileHandler 함수가 호출되도록 한다. 이 콜백 전달은 job_start() 함수에 두 번째 인자로 사전 형식으로 지정한다. close_cb 가 채널이 닫힐 때 호출되는 콜백이다.

function! SCSSCompile1()
    echom 'Compiling: ' . expand('%')
    let l:commands = ['pysassc', expand('%'), expand('%<') . '.css']
    let job = job_start(l:commands, {'close_cb': 'SCSSCompileHandler'})
endfunction

function! SCSSCompile0()
    echo 'Compiling...'
    let cname = expand('%')
    let oname = expand('%<') . '.css'
    normal! ':!sassc ' . cname . ' ' . 'oname'
endfunction

핸들러 함수는 채널을 인자로 받으며, 채널의 상태를 확인하여 표준 출력 부분의 데이터가 남아있으면 이를 읽어서 메시지로 출력한다. 이 때 ch_status() 함수와 ch_read() 함수를 사용한다. 이는 각각 한 줄씩만 읽어들이므로 반복하여 사용해야 한다.

function! SCSSCompileHandler(ch)
    echo 'Compiliation Completed'
    while ch_status(a:ch, {'part': 'out'})
        let output = ch_read(a:ch, {'timeout': 1})
        echom output
    endwhile
endfunction

이제 두 함수중 하나를 읽어들일 명령인 BuildSCSS를 정의한다. 이 명령은 SCSSCompile{ } 로 중괄호를 포함하는 함수를 호출하는데, 중괄호 이름은 내부 표현식의 평가 결과에 의한다. 즉 has('job') 이 있으면 1, 없으면 0이기 때문에 그 때마다 적당한 명령이 실행될 것이다.

command! -nargs=0 BuildSCSS call SCSSCompile{has('job')}()

최종적으로 *.scss, *.sass 파일을 저장할 때마다 이 명령이 실행되도록 autocmd를 등록한다.

augroup PYSASS
    au!
    au BufWritePost *.sass,*.scss BuildSCSS
augroup END

이상으로 scss 파일을 편집하고 저장하면 자동으로 css 파일로 컴파일하는 과정을 구현해보았다. 아래는 전체 코드이다.

function! SCSSCompile1()
    let l:commands = ['pysassc', expand('%'), expand('%<') . '.css']
    let job = job_start(l:commands, {'close_cb': 'SCSSCompileHandler'})
endfunction

function! SCSSCompile0()
    echo 'Compiling...'
    let cname = expand('%')
    let oname = expand('%<') . '.css'
    normal! ':!sassc ' . cname . ' ' . 'oname'
endfunction

function! SCSSCompileHandler(ch)
    echo 'Compiliation Completed'
    while ch_status(a:ch, {'part': 'out'})
        let output = ch_read(a:ch, {'timeout': 1})
        echom output
    endwhile
endfunction

function! SCSSCompile1()
    echom 'Compiling: ' . expand('%')
    let l:commands = ['pysassc', expand('%'), expand('%<') . '.css']
    let job = job_start(l:commands, {'callback': 'SCSSCompileHandler'})
endfunction

function! SCSSCompile0()
    echo 'Compiling...'
    let cname = expand('%')
    let oname = expand('%<') . '.css'
    normal! ':!sassc ' . cname . ' ' . 'oname'
endfunction

command! -nargs=0 BuildSCSS call SCSSCompile{has('job')}()
augroup PYSASS
    au!
    au BufWritePost *.sass,*.scss BuildSCSS
augroup END

vim “:command” 명령

write a new vim command

:command!

:command!는 새로운 vim 명령을 만드는 명령이다. 명령어는 관례적으로 대문자로 시작하며 몇가지 속성과 함께 정의된다. !가 끝에 붙는 경우에는 기존에 동일한 명령이 있는 경우에 이를 재정의하며, 그렇지 않은 경우 에러가 발생한다. 문법은 다음과 같다.

:com[mand][!] [{attr}...] {cmd} {rep}

{cmd}는 실행할 명령이며, {rep}은 대체문자열이다.1

vim “:command” 명령 더보기