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

8
  • 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 ...
    – oOosys
    Commented Mar 25, 2023 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
    Commented Mar 25, 2023 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? Commented Mar 25, 2023 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
    Commented Mar 25, 2023 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.
    – oOosys
    Commented Mar 25, 2023 at 22:25

1 Answer 1

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_ =   /
;;          )==*(`     `) ~ \
;;         /     \     /     \
;;         |     |     ) ~   (
;;        /       \   /     ~ \
;;        \       /   \~     ~/
;; _/\_/\_/\__  _/_/\_/\__~__/_/\_/\_/\_/\_/\_
;; |  |  |  | ) ) |  |  | ((  |  |  |  |  |  |
;; |  |  |  |( (  |  |  |  \\ |  |  |  |  |  |
;; |  |  |  | )_) |  |  |  |))|  |  |  |  |  |
;; |  |  |  |  |  |  |  |  (/ |  |  |  |  |  |
;; |  |  |  |  |  |  |  |  |  |  |  |  |  |  |

(
 (
  (
   (
    (
     (
      (
       (
        (
         (
          (
           (
            (
             (
              (
               (
                (
                 (
                  )
                 )
                )
               )
              )
             )
            )
           )
          )
         )
        )
       )
      )
     )
    )
   )
  )
 )
7
  • 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
    Commented Mar 26, 2023 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?
    – oOosys
    Commented Mar 26, 2023 at 12:15
  • BTW ... your Emacs window is transparent ... showing you? in the background? Which theme allows transparency of Emacs frame?
    – oOosys
    Commented Mar 26, 2023 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
    Commented Mar 26, 2023 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
    Commented Mar 27, 2023 at 17:13

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.