Skip to content

Commit

Permalink
Improve vdiff scrolling
Browse files Browse the repository at this point in the history
(1) It doesn't work to scroll a window by small amounts if there are
virtual removed lines at the top of the window. So if we try and fail to
scroll a given vdiff window, switch to the other window and try the
scrolling there.

(2) vdiff's synchronized scrolling doesn't work when you try to do mouse
scrolling of one window when the other window is active. So force mouse
scrolling to only work on the active window in vdiff mode. (See also
justbur/emacs-vdiff#29.) This is especially
important to make mouse scrolling usable given that we're doing (1),
since which window is active can now change frequently while scrolling.
  • Loading branch information
billsacks committed Mar 23, 2022
1 parent b544632 commit 17d3b96
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 2 deletions.
32 changes: 30 additions & 2 deletions personal/macros.el
Original file line number Diff line number Diff line change
Expand Up @@ -130,9 +130,37 @@ The same result can also be be achieved by \\[universal-argument] \\[unhighlight
(interactive)
(scroll-lock-previous-line 3))

(defun my-vdiff-scroll-up-command (arg)
"Version of scroll-up-command for use in vdiff-mode
This generally works the same as scroll-up-command, but if we
can't scroll the current window, then we switch to the other
window before scrolling up.
This is needed in vdiff mode when the top of a buffer contains
virtual removed lines: trying to scroll that buffer by small
amounts doesn't work.
Note that this can lead to the other window becoming active."
(let ((orig-window-start (window-start)))
(scroll-up-command arg)
(when (eq (window-start) orig-window-start)
;; the scroll was unsuccessful; switch to the other window and try scrolling there

;; this assumes that (other-window 1) gives the other window associated with
;; this vdiff session
(other-window 1)
(scroll-up-command arg))))
(defun my-maybe-vdiff-scroll-up-command (arg)
"Generally works the same as scroll-up-command, but in vdiff mode
this might switch to the other buffer before scrolling up."
(if (bound-and-true-p vdiff-mode)
(my-vdiff-scroll-up-command arg)
(scroll-up-command arg)))

(defun scroll-up-by-3 ()
(interactive)
(scroll-up-command 3))
(my-maybe-vdiff-scroll-up-command 3))
(put 'scroll-up-by-3 'isearch-scroll t)

(defun scroll-down-by-3 ()
Expand All @@ -142,7 +170,7 @@ The same result can also be be achieved by \\[universal-argument] \\[unhighlight

(defun scroll-up-by-10 ()
(interactive)
(scroll-up-command 10))
(my-maybe-vdiff-scroll-up-command 10))
(put 'scroll-up-by-10 'isearch-scroll t)

(defun scroll-down-by-10 ()
Expand Down
14 changes: 14 additions & 0 deletions personal/misc.el
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,20 @@

(require 'vdiff)
(define-key vdiff-mode-map (kbd "C-c") vdiff-mode-prefix-map)
(require 'mwheel)
;; In vdiff-mode, the synchronized scrolling doesn't work if you try to scroll the
;; non-currently-active window (see also
;; https://github.com/justbur/emacs-vdiff/issues/29). So force mouse-based scrolling to
;; always scroll the active window in vdiff-mode. (I thought we would be able to do this
;; by setting mouse-wheel-follow-mouse, but that doesn't seem to have any effect - maybe a
;; bug?)
(defun my-vdiff-mouse-wheel--get-scroll-window (orig-fun &rest args)
(if (bound-and-true-p vdiff-mode)
(selected-window)
(apply orig-fun args)))
(advice-add 'mouse-wheel--get-scroll-window :around #'my-vdiff-mouse-wheel--get-scroll-window)
;; And also switch the cursor back and forth to whichever window is actually scrollable:
(setq mwheel-scroll-up-function 'my-maybe-vdiff-scroll-up-command)

;; This is useful when I have grep results (or similar) displayed in a window that is
;; taking up much of the screen: it prevents the grep results from being split left-right.
Expand Down

0 comments on commit 17d3b96

Please sign in to comment.