Qual atalho de teclado usar para navegar fora de uma string

9

Quando estou no meio de uma sequência looooong, como o seguinte

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

Posso pular o arquivo antes do primeiro "(após o Emacs-beta) com um atalho?

Dieter.Wilhelm
fonte
Não é realmente uma resposta C-r " C-b.
Nome

Respostas:

12

Emacs 25 ou mais recente

Você quer C-M-uqual executa o comando backward-up-list.

Mover para trás fora de um nível de parênteses. Este comando também funcionará em outras expressões parênteses definidas pelo modo de idioma atual.

Se ESCAPE-STRINGS for nulo (como é interativamente), saia também das seqüências anexas.

babá
fonte
Você deve mencionar que são apenas 25.
abo-abo
@ abo-abo Não é: eu apenas testei em 24.5.1. Eu não tenho certeza quando ele foi adicionado, mas se alguém pode descobrir vou editá-lo no.
nanny
@ abo-abo Ops, desculpe, você está correto.
Nanny
Estou com Emacs-24.5 -Quma string, mas estou usando o CMu up-list: Scan error: "Unbalanced parentheses":?
precisa saber é o seguinte
11
@ Dieter.Wilhelm Certo: como você pode ver pelo meu comentário e edição, eu estava enganado. Ele funcionará apenas no Emacs 25 ou mais recente.
Nanny
3

É factível assim:

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

No modo lispy , pressionar pressiona [levará você ao início da lista que contém, saindo de qualquer sequência. Quando estiver no início da lista, você poderá acessar outras partes facilmente, por exemplo, para chegar ao fim da Emacs-betaimpressão 2m.

abo-abo
fonte
1

Esta é realmente uma questão de programação muito interessante do Emacs Lisp. Podemos manter char para frente ou char para trás até encontrarmos o caractere sob o cursor não fazer parte da string.

Você pode usar a face da fonte para decidir se o caractere está dentro da string. Esse é um ótimo truque que aprendi com o flyspell. Em teoria, não é perfeito, mas no mundo real funciona com quase todos os principais modos de linguagem de programação no Emacs23, Emacs24, Emacs25 .

Aqui está o 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)vá para a borda direita, (goto-edge-by-comparing-font-face -1)vá para a borda esquerda
  • não depende de nenhum modo principal específico, você pode usá-lo em qualquer lugar em qualquer idioma

backward-up-listnão é muito confiável do ponto de vista do usuário porque foi projetado como um comando genérico baseado em scan-sexps. Por exemplo, para o código if (true) { return 'hello world'; }no modo js2, ele moverá o foco para o {caractere em vez do primeiro caractere de aspas simples. Para código printf("hello world")no modo c ++, não funcionará. Eu testei com Emacs 24.5

Chen Bin
fonte
Isso vai para a borda direita, o OP pediu até o ponto antes da borda esquerda. E se o modo lisp não estiver ativado?
Nome
(goto-edge-by-compare-font-face -1) vá para a borda esquerda, backward-charou forward-charse você mover o cursor para o lado da borda.
26615 chen bin
Ok, boa ideia, mas se você executá-lo quando o modo de texto estiver ativado, os pontos serão depois ). Portanto, dependendo dos modos, seu código tem comportamentos diferentes.
Nome
Ele usa o mesmo algoritmo que o flyspell. Por isso, apoiar todos os principais modos flyspell apoio
chen bin
0

Aqui está mais uma maneira (que eu costumo usar mais) apenas pela variedade. A solução não é específica para cadeias, mas também funciona para este caso de uso.

  • Instale iy-go-to-char(também disponível no Melpa).
  • Ligue iy-go-to-char-backwarde iy-go-to-charàs ligações preferidas. Para fins de explicação, digamos que você esteja vinculado iy-go-to-char-backwarda C-c C-,e iy-go-to-charpara C-c C-..
  • Agora, se você estiver dentro da string, você chamaria iy-go-to-char-backwarde digitaria ".

    Seria assim C-c C-, ". Se você iy-go-to-char-continue-when-repeatingdefiniu como t(padrão), pressionar "mais uma vez levará você a uma "ocorrência de char antes disso e assim por diante.

  • Se você estiver dentro da string e agora quiser ir para o final da string, você chamaria iy-go-to-chare digitaria ".

    Seria assim C-c C-. ". Se você iy-go-to-char-continue-when-repeatingdefiniu como t(padrão), pressionar "mais uma vez o levará à próxima "ocorrência de char.

Kaushal Modi
fonte