让Emacs在每次大动作中将位置推到标记环

时间:2016-08-17 15:38:50

标签: emacs

我想询问是否有一般方法让Emacs在每次大动作之前将当前位置推到标记环,如向下滚动,向上滚动一页,跳到行,跳转到新缓冲区,搜索文本。 ..,这样我可以更容易地回到历史吗?

我目前的解决方案是def-advice一些相关功能(如下面的示例代码所示),但它并未涵盖所有情况,而且我也不知道我应该做什么{{ 1}}

请分享您对此问题的体验。任何帮助将不胜感激。

def-advice

1 个答案:

答案 0 :(得分:1)

这是一个应该有效的hacky解决方案,但它可能会降低Emacs的速度。我不确定我是否建议使用它,因为它有点核,但如果你想要这种行为是自动的,你可能需要核解决方案。

这是未经测试的,因此可能需要调整。

;; Variable to store the current point
(defvar last-point nil)
(defvar last-buffer nil)
;; What constitutes a "large movement", in characters.
(defvar large-movement 1000)

(defun store-last-point ()
  (setq last-point (point))
  (setq last-buffer (current-buffer)))

(defun magnitude (number)
  ;; Couldn't find a built-in magnitude function. 
  ;; If anyone knows one, feel free to edit.
  (if (>= number 0)
       number
     (- 0 number)))

(defun push-mark-if-large-movement ()
  ;; If point is in the same buffer and has moved 
  ;; significantly, push mark at the original location
  (if (and (eq last-buffer (current-buffer))
           (> (magnitude (- last-point (point))) large-movement))
       (push-mark last-point)))

(add-hook 'pre-command-hook 'store-last-point)
(add-hook 'post-command-hook 'push-mark-if-large-movement)

请注意,这将阻止您使用多个大动作选择大部分文本。如果你想解决这个问题,你需要在push-mark-if-large-movement命令中添加一个检查(即如果标记处于活动状态,请不要按标记)。