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

Read more

워드프레스에서 고스트로 이전

워드프레스에서 고스트로 이전

이 글을 쓰면서도 믿기 힘든 사실인데, 블로그라는 걸 처음 시작한지가 20년이 되었습니다. 이글루스에서 처음 시작했다가, SK컴즈가 인수한다고 발표함과 동시에 워드프레스로 플랫폼을 옮겼죠. 워드프레스오 옮긴 이후에는 호스팅 환경을 이리 저리 옮기긴 했지만 거의 18년 가까이 워드프레스를 사용해온 것 같습니다. 그 동안 워드프레스는 블로깅 툴에서 명실상부한 범용CMS로 발전했습니다. 사실 웬만한 홈페이지들은 이제

By sooop
띄어쓰기에 대한 생각

띄어쓰기에 대한 생각

업무 메일을 쓸 때 가장 많이 쓰는 말 중에 하나가 메일 말미에 ‘업무에 참고 부탁 드립니다.‘인데요, 어느 날부터 아웃룩에서 이 ‘부탁 드립니다’가 틀렸다고 맞춤법 지적을 하기 시작했습니다. 맞는 말은 ‘부탁드립니다’라고 붙여 쓰는 거라고. 사실 아래아한글 시절부터 이전의 MS워드까지, 워드프로세서들의 한국어 맞춤법 검사 실력은 거의 있으나 마나 한

By sooop

구글 포토에서 아이클라우드로 탈출한 후기

한 때 구글 포토가 백업 용량을 무제한으로 제공해 주겠다고해서, 구글 포토를 사용해서 사진을 백업해왔습니다. 물론 이 이야기의 결말은 저나 이 글을 읽고 있는 여러분이나 모두 알고 있습니다. 사실 AI에게 학습 시킬 이미지 데이터를 모으기 위한 것일 뿐이라거나 하는 이야기는 그 당시에도 있었습니다만, 에이 그래도 구글인데 용량은 넉넉하게 주겠지…하는 순진한

By sooop

Julia의 함수 사용팁

연산자의 함수적 표기 Julia의 연산자는 기본적으로 함수이며, 함수 호출 표기와 같은 방식으로 호출하는 것이 가능합니다. 또한 그 자체로 함수이기 때문에 filter(), map() 과 같이 함수를 인자로 받는 함수에도 연산자를 그대로 적용하는 것이 가능합니다. 특히 + 연산자는 sum() 함수와 같이 여러 인자를 받아 인자들의 합을 구할 수 있습니다. 2 + 3 # = 5 +(2,

By sooop