Sync two windows

萝らか妹 提交于 2019-12-24 13:03:25

问题


I have this code that is "partially" working. I am trying to sync two windows, so regardless which window you are in the other will sync and start moving accordingly. The inconsistency I am seeing are around page boundaries; if you move the cursor in one window all the way down till you scroll one more into the next page then directly go up again one line you will notice that both windows will go out of sync. I tried debugging this with no luck. Not sure what is causing this weird behavior.

Here is the code:

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


When the cursor ends up outside a window, Emacs will reposition the window. However, this occurs after the post-command-hook is called.

If you call (sit-for 0) in your post-command-hook, the window will be redisplayed, and you get the new value for window-start etc.



来源:https://stackoverflow.com/questions/22520337/sync-two-windows

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!