vim-users.jp

Hack #17: Vimを終了することなく編集中ファイルのファイル名を変更する

Posted at 2009/05/27
このエントリーをはてなブックマークに追加

編集対象ファイル名を変更するには、シェルで

$ vim aaa.txt
(編集作業)
$ mv aaa.txt bbb.txt
$ vim bbb.txt

のように一旦Vimを終了して開きなおすという方法がありつつも、多くのVim使いはおそらくVimを一旦終了するという行為に強い反感を抱くでしょう。

ファイル名を変更し、新しいファイルを開く

Vimにはシェルのmvに対応する関数rename()があります。これを使い、編集中ファイルをカレントディレクトリのnewfilename.txtというファイル名に変更してみましょう。

:call rename(expand('%'), 'newfilename.txt')
:e newfilename.txt

expand('%')で編集中ファイルのファイル名を得て、rename()で新しいファイル名に変更しています。コマンドmvを持つ環境では、一行目は:!mv % newfilename.txtとほぼ等価です。

この手法には、事前に古いファイルに編集中のデータを保存しておかなければ、新しいファイルに編集分が反映されないという問題点があります。 また、新しいファイル名を二度正確に入力しなければならないという問題点もあります。

新しい名前で保存し、古いファイルを削除する

一旦新しい名前で保存し、古いファイルを削除することで名前の変更を実現します。Vim内で

:w newfilename.txt
:call delete(expand('#'))

とすることで、まず編集中ファイルの中身を新しいファイルnewfilename.txtに書き込み、その後古いファイル名をexpand('#')で参照し、削除しています。UNIX環境では、上記二行目は:!rm #とほぼ等価です。

この手法には、ファイル名の変更の副作用として編集中ファイルが保存されるという問題点があります。大抵の場合それは問題とならないのですが、ファイルの保存時に特別なイベントをフックしているようなケースに問題となります。

ファイル保存先を指定し、古いファイルを削除する

:file newfilename.txt
:call delete(expand('#'))

:file {filename}は編集中バッファのファイル保存先を{filename}に変更します。これ以後、:wするだけで新しいファイル名に保存されます。 また、これまでに述べた二つの手法が持つ問題点の全てを同時に解決しています。

さて、二行目の削除処理を忘れないため、この二行をまとめて一つのコマンドとして定義しましょう。.vimrcに以下の設定を記述します:

command! -nargs=1 -complete=file Rename f <args>|call delete(expand('#'))

これで、以後:Rename newfilename.txtとすることでファイル名を変更することができます。

[UPDATED 2018-03-08] ファイルの保存に失敗しても削除します。かなり危険なので、上記commandは設定しない方がよいです。(コメント欄を参照されたし)

ujihisa

もどる
blog comments powered by Disqus