Vim

lightline.vim を使って vim のステータスラインをカスタマイズ

More than 5 years have passed since last update.

先日 vim-powerline から vim-airline に乗り換えたばかりだったのですが、あっさり lightline.vim に乗り換えてしまいました。

理由は、lightline.vim 作者さんの以下記事に共感したからです。

また、設定方法が直感的で分かりやすい点や、カスタマイズしやすい点なども気に入りました。

インストール

NeoBundle 'itchyny/lightline.vim'

今回のカスタマイズでは、以下のプラグインと連携させているので入れておくと良いです。
(無くてもエラーになったりはしません)

NeoBundle 'tpope/vim-fugitive'
NeoBundle 'airblade/vim-gitgutter'

NeoBundle 以外のインストール方法は、README 読んで下さい。

カスタマイズ

おすすめの設定ですが、README を上から順に試していくのも良いですが、作者さんの設定を真似るのが一番手っ取り早いです。

作者さんの設定は、README の一番最後に記載されています。
もしくは、直接 作者さんの .vimrc を参考にしましょう。

さらに今回は、カーソル下の文字コード表示と、vim-gitgutterと連携してGitの追加/変更/削除のハンク数も表示させるようにしました。

lightline-vim.png

以下が最終的な設定です。

特に解説はしませんが lightline.vim の設定方法は非常に直感的で分かりやすいので、すぐに理解できると思います。
また、README がチュートリアル方式になっているので、もし分からなければ読んでみると良いでしょう。

" vim-gitgutter
let g:gitgutter_sign_added = '✚'
let g:gitgutter_sign_modified = '➜'
let g:gitgutter_sign_removed = '✘'

" lightline.vim
let g:lightline = {
        \ 'colorscheme': 'landscape',
        \ 'mode_map': {'c': 'NORMAL'},
        \ 'active': {
        \   'left': [
        \     ['mode', 'paste'],
        \     ['fugitive', 'gitgutter', 'filename'],
        \   ],
        \   'right': [
        \     ['lineinfo', 'syntastic'],
        \     ['percent'],
        \     ['charcode', 'fileformat', 'fileencoding', 'filetype'],
        \   ]
        \ },
        \ 'component_function': {
        \   'modified': 'MyModified',
        \   'readonly': 'MyReadonly',
        \   'fugitive': 'MyFugitive',
        \   'filename': 'MyFilename',
        \   'fileformat': 'MyFileformat',
        \   'filetype': 'MyFiletype',
        \   'fileencoding': 'MyFileencoding',
        \   'mode': 'MyMode',
        \   'syntastic': 'SyntasticStatuslineFlag',
        \   'charcode': 'MyCharCode',
        \   'gitgutter': 'MyGitGutter',
        \ },
        \ 'separator': {'left': '⮀', 'right': '⮂'},
        \ 'subseparator': {'left': '⮁', 'right': '⮃'}
        \ }

function! MyModified()
  return &ft =~ 'help\|vimfiler\|gundo' ? '' : &modified ? '+' : &modifiable ? '' : '-'
endfunction

function! MyReadonly()
  return &ft !~? 'help\|vimfiler\|gundo' && &ro ? '⭤' : ''
endfunction

function! MyFilename()
  return ('' != MyReadonly() ? MyReadonly() . ' ' : '') .
        \ (&ft == 'vimfiler' ? vimfiler#get_status_string() :
        \  &ft == 'unite' ? unite#get_status_string() :
        \  &ft == 'vimshell' ? substitute(b:vimshell.current_dir,expand('~'),'~','') :
        \ '' != expand('%:t') ? expand('%:t') : '[No Name]') .
        \ ('' != MyModified() ? ' ' . MyModified() : '')
endfunction

function! MyFugitive()
  try
    if &ft !~? 'vimfiler\|gundo' && exists('*fugitive#head')
      let _ = fugitive#head()
      return strlen(_) ? '⭠ '._ : ''
    endif
  catch
  endtry
  return ''
endfunction

function! MyFileformat()
  return winwidth('.') > 70 ? &fileformat : ''
endfunction

function! MyFiletype()
  return winwidth('.') > 70 ? (strlen(&filetype) ? &filetype : 'no ft') : ''
endfunction

function! MyFileencoding()
  return winwidth('.') > 70 ? (strlen(&fenc) ? &fenc : &enc) : ''
endfunction

function! MyMode()
  return winwidth('.') > 60 ? lightline#mode() : ''
endfunction

function! MyGitGutter()
  if ! exists('*GitGutterGetHunkSummary')
        \ || ! get(g:, 'gitgutter_enabled', 0)
        \ || winwidth('.') <= 90
    return ''
  endif
  let symbols = [
        \ g:gitgutter_sign_added . ' ',
        \ g:gitgutter_sign_modified . ' ',
        \ g:gitgutter_sign_removed . ' '
        \ ]
  let hunks = GitGutterGetHunkSummary()
  let ret = []
  for i in [0, 1, 2]
    if hunks[i] > 0
      call add(ret, symbols[i] . hunks[i])
    endif
  endfor
  return join(ret, ' ')
endfunction

" https://github.com/Lokaltog/vim-powerline/blob/develop/autoload/Powerline/Functions.vim
function! MyCharCode()
  if winwidth('.') <= 70
    return ''
  endif

  " Get the output of :ascii
  redir => ascii
  silent! ascii
  redir END

  if match(ascii, 'NUL') != -1
    return 'NUL'
  endif

  " Zero pad hex values
  let nrformat = '0x%02x'

  let encoding = (&fenc == '' ? &enc : &fenc)

  if encoding == 'utf-8'
    " Zero pad with 4 zeroes in unicode files
    let nrformat = '0x%04x'
  endif

  " Get the character and the numeric value from the return value of :ascii
  " This matches the two first pieces of the return value, e.g.
  " "<F>  70" => char: 'F', nr: '70'
  let [str, char, nr; rest] = matchlist(ascii, '\v\<(.{-1,})\>\s*([0-9]+)')

  " Format the numeric value
  let nr = printf(nrformat, nr)

  return "'". char ."' ". nr
endfunction

あとは気に入らない部分を自分好みに変えていくと良いかと思います。

  • vim-gitgutter の sign は私の好みで変えてるだけなので、別にデフォルトのままでも良いです
  • separatorsubseparatorvim-powerline のものなので、対応していない方は設定を削除するか、フォントにパッチを当てて下さい。powerline を使ってる方はそっちでもおk

私の最新の設定はGithubに置いてあるので、良ければ何かの参考にでも。

追記

2010/08/28

  • ファイル名を取得する関数(MyFilename())内の expand(%t)expand(%:t) に修正 (←タイポです)

    %:t でファイル名のみの表示になります。
    以前のようにパスも含めて表示したい場合は、expand('%') として下さい。(t は要りません)