Zuordnung, um das Symbol unter dem Cursor mit einem Ausdruck einzuschließen, der das Symbol enthält

7

Ich habe eine Stunde lang vim-Skriptbeiträge gelesen, aber ich fürchte, ich habe nicht die Fähigkeiten, diese Beiträge auf mein Problem anzuwenden. Beim Bearbeiten von Mathematik in Latexdokumenten möchte ich häufig mathematische Symbole wie +, -, = durch \ Pad {+}, \ Pad {-}, \ Pad {=} ersetzen, wobei \ Pad ein Latexmakro I 'ist. ve definiert, um Platz um das Symbol zu setzen. Ich möchte meinen Cursor auf ein solches Symbol setzen, ein paar Buchstaben eingeben, sagen ;Pund diese Aktion das Symbol durch ersetzen lassen

\Pad{whatever the symbol under the cursor is}

Jede Hilfe wäre sehr dankbar!

`

Leo Simon
quelle

Antworten:

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>

Wenn Sie den vorherigen Code in Ihr vimrc einfügen, sollte es tun, was Sie wollen.

Um es zu verwenden, drücken Sie ;P{motion}und die PadMacro()Funktion sollte die {motion}mit \Pad{und abgedeckten Zeichen einschließen }.

Anwendungsbeispiele:

  • ;Plum das Zeichen unter dem Cursor einzuschließen (da les sich um eine Bewegung handelt, die das Zeichen unter dem Cursor abdeckt)
  • ;Piwum das Wort unter dem Cursor einzuschließen (da iwes sich um ein Textobjekt handelt, das alle Zeichen innerhalb des Wortes unter dem Cursor abdeckt)
  • ;Pisum den Satz einzuschließen, in dem sich der Cursor befindet (weil ises sich um ein Textobjekt handelt, das alle Zeichen in einem Satz abdeckt)
  • ;P$ um die Zeichen zwischen Ihrem Cursor und dem Ende der Zeile einzuschließen
  • ;P um die visuell ausgewählten Zeichen einzuschließen

Alles, was von der PadMacro()Funktion ausgeführt wird, wird als einzelne Ausgabe betrachtet, was bedeutet, dass der Punkt wiederholbar ist.
Mit anderen Worten, wenn Sie mehrere ähnliche Textteile einschließen \Pad{}müssen, müssen Sie die Zuordnung nicht jedes Mal, sondern nur beim ersten Mal treffen (danach können Sie drücken ., um Ihre letzte Ausgabe zu wiederholen).

Eine vollständige Liste der Textobjekte, auf die Sie Ihr Gehäuse anwenden können, finden Sie unter :
:help text-objects.

saginaw
quelle
Fabelhaft, vielen Dank @saginaw. Ich habe tatsächlich ein paar verschiedene Abstandsbefehle, wie \ pad, \ ppad, zusätzlich zu Pad. Natürlich könnte ich das Makro für jedes dieser Elemente duplizieren, aber zu Unterrichtszwecken gibt es vermutlich eine Möglichkeit, ein Argument an das Makro zu übergeben, die Zeile "let string" zu ändern, um das Argument anstelle von Pad einzufügen, und dann eine andere Noremap zu definieren für jede Option, z. B. würde p \ pad einfügen ,; pp würde \ ppad einfügen? Danke noch einmal!
Leo Simon
@LeoSimon Sie können eine ganze Gruppe von Zuordnungen mit einer einzelnen forSchleife und dem :executeBefehl definieren. Ein Beispiel finden Sie hier: github.com/romainl/dotvim/blob/master/vimrc#L307-L312 Es sollte nicht schwierig sein, dasselbe für Ihre Zuordnungen zu tun. Ich weiß jedoch nicht, wie ich "pad", "ppad", ... als Argument an die Funktion übergeben soll. Ich habe eine Idee (nach dem Lesen :h g@scheint es, dass Sie eine optionale Gruppe von Argumenten hinzufügen ...und mit auf das erste Argument dieser Gruppe zugreifen können a:1), aber es ist mir nicht gelungen, eine funktionierende Funktion zu schreiben. Wenn ich kann, werde ich es dich wissen lassen.
Saginaw
Danke @saginaw, ich habe mit der for-Schleife begonnen, konnte aber leider nicht an der ersten Basis vorbei. Ich habe Folgendes als ersten Schritt versucht: innerhalb Ihres Makros
Leo Simon
@LeoSimon Ich hoffe, der Name PadMacroist nicht zu irreführend, weil es nur eine Vimscript-Funktion ist. Ich habe es so genannt, weil Sie sagten, es \Pad{}wurde als Latexmakro interpretiert. Aber wenn Sie es vorziehen, können Sie es auch anders nennen ( PadEnclosurezum Beispiel). Für die Zuordnungen, sagen wir , Sie drei Funktionen haben MyFunctionA, MyFunctionBund MyFunctionC, die jeweils eine bestimmte Transformation auf Ihren Text anwenden. Und Sie möchten sie zuordnen ;Pa, ;Pbund ;Pc. Dann sollte der folgende Code dies für Sie tun können: paste.debian.net/plain/356949 Nicht getestet, daher bin ich mir nicht sicher, ob es funktioniert.
Saginaw
Vielen Dank! @saginaw. PadMacro ist vollkommen in Ordnung. Ihre Schleife hat wunderbar funktioniert. Alles wäre etwas eleganter, wenn ich die eigentliche Skriptfunktion in die Schleife aufnehmen könnte. Es ist einfach, die Zeile \let string = so zu ändern , dass sie ein Listenelement anstelle eines Pads akzeptiert. Der Problemteil besteht darin, den Makronamen als Listenelement anstelle einer Literalzeichenfolge zu definieren, dh das Folgende funktioniert nicht (nicht überraschend) function! s: . func_name . (type) abort. Vielleicht gibt es eine Möglichkeit, die Funktion mit einem generischen Namen zu erstellen und dann innerhalb der Schleife die generische Funktion nach func_name zu kopieren?
Leo Simon
5

Die Idee ist einfach:

  1. Sie schneiden den Text, den Sie umgeben möchten, und wechseln in den Einfügemodus.
  2. Sie fügen den ersten Teil ein,
  3. Sie fügen den Inhalt des unbenannten Registers ein.
  4. Sie fügen den letzten Teil ein,
  5. Sie verlassen den Einfügemodus.

Für Ihr Beispiel würden Sie tun:

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

Welches kann für Ihre Bequemlichkeit abgebildet werden:

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

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

Beachten Sie, dass es möglich ist, ein anderes Register zu verwenden, wenn Sie das unbenannte Register nicht überladen möchten. Hier benutze ich das zRegister:

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

Nur noch eine Lösung für den Fall, dass Surround nicht nur ein Symbol enthält (Beispiel aus meiner Konfiguration für Surround mit "[" & "]"

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

Der Schlüssel ist, "o" & "O" zu verwenden, um zum Anfang / Ende der Auswahl zu gelangen

dartNNN
quelle