hasciiの日記

多分プログラミング関係

Vim で現在の単語を強調表示する

はじめに

IDE なんかでよくある現在の単語が強調表示されるあの機能が vim でも欲しくなった。
ググっても似たようなことしてる人も見つからないし、簡単な内容なので、vim script の勉強がてら書いてみる

以下ができれば実現できるはず

  • カーソル下の単語取得
  • highlight の設定方法
  • 適当なトリガー設定

コード

もったいぶるほどでもないので書いてしまうと以下のようになった

highlight CurrentWord term=NONE ctermbg=DarkMagenta ctermfg=NONE

function! s:EscapeText( text )
  return substitute( escape(a:text, '\' . '^$.*[~'), "\n", '\\n', 'ge' )
endfunction

function! s:GetCurrentWord()
  let l:cword = expand('<cword>')
  if !empty(l:cword)
    let l:regexp = s:EscapeText(l:cword)
    if l:cword =~# '^\k\+$'
      let l:regexp = '\<' . l:regexp . '\>'
    endif
    return l:regexp
  else
    return ''
  endif
endfunction

function! s:HighlightCurrentWord()
  let l:word = s:GetCurrentWord()
  if !empty(l:word)
    if exists("w:current_match")
      call matchdelete(w:current_match)
    endif
    let w:current_match = matchadd('CurrentWord', l:word, 0)
  endif
endfunction

augroup cwh
  autocmd!
  autocmd CursorMoved,CursorMovedI * call s:HighlightCurrentWord()
augroup END

上の内容を vimrc に記述すればスコープとかは気にしなければ大体思った機能になる

内容メモ

大雑把な内容は
1. カーソル下の単語取得
2. 取得した単語をエスケープしたりマッチングする文字列に変換
3. すでにマッチングしてるものがある場合は highlight 対象から削除
4. highlight にマッチング対象文字列追加

autocmd のカーソル移動系にこの関数を追加

関連する help

上の内容に関係する vim の help

  • eval
  • highlight
  • autocmd
  • escape()
  • matchadd()
  • matchdel()
  • substitute()

課題

  • カーソル移動系から呼ぶと無駄に重い
  • スコープを考慮できたらいいかもしれない
  • if とか while とか matchit 系は対応するキーワードが強調された方が多分便利