vimのtextobjで検索文字列を指定する
Vim Advent Calendar 2012の331日目の記事になります。
330日目は@LeafCageさんによる 俺が見たいのはメッセージの最後なんだ!:messagesを便利にするVimプラグイン でした。
はじめに
先日このようなvimの記事を見つけました。
feedkeys() を使用します。
function! HLsearch() call feedkeys(":set hlsearch\<CR>", "n") endfunction call HLsearch()これでハイライトが行われます。
少々バッドノウハウっぽくはありますが、自分はこの関数内でのset hlsearchの方法を待ち望んでいました。
過去にvim-operator-userを使って検索オペレータを作ろうと思い立つも、関数内ハイライトの壁に阻まれて諦めていたのです。
でもこの方法さえ知ればもう怖いものはない、一度敗れた雪辱を果たしてやろうと思います。倍返しです。
ちなみに関数内でハイライトが効かないのは仕様だそうです(:h nohlsearch)。
実装
では早速実装してみましょう。
こんな感じ。
NeoBundle 'kana/vim-operator-user' " 検索オペレータ map <SPACE>/ <Plug>(operator-search) call operator#user#define('search', 'OperatorSearch') function! OperatorSearch(motion_wise) " v or V or <C-v> let v = operator#user#visual_command_from_wise_name(a:motion_wise) " textobjで選択した文字列を検索パターン用レジスタに格納 let orig = @" execute 'normal! `[' . v . '`]y' let @/ = '\V' . substitute(escape(@", '\'), '\n', '\\n', 'g') let @" = orig " 検索履歴に追加 call histadd('/', @/) " 強調表示 if &hlsearch call feedkeys(":set hlsearch\<CR>", 'n') endif endfunction
どやろか?
ただ上記は思いっきり自分仕様に作ってます。
自分は*の動作でも移動はせずハイライトのみするようにしているので、これも同じように作成しました。
その後n/Nで移動する感じです。
とりあえず動かしてみる。
うーん、いい感じっす。
あと捕捉ですがilの動作はvim-textobj-lineでやってます。
いやぁハイライトって本当にいいものですね。
私もう満足です。
一片の悔いなしっす。
が一応
さっきも言ったように上記は思いっきりオレオレ仕様であります。
普通は初回の動作でも移動+ハイライトになると思うので頑張って作ってみたいと思います。
map <SPACE>/ <Plug>(operator-search-forward) map <SPACE>? <Plug>(operator-search-backward) call operator#user#define('search-forward', 'OperatorSearch', 'call SetOpSearchCmdtype("/")') call operator#user#define('search-backward', 'OperatorSearch', 'call SetOpSearchCmdtype("?")') let s:op_search_cmdtype = '' function! SetOpSearchCmdtype(cmdtype) let s:op_search_cmdtype = a:cmdtype endfunction function! OperatorSearch(motion_wise) let v = operator#user#visual_command_from_wise_name(a:motion_wise) let save = @" execute 'normal! `[' . v . '`]y' let @/ = '\V' . substitute(escape(@", '\'), '\n', '\\n', 'g') let @" = save call histadd('/', @/) if &hlsearch call feedkeys(":set hlsearch\<CR>", 'n') endif " キーマップから実行することで<SPACE>?でのn/Nの方向が?と同じになる call feedkeys(s:op_search_cmdtype . "\<CR>", 'n') endfunction
うーん、検索周りは自分のつたないvimscript力ではこの辺が限界か。
一応動作はしますが、納得はいってません。
特に2回もfeedkeys()を使わされているのが悔しいです。
v:searchforwardもまた関数から出ると元に戻るようで。
プラグイン化も考えてたけどまた次回に・・・。
だれかキレイなものを作ってくれる方募集中です。
まとめ
@thincaさんのvim-visualstarはすっごいよく出来てる。