同时将两个emacs窗口同步

时间:2014-02-27 22:15:30

标签: emacs elisp

我的dotemacs文件中有一段代码可以并排同步两个打开的缓冲区(感谢Tobias),在主缓冲区中滚动会导致从属缓冲区移动,因此匹配光标所在的相同“行”在

我一直在尝试修改代码,并且当一个缓冲区具有焦点并且另一个缓冲区充当跟随引导线的奴隶时,它将充当主缓冲区。基本上,无论滚动哪个缓冲区,我都希望两者同步。

不幸的是,两个缓冲区上的应用(Xsync-window)都失败了,因为主服务器和从服务器的同步程度非常紧密。

以下是代码:

(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 " ⇕"
  (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'."
  (with-selected-window (or window (selected-window))
    (when sync-window-mode
      (Xsync-window display-start)
      )))

1 个答案:

答案 0 :(得分:1)

这应该可以解决问题:

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

这基本上通过sync-window-mode-active保护,无论Xsync-windows是否已经正常工作。

您还可以在两个窗口中同时切换模式:

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