Löschen Sie einen Teil der Isearch-Zeichenfolge, der nicht übereinstimmt, oder das letzte Zeichen, wenn die Übereinstimmung vollständig ist

11

Ich habe folgendes

(defun isearch-del-fail-or-char ()
  "Delete failed isearch text, or if there is none, a single character."
  (interactive)
  (if (isearch-fail-pos)
      (delete-region (isearch-fail-pos) (point))
    (isearch-del-char)))

(define-key isearch-mode-map (kbd "DEL") 'isearch-del-fail-or-char)

Der Zweck des Codes besteht darin, deletein isearch die gesamte fehlgeschlagene Zeichenfolge zu löschen (oder wenn keine fehlerhafte Zeichenfolge vorhanden ist, nur ein einziges Zeichen).

Beim delete-regionLöschen von Text aus dem Puffer isearchwird jedoch nicht im Suchpuffer selbst gesucht.

Was ist der richtige Weg, um dies zu tun? Kritik am Rest meines Emacs-Lisp-Stils ist ebenfalls willkommen :)

asmeurer
quelle

Antworten:

12

Ah ja. Isearch liest die von Ihnen eingegebenen Schlüssel, schlägt sie nach isearch-mode-mapund ruft sie im aktuellen Puffer auf .

Isearch tut nicht , trotz der Erscheinungen, verwenden Sie den Minipuffer. Es verwendet den Echo-Bereich. Das heißt, was Sie dort sehen, sind tatsächlich ausgegebene Nachrichten, einschließlich Echos der von Ihnen eingegebenen Zeichen.

Dies sollte tun, was Sie fragen:

(defun mydelete ()
  "Delete the failed portion of the search string, or the last char if successful."
  (interactive)
  (with-isearch-suspended
      (setq isearch-new-string
            (substring
             isearch-string 0 (or (isearch-fail-pos) (1- (length isearch-string))))
            isearch-new-message
            (mapconcat 'isearch-text-char-description isearch-new-string ""))))

(define-key isearch-mode-map (kbd "DEL") 'mydelete)

(Übrigens, Ihre Frage sagt das deleteZeichen, aber Sie haben geschrieben DEL, welches das Rücktastezeichen ist.)


Wie @Malabarba in einem Kommentar hervorhebt, wird beim Setzen der neuen Suchzeichenfolge auf ""(leere Zeichenfolge) die with-isearch-suspendedSuche nach der letzten Suchzeichenfolge fortgesetzt , anstatt mit einer leeren Suchzeichenfolge zu beginnen.

Dies ist ein " Merkmal " von with-isearch-suspendedim Allgemeinen. Aber weil Sie manchmal wirklich die Suchzeichenfolge für die Wiederaufnahme leeren möchten, habe ich in der Version von with-isearch-suspendedin isearch + .el eine Variable hinzugefügt isearchp-if-empty-prefer-resuming-with-last, um dies zu steuern. Wenn Sie dies binden nilund festlegen isearch-new-string, ""wird die Suche mit einer leeren Suchzeichenfolge fortgesetzt.

Mit Isearch + können Sie also mit dieser Definition tun, was Sie wollen:

(defun mydelete ()
  "Delete the failed portion of the search string, or the last char if successful."
  (interactive)
  (let ((isearchp-if-empty-prefer-resuming-with-last  nil))
    (with-isearch-suspended
        (setq isearch-new-string
              (substring
               isearch-string 0 (or (isearch-fail-pos) (1- (length isearch-string))))
              isearch-new-message
              (mapconcat 'isearch-text-char-description isearch-new-string "")))))

Ich stelle fest , auch jetzt , dass Emacs 24.4 eine Regression eingeführt, die ich eingereicht habe Emacs Bug # 20466 für, was bedeutet , dass die Bindung DELin isearch-mode-mapnicht ausreichend. Sie fügten <backspace>zusätzlich zu einer für eine separate Bindung für hinzu DEL. Das bedeutet, dass für Isearch <backspace>nicht mehr übersetzt DELwird (aber für Emacs wird es im Allgemeinen immer noch so übersetzt).

Also , wenn Sie die Rücktaste tun wollen , was Sie in Emacs gefragt 24.4 oder später , dann können Sie nicht nur binden DELzu mydelete. Sie müssen sich binden <backspace>zu mydelete. Dumm, AFAICT, mais auf n'arrete pas le Progres ...


Ich habe Isearch + einen ähnlichen Befehl hinzugefügt und an ihn gebunden C-M-l(denselben Schlüssel, mit dem eine Nichtübereinstimmung der Fertigstellung in Eiszapfen entfernt wurde ).

C-gBeachten Sie auch, dass in Isearch bei Nichtübereinstimmung auch der nicht übereinstimmende Text entfernt wird. (Wirkt sich aber C-gauch bei erfolgreicher Suche aus.)


Ich hätte erwähnen sollen, dass Isearch + seit einiger Zeit auch ein optionales Verhalten in ähnlicher Richtung aufweist. M-kWährend der Suche wird zwischen drei Verhaltensweisen umgeschaltet, die durch den Wert der Option gesteuert werden isearchp-drop-mismatch:

  • replace-last- Ihre aktuelle Eingabe ersetzt den letzten nicht übereinstimmenden Text. Sie können Ihre letzte Eingabe immer sehen, auch wenn es sich um eine Nichtübereinstimmung handelt. Und es steht zur Bearbeitung mit zur Verfügung M-e.

  • nil - Ihre aktuelle Eingabe wird angehängt, auch wenn die vorherige Eingabe nicht übereinstimmt.

  • alles andere - Ihre aktuelle Eingabe wird ignoriert (entfernt), wenn sie zu einer Nichtübereinstimmung führt. Die Suchzeichenfolge hat immer erfolgreiche Übereinstimmungen.

Drew
quelle
Übrigens habe ich darüber nachgedacht, Isearch + einen ähnlichen Befehl hinzuzufügen , seit ich den fehlgeschlagenen Teil hervorgehoben habe (vor Jahren, bevor ich ihn zu GNU Emacs hinzugefügt habe), aber ich bin nie dazu gekommen. Das habe ich jetzt gemacht . (Ich habe jedoch das Löschen eines Zeichens nicht eingeschlossen. Der Befehl, den ich hinzugefügt habe, ist ein No-Op, wenn es keinen fehlgeschlagenen Teil gibt.)
Drew
Ich bin unter OS X. Ich meinte rückwärts löschen.
Asmeurer
Das Verhalten isearch + replace-last sieht ziemlich gut aus. Gibt es eine Möglichkeit, es nicht jedes Mal klingeln zu lassen, wenn die Suche fehlschlägt?
Asmeurer
2
Ich habe eine neue Version von hochgeladen isearch+.el. Es (a) behebt die automatische Entfernung von Fehlanpassungen, so dass der Wraparound in Ordnung funktioniert. Außerdem wird eine Option hinzugefügt, isearchp-ring-bell-functionmit der Sie die Glocke während der Suche unterdrücken können.
Drew
3
Malabarba, interessant. Ich habe auf den Bug geschossen und bin damit fertig geworden . Meistens frachtkultiviert von isearch-del-charund Drews Antwort, aber es scheint wie beabsichtigt zu funktionieren. Das with-isearch-suspendedMakro war der Schuldige.
jbm