3

I have tried:

(defun my-change-fringes ()
  (set-window-fringes (selected-window) 20 0))

(add-hook 'magit-mode-hook 'my-change-fringes))

The problem seems to be that when I open a magit buffer for the first time, the selected window is for some reason the previous window.

caisah
  • 4,056
  • 1
  • 23
  • 43
  • Window focus probably hasn't updated yet when running the hook. Try resolving the window using `current-buffer` (the magit buffer in the case of the mode hook). Maybe `(get-buffer-window (current-buffer))` ? – ebpa Feb 07 '19 at 20:00

1 Answers1

2

Note that if you call set-window-fringes in a mode hook, then your change will not be in effect if that existing magit buffer is then displayed in a different window.

The simplest solution to your problem is:

(defun my-magit-mode-hook ()
  "Custom `magit-mode' behaviours."
  (setq left-fringe-width 20
        right-fringe-width 0))

(add-hook 'magit-mode-hook 'my-magit-mode-hook)

A slightly more complex approach would be to use a buffer-local C-hv window-configuration-change-hook (see which for details) to make your set-window-fringes call:

(defun my-magit-window-config ()
  "Used in `window-configuration-change-hook' to configure fringes for Magit."
  (set-window-fringes nil 20 0))

(defun my-magit-mode-hook ()
  "Custom `magit-mode' behaviours."
  (add-hook 'window-configuration-change-hook
            'my-magit-window-config nil :local))

(add-hook 'magit-mode-hook 'my-magit-mode-hook)

And you can safely ignore the following entirely, but just in case it's of interest...

When the buffer changes in a given window it is still the same window object being used, and as such I had initially assumed that it would also be necessary to restore the default fringe sizes when a non-Magit buffer was displayed in a window.

However, set-window-buffer by default "resets WINDOW’s position, display margins, fringe widths, and scroll bar settings, based on the local variables in the specified buffer" (which is, of course, where the left-fringe-width and right-fringe-width buffer-local variables come into play).

Consequently the house-keeping I was attempting was entirely unnecessary (and moreover was undoubtedly problematic for anything else trying to set fringe widths).

So don't use the following code; but I'll leave it here in case it's of interest for any reason.

(defun my-magit-window-config ()
  "Used in `window-configuration-change-hook' to configure fringes for Magit."
  (let ((left (frame-parameter nil 'left-fringe))
        (right (frame-parameter nil 'right-fringe)))
    (cl-loop for win being the windows
             if (with-selected-window win (derived-mode-p 'magit-mode))
             do (set-window-fringes win 20 0)
             else do (set-window-fringes win left right))))

(add-hook 'window-configuration-change-hook 'my-magit-window-config)
phils
  • 48,657
  • 3
  • 76
  • 115
  • Excellent explanation! The buffer-local hook setting is a trick I didn't know before. Now magit buffers show the section indicators without affecting other documents. Sweet! – ctietze Dec 21 '21 at 10:37