我试图在 emacs 中找到一个包/函数,它可以并排打开两个文件,使其位于同一行位置,镜像正在移动的缓冲区的移动。
这意味着,对于并排打开的两个缓冲区,在其中一个缓冲区中移动(向上/向下翻页、移动光标等)将在另一个缓冲区中进行相同的移动。
更具体地说,当打开缓冲区时(并且在激活此模式时),打开的缓冲区应该已经位于另一个缓冲区窗口中已打开的缓冲区的行位置。
你可以尝试scroll-all-mode
。这将打开一帧的所有窗口的并行滚动。
Scrolling with the mouse and scroll bar do not work for me. But all scrolling with keys (such as Pg-Down, Pg-Down and cursor movements) works fine.
编辑:
您也可以尝试以下代码。它仅适用于具有两个窗口的框架,不计算迷你缓冲区。您必须首先打开文件并确保它们并排显示在两个窗口中。然后通过激活定义主窗口sync-window-mode
为了它。确保两个窗口的换行均已关闭。
编辑:修复了一个问题(有时必须按两次按钮才能同步)。
解决方案:也挂钩window-scroll-functions
. At post-command-hook
正确的window-start
位置未知,因为redisplay
还没跑。未来的第一点window-start
已知位于window-scroll-functions
.
(defun sync-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 (point))
(start (or display-start (window-start)))
(vscroll (window-vscroll)))
(other-window 1)
(goto-char (min (max p (point-min)) (point-max)))
(set-window-start (selected-window) start)
(set-window-vscroll (selected-window) vscroll)
(other-window 1)
)))
(define-minor-mode sync-window-mode
"Synchronized view of two buffers in two side-by-side windows."
:group 'windows
:lighter " ⇕"
(if sync-window-mode
(progn
(add-hook 'post-command-hook 'sync-window-wrapper 'append t)
(add-to-list 'window-scroll-functions 'sync-window-wrapper)
(sync-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'."
(with-selected-window (or window (selected-window))
(when sync-window-mode
(sync-window display-start))))
(provide 'sync-window)
接下来是同步行而不是字符位置的版本。
如果您选择主缓冲区中的某些行,这也会标记从属缓冲区中的相应行。突出显示将保持永久状态,直到您在主缓冲区中选择另一个区域。它甚至在停用后仍然存在sync-window-mode
在主缓冲区中。您可以通过以下方式获得突出显示效果
M-x sync-window-cleanup
在从属缓冲区中。
(defface sync-window-face ;; originally copied from font-lock-function-name-face
'((((class color) (min-colors 88) (background light)) (:foreground "Yellow" :background "Blue1"))
(((class color) (min-colors 88) (background dark)) (:foreground "Red" :background "LightSkyBlue"))
(((class color) (min-colors 16) (background light)) (:foreground "Blue" :background "Yellow"))
(((class color) (min-colors 16) (background dark)) (:foreground "LightSkyBlue" :background "Yellow"))
(((class color) (min-colors 8)) (:foreground "blue" :bold t))
(t (:bold t)))
"Face used to highlight regions in `sync-window-mode' slaves."
:group 'sync-window)
(defvar sync-window-overlay nil
"Overlay for current master region in `sync-window-mode' slaves.")
(make-variable-buffer-local 'sync-window-overlay)
(defun sync-window-cleanup ()
"Clean up after `sync-window-mode'."
(interactive)
(if (overlayp sync-window-overlay)
(progn
(delete-overlay sync-window-overlay)
(setq sync-window-overlay nil))
(remove-overlays (point-min) (point-max) 'sync-window-slave t)))
(defvar sync-window-master-hook nil
"Hooks to be run by `sync-window' in the master window ")
(defun sync-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))
breg ereg)
(when (use-region-p)
(setq breg (line-number-at-pos (region-beginning))
ereg (line-number-at-pos (if (looking-back "\n") (1- (region-end)) (region-end)))))
(run-hooks 'sync-window-master-hook)
(other-window 1)
(goto-char (point-min))
(when breg
(sync-window-cleanup)
(overlay-put (setq sync-window-overlay (make-overlay (line-beginning-position breg) (line-end-position ereg))) 'face 'sync-window-face)
(overlay-put sync-window-overlay 'sync-window-slave t))
(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))
)))
(defvar sync-window-mode-hook nil
"Hooks to be run at start of `sync-window-mode'.")
(define-minor-mode sync-window-mode
"Synchronized view of two buffers in two side-by-side windows."
:group 'windows
:lighter " ⇕"
(if sync-window-mode
(progn
(add-hook 'post-command-hook 'sync-window-wrapper 'append t)
(add-to-list 'window-scroll-functions 'sync-window-wrapper)
(run-hooks 'sync-window-mode-hook)
(sync-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'."
(with-selected-window (or window (selected-window))
(when sync-window-mode
(sync-window display-start))))
(provide 'sync-window)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)