Grundlagen von Mehrfachcursorn

55

Ich habe kürzlich davon erfahren multiple-cursorsund es sieht aus wie ein sehr nützliches Paket. Ich habe die Dokumentation des Original-Repos durchgesehen , aber die Befehle erscheinen mir immer noch etwas dunkel.

Ich habe mir dann das Video in Emacs Rocks! Angesehen, und das Video ist großartig, aber es konzentriert sich hauptsächlich auf das, was multiple-cursorsdazu in der Lage ist, und nicht darauf, wie es gemacht wird.

Gibt es Anleitungen, Tutorials oder Beispiele, die die grundlegendsten Funktionen veranschaulichen?

Amelio Vazquez-Reina
quelle
4
Ich konnte mich multiple-cursorssehr schnell einarbeiten, indem ich die README-Datei las. Meine Empfehlung ist, einfach zu lernen mc/mark-next-like-this. Probieren Sie es aus und machen Sie sich mit der Funktionsweise vertraut. Lesen Sie von dort aus die README-Datei, wenn Sie eine Frage haben, die mit "Ich frage mich, ob mehrere Cursor das können ..." beginnt. Video wäre hilfreich für Anfänger.
Nispio
Stimme voll und ganz zu! Absolut unklar, wie man es benutzt. Ich habe nur Zeilen maskiert und dann mc / edit-Zeilen mit KBD gebunden (nicht durch Mx, wie bei Github angegeben). Dann sehe ich mehrere Cursor, aber sie verschwinden nur nach jeder Texteingabe
Dima Fomin

Antworten:

19

Zusätzlich zu den beschriebenen Verwendungen von @bastibe benutze ich mehrere Cursor, um Text am Anfang / Ende einer Zeilengruppe hinzuzufügen oder zu entfernen:

  1. Bewegen Sie den Punkt an den Anfang oder das Ende des gewünschten Bereichs
  2. call set-rectangular-region-anchor(gebunden an einen beliebigen Schlüssel, ich denke der Vorschlag von Magnars war H-space, wenn Sie einen Hyper-Schlüssel haben)
  3. Bewegt den Punkt um eine Zeile ( C-nund C-p) vorwärts oder rückwärts, bis Sie auf jeder Zeile, die Sie bearbeiten möchten, einen Cursor haben
  4. Fügen Sie nach Bedarf Text ein oder löschen Sie ihn, und verschieben Sie ihn optional an das Ende der Zeile ( C-e), um dort Änderungen vorzunehmen.

Sie können verwendet werden forward-word, forward sentenceusw. hin und her entlang der Linien bewegen, die Ihnen das vierte Wort in jeder Zeile bearbeiten kann, auch wenn der Text in jeder Zeile nicht identisch ist.

Zum Beispiel mache ich diese Art von Arbeit die ganze Zeit:

  • C-u M-!ls / test-dat / pp5 / * fsaRETURN

    Dies fügt die Inhalte des pp5-Verzeichnisses in den Puffer ein. Ich platziere Punkt !zu Beginn der Auflistung:

!/test-dat/pp5/ONAB-6-5_Frag#89.fsa
/test-dat/pp5/QCJB-22-5_Frag#90.fsa
/test-dat/pp5/ONGL-1-5_Frag#102.fsa
/test-dat/pp5/ONGL-1-5_Frag#78.fsa
  • Fügen Sie zu jeder Zeile mit H-space, C-nx 4 Cursor hinzu
  • duplizieren Sie jede Zeile mit C-k C-y space C-y C-a

!/test-dat/pp5/ONAB-6-5_Frag#89.fsa /test-dat/pp5/ONAB-6-5_Frag#89.fsa
!/test-dat/pp5/QCJB-22-5_Frag#90.fsa /test-dat/pp5/QCJB-22-5_Frag#90.fsa
!/test-dat/pp5/ONGL-1-5_Frag#102.fsa /test-dat/pp5/ONGL-1-5_Frag#102.fsa
!/test-dat/pp5/ONGL-1-5_Frag#78.fsa /test-dat/pp5/ONGL-1-5_Frag#78.fsa
  • schneiden Sie den ersten Abschnitt in Variablennamen mit M-dx 3 C-d C-fx 3 M-dx 3 <-

ONAB-6-5 <-! /test-dat/pp5/ONAB-6-5_Frag#89.fsa
QCJB-22-5 <-! /test-dat/pp5/QCJB-22-5_Frag#90.fsa
ONGL-1-5 <-! /test-dat/pp5/ONGL-1-5_Frag#102.fsa
ONGL-1-5 <-! /test-dat/pp5/ONGL-1-5_Frag#78.fsa
  • Dann den tatsächlichen Dateinamen in die Funktion einbinden, um sie zu laden: read.file ( C-d" C-e")RETURN

ONAB-6-5 <- read.file("/test-dat/pp5/ONAB-6-5_Frag#89.fsa")
QCJB-22-5 <- read.file("/test-dat/pp5/QCJB-22-5_Frag#90.fsa")
ONGL-1-5 <- read.file("/test-dat/pp5/ONGL-1-5_Frag#102.fsa")
ONGL-1-5 <- read.file("/test-dat/pp5/ONGL-1-5_Frag#78.fsa")

Und voila, Sie haben eine Dateiliste in den Code konvertiert, um diese Liste zu lesen. Es ist tatsächlich viel schwieriger zu beschreiben, als es tatsächlich zu tun!

Tyler
quelle
3
Wenn Sie dasselbe häufig tun, können Sie es in ein Tastaturmakro einschließen. Tastaturmakros und multiple-cursorskönnen eine wirklich leistungsfähige Kombination bilden.
Nispio
@nispio hat zugestimmt! Manchmal wiederhole ich den gleichen Vorgang und ein Makro wäre nützlich. Häufig gibt es jedoch kleine Unterschiede in der Mitte des Arbeitsablaufs, die geringfügige Änderungen erfordern, die ein Makro „brechen“ würden.
Tyler
1
Sie können die Position, zu der der Cursor springen soll, häufig mit einem regulären Ausdruck genau beschreiben. In solchen Fällen kann using phi-searchrobuster sein als das Navigieren mit Befehlen wieM-f (x3)
nispio
@nispio sicher, es kommt auf die situation an. Mit durchgehend strukturierten Namen ist es einfach, sich wortweise zu bewegen. Ich hatte die Suche nicht in mehreren Cursorn verwendet, da die eingebauten Emacs-Suchbefehle mit mc spröde sind. Ich wusste nicht phi-search, das sieht gut aus!
Tyler
22

Grundsätzlich habe ich zwei häufige Anwendungsfälle für multiple-cursors:

  • Ersetzen Sie eine Zeichenfolge. Markieren Sie eine Instanz einer Zeichenfolge und verwenden Sie dann mc/mark-next-like-thisund mc/mark-previous-like-this, um weitere Instanzen davon zu markieren. Ich C-wdrücke dann sofort , um jede Instanz zu löschen, und schreibe stattdessen eine neue Zeichenfolge. Ich benutze dies oft, um eine Variable im Code umzubenennen.
  • Bearbeiten Sie mehrere Orte gleichzeitig. Markieren Sie entweder mehrere Instanzen einer Zeichenfolge wie zuvor, brechen Sie jedoch die Auswahl (jedoch nicht die Cursor) sofort mit ab C-g, oder platzieren Sie die Markierung und den Punkt in derselben Spalte in verschiedenen Zeilen, und verwenden Sie mc/edit-lines, um einen Cursor pro Zeile zu erhalten. Sie können jetzt reguläre Bearbeitungsbefehle verwenden, die auf jeden dieser Cursor angewendet werden.

Der erste Anwendungsfall ist besonders nützlich bei expand-region. Ich habe er/expand-regionan C-jund mc/mark-next-like-thisund mc/mark-previous-like-thisan C->und gebunden C-<. Damit kann ich leicht auswählen, an welcher Stelle das Wort steht, und das nächste / vorherige Vorkommen dieses Wortes sofort markieren.

Der zweite Anwendungsfall ersetzte für mich die meisten Anwendungen von Makros. Anstatt ein Makro aufzuzeichnen und dieses dann an mehreren Stellen anzuwenden, platziere ich einen Cursor an jeder Stelle und führe die Operation nur an allen Stellen gleichzeitig aus.

Bastibe
quelle
Vielen Dank @ Bastibe. Irgendwelche speziellen Bindungen, die Sie oder multiple-cursors zB für mark-next-like-this& empfehlen mark-previous-like-this?
Amelio Vazquez-Reina
@ user815423426 wie in der post umrissen benutze ich C->und C-<für mark-next-like-thisund mark-previous-like-this.
Bastibe
Warum nicht Standard-M-% zum Suchen und Ersetzen verwenden ?
Dima Fomin
6

Ich möchte einige Extras hinzufügen, mit denen ich manchmal arbeite multiple-cursors.

Ich habe Folgendes für nützlich befunden:

Iy-Go-To-Char

Manchmal müssen Sie zum nächsten #oder zum nächsten ,oder einem bestimmten Trennzeichen wechseln . Dies ist besonders praktisch, wenn Sie für jeden Cursor eine andere Anzahl von Wörtern verwenden müssen. Es bietet die Funktionen iy-go-to-charund iy-go-to-char-backward, die Sie binden und schön nutzen können.

expand-region

Dies ist aus ähnlichen Gründen sehr nützlich wie iy- wenn Sie unter jedem Cursor leicht abweichende Linien haben und möglicherweise die Zeichenfolge in Anführungszeichen unter dem Punkt oder ähnlichem auswählen möchten.

benutzerdefinierte Sachen

Dies sind Dinge, die nur in meiner Konfiguration elisp sind, aber ich finde nützlich. Wahrscheinlich nicht von mir geschrieben.

Eingabeaufforderung
Ich erhielt diese von Magnars als Antwort auf die Aufforderung, unter jeden Cursor eine andere Zeichenfolge zu stellen. Der Code ist einfach, aber die Bindung an etwas und die Verwendung für mehrere Cursor ist eine praktische Möglichkeit, an jeder Stelle etwas anderes einzufügen.

(defun prompt-for-insert ()
  (interactive)
  (insert (read-string "Insert: ")))

Inkrement-Nummer am Punkt
Dies kam entweder von SO oder von emacswiki. Ich weiß nicht was. Es ist sehr nützlich für sich und auch in Kombination mitmc/insert-numbers

(defun my-increment-number-decimal (&optional arg)
  "Increment the number forward from point by 'arg'."
  (interactive "p*")
  (save-excursion
    (save-match-data
      (let (inc-by field-width answer)
        (setq inc-by (if arg arg 1))
        (skip-chars-backward "0123456789")
        (when (re-search-forward "[0-9]+" nil t)
          (setq field-width (- (match-end 0) (match-beginning 0)))
          (setq answer (+ (string-to-number (match-string 0) 10) inc-by))
          (when (< answer 0)
            (setq answer (+ (expt 10 field-width) answer)))
          (replace-match (format (concat "%0" (int-to-string field-width) "d")
                                 answer)))))))

eval-and-replace
Dies ist sehr mächtig und ermöglicht einige wirklich nützliche Teile. Es wertet das Geschlecht aus, das sich hinter dem Cursor befindet, und fügt das Ergebnis der Auswertung ein.
Kombinieren Sie es mit, multiple-cursors-numbersum z. B. Potenzen von zwei oder eine Reihe einzufügen, die 0 1 2 0 1 2 0 1 2über jede Zeile oder etwas geht. (Ich habe beides nützlich gemacht) Oder benutze es s.el, um diese langweilige Java-Konfiguration mit Standard-Dingen zu schreiben. Sie schreiben jedes aus CONFIG_VALUE_VARIABLEund wandeln es dann CONFIG_VALUE_VARIABLE = "configValueVariable"durch Ausführen in um s-camel-case.

(defun eval-and-replace ()
  (interactive)
  (let ((value (eval (preceding-sexp))))
    (kill-sexp -1)
    (insert (format "%s" value))))
Tintenfisch
quelle
iy-go-to-char ist super hilfreich. Genau das, wonach ich gesucht habe.
Heinrich Hartmann
1
  1. Gehen Sie zum Ende * von dem, was Sie auswählen möchten.
  2. Drücken Sie C-S-boder M-S-b, um rückwärts zu wählen, bis Sie einen Teil ausgewählt haben. Sie können auch den Linkspfeil verwenden.
  3. Drücken Sie dann C->(drücken Sie die Umschalttaste, wenn sich die Taste >über der Tastaturtaste befindet), bis Sie mehr als ein Element ausgewählt haben.

* Es ist wichtig, rückwärts zu wählen, da sonst der Cursor bei der ersten Auswahl an der falschen Position positioniert wird.

Morishi
quelle