Abfrage-Ersetzen im Tastaturmakro

7

Lassen Sie mich ein Tastatur-Makro definieren: Ich gebe ein C-x (, gehe dann zum Anfang mit M-<und M-%tippe, um einige Vorkommen von foo durch Balken abzufragen und zu ersetzen . Von 3 gefundenen Vorkommen ersetze ich nur die letzten 2, speichere dann mit C-x C-sund beende das kbd-Makro mit C-x ). Gut gemacht!!

Wenn ich jetzt das kbd-Makro in einem anderen Puffer ausführe, werde ich nicht gefragt, ob ich foo durch bar ersetzen möchte. Es werden genau meine vorherigen Nein-Ja-Ja-Antworten reproduziert und das 2. und 3. Vorkommen ersetzt! Es wird nicht nach dem 4. oder 5. Vorkommen gefragt (dieser 2. Puffer enthält mehr Foo s) !! Dies habe ich nicht erwartet, als ich das Makro definiert habe. Ich wollte, dass es anruft query-replaceund ich seine Fragen beantworten kann ...

Nebenfrage: Findest du das nicht falsch? [Ich kann M-x edit-last-kbd-macround sehe, was aufgezeichnet ist und verstehe die Logik von allem, aber ich finde das immer noch falsch.]

Echte Frage: Was hätte ich verwenden können, anstatt query-replacemein kbd-Makro wie erwartet zum Laufen zu bringen?

phs
quelle
1
Persönlich finde ich es nicht falsch. Das Tastaturmakro zeichnet alle Ihre Tastenanschläge auf - einschließlich derjenigen, für die die Eingaben festgelegt wurden M-%- und gibt sie genau wieder. Ich habe noch nie ein Makro mit interaktiven Teilen gesehen und würde es auch nicht erwarten. An dieser Stelle ist es wahrscheinlich besser, eine normale interaktive Elisp-Funktion zu schreiben.
Tikhon Jelvis
Einfach. Beenden Sie Ihr Tastaturmakro, bevor Sie eine der Fragen beantworten. EDIT: Ich habe es gerade versucht, vielleicht ist es nicht so einfach. Ich denke, jemand könnte einen neuen Befehl schreiben start-kbd-macro-dwim.
Nispio

Antworten:

6

Emacs-Makros geben alles wieder, was der Benutzer im Verlauf des Makros eingibt, es sei denn, sie entkommen dem Makro. Der Weg, um einem laufenden Makro zu entkommen, ist mit C-x q kbd-macro-query.

Insbesondere glaube ich, dass Sie eine rekursive Bearbeitung eingeben müssen, die einen Befehl im Minibuffer auffordern kann, bevor Sie das Makro fortsetzen.

Ich denke, Sie möchten Ihre definieren, query-replacewenn Sie das Makro aufrufen.

  • F3 Starten Sie das Makro
  • M-< zum Anfang springen
  • C-u C-x q um eine rekursive Bearbeitung einzugeben
  • C-M-c um die rekursive Bearbeitung zu beenden
  • ... Rest der Makroaktionen
  • F4 zu speichern und zu wiederholen

Beim nächsten Mal kmacro-end-or-call-macrospringt es zum Anfang des Puffers und gibt eine rekursive Bearbeitung ein, in der Sie aufrufen können query-replace. Wenn Sie dann die rekursive Bearbeitung beenden, C-M-cwird das Makro von diesem Punkt aus fortgesetzt.

Wenn Sie nach einem alternativen Argument fragen möchten query-replace, ist es möglicherweise sinnvoll, eine einfache interaktive Wrapper-Funktion zu schreiben, query-replaceanstatt eine rekursive Bearbeitung zu verwenden.

dgtized
quelle
1
Sofern ich nicht falsch verstehe, zeichnet dies alles außer dem Anruf an auf query-replace. Es scheint nicht einmal so, als würde dies das FROM-STRINGoder retten TO-STRING.
Nispio
1
Ja, genau das habe ich gesagt. Wenn Query-
Replace
3

Dies scheint nicht gut für ein Tastaturmakro zu passen, da Sie nach Benutzereingaben fragen möchten. Vermutlich möchten Sie ein Makro aufzeichnen, da dies query-replacehäufig beabsichtigt ist. Wenn Sie das Tastaturmakro nicht dazu bringen können, das zu tun, wonach Sie suchen, können Sie eine Tastenkombination für Ihren spezifischen Aufruf query-replacewie folgt erstellen :

(global-set-key (kbd "C-c q")   ;; Create a key binding for "Ctrl+c, q"
  (lambda () (interactive)      ;; Define an anonymous interactive funcion
  (query-replace "foo" "bar"    ;; Query-replace "foo" with "bar"
   nil                          ;; Don't require matching whole words
   1 (buffer-end 1))))          ;; Run from beginning to end of buffer

Sie können dies entweder zu Ihrer Init-Datei hinzufügen und es steht Ihnen beim nächsten Start von Emacs zur Verfügung, oder Sie können es für eine Probefahrt nehmen, indem Sie es in den *scratch*Puffer einfügen und ausführen M-x eval-buffer. Es ist gebunden an C-c q, aber das kann leicht geändert werden, was Sie wollen.

Nispio
quelle