netrw を使うために

ぺりー
7 min readFeb 28, 2024

--

http://www.drchip.org/astronaut/vim/#NETRW

本記事は Vim駅伝 2024–02–28 に寄稿しました。

こんにちは!ぺりーです。

本日は Vim 標準のファイラーでありリモートファイルを直接操作できるプラグインの netrw を使うためのオレオレな設定を紹介します。

netrw と評判

Vim でファイル操作を行う際に多くの人がファイラーを使用すると思いますが、Vim 標準のファイラーでありリモートファイルを直接操作できる多機能なプラグイン netrw を常用する Vimmer はあまり多くないと思います。

netrw は操作が直感的ではなく、内部コードが難解でメンテナが不在でバグを修正できないからなど、さまざまな理由でさまざまな人から Vim のお荷物認定されています。

某vim-jpより

とはいえ、Neovim はともかく、Vim から削除されることは互換性の観点から考えにくいので、ファイラー系プラグインを導入していない場合は netrw と仲良くしておくのが吉です。

netrw の不便な点

netrw が提供している設定だけでは netrw を普段使いすることは難しいです。
先に挙げた理由のほかに、例えば下記の不便な点があったからです。

  • ディレクトリは空でなければ削除できない
  • コピーにはマーク(ファイル選択と同じ:h netrw-mf)をする必要があり、プロンプトを介してできない
  • ディレクトリはコピーできない
  • 一度に複数ファイルを移動・コピーできない

私の場合は、ローカルファイルのディレクトリ・ファイルのブラウジング、コピー、移動(=リネーム)、削除ができれば満足だったので、

解決策1 外部コマンド

初めは netrw を起動し -(:h netrw--)などを使ってブラウジングを行い、ファイル操作は netrw バッファからファイル名修飾子を使って(%:hなど)外部コマンドを実行して対処していました。

解決策2 netrw のマッピングを追加・変更する

外部コマンドを使用する解決策1では、外部コマンドを入力する際のカーソル移動や、外部コマンド実行時のスクリーンの描画の中断(Press ENTER or type command to continue)が発生してしまいます。

それを避けるため、netrw でのみ有効な割り当てを行い、外部コマンドを直接入力しないようにしました。

vim9script

# OperateUnderCursor accepts 'remove', 'copy', 'move'.
def! g:OperateUnderCursor(op: string): void #{{{
const dir: string = expand('%:p:h') .. '/'
const path: string = dir .. expand('<cfile>')
var cmd: string = ''
if op ==# 'remove'
if isdirectory(path)
delete(path, 'rf')
else
delete(path)
endif
return
elseif op ==# 'copy'
cmd = 'cp -a ' .. path .. ' ' .. input('Copying ' .. path .. ' to: ', dir, 'dir')
elseif op ==# 'move'
if isdirectory(path)
cmd = 'mv ' .. path .. ' ' .. input('Moving ' .. path .. ' to: ', dir, 'dir')
else
cmd = 'mv ' .. path .. ' ' .. input('Moving ' .. path .. ' to: ', dir, 'file')
endif
else
return
endif
const out: string = system(cmd)
histadd('cmd', 'call system("' .. cmd .. '")')
if v:shell_error
echoerr out
endif
enddef #}}}

def NetrwRemap(): void
nnoremap <buffer> D <Cmd>call g:OperateUnderCursor('remove') \| :e!<CR>
nnoremap <buffer> CP <Cmd>call g:OperateUnderCursor('copy') \| :e!<CR>
nnoremap <buffer> MV <Cmd>call g:OperateUnderCursor('move') \| :e!<CR>
enddef
autocmd MyVimrcCmd FileType netrw call NetrwRemap()

上記の関数ではカーソル下を対象に削除、移動、コピー操作することができ、netrw でのみ有効なマッピングになっています。

system() を使用してコマンドを実行することで、スクリーンの描画が中断されることはなくなりました。

netrw の D は空ディレクトリの削除とファイルの削除に割り当てられていますが、マッピングを上書きしています。(Visual Mode では上書きされず、 netrw の D が使用されるため、ファイルの一括削除等ができます。)

netrw の R (:h netrw-R) はフルパスを変更するので移動も行えますが、移動先の補完が効かないため、移動は MV に上記の関数をマッピングして区別して利用しています。

まとめ

このような設定を書くことで netrw でブラウジングしながらコピー、移動(リネーム)、削除を自由にすることができるようになり、少なくとも僕は netrw を常用できるようになりました。

netrw を使う物好きに参考にしてもらえたら幸いです。

d でディレクトリが作成できるのですが、下記の設定を反映することで子ディレクトリも一気に作成できるようになるのでおすすめです。

g:netrw_localmkdiropt = ' -a'

そのほかの netrw の設定やカスタマイズなどはヘルプもしくは下記リンクを参考にすると良いと思います。

ファイラー系のプラグイン比較はぜひ Alisue さんの記事を

--

--

ぺりー

Satoru Kitaguchi. Backend Engineer at eureka, Inc.