LoginSignup
7
7

More than 5 years have passed since last update.

Vimのコマンドラインモード(:)で、シェル同様のヒストリ展開(!$)を使う

Last updated at Posted at 2014-03-08

:e ~/path/to/filenameした時に以下のエラーになって、
:e! ~/path/to/filenameでやり直すことになる場合が時々あります。

E37: No write since last change (add ! to override)
  1. 再度~/path/to/filenameを入力するのは面倒。
  2. 上カーソルキーでヒストリを戻ってコマンドラインを編集 (:<Up><Home><Left>!。もしくは:cnoremap <C-A> <Home>等を設定しておいて :<C-P><C-A><C-F>!)
  3. :e! !$ (bashやzshでの操作と同様)

2.の操作をしていたのですが、どうもまどろっこしい印象なので、
3.の操作でやりたい、と思ったので少し調べてみました。
(実は2.の方が打鍵数は少ないですが)
(その他有効な場面としては、:'a,.w ~/path/to/newfileした後、:e !$)

以下の記事が見つかりました。

Is there a vim equivalent to bash's '!$'? - Stack Overflow

.vimrc
cnoreabbr <expr> !$  getcmdtype() == ':' ? split(@:,'\s\+')[-1] : '!$'
cnoreabbr <expr> !*  getcmdtype() == ':' ? join(split(@:,'\s\+')[1:], ' ') : '!*'
cnoreabbr <expr> !!  getcmdtype() == ':' ? @: : '!!'
cnoreabbr <expr> !-2 getcmdtype() == ':' ? histget(':', -2) : '!-2'

stackoverflowの記事でも指摘されていますが、
スペースで分割しているだけなので、
""等でくくられていてもスペースが含まれていると分割されます。
(vimlparserを使ってきちんと解析することはできそうです。)

ちなみに、シェルのヒストリ展開で個人的によく使うのは以下なのですが、
シェルに合わせた操作をVimでできるようにするよりも、Vimに合わせて、
上カーソルキーでヒストリをたどって編集するか、
さらに複雑な変更をしたい場合は、q:でコマンドラインウィンドウを
使うことでいいかと思っています。

  • CTRL-Rによるヒストリ検索
  • !v等で再実行
  • ^str1^str2による置換実行(たまに)

その他、Vimのコマンドラインモードでのファイル名補完が、
シェルの補完と違うとわずらわしいので、Vim側で以下の設定をしています。

.vimrc
set wildmode=longest:full
set wildmenu
7
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
7