第24回 Vimスクリプト入門みたいの(スクリプトを読みながら勉強してみる、2-5)

まずは OpenSearchWindow() に可変長の引数を追加する。b:searchWordType という変数を作り、既定値を 0 ( オリジナルの動作 ) としておく。

" 検索結果表示用ウィンドウを開く
" searchWord が空でなければ searchWord をハイライト.
" searchWord を b:searchWord に格納.
function! s:OpenSearchWindow(searchWord, ...)
  " ...
  let b:searchWord = a:searchWord
  let b:searchWordType = (a:0 > 0 ? a:1 : 0)
  call s:HighlightSearchWord()
  " ...
endfunction

HighlightSearchWord() を修正する。OpenSearchWindow() で設定した b:searchWordType を使って、Vim正規表現を受けつけるようにする。

" b:searchWord にしたがって、ハイライトを設定する
" b:searchWord は OpenSearchWindow() で設定される
" OpenSearchWindow(), HighlightPreview() から呼ばれる。
" b:searchWordType が 1 なら b:searchWord を Vim の正規表現として扱う
function! s:HighlightSearchWord()
  let searchWord = exists('b:searchWord') ? b:searchWord : ''
  let searchWordType = exists('b:searchWordType') ? b:searchWordType : 0
  if searchWord == '' | return | endif
  let pat = (searchWordType ? searchWord : '\c\v'.escape(searchWord, '=~@%'))
  exe 'syntax match howmSearchWord display "'.pat.'"'
  hi howmSearchWord ctermfg=Red ctermbg=Grey guifg=Red guibg=bg
endfunction

次に Vim正規表現を受けつける GrepSearch() を作成する。

" s:GrepSearch と同様の出力をする関数
" searchWord: Vim の正規表現
" TODO: HInr のうち I に対応できていない
" TODO: &lazyredraw に意味があるか確認する
" TODO: filename が若干違う
function! s:VimGrepSearch(searchWord)
  let save_lazyredraw = &lazyredraw
  let &lazyredraw = 1
  let save_qflist = deepcopy(getqflist())
  silent! execute 'vimgrep /'. a:searchWord .'/gj '. g:howm_dir .'**/*.*'
  let retval = join(map(getqflist(), "fnamemodify(bufname(v:val['bufnr']),':p:.:gs?\\?/?').':'.v:val['lnum'].':'.v:val['text']"), "\n")
  call setqflist(save_qflist)
  let &lazyredraw = save_lazyredraw
  return retval
endfunction

次に FullTextSearch() 第2引数を変更して、Vim正規表現を解釈できるようにする。インデントが邪魔だったので a:searchWord の空文字チェックは最初の一行にまとめた。:vimgrep は 7 以降のものらしいので、v:version >= 700 とした。

http://d.hatena.ne.jp/eclipse-a/20080205/1202171988 Vimスクリプト入門みたいの 35 で若干修正しました。

" TODO: 引数を考え直した方がいいかも
"
" searchType: searchWord の種類
"  0: 固定文字列
"  1: 正規表現 ( grep )
"  2: 正規表現 ( Vim )
function! s:FullTextSearch(searchWord, searchType)
  if a:searchWord == '' | return 0 | endif
  call s:OpenSearchWindow(a:searchWord, (a:searchType == 2))
  " ...
  if v:version >= 700 && (a:searchType == 2)
    let grep_result = s:VimGrepSearch(a:searchWord)
  else
    if a:searchType == 2
      " TODO: エラーメッセージ
      return 0
    endif
    let grep_result = s:GrepSearch(a:searchWord, a:searchType)
  endif
  if s:ParseSearchResult(grep_result) > 0 || path != ''
    " ...
  endif
  return retval
endfunction

最後に FullTextSearchInput() に has('migemo') && v:version >= 700 のとき、FullTextSearch(searchWord, 2) を使う形に変更した。

" ユーザから検索語を受け取り,全文検索を行う.
" s:fulltext_prompt を使うのでいちいち関数を作った.
function! s:FullTextSearchInput(searchType)
  " ...
  elseif a:searchType == 'migemo'
    if has('migemo') && v:version >= 700
      let searchWord = input(s:prefix_howm.s:prompt_search_migemo)
      let searchWord = migemo(searchWord)
      call s:FullTextSearch(searchWord, 2)
    else
      " ...
    endif
  else
    " TODO: エラーメッセージ
    return
  endif
endfunction

ここまでで動作するかを確認してみる。よし。これで、一応 migemo() で動くようになったはず。