Wireframe

컬러스킴을 전환하기

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

전체 컬러 목록 만들기

컬러 스킴을 전환하려면 사용 가능한 전체 컬러의 이름 목록이 있어야 할 것이다. 이 목록을 만드는 작업부터 시작해보자.

let s:colorNameList = []
func! s:GetThemeNames()
  let s:colorNameList = []
  let s:paths = split(glob("$VIMRUNTIME/colors/*.vim"), '\n')
  for s:path in s:paths
    let s:name = fnamemodify(s:path, ":r:t")
    call add(s:colorNameList, s:name)
  endfor
endfunc

s:colorNameList는 컬러스킴의 이름을 담아두는 리스트이다. 기본적인 컬러테마는 vim 설치위치 내에 colors 디렉토리 아래에 vim 파일로 정리되어 있다. glob() 함수를 사용해서 이 파일들의 경로를 얻은 다음, 개행문자로 분리하여 파일 경로의 리스트를 얻는다. 각각의 경로는 fnamemodify() 함수에 ":r:t" 옵션을 사용하여 확장자를 제외한 파일의 이름만 추출한다. 이 때, :t 옵션은 경로의 최하위 컴포넌트 (이름.확장자)를 의미하며, :r 옵션은 확장자를 제외하는 것을 말한다.

이렇게 얻은 이름들을 하나씩 s:colorNameList에 추가한다. 리스트에 추가하는 함수는 add() 인데, 명령줄 상태에서 함수만 호출해야하므로 call 명령을 쓰고 있음에 유의하자.


현재 스킴 파악하기

다음 컬러스킴으로 변경하기 위해서는 현재 컬러스킴이 이름 목록에서 몇 번째인지를 알아내야 한다. 이 동작을 s:GetCurrentThemeIndex()함수에서 정의하고 있다. 현재 컬러 스킴의 이름은 :colorscheme 명령을 실행하여 알 수 있는데, g:colors_name에도 이 값이 기록되어 있기 때문에 그대로 사용하면 되겠다.

func s:GetCurrentThemeIndex()
  let s:name = g:colors_name
  return index(s:colorNameList, s:name)
endfunc

최종적으로 index() 함수를 사용해서 리스트에서 몇 번째 이름의 컬러스킴을 사용하는지 알아낼 수 있고 이 값을 리턴하면 된다.


컬러 변경 동작 구현하기

이번엔 컬러스킴을 변경하는 함수를 작성할 차례이다. 여기서도 역시 :colorscheme 명령을 사용할 것이다. 주의할 점은 :colorscheme 명령은 그 자체로도 Ex명령이지만, 이 경우에 컬러스킴 이름이 변수에 있기 때문에 colorscheme s:nname 이라고 하면 "s:nname"이라는 컬러를 사용하려고 시도하기 때문에 동작하지 않는다. 따라서 :execute 명령을 사용해서 컬러를 전환한다. 이 명령에서 인자로 받는 명령은 문자열 형태로 전달해주면 되기 때문에 변수의 내용을 사용할 수 있다.

이제 다음 번 컬러로의 변환하는 방법은 간단하다. 현재 컬러의 다음 인덱스를 구해서 해당 위치의 컬러 이름으로 ":colorscheme 다음색이름" 명령을 실행하면 된다.

s:ChangeToNexTheme() 함수가 이를 수행한다. 먼저 s:colorNameList 의 원소의 개수를 구해서 2개미만이면 s:GetThemeList()를 호출해서 리스트를 구성한다. 그리고 다음 인덱스를 계산한 후, 그에 해당하는 이름을 얻는다.

func! s:ChangeToNextTheme()
  if len(s:colorNameList) < 2
    call s:GetThemeNames()
  endif
  let s:cid = (s:GetCurrentThemeIndex() + 1) % len(s:colorNameList)
  let s:nname = s:colorNameList[s:cid]
  execute "colorscheme " . s:nname
endfunc

끝으로 s:ChangeToNextTheme() 함수를 실행해주는 명령을 등록하고, F10 키를 여기에 맵핑하자.

command! -nargs=0 ColorNext call s:ChangeToNextTheme()
nnoremap <F10> :ColorNext<cr>

함수, 명령 설명

이 글에서 사용한 함수나 명령에 대한 간략한 설명을 따로 정리했다. 자세한 내용은 vim의 :help 명령을 사용해서 확인하자.

부록 2 – 파일이름 수정자

fnamemodify() 함수에서 사용할 수 있는 파일 이름 수정자는 아래와 같다. 이 수정자는 expand() 함수에서도 같이 사용할 수 있다.

Exit mobile version