Qué método abreviado de teclado usar para navegar fuera de una cadena

9

Cuando estoy en medio de una cadena muuuy larga, como la siguiente

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

¿Puedo omitirlo, justo antes del primero "(después de Emacs-beta) con un atajo?

Dieter.Wilhelm
fuente
Realmente no es una respuesta C-r " C-b.
Nombre

Respuestas:

12

Emacs 25 o más reciente

Quieres C-M-uque ejecute el comando backward-up-list.

Retroceder fuera de un nivel de paréntesis. Este comando también funcionará en otras expresiones parecidas a paréntesis definidas por el modo de idioma actual.

Si ESCAPE-STRINGS no es nulo (como lo es interactivamente), salga también de las cadenas de cerramiento.

niñera
fuente
Deberías mencionar que solo son 25.
abo-abo
@ abo-abo No lo es: acabo de probarlo en 24.5.1. No estoy seguro de cuándo se agregó, pero si alguien puede averiguarlo, lo editaré.
niñera
@ abo-abo Vaya, lo siento, tienes razón.
niñera
Estoy con Emacs-24.5 -Quna cadena, pero estoy con CMu up-list: Scan error: "Unbalanced parentheses":?
Dieter.Wilhelm
1
@ Dieter.Wilhelm Correcto: como puede ver en mi comentario y edición, me equivoqué. Solo funcionará en Emacs 25 o posterior.
niñera
3

Es factible así:

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

En el modo lispy , presionar [lo llevará al comienzo de la lista que contiene, saliendo de cualquier cadena. Una vez que esté al principio de la lista, puede llegar fácilmente a otras partes, por ejemplo, para llegar al final de la Emacs-betaimprenta 2m.

abo-abo
fuente
1

Esta es realmente una pregunta de programación muy interesante de Emacs Lisp. Podemos mantener forward-char o backward-char hasta que encontremos que el carácter debajo del cursor no es parte de la cadena.

Puede usar la fuente para decidir si el carácter está dentro de la cadena. Este es un gran truco que aprendí de flyspell. En teoría no es perfecto, pero en el mundo real funciona con casi todos los modos principales de lenguaje de programación en Emacs23, Emacs24, Emacs25 .

Aquí está el código completo:

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

Uso:

  • (goto-edge-by-comparing-font-face 1)ir al borde derecho, (goto-edge-by-comparing-font-face -1)ir al borde izquierdo
  • no depende de ningún modo principal específico, puede usarlo en cualquier lugar en cualquier idioma

backward-up-listno es muy confiable desde el punto de vista del usuario porque está diseñado como un comando genérico basado en scan-sexps. Por ejemplo, para el código if (true) { return 'hello world'; }en modo js2, moverá el foco al {carácter en lugar del primer carácter de comillas simples. Para el código printf("hello world")en modo c ++, no funcionará. Probé con Emacs 24.5

Chen Bin
fuente
Esto va al borde derecho, el OP ha pedido al punto antes del borde izquierdo. ¿Qué pasa si el modo lisp no está activado?
Nombre
(goto-edge-by-comparing-font-face -1) vaya al borde izquierdo, backward-charo forward-charsi mueve el cursor fuera del borde.
chen bin
Ok, buena idea, pero si lo ejecutas cuando el modo de texto está activado, los puntos van después ). Entonces, dependiendo de los modos, su código tiene comportamientos diferentes.
Nombre
Utiliza el mismo algoritmo que flyspell. Por lo tanto, admite todos los modos principales de soporte de flyspell
chen bin
0

Aquí hay una forma más (que tiendo a usar más) solo por variedad. La solución no es específica para las cadenas, pero también funciona para este caso de uso.

  • Instalar iy-go-to-char(también disponible en Melpa).
  • Enlace iy-go-to-char-backwardy iy-go-to-chara sus enlaces preferidos. Por el bien de esta explicación, digamos que está obligado iy-go-to-char-backwarda C-c C-,y iy-go-to-chara C-c C-..
  • Ahora, si está dentro de la cadena, debería llamar iy-go-to-char-backwardy escribir ".

    Eso se vería así C-c C-, ". Si lo ha iy-go-to-char-continue-when-repeatingconfigurado en t(predeterminado), presionar "una vez más lo llevará a una "aparición de caracteres antes de eso, y así sucesivamente.

  • Si está dentro de la cadena y ahora desea ir al final de la cadena, debe llamar iy-go-to-chary escribir ".

    Eso se vería así C-c C-. ". Si lo iy-go-to-char-continue-when-repeatingconfiguró en t(predeterminado), presionar "una vez más lo llevará a la siguiente "aparición de caracteres.

Kaushal Modi
fuente