Какой сочетания клавиш использовать для навигации из строки

9

Когда я нахожусь в середине Looooong строки, как следующий

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

Могу ли я пропустить это, прямо перед первым "(после Emacs-бета) с ярлыком?

Dieter.Wilhelm
источник
Не совсем ответ C-r " C-b.
Имя

Ответы:

12

Emacs 25 или новее

Вы хотите, C-M-uкоторый запускает команду backward-up-list.

Переместиться назад на один уровень в скобках. Эта команда также будет работать с другими подобными скобкам выражениями, определенными текущим языковым режимом.

Если ESCAPE-STRINGS не ноль (как и в интерактивном режиме), также удалите вложенные строки.

няня
источник
Вы должны упомянуть, что это только 25.
abo-abo
@ abo-abo Это не так: я только что проверил это в 24.5.1. Я не уверен, когда это было добавлено, но если кто-то может узнать, я отредактирую это.
няня
@ abo-abo Ой, прости, ты прав.
няня
Я с Emacs-24.5 -Qв строке, но я получаю с КУМ: up-list: Scan error: "Unbalanced parentheses"?
Дитер. Вильгельм
1
@ Dieter.Wilhelm Справа: как вы можете видеть по моим комментариям и редактированию, я ошибся. Это будет работать только в Emacs 25 или новее.
няня
3

Это выполнимо так:

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

В режиме lispy нажатие [приведет вас к началу списка содержимого, выходя из любой строки. Как только вы окажетесь в начале списка, вы можете легко добраться до других частей, например, до конца Emacs-betaпечати 2m.

Або-або
источник
1

На самом деле это очень интересный вопрос программирования Emacs Lisp. Мы можем держать forward-char или backward-char, пока не обнаружим, что символ под курсором не является частью строки.

Вы можете использовать шрифт, чтобы решить, находится ли символ внутри строки. Это отличный трюк, который я узнал из flyspell. Теоретически он не идеален, но в реальном мире он работает практически с основными режимами любого языка программирования на Emacs23, Emacs24, Emacs25 .

Вот полный код:

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

Применение:

  • (goto-edge-by-comparing-font-face 1)перейти к правому краю, (goto-edge-by-comparing-font-face -1)перейти к левому краю
  • это не зависит от какого-либо конкретного основного режима, вы можете использовать его в любом месте на любом языке

backward-up-listне очень надежен с точки зрения пользователя, потому что он разработан как общая команда, основанная на scan-sexps. Например, для кода if (true) { return 'hello world'; }в режиме js2 он переместит фокус на {символ вместо первого символа одинарных кавычек. Для кода printf("hello world")в режиме c ++ - он не будет работать. Я тестировал с Emacs 24.5

чен бен
источник
Это идет к правому краю, ОП попросил точку перед левым краем. Что если режим lisp не активирован?
Имя
(goto-edge-by-comparing-font-face -1) перейти к левому краю backward-charили, forward-charесли вы переместите курсор за пределы края.
Чен бин
Хорошо, хорошая идея, но если вы запустите его, когда текстовый режим активирован, точки идут после ). Таким образом, в зависимости от режимов, ваш код имеет различное поведение.
Имя
Он использует тот же алгоритм, что и flyspell. Так что он поддерживает все основные режимы поддержки flyspell
чен бен,
0

Вот еще один способ (который я использую чаще) только для разнообразия. Решение не относится только к строкам, но оно работает и для этого варианта использования.

  • Установить iy-go-to-char(также доступно на Melpa).
  • Привязка iy-go-to-char-backwardи iy-go-to-charваши предпочтительные привязки. Ради этого объяснения, скажем, вы связаны iy-go-to-char-backwardс C-c C-,и iy-go-to-charк C-c C-..
  • Теперь, если вы находитесь внутри строки, вы должны позвонить iy-go-to-char-backwardи напечатать ".

    Это будет выглядеть так C-c C-, ". Если вы iy-go-to-char-continue-when-repeatingустановили t(по умолчанию), "повторное нажатие приведет вас к появлению "символа до этого и так далее.

  • Если вы находитесь внутри строки и хотите перейти к концу строки, вы должны позвонить iy-go-to-charи набрать ".

    Это будет выглядеть так C-c C-. ". Если вы iy-go-to-char-continue-when-repeatingустановили t(по умолчанию), "повторное нажатие приведет вас к следующему "появлению символа.

Каушал Моди
источник