32
25

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Vimでコピぺする時に置き換え元の文字でクリップボードを上書きしないいくつかの方法

Last updated at Posted at 2025-08-10

記事を書くにあたって使用した環境はこちらです。
(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
    • cdで削除するときは削除したテキストをクリップボードレジスタへ格納しないようにする方法
    • そもそもクリップボードを共有しない方法

はじめに

Vimへコピペするとき、あらかじめコピーしたテキストを削除したテキストで上書きした経験ってありませんか?

example.gif

(new_access_tokenをコピーして貼り付けようとしたがdwでクリップボードをold_access_tokenで上書きしてしまった悲しき図)

どうしてこれが起きるの?

これを経験した人のほとんどが.vimrcもしくはinit.luaにVimとシステムのクリップボードを共有する設定をしているかと思います。

.vimrc
set clipboard+=unnamedplus
init.lua
vim.opt.clipboard:append{'unnamedplus'}

この設定を行うと、Vimで行ったコピー、削除、変更、ペーストなどで、クリップボードレジスタを変更する挙動になります。

options - Vim日本語ドキュメントより

    unnamedplus    "unnamed" と似ているがコピー、削除、変更、ペーストなど
                   の操作で、普通なら無名レジスタが使われるところで、ク
                   リップボードレジスタ '+' (quoteplus) が使われる。
                   "unnamed" も同時に指定した場合は、コピー操作 (削除、変
                   更、ペースト以外の操作) で、レジスタ '*' にもテキスト
                   がコピーされる

したがって、Vimでヤンクしたテキストはシステムのクリップボードに共有されますし、Vimで削除したテキストもシステムのクリップボードに上書きされるという結果になります。

これを回避するにはどうすればいいの?

ブラックホールレジスタを使って削除してクリップボードレジスタを守る方法

Vimには削除専用のレジスタであるブラックホールレジスタ(_)があります。このレジスタに向けて削除や変更コマンドを操作することで、置き換えたいテキストを削除する際にクリップボードレジスタを上書きせずに済みます。

置き換えに使ったコマンド: "_dwP

blackhole.gif

簡単な解説

  1. "_でブラックホールレジスタを使うことを指定
  2. dwでカーソル位置にある単語を削除
  3. Pでカーソル位置より前にペースト

ビジュアルモードで置換したいテキストを選択してペーストする方法

ビジュアルモード中に置換したいテキストを選択し、pコマンドを実行することで、選択したテキストを置き換えることができます。

置き換えに使ったコマンド: vep

visual.gif

簡単な解説

  1. vでビジュアルモードに入る
  2. eで単語の最後までを選択
  3. pで選択したテキストをレジスタで置き換える

pを使って置き換えると、置き換え前のテキストをレジスタに置き換えてしまい、これはこれでクリップボードが上書きされます。
このようなときはvePのようにPコマンドを使用するとクリップボードをレジスタを置き換えられずに済みます。

change - Vim日本語ドキュメントより

ビジュアルモードで p や P 等の貼り付けコマンドを使ったとき、Vimは選択されたテキストをレジスタの中身で置き換えようとする。(中略)
p だとそれまで選択されていたテキストが無名レジスタに保存される(そして場合によっては選択テキストおよび/またはクリップボードも)。これは選択テキストを別の場所にプットするのに便利である。しかし、同じ変更を繰り返せない。P を使用すると、無名レジスタは変更されず(そして選択テキストもクリップボードも)、同じ変更を繰り返すことができる。

cdで削除するときは削除したテキストをクリップボードレジスタへ格納しないようにする方法

Vimにはテキストをヤンクした際にTextYankPostというイベントが発火します。この時に動作する関数を作成するそうです。
v:operator == "y"という条件を使い、ヤンクを実行したときのみ無名レジスタの中身をクリップボードをレジスタに格納する方法。

そもそもクリップボードを共有しない方法

クリップボードとクリップボードレジスタを共有するからクリップボードが壊れるので、クリップボードを共有しないという方法。
コピペはターミナル側で行うという考え方。

not-share.gif

あとがき

「そろそろNeovim使い始めて6年は経つのに、未だにスマートなコピペの方法わからねえ……」と思い、vim-jpのSlack(https://vim-jp.slack.com/)で尋ねたところ、多くの方から回答をいただきました。感謝です。
個人的にはv{motionもしくはtext-object}のやり方が一番直感的かつスマートかと思いました。他のエディタでいうと置き換えたいテキストを選択してペーストするという操作と同じだと思っています。

余談ですが、前回の記事であるVimでヤンクした内容の上書き回避にはマイナス(-)をブラックホールレジスタにマッピングするといいよも、この回答の一つかと思います。
ブラックホールレジスタを扱うフックとして"_-にマッピングすることで、最初の"_dwP-dwPになります。"_って微妙に入力しづらいですからね。

それでは皆さんよいコピペライフを。

参考リンク

この記事を書くにあたり、以下の記事を参考にさせていただきました。

32
25
1

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
32
25

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?