シンボルを含む式でカーソルの下のシンボルを囲むマッピング


7

vimスクリプトの投稿を1時間読んでいますが、これらの投稿を自分の問題に適用するスキルがありません。Latexドキュメントで数学を編集しているときに、+、-、=などの数学記号を\ Pad {+}、\ Pad {-}、\ Pad {=}に置き換えたいと思っています。ここで、\ PadはLatexマクロです。シンボルの周囲にスペースを配置するように定義されています。カーソルをそのような記号の上に置いて、2、3文字入力して、;Pこのアクションで記号を次のように置き換えられるようにしたい

\Pad{whatever the symbol under the cursor is}

どんな助けでも大歓迎です!

`

回答:


5
function! s:PadMacro(type) abort
    if a:type ==# 'char'
        normal! `[v`]d
    elseif a:type ==# 'line'
        normal! '[V']d
    elseif a:type ==# 'v'
        normal! `<v`>d
    else
        return
    endif
    let string = '\Pad{' . @" . '}'
    silent execute "normal! i\<c-r>=string\r"
endfunction
nnoremap <silent> ;P :set operatorfunc=<sid>PadMacro<cr>g@
vnoremap <silent> ;P :<c-u>call <sid>PadMacro(visualmode())<cr>

以前のコードをvimrcに入れれば、望みどおりの動作をするはずです。

これを使用するには、を押して;P{motion}PadMacro()関数がとでカバーされる文字を囲む必要{motion}\Pad{あり}ます。

使用例:

  • ;Plカーソルの下のキャラクターを囲むため(lカーソルの下のキャラクターを覆う動きのため)
  • ;Piwカーソルの下の単語を囲むには(iwカーソルの下の単語内のすべての文字をカバーするテキストオブジェクトであるため)
  • ;Pisカーソルが置かれている文を囲む(is文内のすべての文字をカバーするテキストオブジェクトであるため)
  • ;P$ カーソルと行末の間の文字を囲む
  • ;P 視覚的に選択された文字を囲む

PadMacro()関数によって実行されるすべては単一の版と見なされます。つまり、ドットの繰り返しが可能です。
言い換えると、囲むテキストの類似した部分が複数ある場合\Pad{}、毎回マッピングをヒットする必要はなく、初回のみです(その後、ヒット.して最後の版を繰り返すことができます)。

エンクロージャーを適用できるテキストオブジェクトの完全なリストについては、を参照してください
:help text-objects


素晴らしい、@ saginawに感謝します。実際、私は、パッドに加えて、\ pad、\ ppadのようないくつかの異なる間隔コマンドを使用しています。もちろん、これらのそれぞれに対してマクロを複製することもできますが、説明のために、引数をマクロに渡し、「文字列を追加する」行を変更して、Padの代わりに引数を挿入し、別のnoremapを定義する方法があると思いますオプションごとに、たとえば、; pは\ padを挿入し、; ppは\ ppadを挿入しますか?再度、感謝します!
Leo Simon

@LeoSimon単一のforループと:executeコマンドでマッピングのグループ全体を定義できます。例については、こちらをご覧ください:github.com/romainl/dotvim/blob/master/vimrc#L307-L312マッピングに対して同じことを行うことは難しくありません。ただし、「pad」、「ppad」などを関数の引数として渡す方法がわかりません。私はアイデアを持っています(を読んだ後:h g@、オプションの引数グループをで追加し、...このグループの最初の引数にでアクセスできるようですa:1)が、機能する関数を作成することに成功していません。できればお知らせします。
saginaw

@saginawに感謝し、forループを開始しましたが、残念ながら一塁を通過できませんでした。私は最初のステップとして次のことを試みました:マクロ内で
Leo Simon

@LeoSimon PadMacroそれは単なるvimscript関数なので、名前が誤解を招きすぎないことを願っています。あなた\Pad{}がラテックスマクロとして解釈されたと言ったので、私はそれをそのように呼びました。ただし、必要に応じて、他の名前(PadEnclosureたとえば)にすることもできます。マッピングについて、3つの関数MyFunctionAMyFunctionBおよびがありMyFunctionC、それぞれがテキストに特定の変換を適用するとします。そして;Pa、それらをにマッピングしたい;Pbとし;Pcます。その後、次のコードでそれを行うことができます:paste.debian.net/plain/356949テストされていないため、動作するかどうかはわかりません。
saginaw

ありがとう!@saginaw。PadMacroは完全に問題ありません。ループは美しく機能しました。ループに実際のスクリプト関数を含めることができれば、すべてが少しエレガントになります。\let string = パッドの代わりにリストアイテムを受け入れるように行を変更するのは簡単 です。問題の部分は、マクロ名をリテラル文字列ではなくリスト項目として定義することfunction! s: . func_name . (type) abortです。つまり、以下は機能しません(当然のことです) 。たぶん、ジェネリック名で関数を作成するいくつかの方法があり、次にループ内でジェネリック関数をfunc_nameにコピーしますか?
Leo Simon、

5

アイデアは簡単です:

  1. 囲んだいテキストをカットして挿入モードに入る
  2. あなたは最初の部分を挿入し、
  3. 名前のないレジスタの内容を挿入し、
  4. 最後の部分を挿入し、
  5. 挿入モードが終了します。

あなたの例では、あなたはそうするでしょう:

s\Pad{<C-r>"}<Esc>

あなたの便宜のためにマッピングすることができます:

" normal mode, for single characters
nnoremap ;P s\Pad{<C-r>"}<Esc>

" visual mode, for multiple characters
xnoremap ;P s\Pad{<C-r>"}<Esc>

名前のないレジスタを乱雑にしたくない場合は、別のレジスタを使用することが可能であることに注意してください。ここで私はzレジスタを使用します:

"zs\Pad{<C-r>z}<Esc>

3

シンボルが1つだけではない場合のもう1つの解決策( "["と "]"を含むサラウンドの構成からのサンプル)

vmap Q[ O<Esc>i[<Esc>gvo<Esc>la]<Esc>
nnoremap Q[ veO<Esc>i[<Esc>gvo<Esc>la]<Esc>

キーは、「o」と「O」を使用して選択の開始/終了に移動することです

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.