Którego skrótu klawiaturowego użyć do nawigowania po łańcuchu

9

Kiedy jestem w środku długiego ciągu, jak poniżej

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

Czy mogę go pominąć tuż przed pierwszym "(po Emacs-beta) skrótem?

Dieter.Wilhelm
źródło
Naprawdę nie odpowiedź C-r " C-b.
Imię i nazwisko

Odpowiedzi:

12

Emacs 25 lub nowszy

Chcesz, C-M-uktóry uruchamia polecenie backward-up-list.

Przejdź do tyłu o jeden poziom w nawiasach. To polecenie będzie także działać na innych wyrażeniach podobnych do nawiasów zdefiniowanych przez bieżący tryb języka.

Jeśli ESCAPE-STRINGS ma wartość inną niż zero (ponieważ jest interaktywna), wyjdź także z otaczających łańcuchów.

niania
źródło
Powinieneś wspomnieć, że jest tylko 25.
abo-abo
@ abo-abo To nie jest: Właśnie przetestowałem to w 24.5.1. Nie jestem pewien, kiedy został dodany, ale jeśli ktoś się dowie, będę go edytować.
niania
@ abo-abo Ups, przepraszam, masz rację.
niania
Jestem z Emacs-24.5 -Qna sznurku, ale ja dostaję z CMU: up-list: Scan error: "Unbalanced parentheses"?
Dieter.Wilhelm
1
@ Dieter.Wilhelm Right: jak widać po moim komentarzu i edycji, pomyliłem się. Będzie działać tylko w Emacsie 25 lub nowszym.
niania
3

Można to zrobić w następujący sposób:

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

W trybie lispy naciśnięcie [spowoduje przejście do początku listy zawierającej, opuszczając dowolny ciąg. Gdy znajdziesz się na początku listy, możesz łatwo dotrzeć do innych części, na przykład, aby dotrzeć do końca Emacs-betaprasy 2m.

abo-abo
źródło
1

To jest naprawdę bardzo interesujące pytanie programistyczne Emacsa Lispa. Możemy zachować znak do przodu lub do tyłu, dopóki nie znajdziemy znaku pod kursorem, który nie jest częścią ciągu.

Możesz użyć powierzchni czcionki, aby zdecydować, czy znak znajduje się w ciągu. To świetna sztuczka, której nauczyłem się od flyspell. Teoretycznie nie jest idealny, ale w prawdziwym świecie działa z prawie wszystkimi głównymi trybami języka programowania na Emacs23, Emacs24, Emacs25 .

Oto pełny kod:

(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)))

Stosowanie:

  • (goto-edge-by-comparing-font-face 1)idź do prawej krawędzi, (goto-edge-by-comparing-font-face -1)idź do lewej krawędzi
  • nie jest zależny od żadnego konkretnego trybu głównego, można go używać w dowolnym miejscu w dowolnym języku

backward-up-listnie jest bardzo wiarygodny z punktu widzenia użytkownika, ponieważ został zaprojektowany jako ogólne polecenie oparte na scan-sexps. Na przykład w przypadku kodu if (true) { return 'hello world'; }w trybie js2 przenosi fokus na {znak zamiast pierwszego znaku pojedynczego cudzysłowu. Dla kodu printf("hello world")w trybie c ++ nie zadziała. Testowałem z Emacsem 24.5

Chen Bin
źródło
To idzie do prawej krawędzi, OP poprosił o punkt przed lewą krawędzią. Co jeśli tryb seplenienia nie zostanie aktywowany?
Imię
(goto-edge-by-porównując-czcionkę-twarz -1) przejdź do lewej krawędzi backward-charlub forward-charjeśli przesuniesz kursor poza krawędź.
chen bin
Ok, fajny pomysł, ale jeśli uruchomisz go, gdy tryb tekstowy jest aktywowany, punkty pójdą dalej ). W zależności od trybów kod ma różne zachowania.
Imię
Używa tego samego algorytmu co flyspell. Obsługuje więc wszystkie główne tryby obsługi flyspell
chen bin
0

Oto jeszcze jeden sposób (którego zwykle używam) tylko dla odmiany. Rozwiązanie nie jest specyficzne dla ciągów, ale działa również w tym przypadku użycia.

  • Zainstaluj iy-go-to-char(dostępne również w Melpa).
  • Wiąż iy-go-to-char-backwardi iy-go-to-charpreferowane wiązania. Ze względu na to wyjaśnienie, powiedzmy, że związałeś iy-go-to-char-backwardsię C-c C-,i iy-go-to-chardo C-c C-..
  • Teraz, jeśli jesteś w ciągu, zadzwonisz iy-go-to-char-backwardi napiszesz ".

    To by wyglądało C-c C-, ". Jeśli iy-go-to-char-continue-when-repeatingustawiłeś t(domyślnie), "ponowne naciśnięcie spowoduje przejście do "wystąpienia znaku przedtem i tak dalej.

  • Jeśli znajdujesz się w ciągu i jeśli chcesz teraz przejść do końca łańcucha, zadzwoń iy-go-to-chari wpisz ".

    To by wyglądało C-c C-. ". Jeśli iy-go-to-char-continue-when-repeatingustawiłeś t(domyślnie), "ponowne naciśnięcie spowoduje przejście do następnego "wystąpienia znaku.

Kaushal Modi
źródło