Search code examples
emacselisp

Emacs -- test for same buffer in other windows with different width


I am looking for some assistance, please, to test for the existence of the same buffer in more than one window (on any frame) and whether the window-width of those windows (containing that particular buffer) are different.


  • Example I

Frame # 1:

Window A -- minor-mode-xyz -- (= (window-width) 55) -- (equal (buffer-name) "*TEST*")

Window B -- nothing important to this example

Window C -- minor-mode-xyz -- (= (window-width) 55) -- (equal (buffer-name) "*TEST*")

Frame # 2:

Window A -- minor-mode-xyz -- (= (window-width) 100) -- (equal (buffer-name) "*TEST*")

Window B -- nothing important to this example

Window C -- minor-mode-xyz -- (= (window-width) 55) -- (equal (buffer-name) "*TEST*")

Result: (message "The test yielded a positive result -- do something now.")


  • Example II

Frame # 1:

Window A -- minor-mode-xyz -- (= (window-width) 100) -- (equal (buffer-name) "*TEST*")

Window B -- nothing important to this example

Window C -- minor-mode-xyz -- (= (window-width) 100) -- (equal (buffer-name) "*TEST*")

Frame # 2:

Window A -- minor-mode-xyz -- (= (window-width) 100) -- (equal (buffer-name) "*TEST*")

Window B -- nothing important to this example

Window C -- minor-mode-xyz -- (= (window-width) 100) -- (equal (buffer-name) "*TEST*")

Result: (message "Everything is PERFECT -- do not do anything !!!")


  • Example III

Frame # 1:

Window A -- minor-mode-xyz -- (= (window-width) 100) -- (equal (buffer-name) "*TEST*")

Window B -- nothing important to this example

Window C -- nothing important to this example

Frame # 2:

Window A -- nothing important to this example

Window B -- nothing important to this example

Window C -- nothing important to this example

Result:  (message "Everything is PERFECT -- do not do anything !!!")


Here is an example where the window-width in both windows is exactly equal, and the minor mode works well.

Example
(source: lawlist.com)


Here is an example where the window-width in the windows are not equal, and the minor mode goes haywire in any window that does not have focus -- e.g., the horizontal / vertical yellow lines are not drawn correctly. When a situation like this arises, the best way to handle it would probably be to have a test and when it returns positive, disable the yellow horizontal / vertical lines in all windows.

Example
(source: lawlist.com)


The following is just a draft concept idea, but is not yet capable of handling the test that is needed:

(defun test-function (&optional all-frames)
"If the same buffer displays on any frame -- with different `window-width`,
then do something."
  (let* (
      (wins (window-list (selected-frame) 'no-minibuf))
      (bufs (delete-dups (mapcar #'window-buffer wins))))
    (dolist (buf bufs)
      (with-current-buffer buf
        (dolist (win
            (get-buffer-window-list (current-buffer) 'no-minibuf all-frames))
          (select-window win)
          (when test-mode
            (message "hello-world.")))))))

Solution

  • Here is a function that returns a list of pairs of windows that share the same buffer but have different width:

    (defun window-pairs ()
      (let (wmap ret)
        ;; get a list of all windows
        (dolist (frame (frame-list))
          (dolist (window (window-list frame))
            (let* ((buffer (window-buffer window))
                   (assoc (assoc buffer wmap)))
              ;; if the window shares the window with some previously
              ;; visited windows, also compare their widths
              (if assoc
                  (let ((other-windows (cdr assoc)))
                    (dolist (other-window other-windows)
                      (unless (= (window-width window) (window-width other-window))
                        (push (cons window other-window) ret)))
                    (push (cons buffer (cons window other-windows)) wmap))
                (push (cons buffer (list window)) wmap)))))
        ret))
    

    It finds all windows that share the same buffer, and each time a new window is found whose buffer has been seen before, it iterates over the previous windows to compare their widths with that of the current window.