本記事はVim 駅伝の2025-08-11の記事です。
前回の記事はatusyさんの「Vimでヤンクした内容の上書き回避にはマイナス(-)をブラックホールレジスタにマッピングするといいよ」でした。
記事を書くにあたって使用した環境はこちらです。
(Neovimを使用していますが、操作はVimと同じです)
$ nvim --version
NVIM v0.11.3
Build type: Release
LuaJIT 2.1.1741730670
Run "nvim -V1 -v" for more info
記事要約
- Vimでクリップボードをシステムと共有する設定をしていると削除したテキストでクリップボードを上書きされることがある
- これはVimで行ったコピー、削除、変更、ペーストなどでクリップボードレジスタを変更する挙動になるため
- 回避法をvim-jpのSlackで尋ねてみたところ、いろいろな回答があった
- ブラックホールレジスタを使って削除してクリップボードレジスタを守る方法
"_d{motionもしくはtext-object}"
- ビジュアルモードで置換したいテキストを選択してペーストする方法
v{motionもしくはtext-object}p
-
c
やd
で削除するときは削除したテキストをクリップボードレジスタへ格納しないようにする方法 - そもそもクリップボードを共有しない方法
- ブラックホールレジスタを使って削除してクリップボードレジスタを守る方法
はじめに
Vimへコピペするとき、あらかじめコピーしたテキストを削除したテキストで上書きした経験ってありませんか?
(new_access_token
をコピーして貼り付けようとしたがdw
でクリップボードをold_access_token
で上書きしてしまった悲しき図)
どうしてこれが起きるの?
これを経験した人のほとんどが.vimrc
もしくはinit.lua
にVimとシステムのクリップボードを共有する設定をしているかと思います。
set clipboard+=unnamedplus
vim.opt.clipboard:append{'unnamedplus'}
この設定を行うと、Vimで行ったコピー、削除、変更、ペーストなどで、クリップボードレジスタを変更する挙動になります。
unnamedplus "unnamed" と似ているがコピー、削除、変更、ペーストなど の操作で、普通なら無名レジスタが使われるところで、ク リップボードレジスタ '+' (quoteplus) が使われる。 "unnamed" も同時に指定した場合は、コピー操作 (削除、変 更、ペースト以外の操作) で、レジスタ '*' にもテキスト がコピーされる
したがって、Vimでヤンクしたテキストはシステムのクリップボードに共有されますし、Vimで削除したテキストもシステムのクリップボードに上書きされるという結果になります。
これを回避するにはどうすればいいの?
ブラックホールレジスタを使って削除してクリップボードレジスタを守る方法
Vimには削除専用のレジスタであるブラックホールレジスタ(_
)があります。このレジスタに向けて削除や変更コマンドを操作することで、置き換えたいテキストを削除する際にクリップボードレジスタを上書きせずに済みます。
置き換えに使ったコマンド: "_dwP
簡単な解説
-
"_
でブラックホールレジスタを使うことを指定 -
dw
でカーソル位置にある単語を削除 -
P
でカーソル位置より前にペースト
ビジュアルモードで置換したいテキストを選択してペーストする方法
ビジュアルモード中に置換したいテキストを選択し、p
コマンドを実行することで、選択したテキストを置き換えることができます。
置き換えに使ったコマンド: vep
簡単な解説
-
v
でビジュアルモードに入る -
e
で単語の最後までを選択 -
p
で選択したテキストをレジスタで置き換える
p
を使って置き換えると、置き換え前のテキストをレジスタに置き換えてしまい、これはこれでクリップボードが上書きされます。
このようなときはveP
のようにP
コマンドを使用するとクリップボードをレジスタを置き換えられずに済みます。
ビジュアルモードで p や P 等の貼り付けコマンドを使ったとき、Vimは選択されたテキストをレジスタの中身で置き換えようとする。(中略)
p だとそれまで選択されていたテキストが無名レジスタに保存される(そして場合によっては選択テキストおよび/またはクリップボードも)。これは選択テキストを別の場所にプットするのに便利である。しかし、同じ変更を繰り返せない。P を使用すると、無名レジスタは変更されず(そして選択テキストもクリップボードも)、同じ変更を繰り返すことができる。
c
やd
で削除するときは削除したテキストをクリップボードレジスタへ格納しないようにする方法
Vimにはテキストをヤンクした際にTextYankPost
というイベントが発火します。この時に動作する関数を作成するそうです。
v:operator == "y"
という条件を使い、ヤンクを実行したときのみ無名レジスタの中身をクリップボードをレジスタに格納する方法。
そもそもクリップボードを共有しない方法
クリップボードとクリップボードレジスタを共有するからクリップボードが壊れるので、クリップボードを共有しないという方法。
コピペはターミナル側で行うという考え方。
あとがき
「そろそろNeovim使い始めて6年は経つのに、未だにスマートなコピペの方法わからねえ……」と思い、vim-jpのSlack(https://vim-jp.slack.com/)で尋ねたところ、多くの方から回答をいただきました。感謝です。
個人的にはv{motionもしくはtext-object}
のやり方が一番直感的かつスマートかと思いました。他のエディタでいうと置き換えたいテキストを選択してペーストするという操作と同じだと思っています。
余談ですが、前回の記事であるVimでヤンクした内容の上書き回避にはマイナス(-)をブラックホールレジスタにマッピングするといいよも、この回答の一つかと思います。
ブラックホールレジスタを扱うフックとして"_
を-
にマッピングすることで、最初の"_dwP
が-dwP
になります。"_
って微妙に入力しづらいですからね。
それでは皆さんよいコピペライフを。
参考リンク
この記事を書くにあたり、以下の記事を参考にさせていただきました。
-
VHS で楽に Neovim のデモ動画を録る
この記事がなければデモ動画は載ることがなかったでしょう。本当にありがとうございます。 -
options - Vim日本語ドキュメント
clipboard+=unnamedplus
を行うと何が起きるかが書いてあるドキュメント -
change - Vim日本語ドキュメント
ビジュアルモード中にp
を行った時についてのドキュメント -
Vimで使っている簡単キーマッピングたちを共有
「ビジュアルモード中のp
をP
にマッピングしておくと便利」というTipsが載っている
他にもいろんなTipsが載っているので参考になります