Как двигаться вперед и назад в кольце меток Emacs - PullRequest
27 голосов
/ 03 августа 2010

В Emacs, C-u C-SPC будет «переходить к метке и устанавливать метку с позиции, снятой с локального кольца меток».Есть ли способ обойти кольцо с метками?Допустим, вы несколько раз набрали Cu C-SPC и хотите вернуться к отметке, которую вы видели, не пройдя весь круг.

Ответы [ 8 ]

13 голосов
/ 26 января 2013

В отличие от предыдущих ответов, этот делает только то, что было задано: обратная сторона C-u C-SPC. Я считаю это наиболее полезным.

(defun unpop-to-mark-command ()
  "Unpop off mark ring. Does nothing if mark ring is empty."
  (interactive)
      (when mark-ring
        (setq mark-ring (cons (copy-marker (mark-marker)) mark-ring))
        (set-marker (mark-marker) (car (last mark-ring)) (current-buffer))
        (when (null (mark t)) (ding))
        (setq mark-ring (nbutlast mark-ring))
        (goto-char (marker-position (car (last mark-ring))))))

По сравнению с ответом scottfrazer, эта команда имеет небольшую разницу в том, как она перемещает курсор и метку, что более точно отражает Cu C-spc, и не требует, чтобы предыдущая команда была unpop / pop-to -Марк-команды.

6 голосов
/ 26 декабря 2014

Вот решение, которое я только что закончил тратить слишком много времени.Разница между этим и другими решениями заключается в том, что он работает через буферы, то есть работает на «глобальном кольце меток».Моей целью было эмулировать просмотр истории, похожий на Eclipse или IntelliJ.Я связываю его с М-левой и М-правой, очевидно, вы можете выбрать разные ключи для этого.

(defun marker-is-point-p (marker)
  "test if marker is current point"
  (and (eq (marker-buffer marker) (current-buffer))
       (= (marker-position marker) (point))))

(defun push-mark-maybe () 
  "push mark onto `global-mark-ring' if mark head or tail is not current location"
  (if (not global-mark-ring) (error "global-mark-ring empty")
    (unless (or (marker-is-point-p (car global-mark-ring))
                (marker-is-point-p (car (reverse global-mark-ring))))
      (push-mark))))


(defun backward-global-mark () 
  "use `pop-global-mark', pushing current point if not on ring."
  (interactive)
  (push-mark-maybe)
  (when (marker-is-point-p (car global-mark-ring))
    (call-interactively 'pop-global-mark))
  (call-interactively 'pop-global-mark))

(defun forward-global-mark ()
  "hack `pop-global-mark' to go in reverse, pushing current point if not on ring."
  (interactive)
  (push-mark-maybe)
  (setq global-mark-ring (nreverse global-mark-ring))
  (when (marker-is-point-p (car global-mark-ring))
    (call-interactively 'pop-global-mark))
  (call-interactively 'pop-global-mark)
  (setq global-mark-ring (nreverse global-mark-ring)))

(global-set-key [M-left] (quote backward-global-mark))
(global-set-key [M-right] (quote forward-global-mark))
5 голосов
/ 25 февраля 2011

После моего комментария к очень удобному решению от scottfrazer , вот несколько советов, которые работают в сочетании с этим, чтобы упростить изменение направления вокруг кольца меток по желанию, без необходимости использовать другой ключ -привязка для каждого направления.

Я использую cua-selection-mode, поэтому для меня C-SPC связан с cua-set-mark, но я написал это как макрос, чтобы сообщить, какая функция связана с C -SPC и проверил, что он работает по умолчанию set-mark-command.

Чтобы отменить удаление, просто укажите аргумент с отрицательным префиксом. например C - C-SPC

Одна из приятных особенностей cua-set-mark заключается в том, что после начального Cu C-SPC вы можете продолжать добавлять последовательные метки всего с C-SPC , и я включил это поведение здесь: после начального C - C-SPC вы можете продолжить отмену вызова, просто C-SPC, Чтобы снова изменить направление и вызвать pop-to-mark, просто введите положительный аргумент еще раз с C-u C-SPC .

(defmacro my-unpop-to-mark-advice ()
  "Enable reversing direction with un/pop-to-mark."
  `(defadvice ,(key-binding (kbd "C-SPC")) (around my-unpop-to-mark activate)
     "Unpop-to-mark with negative arg"
     (let* ((arg (ad-get-arg 0))
            (num (prefix-numeric-value arg)))
       (cond
        ;; Enabled repeated un-pops with C-SPC
        ((eq last-command 'unpop-to-mark-command)
         (if (and arg (> num 0) (<= num 4))
             ad-do-it ;; C-u C-SPC reverses back to normal direction
           ;; Otherwise continue to un-pop
           (setq this-command 'unpop-to-mark-command)
           (unpop-to-mark-command)))
        ;; Negative argument un-pops: C-- C-SPC
        ((< num 0)
         (setq this-command 'unpop-to-mark-command)
         (unpop-to-mark-command))
        (t
         ad-do-it)))))
(my-unpop-to-mark-advice)
5 голосов
/ 03 августа 2010

Вот функция для этого:

(defun unpop-to-mark-command ()
  "Unpop off mark ring into the buffer's actual mark.
Does not set point.  Does nothing if mark ring is empty."
  (interactive)
  (let ((num-times (if (equal last-command 'pop-to-mark-command) 2
                     (if (equal last-command 'unpop-to-mark-command) 1
                       (error "Previous command was not a (un)pop-to-mark-command")))))
    (dotimes (x num-times)
      (when mark-ring
        (setq mark-ring (cons (copy-marker (mark-marker)) mark-ring))
        (set-marker (mark-marker) (+ 0 (car (last mark-ring))) (current-buffer))
        (when (null (mark t)) (ding))
        (setq mark-ring (nbutlast mark-ring))
        (goto-char (mark t)))
      (deactivate-mark))))
4 голосов
/ 20 августа 2011

Существует два кольца маркеров: один локальный для текущего буфера и один глобальный среди всех буферов.

По умолчанию в Сосульки Сосулька Глобальный минорный режим):

  • C-- C-SPC позволяет вам путешествовать среди местных маркеров
  • C-- C-x C-SPC позволяет вам путешествовать среди глобальных маркеров

IOW, с отрицательным префиксом arg, C-SPC и C-x C-SPC навигации. Без этого они просто делают то, что обычно делают (set-mark-command и pop-global-mark соответственно).

Навигация работает следующим образом:

  • Местоположения доступны в качестве кандидатов на завершение: текст строки маркера.
  • Завершение: вы можете использовать подстроку, регулярное выражение, префикс, нечеткий (различные виды).
  • Вы можете переключаться между любыми кандидатами на прохождение или напрямую обращаться к любому из них.

Ключи, доступные при завершении:

  • up, down - цикл среди кандидатов в *Completions*, без перехода к их местоположениям

  • C-up, C-down - цикл, переход к каждому местоположению по очереди

  • C-RET, C-mouse-2 - перейти непосредственно к текущему / выбранному кандидату (например, в *Completions*)

  • RET, mouse-2 - аналогично предыдущему (перейти к кандидату), но завершить команду (выполнено)

  • S-TAB - относительно завершено (подстрока / регулярное выражение)

  • TAB - префикс или нечеткий полный

2 голосов
/ 03 августа 2010

Он не выполняет в точности то, что вы просите, но, возможно, стоит поискать пакет под названием marker-visit.el, который позволяет перемещаться по меткам в текущем буфере в «порядке расположения в буфере». Из этого файла:

;;; Commentary:

;; This file provides a simple way to navigate among marks in a
;; buffer.  C-u C-SPC is similar, but takes you haphazardly around the
;; buffer.  Setting bookmarks is a lot of extra work if you just want
;; to jump around your buffer quickly; plus, you have to come up with
;; a name for every bookmark.

;; All the marks you've left while editing a buffer serve as bread
;; crumb trails of areas in the buffer you've edited.  It is
;; convenient to navigate back and forth among these marks in order.
;; This file provides two methods to do just that, marker-visit-prev
;; and marker-visit-next.  These two functions will take you, from
;; point, to the nearest mark in either direction.  The function
;; marker-visit-truncate-mark-ring will truncate the mark ring.

;; The marks you can visit in a buffer consist of: "the mark" plus the
;; contents of the mark-ring.

Я связываю [S-up] и [S-down] соответственно с маркером-визит-пред-и маркером-визит-след.

Если вы действительно хотите / должны перемещаться в том порядке, в котором находится ваш mark-ring, то вы можете получить что-то, посмотрев функции pop-to-mark-command и pop-mark и внедрив свои собственные версии для поворота пометить кольцо в обратном направлении.

1 голос
/ 03 августа 2010

В инструкции сказано следующее:

Переменная mark-ring-max указывает максимальное количество записей, которые следует хранить в кольце меток.Если существует такое количество записей, а другая отправляется, самая ранняя в списке отбрасывается.Повторение «Cu C-» циклически перебирает позиции, которые в данный момент находятся в кольце.

Я предлагаю вам использовать это, чтобы содержать размер кольца меток (для 3 или 4, у меня сейчас 16).Тогда вы можете перемещаться по нему гораздо быстрее, используя префиксы.

Также:

Если вы хотите снова и снова возвращаться в одно и то же место, кольцо с метками может оказаться недостаточно удобным.,Если это так, вы можете записать позицию в регистр для последующего поиска (* примечание Сохранение позиций в регистрах: RegPos.).

0 голосов
/ 03 августа 2010

Вы пробовали browse-kill-ring? Загрузите его из Emacswiki , поместите его в путь загрузки и добавьте его в свой emacs-conf:

(when (require 'browse-kill-ring nil 'noerror)
  (browse-kill-ring-default-keybindings))

Затем, когда вы нажмете M-y, вам будет показан список убийств, ищите его как обычный текст и т.д. . Действительно удобно. Существует также более практическая информация о том, как использовать browse-kill-ring

в emacs-fu .
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...