同步两个窗口

时间:2014-03-19 23:24:57

标签: emacs elisp

我的代码是"部分"工作。 我正在尝试同步两个窗口,因此无论您在另一个窗口中哪个窗口都会同步并开始相应地移动。 我看到的不一致是页面边界;如果你将光标一直向下移动到另一个窗口直到你再滚动到下一页然后直接再向上一行,你会发现两个窗口都会不同步。我试着调试这个没有运气。不确定是什么导致了这种奇怪的行为。

以下是代码:

(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)))))

1 个答案:

答案 0 :(得分:1)

当光标在窗口外结束时,Emacs将重新定位窗口。但是,在调用post-command-hook之后会发生

如果您在(sit-for 0)中致电post-command-hook,则会重新显示该窗口,并获得window-start等的新值。