d [count] dをマップするにはどうすればよいですか?


18

NBこれは、「d3fg」コマンドどのように機能するかを複製したものではありませんか?投票する前に読んでください!

小さな削除を大きな削除のようにしようとする私の探求で少し行き詰まりになりました。私が持っている問題は、のようなコマンドを再マップする方法を理解できないことd3dです。実際、そもそもそれらがどのように機能するかを理解することも、Vimのヘルプでそれらの言及を見つけることもできません。

d3j簡単です:dオペレータを3jモーションに適用します。

3ddまた、簡単ddです。3の「カウント」でコマンドを実行します。

d3d それは簡単なように見えますが、d演算子を...に適用しますが、何3dですか?それは動きではありません。自分で入力3dした場合、Vimはそれをカウントの後に演算子が続くものとして扱い、それ以上の入力を辛抱強く待ちます。

また、演算子を他の演算子に適用することはできません。ddヘルプでは、2つの演算子のシーケンスとして説明されていません。これは、独立した2キーストロークコマンドです。(cf. dc、何もしません。)

また、2つのキーストロークを必要とするコマンドの場合、カウントの配置が柔軟であるということはないようです:2gjカーソルを2画面行下に移動しますがg2j、最初の2キーを完全に破棄し、カーソルを1行下に移動します。

それでは、どのように機能しますか?これはVimの内部コードの特殊なケースですか?d[count]dマッピングを作成する方法はありますか?

編集:それはテキストオブジェクトですか?:h text-objects「テキストオブジェクト選択コマンド」のリストには含まれませんが、「小さなオブジェクトから大きなオブジェクトにグループ化された」削除のリストにはdd 含まれます。そしてd2aw、カーソルの下の単語と次の単語を削除します。一方、c2d何もしません。

*それらについての言及が存在するに違いないと確信していますが、見つけることができません。私が読んだ:help deleting:help motion.txtと試してみました:helpgrep dNd1-9からのNの全ての値のために


2
最後のdものは確認として機能すると思います。ですから、と同じd3<CR>です。y3yそしてc3c助け、VI(1)、NVI(1)、またはPOSIX仕様...それはで同じ動作を行います。また、Vimのいずれかでけれども、私はこの上の任意のドキュメントを見つけることができない...同じように動作viし、nviところで。
マーティントゥルノイ

1
ある意味でddは、はと同じですd__カーソルを([count]-1)行目の最初の非空白に移動しますが、行単位であるため、演算子と組み合わせた場合、行全体で動作します。そのため、2つdの間にカウントが表示されることは理にかなっています。
tommcdo

回答:


28

オペレーター保留モード

オペレータ(のような入力との間にdcまたはgU)動きを(のようなwi}または/foo<CR>)、Vimはオペレータ待機モードになっています。:omapとを使用して、このマッピングを作成できます:onoremap

私の例では、Operator-pending dをにマップしwます。あなたが実際にそれを何に使いたいかわからないので、これはランダムな選択です。

omapを作成する

dオペレーター保留モードでのマッピングを作成しましょう。ここで(などで.vimrc)VimScriptを記述していると想定するので、先頭:のs は省略します。

onoremap d w

これは作るddように行動をdw。それはまたのd[count]dように行動しd[count]wます。しかし、あなたはdd(つまり、[count]提供されていない)の動作に影響を与えたくなかったに違いありません。

式マッピング

式マッピングにより、VimScript式を評価して、マッピングの右側を生成できます。式は文字列に評価される必要があります。式マッピングは<expr>キーワードで示されます。

Vimにはいくつかの組み込み変数もあり、これらはさまざまな時点で入力され、マッピング中に役立つことがよくあります。それらの1つはでありv:count、これは[count]オペレーターまたはモーションに提供されます。

それをすべてまとめましょう。[count]が指定されていない場合、にv:countなります0dその場合に使用するようにマッピングを指示できます。

onoremap <expr> d v:count == 0 ? 'd' : 'w'

現在ddはデフォルトのように動作します(行を削除します)が、のd[count]dように動作しd[count]wます。涼しい!

d演算子の後に使用するように制限する

ただし、何かに気付くかもしれません。今cdも同じように動作しcw。これは問題ではないかもしれませんが、完全を期すために、dオペレーターの後にのみ機能するように制限しましょう。

Vimには、v:operator最後に使用された演算子を含む別の変数があります。特別なことをする前に、それも確認しましょう。

onoremap <expr> d (v:count == 0 \|\| v:operator != 'd') ? 'd' : 'w'

注::mapコマンドはでチェーン化できるため|、ここでの式ではコマンドをエスケープする必要があります。したがって、論理OR演算子はに||なり\|\|ます。

かっこいいのでcdc[count]d以前のように何もしないことに戻ります。これは、他のプラグインが定義できるようにするのに適していますcd

他のモーションを削除したくありません

d[count]dテキストを削除することとはまったく関係のないまったく異なるものにマッピングしたい場合は、それも機能させることができます。

通常モードでコマンドを入力しているときに、誤ってコマンドを入力し始めた場合、<Esc>そのコマンドをキャンセルするためにヒットできます。同じことがマッピングにも当てはまります。

d[count]d現在の行を何にでも変更しましょう[count]

onoremap <expr> d (v:count == 0 \|\| v:operator != 'd') ? 'd' : '<Esc>cc' . v:count . '<Esc>'

マッピングの最後の部分はVimScript式です<Esc>cc' . v:count . '<Esc>'。それ<Esc>は、保留中のdコマンドをキャンセルしcc、現在の行を変更しv:count[count](挿入モードで)値を入力し、<Esc>通常モードに戻ることです。ここでは、VimScript連結演算子を使用して文字列を作成していることに注意してください.


実際のユースケースは、ここで説明したものとはおそらく異なる可能性がありますが、うまくいけば、ボールを転がすのに役立ちます。

ハッピーバイミング!


素晴らしい答えです!賛成。質問の冒頭で(vi.SEでも)ユースケースにリンクしましたが、見逃してしまったに違いないと思います。基本的に:omap d d(!)する必要がありますが、残念ながら、カスタムオペレーター関数を設定するdのマッピングのため、オペレーター保留モードに実際に到達することはありません。d3dしかし、うまくいくように調整することが可能であることを願っています。(アイデアがあれば教えてください。または、必要に応じて他の質問に対する完全な解決策を投稿してください。)すぐに理解できない場合は、これを受け入れて、より具体的な別の質問を投稿します。ありがとう!
リッチ

1
実際に、考え直して、私は今これを受け入れています。そのようなマッピングを作成する方法と、それが内部でどのように機能するかについて説明しました。
リッチ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.