【问题标题】:Sync two windows同步两个窗口
【发布时间】:2014-03-19 23:24:56
【问题描述】:

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

代码如下:

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

【问题讨论】:

  • 您是否正在寻找scroll-all-modefollow-mode 未提供的某些特定行为?
  • 克里斯,感谢您的意见。我通常将此功能与 Mercurial 责备一起使用,赢得一个窗口我有原始文件,第二个我有责备文件“这基本上是相同的原始文件,每一行都有关于开发人员最后更改它以及何时更改的注释”。我需要两个缓冲区在相同的“行号”上同步。 Scroll-all-mode 无法实现这一点,因为任何一个窗口都可能是不同的行号。
  • follow-mode 中,我在post-command-hook 中调用(sit-for 0) 来重新定位窗口以包含光标,然后我重新排列它周围的其他窗口。也许你可以尝试类似的技巧?
  • Lindydancer,我用这个模式和 Mercurial 责备。我通常会浏览一个文件然后激活责备和双窗口模式。两个窗口将在我所在的任何一行同步。当您处理包含数千行代码的文件时,您不想再次从文件开头开始搜索您感兴趣的行。
  • @Ammari,哦,我不是这么说的。我认为您面临的问题是 Emacs 会在光标结束时重新定位窗口,但这发生在 后命令挂钩之后。如果您执行sit-for,则强制重新显示,以便您可以启动新窗口等。(顺便说一句,我是follow-mode 的作者,我只是试图解释我是如何解决类似问题的那个包。)

标签: emacs elisp


【解决方案1】:

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

如果您在post-command-hook 中调用(sit-for 0),窗口将重新显示,您将获得window-start 等的新值。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-20
    • 1970-01-01
    • 2012-01-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多