fli
fli

Reputation: 170

Centre Emacs buffer within window

I wrap all my code at 80 columns, and there are times where the Emacs window is wider than 80 columns and there is a lot of unused whitespace on the right side.

I would like to position the Emacs buffer, so all the text is displayed in the middle of the window.

This is different to centre aligning text (more akin to the whitespace on either side of the text when viewing pdfs).

I think this can be achieved by dynamically adjusting the fringe mode widths, depending on the current window size, but I'm not sure where to start. Any ideas?

Upvotes: 11

Views: 6809

Answers (5)

mgsloan
mgsloan

Reputation: 3295

Modern answer are olivetti, visual-vill-column or writeroom-mode.

All of those work out of the box, although writeroom-mode also includes other hooks.

Upvotes: 4

user3800477
user3800477

Reputation: 74

Center window mode

https://github.com/anler/centered-window-mode

Global minor mode that centers the text of the window.

If another window is visible the text goes back to normal if its width is less than "cwm-centered-window-width."

Upvotes: 1

ryuslash
ryuslash

Reputation: 1262

As demonstrated here this is indeed possible:

(set-fringe-mode
 (/ (- (frame-pixel-width)
       (* 80 (frame-char-width)))
    2))

However, as I am testing this I seem to have more luck with using margins, at least when also resizing my frame:

(defun my-resize-margins ()
  (let ((margin-size (/ (- (frame-width) 80) 2)))
    (set-window-margins nil margin-size margin-size)))

(add-hook 'window-configuration-change-hook #'my-resize-margins)
(my-resize-margins)

Upvotes: 13

Drew
Drew

Reputation: 30708

You ask to display the buffer in the center of the window, which just moves some of the extra whitespace to the left of the buffer, from the right.

How about a solution that eliminates that extra whitespace instead? If that is acceptable, here are two approaches.

  1. If the buffer is alone in its frame, then you can fit the frame to the buffer, using library fit-frame.el. I bind command fit-frame to C-x C-_. This saves space not only within Emacs but for your desktop. (Library zoom-frm.el lets you also shrink/enlarge a frame incrementally, so you can save space by shrinking a frame when you don't need to see its content in detail.)

  2. If not (so the buffer is shown in a frame where there are multiple windows), and if the buffer's window has another window to the left or right of it, then you can do one of the following:

    2a. If the buffer's window has another window to the left or right of it, then you can use command fit-window-to-buffer. But you will also need to set option fit-window-to-buffer-horizontally to non-nil.

    2b. Use C-{ (shrink-window-horizontally), followed by C-x z z z..., to incrementally shrink the window width (removing the extra whitespace).

    2c. Load library face-remap+.el. Whenever you use text-scaling (e.g. C-x C- or C-x =), the window size grows or shrinks along with the text size, so you don't get extra whitespace added at the right when you shrink the text. This is controlled by user option text-scale-resize-window.

Upvotes: 1

Here is a function which should do what you want, using margins instead of fringes (since I tend to display buffer boundaries in the fringe and I find it becomes ugly if the fringe is too large).

(defun my/center (width)
  (interactive "nBuffer width: ")
  (let* ((adj          (- (window-text-width)
                          width))
         (total-margin (+ adj
                          left-margin-width
                          right-margin-width)))
    (setq left-margin-width  (/ total-margin 2))
    (setq right-margin-width (- total-margin left-margin-width)))
  (set-window-buffer (selected-window) (current-buffer)))

Upvotes: 4

Related Questions