diary.sasaplus1.com

#1

Vimで:sを使ってテキストを置換する際に不便だったのを改善した。

Vimの正規表現は自分にとってとても難しい。拡張正規表現よりもずっと強力なのは良いのだけど、記号類が多すぎて覚えられないし、記号のエスケープの要不要がわからない。 どうせ簡単な正規表現しか書かないので、昔からeregex.vimをインストールして:Sを使って置換をしてきたのだけど、very magicで事足りるのでは?と思ったのでそれを活用するようにした。だけど、\vを入力するのが面倒で、:Sを使ってしまうので改善することにした。

以下のVim scriptを.vimrcに書く。

cnoremap <expr> /
      \ (
      \   getcmdtype() == ':' && (
      \     (getcmdline() ==#      's' && getcmdpos() == 2) \|\|
      \     (getcmdline() ==#     '%s' && getcmdpos() == 3) \|\|
      \     (getcmdline() ==# "'<,'>s" && getcmdpos() == 7)
      \   )
      \ ) ? '/\v' :
      \ (
      \   getcmdtype() == ':' && (
      \     (getcmdline() ==#      's/\v' && getcmdpos() ==  5) \|\|
      \     (getcmdline() ==#     '%s/\v' && getcmdpos() ==  6) \|\|
      \     (getcmdline() ==# "'<,'>s/\v" && getcmdpos() == 10)
      \   )
      \ ) ? "\<BS>\<BS>/" : '/'

挙動はどういう風になるかというと、:s/を入力すると:s/\vになる。しかし、その直後/を入力して:s/\v/とすると:s//になる。

どうしてこういう挙動かというと、以下の2つの目的を達成するため。

  1. 自分で正規表現を入力する場合は\vを付加したい
  2. *で検索した直後などlast-patternを使って置換したいときは\vを付加したくない

1.は自分で正規表現を入力したい場合、:s/の後に文字を入力していくと思うので単純に\vを付加している。

2.は:s//と入力したつもりが、このVim scriptを入れていると:s/\v/になってしまうので\<BS>\<BS>を先に入力することで\vを削除して:s//になるようにしている。あまり綺麗ではないけれど……

これでvery magicを活用できそうなので、しばらく試してみたいと思う。

もっと良いVim scriptに書き直すことはできそうだけど、目的は達成できたのでこのままにしておこうと思う。より良く書き直すためにはVim scriptをもっと学ばないといけないのだけど、今はそれよりもを優先的にやることがあるのでまた今度。