【发布时间】:2014-03-19 23:24:56
【问题描述】:
我有这个“部分”工作的代码。 我正在尝试同步两个窗口,因此无论您在另一个窗口中的哪个窗口都会同步并开始相应地移动。 我看到的不一致是在页面边界附近;如果您将光标在一个窗口中一直向下移动,直到您再滚动一个进入下一页,然后再直接向上移动一行,您会注意到两个窗口将不同步。我尝试调试这个没有运气。不知道是什么导致了这种奇怪的行为。
代码如下:
(defun Xsync-window (&optional display-start)
"Synchronize point position other window in current frame.
Only works if there are exactly two windows in the active wrame not counting the minibuffer."
(interactive)
(when (= (count-windows 'noMiniBuf) 2)
(let ((p (line-number-at-pos))
(start (line-number-at-pos (or display-start (window-start))))
(vscroll (window-vscroll)))
(other-window 1)
(goto-char (point-min))
(setq start (line-beginning-position start))
(forward-line (1- p))
(set-window-start (selected-window) start)
(set-window-vscroll (selected-window) vscroll)
(other-window 1)
(unless display-start
(redisplay t))
)))
(define-minor-mode sync-window-mode
"Synchronized view of two buffers in two side-by-side windows."
:group 'windows
:lighter " ⇕"
(unless (boundp 'sync-window-mode-active)
(setq sync-window-mode-active nil))
(if sync-window-mode
(progn
(add-hook 'post-command-hook 'sync-window-wrapper 'append t)
(add-to-list 'window-scroll-functions 'sync-window-wrapper)
(Xsync-window)
)
(remove-hook 'post-command-hook 'sync-window-wrapper t)
(setq window-scroll-functions (remove 'sync-window-wrapper window-scroll-functions))
))
(defun sync-window-wrapper (&optional window display-start)
"This wrapper makes sure that `sync-window' is fired from `post-command-hook'
only when the buffer of the active window is in `sync-window-mode'."
(unless sync-window-mode-active
(setq sync-window-mode-active t)
(with-selected-window (or window (selected-window))
(when sync-window-mode
(Xsync-window display-start)))
(setq sync-window-mode-active nil))
)
(defun sync-window-dual ()
"Toggle synchronized view of two buffers in two side-by-side windows simultaneously."
(interactive)
(if (not (= (count-windows 'noMiniBuf) 2))
(error "restricted to two windows")
(let ((mode (if sync-window-mode 0 1)))
(sync-window-mode mode)
(with-selected-window (selected-window)
(other-window 1)
(sync-window-mode mode)))))
【问题讨论】:
-
您是否正在寻找
scroll-all-mode或follow-mode未提供的某些特定行为? -
克里斯,感谢您的意见。我通常将此功能与 Mercurial 责备一起使用,赢得一个窗口我有原始文件,第二个我有责备文件“这基本上是相同的原始文件,每一行都有关于开发人员最后更改它以及何时更改的注释”。我需要两个缓冲区在相同的“行号”上同步。 Scroll-all-mode 无法实现这一点,因为任何一个窗口都可能是不同的行号。
-
在
follow-mode中,我在post-command-hook中调用(sit-for 0)来重新定位窗口以包含光标,然后我重新排列它周围的其他窗口。也许你可以尝试类似的技巧? -
Lindydancer,我用这个模式和 Mercurial 责备。我通常会浏览一个文件然后激活责备和双窗口模式。两个窗口将在我所在的任何一行同步。当您处理包含数千行代码的文件时,您不想再次从文件开头开始搜索您感兴趣的行。
-
@Ammari,哦,我不是这么说的。我认为您面临的问题是 Emacs 会在光标结束时重新定位窗口,但这发生在 后命令挂钩之后。如果您执行
sit-for,则强制重新显示,以便您可以启动新窗口等。(顺便说一句,我是follow-mode的作者,我只是试图解释我是如何解决类似问题的那个包。)