我正在尝试在emacs中找到一个包/函数,它将两个文件并排打开,以便在相同的行位置镜像移动哪个缓冲区。 意思是,对于并排打开的两个缓冲区,在其中一个缓冲区中移动(向上/向下翻页,移动光标。,等等)将在另一个缓冲区中具有相同的移动。
更具体地说,当打开缓冲区时(以及激活此模式时),打开的缓冲区应该已经位于已在另一个缓冲区窗口中打开的缓冲区的行位置。
答案 0 :(得分:4)
您可以尝试scroll-all-mode
。这会打开一帧所有窗口的并行滚动。
使用鼠标和滚动条滚动对我不起作用。但所有用键滚动(例如 Pg-Down , Pg-Down 和光标移动)都能正常工作。
编辑:
您还可以尝试以下代码。它仅适用于具有两个不计算迷你缓冲区的窗口的帧。您必须首先打开文件,并确保它们并排显示在两个窗口中。然后通过激活sync-window-mode
来定义主窗口。确保两个窗口都没有换行。
编辑:修正了一个问题(有时必须按两次按钮才能同步)。
解决方案:还要挂钩window-scroll-functions
。在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
接下来是一个同步行而不是字符位置的版本。
如果在主缓冲区中选择了一些行,这也标记了从属缓冲区中的相应行。突出显示保持永久性,直到您在主缓冲区中选择另一个区域。它甚至可以在主缓冲区中停用sync-window-cleanup
。
M-x (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)
在从属缓冲区中。
{{1}}