@@ -324,6 +324,122 @@ Default value of `git-gutter:separator-sign` is `nil`.
324324Please set ` git-gutter:always-show-separator ` to non-nil, if you want to show
325325separator always.
326326
327+ ### Theming the gutter column background
328+
329+ Many modern themes — for example the built-in ` modus-operandi ` and
330+ ` modus-vivendi ` (see https://github.com/protesilaos/modus-themes ) — give the
331+ line-number column a background color that differs from the main buffer
332+ background. git-gutter places its change indicators in that same left-margin
333+ area, so when a theme colors the line numbers, the gutter should share that
334+ background for the column to look uniform.
335+
336+ git-gutter uses a dedicated face for each type of change: ` git-gutter:added `
337+ for added lines, ` git-gutter:modified ` for modified lines, and
338+ ` git-gutter:deleted ` for deleted lines. On those rows, the sign character
339+ configured under [ Look and feel] ( #look-and-feel ) (e.g. ` git-gutter:added-sign ` )
340+ is drawn in the foreground color of the corresponding face, against that face's
341+ background color.
342+
343+ How the * remaining* rows — those with no changes — get their background
344+ depends on your Emacs version.
345+
346+ #### Emacs 31.1 and later: use the built-in ` margin ` face
347+
348+ Emacs 31.1 introduced a new basic face called ` margin ` (see
349+ [ bug #80693 ] ( https://debbugs.gnu.org/cgi/bugreport.cgi?bug=80693 ) ). The
350+ display engine fills every empty cell in the left and right window margins
351+ with this face's background. Content written into the margin (such as a
352+ git-gutter sign) is drawn with its own face, but where that face does not
353+ specify a background of its own, it inherits from the ` margin ` face. So,
354+ configuring ` margin ` once yields a visually uniform gutter column background,
355+ without any per-package further customization.
356+
357+ Note that the line-number area is a separate display column with its own
358+ face (` line-number ` ); the ` margin ` face does not affect it. Most users will
359+ want the two backgrounds to match visually, when the line numbers are displayed.
360+ This is something themes can arrange and the example below does explicitly.
361+ The ` margin ` face was added in May 2026, so it will take time before third-party
362+ themes ship explicit support — until then, customizing it yourself is the way to go.
363+
364+ To match the line-number column without hardcoding a color:
365+
366+ ``` lisp
367+ (defun my/margin-update-face ()
368+ (let ((bg (face-background 'line-number nil t)))
369+ (when bg
370+ (set-face-background 'margin bg))))
371+
372+ (add-hook 'enable-theme-functions (lambda (&rest _) (my/margin-update-face)))
373+ (my-margin-update-face)
374+ ```
375+
376+ With this in place, you do ** not** need to set ` git-gutter:unchanged-sign ` or
377+ ` git-gutter:always-show-separator ` just to fill the gutter background — and
378+ on large files you should actively * avoid* them for that purpose, because
379+ each requires git-gutter to install an overlay on every line of the buffer.
380+ That cost becomes prohibitive on files with tens of thousands of lines (e.g.
381+ Emacs' own ` xdisp.c ` ); the ` margin ` face approach moves the work to the C
382+ display loop, where it costs nothing per line.
383+
384+ If you want a visual gap between the change indicator and the buffer text,
385+ the right approach on 31.1+ is to widen the gutter — for example
386+ ` (setq git-gutter:window-width 2) ` — and let the ` margin ` face fill the
387+ extra column for free. ` git-gutter:unchanged-sign ` and
388+ ` git-gutter:separator-sign ` retain their original meaning only when you
389+ actually want a visible character drawn on every unchanged line.
390+
391+ #### Emacs 30.x and earlier: fill via git-gutter's own faces
392+
393+ Before the ` margin ` face existed, an unwritten margin cell fell back to the
394+ default frame or terminal background. git-gutter had no way to influence
395+ cells it did not render into, so a uniform gutter background required filling
396+ those cells via git-gutter itself, using ` git-gutter:unchanged ` (when
397+ ` git-gutter:unchanged-sign ` is set) or ` git-gutter:separator ` (when
398+ ` git-gutter:always-show-separator ` is non-nil).
399+
400+ ** Important gotcha:** ` git-gutter:window-width ` reserves space for the gutter
401+ column in every buffer, but on unchanged rows nothing is written into that space
402+ unless one of the two signs above is configured. A cell that is reserved but
403+ never written falls back to the default frame or terminal background — so
404+ setting a background color on ` git-gutter:unchanged ` or ` git-gutter:separator `
405+ has no visible effect unless the corresponding sign is also set (even a single
406+ space ` " " ` ). Once a sign is in place, those two faces control the background
407+ of every cell not covered by a diff sign, making them the key to a visually
408+ uniform column.
409+
410+ To keep the gutter background in sync with the active theme without hardcoding
411+ a color, derive it from the ` line-number ` face:
412+
413+ ``` lisp
414+ (defun my-git-gutter-update-faces ()
415+ (let ((bg (face-background 'line-number nil t)))
416+ (when bg
417+ ;; All gutter cells share the same background as the line-number column.
418+ (dolist (face '(git-gutter:added git-gutter:modified git-gutter:deleted
419+ git-gutter:unchanged git-gutter:separator))
420+ (set-face-background face bg))
421+ ;; Make unchanged and separator invisible by matching foreground to background.
422+ (dolist (face '(git-gutter:unchanged git-gutter:separator))
423+ (set-face-foreground face bg)))))
424+
425+ ;; Re-run after every theme change (Emacs 29+).
426+ (add-hook 'enable-theme-functions (lambda (&rest _) (my-git-gutter-update-faces)))
427+ (my-git-gutter-update-faces)
428+ ```
429+
430+ #### Recommendation for theme designers
431+
432+ On Emacs 31.1+, themes should set the background of the ` margin ` face —
433+ typically matching ` line-number ` 's background, or a related accent. This
434+ single setting covers every margin cell in every buffer.
435+
436+ For backward compatibility with Emacs ≤30.x, themes that include explicit
437+ support for git-gutter should additionally set the background of
438+ ` git-gutter:unchanged ` and ` git-gutter:separator ` to the same color. Leaving
439+ these backgrounds unspecified is the most common cause of a broken-looking
440+ gutter column on those older Emacs versions: an empty stripe drawn in the
441+ frame's default background, mismatched against the line-number column.
442+
327443### Hide gutter if there are no changes
328444
329445Hide gutter when there are no changes if ` git-gutter:hide-gutter ` is non-nil.
0 commit comments