Quand je suis au milieu d'une chaîne looooong, comme ce qui suit
(setq Emacs-beta "Which keyboard shortcut to use for navigating out of a string")
Puis-je en sauter juste avant le premier "
(après Emacs-beta) avec un raccourci?
Quand je suis au milieu d'une chaîne looooong, comme ce qui suit
(setq Emacs-beta "Which keyboard shortcut to use for navigating out of a string")
Puis-je en sauter juste avant le premier "
(après Emacs-beta) avec un raccourci?
Réponses:
Vous voulez C-M-u
qui exécute la commande backward-up-list
.
Reculez d'un niveau de parenthèses. Cette commande fonctionnera également sur d'autres expressions de type parenthèses définies par le mode de langue actuel.
Si ESCAPE-STRINGS n'est pas nul (comme c'est interactif), sortez également des chaînes englobantes.
Emacs-24.5 -Q
une chaîne, mais je reçois avec CMu: up-list: Scan error: "Unbalanced parentheses"
?
C'est faisable comme ça:
(defun exit-string-backwards ()
(interactive)
(goto-char (nth 8 (syntax-ppss))))
En mode lispy , appuyer sur
[vous amènera au début de la liste contenant, en quittant n'importe quelle chaîne. Une fois que vous êtes au début de la liste, vous pouvez accéder facilement à d'autres parties, par exemple, pour atteindre la fin de la Emacs-beta
presse 2m.
Il s'agit en fait d'une question de programmation Emacs Lisp très intéressante. Nous pouvons conserver les caractères avant ou arrière jusqu'à ce que nous trouvions que le caractère sous le curseur ne fait pas partie de la chaîne.
Vous pouvez utiliser le visage de la police pour décider si le caractère se trouve à l'intérieur de la chaîne. C'est un excellent truc que j'ai appris de flyspell. En théorie, ce n'est pas parfait, mais dans le monde réel, il fonctionne avec presque tous les principaux modes de langage de programmation sur Emacs23, Emacs24, Emacs25 .
Voici le code complet:
(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)))
Usage:
(goto-edge-by-comparing-font-face 1)
aller au bord droit, (goto-edge-by-comparing-font-face -1)
aller au bord gauchebackward-up-list
n'est pas très fiable du point de vue de l'utilisateur car il est conçu comme une commande générique basée sur scan-sexps
. Par exemple, pour le code if (true) { return 'hello world'; }
en mode js2, il déplacera le focus sur le {
caractère au lieu du premier caractère de guillemet simple. Pour le code printf("hello world")
en mode c ++, cela ne fonctionnera pas. J'ai testé avec Emacs 24.5
backward-char
ou forward-char
si vous déplacez le curseur hors du bord.
)
. Ainsi, selon les modes, votre code a des comportements différents.
Voici une autre façon (que j'ai tendance à utiliser plus) juste pour la variété. La solution n'est pas spécifique aux chaînes mais elle fonctionne également pour ce cas d'utilisation.
iy-go-to-char
(également disponible sur Melpa).iy-go-to-char-backward
et iy-go-to-char
à vos fixations préférées. Pour cette explication, disons que vous êtes lié iy-go-to-char-backward
à C-c C-,
et iy-go-to-char
à C-c C-.
.Maintenant, si vous êtes à l'intérieur de la chaîne, vous appelez iy-go-to-char-backward
et tapez "
.
Cela ressemblerait C-c C-, "
. Si vous avez iy-go-to-char-continue-when-repeating
défini sur t
(par défaut), "
une nouvelle pression vous amènera à une "
occurrence char avant, et ainsi de suite.
Si vous êtes à l'intérieur de la chaîne et si vous voulez maintenant aller à la fin de la chaîne, vous appelez iy-go-to-char
et tapez "
.
Cela ressemblerait C-c C-. "
. Si vous avez iy-go-to-char-continue-when-repeating
défini sur t
(par défaut), "
une nouvelle pression vous amènera à l' "
occurrence de caractère suivante.
C-r " C-b
.