2

Say a frame is split (by C-x 3) into 2 windows that both display the same buffer.

If I enable follow-mode, the left window will always display the content closer to the beginning-of-buffer than the right one.

Q:

How to swap these two windows (so that the left window will display the content following what is displayed by the right one)


How my Emacs currently behaves:

enter image description here

emacs-version: 28.2
system-configuration: x86_64-w64-mingw32

shynur
  • 4,065
  • 1
  • 3
  • 23
  • 1
    Nice demo of rainbow-brackets use (y) :) ,ASCII-Art and a dark theme. And it would be nice to have also the text to test a solution ... – Claudio Mar 25 '23 at 17:41
  • 1
    I think the reason it behaves like it does is because the behavior mimics reading a book: the LH window shows a "page" and the RH window shows the next "page". That feels natural to me. – NickD Mar 25 '23 at 18:59
  • 1
    `follow-mode` assumes that windows to the left should display earlier parts of the buffer, this is hardcoded into the algorithm. When I wrote it I didn't envision that anybody would like it the other way around, sorry about that... Just curious, why would you like the swap the windows? – Lindydancer Mar 25 '23 at 20:37
  • @Lindydancer: For some reason, the left *window* is closer to me in distance. I focus on the *window* closer to me (the left one), and hope to use the right one to review what I've already read. – shynur Mar 25 '23 at 21:22
  • @Lindydancer : it seems to be very easy to provide an option changing the left to right order to right to left as shown in my answer. Hopefully the proposed solution does not come with side-effects I am not aware of. – Claudio Mar 25 '23 at 22:25
  • I should be relatively easy, as long as you can pinpoint all the places where the package look at the previous/next window. FSF has taken over the maintenance of the package, so I suggest that you file a feature request or, even better, a patch. – Lindydancer Mar 26 '23 at 07:26
  • @Lindydancer : may you share here a hint where to look in code to modify it so that the cursor always stays in the active window while scrolling (i.e. preventing 'jumping' to the other windows)? – Claudio Mar 26 '23 at 12:30
  • I would start to look into `follow-post-command-hook`. It does a lot of hard work to move the cursor to a suitable window, if it lands outside the selected window. If you disable that code, it would probably stay in the current window. – Lindydancer Mar 26 '23 at 18:46

1 Answers1

0

To achieve the desired effect you need to change two lines in the source code of 'follow.el' as done below:

(defun follow--window-sorter (w1 w2)
  "Sorting function for W1 and W2 based on their positions.
Return non-nil if W1 is above W2; if their top-lines
are at the same position, return non-nil if W1 is to the
left of W2."
  (let* ((edge-1 (window-pixel-edges w1))
     (edge-2 (window-pixel-edges w2))
     (y1 (nth 1 edge-1))
     (y2 (nth 1 edge-2)))
    (if (= y1 y2)
;;  (< (car edge-1) (car edge-2)) ;; <<<===
    (< (car edge-2) (car edge-1))
;;      (< y1 y2))))  ;; <<<===
      (< y2 y1))))

See how it looks like if changed as above:

enter image description here

Knowing this above feel free to update my answer with code of a function follow-toggle-right-to-left-order toggling a value of follow-right-to-left-order variable used to switch the sorting order in follow--window-sorter.

Below the not yet tested code of a patch with the above mentioned functionality:

(setq follow-right-to-left-order nil)

(defun follow-toggle-right-to-left-order ()
  "toggle value used by  (defun follow--window-sorter ..."
  (= follow-right-to-left-order t
       (setq follow-right-to-left-order nil)
       (setq follow-right-to-left-order t)
  )
)

(defun follow--window-sorter (w1 w2)
  "Sorting function for W1 and W2 based on their positions.
  Return non-nil if W1 is above W2; if their top-lines
  are at the same position, return non-nil if W1 is to the
  left of W2."
  (let* ((edge-1 (window-pixel-edges w1))
         (edge-2 (window-pixel-edges w2))
         (y1 (nth 1 edge-1))
         (y2 (nth 1 edge-2))))
  (if (= y1 y2)
    (if follow-right-to-left-order
      (< (car edge-2) (car edge-1))
      (< (car edge-1) (car edge-2))
    ))
  (if  follow-right-to-left-order
      (< y2 y1)
      (< y1 y2)
  )
)
;;     *
;;      May the Code be with You!
;;     .                                 .
;;                               *
;;          /\/|_      __/\\
;;         /    -\    /-   ~\  .              '
;;         \    = Y =T_ =   /
;;          )==*(`     `) ~ \
;;         /     \     /     \
;;         |     |     ) ~   (
;;        /       \   /     ~ \
;;        \       /   \~     ~/
;; _/\_/\_/\__  _/_/\_/\__~__/_/\_/\_/\_/\_/\_
;; |  |  |  | ) ) |  |  | ((  |  |  |  |  |  |
;; |  |  |  |( (  |  |  |  \\ |  |  |  |  |  |
;; |  |  |  | )_) |  |  |  |))|  |  |  |  |  |
;; |  |  |  |  |  |  |  |  (/ |  |  |  |  |  |
;; |  |  |  |  |  |  |  |  |  |  |  |  |  |  |

(
 (
  (
   (
    (
     (
      (
       (
        (
         (
          (
           (
            (
             (
              (
               (
                (
                 (
                  )
                 )
                )
               )
              )
             )
            )
           )
          )
         )
        )
       )
      )
     )
    )
   )
  )
 )
shynur
  • 4,065
  • 1
  • 3
  • 23
Claudio
  • 410
  • 2
  • 11
  • The key is the function **`follow--window-sorter`**, that's all enough. Thanks. BTW, the ASCII picture in my *buffer* `*scratch*` is copied from *package* `sly`; I've committed an edit on your answer to provide the original picture. – shynur Mar 26 '23 at 10:22
  • Using this mode I would prefer to stay in the active window. The current behavior where the point/cursor jumps to another window drives my intuition crazy. With three windows of same buffer I expect to see the previous and the following text but stay editing and scrolling in the active current window. This should also be possible with some further modifications to `follow.el`. Any idea how to accomplish that? Is it worth another question? – Claudio Mar 26 '23 at 12:15
  • BTW ... your Emacs window is transparent ... showing you? in the background? Which theme allows transparency of Emacs frame? – Claudio Mar 26 '23 at 12:19
  • "Which theme allows transparency of Emacs frame?" --- `transwin` from *melpa*; "Any idea how to accomplish that?" --- I'll think about it after finishing my homework (probably taking me two days). – shynur Mar 26 '23 at 13:57
  • "*Any idea how to accomplish that?*" --- I find that (considering that a frame is split into 3 parts and you want to only activate the middle one) if you just move the cursor slowly (in other words, one keystroke per several seconds), the cursor always stays in the middle window. (It only works for me because I noticed that when Emacs is passed `-Q` it doesn't do so.) I have no idea about that behavior. – shynur Mar 27 '23 at 17:13
  • Yes, I think it's worth asking. – shynur Mar 27 '23 at 17:19
  • https://emacs.stackexchange.com/questions/76499/how-to-modify-follow-el-elisp-script-to-keep-the-point-cursor-in-the-active-wind ( How to modify follow.el elisp script to keep the point/cursor in the active window? ) – Claudio Mar 27 '23 at 17:21