在Emacs中,C-u C-SPC将"跳到标记处,并从当地标记环上弹出的位置设置标记".有没有办法在标记环周围走相反的方向?假设您已多次键入Cu C-SPC并想要回到您所看到的标记,而不是一直绕着环.
Ian*_*ing 13
与之前的答案不同,这个问题只与我们提出的问题完全相同:Cu 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))))))
Run Code Online (Sandbox Code Playgroud)
相较于由scottfrazer答案,这个命令有它如何移动光标,标志,能更准确地反映铜C-SPC一个微妙的差异,它不要求前面的命令是一个unpop /流行到mark-命令.
这是我刚刚花了太多时间的解决方案.这个和其他解决方案之间的区别在于它适用于缓冲区,即它适用于"全局标记环".我的目标是模拟类似于Eclipse或IntelliJ的历史浏览.我将它绑定到M-left和M-right,显然你可以选择不同的键.
(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))
Run Code Online (Sandbox Code Playgroud)
这是一个功能:
(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))))
Run Code Online (Sandbox Code Playgroud)
继续我对scottfrazer 非常方便的解决方案的评论之后,这里提供了一些与之配合使用的建议,以便轻松地随意反转标记环周围的方向,而无需为每个方向使用不同的键绑定.
我使用cua-selection-mode,所以对我来说C-SPC是必然的cua-set-mark,但我把它写成一个宏,以便建议任何一个函数绑定C-SPC,并验证它是否适用于默认值set-mark-command.
要取消启动,只需提供一个否定前缀参数.例如C-- C-SPC
其中一个好处cua-set-mark是,在初始之后C-u 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)
Run Code Online (Sandbox Code Playgroud)
有两个标记环:一个是当前缓冲区的本地标记,另一个是所有缓冲区中的全局标记。
默认情况下,在Icicles 中(在Icicle全局次要模式下):
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 -- apropos-complete(子字符串/正则表达式)
TAB -- 前缀或模糊完成
小智 2
它并不完全符合您的要求,但可能值得寻找一个名为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.
Run Code Online (Sandbox Code Playgroud)
我将[S-up]和[S-down]分别绑定到marker-visit-prev和marker-visit-next。
如果您确实想要/需要按照标记环当前的顺序进行导航,那么您可能会通过查看 pop-to-mark-command 和 pop-mark 函数并实现您自己的版本来旋转标记环来达到目的相反的方向。