Welche Tastenkombination zum Navigieren aus einer Zeichenfolge verwendet werden soll

9

Wenn ich mitten in einer laaaangen Saite bin, wie folgt

(setq Emacs-beta "Which keyboard shortcut to use for navigating out of a string")

Kann ich es kurz vor dem ersten "(nach Emacs-Beta) mit einer Verknüpfung überspringen ?

Dieter.Wilhelm
quelle
Keine wirkliche Antwort C-r " C-b.
Name

Antworten:

12

Emacs 25 oder neuer

Sie möchten, C-M-uwelcher Befehl ausgeführt wird backward-up-list.

Bewegen Sie sich rückwärts aus einer Ebene von Klammern heraus. Dieser Befehl funktioniert auch mit anderen klammerartigen Ausdrücken, die vom aktuellen Sprachmodus definiert werden.

Wenn ESCAPE-STRINGS nicht null ist (da es interaktiv ist), verlassen Sie auch die einschließenden Strings.

Tagesmutter
quelle
Sie sollten erwähnen, dass es nur 25 ist.
abo-abo
@ abo-abo Es ist nicht: Ich habe es gerade in 24.5.1 getestet. Ich bin nicht sicher, wann es hinzugefügt wurde, aber wenn jemand herausfinden kann, werde ich es bearbeiten.
Kindermädchen
@ abo-abo Ups, es tut mir leid, du hast recht.
Kindermädchen
Ich bin mit Emacs-24.5 -Qin einer Schnur, aber ich bekomme mit CMu : up-list: Scan error: "Unbalanced parentheses"?
Dieter.Wilhelm
1
@ Dieter.Wilhelm Richtig: Wie Sie an meinem Kommentar und meiner Bearbeitung sehen können, habe ich mich geirrt. Es funktioniert nur in Emacs 25 oder neuer.
Kindermädchen
3

Es ist so machbar:

(defun exit-string-backwards ()
  (interactive)
  (goto-char (nth 8 (syntax-ppss))))

Im Lispy-Modus gelangen Sie durch Drücken [von zum Anfang der enthaltenen Liste und verlassen eine beliebige Zeichenfolge. Sobald Sie am Anfang der Liste angekommen sind, können Sie andere Teile leicht erreichen, um beispielsweise das Ende der Emacs-betaDrucklegung zu erreichen 2m.

abo-abo
quelle
1

Dies ist tatsächlich eine sehr interessante Emacs Lisp-Programmierfrage. Wir können Forward-Char oder Backward-Char beibehalten, bis wir festgestellt haben, dass das Zeichen unter dem Cursor nicht Teil der Zeichenfolge ist.

Sie können die Schriftart verwenden, um zu entscheiden, ob sich das Zeichen in der Zeichenfolge befindet. Dies ist ein großartiger Trick, den ich aus Flyspell gelernt habe. Theoretisch ist es nicht perfekt, aber in der realen Welt funktioniert es mit fast allen Hauptmodi der Programmiersprache auf Emacs23, Emacs24, Emacs25 .

Hier ist der vollständige Code:

(defun font-face-is-similar (f1 f2)
  (let (rlt)
    ;; (message "f1=%s f2=%s" f1 f2)
    ;; in emacs-lisp-mode, the '^' from "^abde" has list of faces:
    ;;   (font-lock-negation-char-face font-lock-string-face)
    (if (listp f1) (setq f1 (nth 1 f1)))
    (if (listp f2) (setq f2 (nth 1 f2)))

    (if (eq f1 f2) (setq rlt t)
      ;; C++ comment has different font face for limit and content
      ;; f1 or f2 could be a function object because of rainbow mode
      (if (and (string-match "-comment-" (format "%s" f1)) (string-match "-comment-" (format "%s" f2)))
          (setq rlt t)))
    rlt))

(defun goto-edge-by-comparing-font-face (&optional step)
"Goto either the begin or end of string/comment/whatever.
If step is -1, go backward."
  (interactive "P")
  (let ((cf (get-text-property (point) 'face))
        (p (point))
        rlt
        found
        end)
    (unless step (setq step 1)) ;default value
    (setq end (if (> step 0) (point-max) (point-min)))
    (while (and (not found) (not (= end p)))
      (if (not (font-face-is-similar (get-text-property p 'face) cf))
          (setq found t)
        (setq p (+ p step))))
    (if found (setq rlt (- p step))
      (setq rlt p))
    ;; (message "rlt=%s found=%s" rlt found)
    (goto-char rlt)))

Verwendungszweck:

  • (goto-edge-by-comparing-font-face 1)Gehe zum rechten Rand, (goto-edge-by-comparing-font-face -1)gehe zum linken Rand
  • Es ist nicht abhängig von einem bestimmten Hauptmodus, Sie können es überall in jeder Sprache verwenden

backward-up-listist aus Anwendersicht nicht sehr zuverlässig, da es als generischer Befehl basierend auf konzipiert ist scan-sexps. Bei Code if (true) { return 'hello world'; }im js2-Modus wird beispielsweise der Fokus auf das {Zeichen anstatt auf das erste einfache Anführungszeichen verschoben . Für Code printf("hello world")im c ++ - Modus funktioniert es nicht. Ich habe mit Emacs 24.5 getestet

Chen Bin
quelle
Dies geht zum rechten Rand, der OP hat bis zum Punkt vor dem linken Rand gefragt. Was ist, wenn der Lisp-Modus nicht aktiviert ist?
Name
(gehe zu Kante durch Vergleichen der Schriftfläche -1) gehe zum linken Rand backward-charoder forward-charwenn du den Cursor außerhalb der Kante bewegst.
Chen Bin
Ok, nette Idee, aber wenn Sie es ausführen, wenn der Textmodus aktiviert ist, gehen die Punkte nach ). Abhängig von den Modi hat Ihr Code unterschiedliche Verhaltensweisen.
Name
Es verwendet den gleichen Algorithmus wie Flyspell. So unterstützt es alle wichtigen Modi Flyspell-Unterstützung
Chen Bin
0

Hier ist noch ein Weg (den ich eher benutze), nur für Abwechslung. Die Lösung ist nicht spezifisch für Zeichenfolgen, funktioniert jedoch auch für diesen Anwendungsfall.

  • Installieren iy-go-to-char(auch auf Melpa verfügbar).
  • Binden Sie iy-go-to-char-backwardund iy-go-to-charan Ihre bevorzugten Bindungen. Für die Zwecke dieser Erklärung, sagen wir , Sie gebunden iy-go-to-char-backwardzu C-c C-,und iy-go-to-charzu C-c C-..
  • Wenn Sie sich jetzt in der Zeichenfolge befinden, würden Sie aufrufen iy-go-to-char-backwardund eingeben ".

    Das würde so aussehen C-c C-, ". Wenn Sie iy-go-to-char-continue-when-repeatingeinstellen t(Standard), drücken "erneut werden Sie zu einem nehmen "char Auftreten vorher, und so weiter.

  • Wenn Sie sich innerhalb der Zeichenfolge befinden und jetzt zum Ende der Zeichenfolge gehen möchten, würden Sie aufrufen iy-go-to-charund eingeben ".

    Das würde so aussehen C-c C-. ". Wenn Sie iy-go-to-char-continue-when-repeatingeinstellen t(Standard), drücken "erneut gelangen Sie zum nächsten nehmen "char Auftreten.

Kaushal Modi
quelle