Next: , Previous: , Up: Advanced customization   [Index]

7.18 DIY Use more spacious margins or padding in Emacs frames

[ UPDATE 2023-06-25: Instead of following these instructions, you can simply install my spacious-padding package from GNU ELPA. It implements the padding and provides relevant user options. ]

By default, Emacs frames try to maximize the number of characters that fit in the current visible portion of the buffer. Users may prefer to have some extra padding instead. This can make Emacs frames look more pleasant, but also make it easier to identify the currently active window.

The way to implement such padding is two-fold:

  1. In the ‘early-init.el’ file instruct Emacs to use a higher value for the internal-border-width of all frames, as well as for the right-divider-width. The former concerns the outer boundaries of Emacs frames, while the latter pertains to dividers between Emacs windows.
  2. Make the relevant faces invisible by changing the value of their relevant attributes to that of the current theme’s main background.

The parameters of Emacs frames are specified in the variables initial-frame-alist and default-frame-alist. The “initial frame” refers to the first frame that appears on Emacs startup. The “default” refers to the fallback values that apply to all other frames that Emacs creates (unless those are explicitly overridden by a bespoke make-frame call).

In detail, first we use the same values for the two frame alist variables:

;; This must go in the early-init.el so that it applies to the initial
;; frame.
(dolist (var '(default-frame-alist initial-frame-alist))
  (add-to-list var '(right-divider-width . 20))
  (add-to-list var '(internal-border-width . 20)))

What the dolist does is to call add-to-list for the two variables we specify there. This economizes on typing.

Then we define a function that makes the relevant faces invisible. The reason we do this with a function is so we can hook it to the “post load” phase of a theme, thus applying the new background value (otherwise you keep the old background, which likely means that the faces will no longer be invisible).

(defun my-modus-themes-invisible-dividers (&rest _)
  "Make window dividers invisible.
Add this to the `modus-themes-post-load-hook'."
  (let ((bg (face-background 'default)))
    (custom-set-faces
     `(fringe ((t :background ,bg :foreground ,bg)))
     `(window-divider ((t :background ,bg :foreground ,bg)))
     `(window-divider-first-pixel ((t :background ,bg :foreground ,bg)))
     `(window-divider-last-pixel ((t :background ,bg :foreground ,bg))))))

(add-hook 'modus-themes-post-load-hook #'my-modus-themes-invisible-dividers)

Using a hook at the post-load-theme phase.

The above will work only for themes that belong to the Modus family. For users of Emacs version 29 or higher, there exists a theme-agnostic hook that takes a function with one argument—that of the theme—and calls in the “post enable” phase of theme loading. Here is the above snippet, with the necessary tweaks:

(defun my-modus-themes-invisible-dividers (&rest _)
  "Make window dividers for THEME invisible."
  (let ((bg (face-background 'default)))
    (custom-set-faces
     `(fringe ((t :background ,bg :foreground ,bg)))
     `(window-divider ((t :background ,bg :foreground ,bg)))
     `(window-divider-first-pixel ((t :background ,bg :foreground ,bg)))
     `(window-divider-last-pixel ((t :background ,bg :foreground ,bg))))))

(add-hook 'enable-theme-functions #'my-modus-themes-invisible-dividers)

Users of older versions of Emacs can read the entry herein about defining their own theme-agnostic hook (A theme-agnostic hook for theme loading).

Next: DIY Custom hl-todo colors, Previous: DIY Toggle themes without reloading them, Up: Advanced customization   [Index]