Shrink-Wrapping Frames

This page is part of the description of OneOnOneEmacs, by DrewAdams.

One advantage a Frame has over an Emacs Window is that the frame can be made to fit the buffer it displays. With windows, this wouldn’t make much sense, since multiple windows tiled in the same direction (in the same frame) have the same width or height. (You can vary the height or width of all windows tiled in the same direction, but even that is not very natural.)

This is not only possible for frames, it is also very useful. It means that most buffers need never be displayed with wrap-around or truncated text. And a frame need never be larger than what is needed to display its buffer.

Command `fit-frame'

Command ‘fit-frame’ “shrink-wraps” a frame to fit its displayed buffers or just its selected buffer – always within the limits imposed by the maximum-size user options (see below). Its behavior depends on the prefix argument, if any, that you use:

Goldilocks And The 3 Frames -- Here are some screenshots:

DrewsEmacsShrinkWide
DrewsEmacsShrinkNarrow
DrewsEmacsShrinkFit

The resulting size is determined automatically by ‘fit-frame’, but there are user variables that give you control over this calculation. Alternatively, with a non-negative numeric prefix argument, ‘fit-frame’ prompts you for an absolute width and height. A negative prefix argument uses the value of ‘fill-column’ for the width.

Automatically Fitting All Frames

Because I found this so useful, I decided to apply shrink-wrapping automatically, by default, to all frames. To do this, the first step was just to use ‘fit-frame’ as a hook function, whenever a frame is created:

  (add-hook 'after-make-frame-functions 'fit-frame)

This takes care of fitting normal, user-created frames at their creation, but what about when a different buffer is displayed in an existing frame? Other changes I made (see below) modified Emacs behavior to use frames generally, instead of Emacs windows. To get Emacs to fit all frames whenever appropriate, I redefined a few important functions so that they called ‘fit-frame’ at the appropriate time.

Each of these functions was changed to fit the frame if the buffer’s window is the only one in it:

I also added function ‘fit-frame-if-one-window’ to ‘temp-buffer-show-hook’. This hook (undocumented in Emacs 20) is used by a few standard Emacs functions; for example, ‘pp-eval-expression’. (Function ‘fit-frame-if-one-window’ calls ‘fit-frame’ if the frame has only one window.)

User Variables for Frame Fitting

Having done this, I created various user variables to turn automatic frame fitting on/off.

In a few cases, I used these variables to inhibit inappropriate frame fitting in standard Emacs functions. For example, in function ‘compile-internal’, which performs a ‘make’ or ‘grep’ operation and displays the results of the process, I temporarily reset option ‘fit-frame-inhibit-fitting-flag’ to inhibit premature fitting of the output buffer frame by ‘display-buffer’.

  (let ((fit-frame-inhibit-fitting-flag t)) (display-buffer outbuf))

Another useful user option for frame-fitting is ‘fit-frame-skip-header-lines-alist’. It takes care of modes, such as InfoMode and DiredMode, that have headers that are sometimes much wider than the rest of the buffer. You use this option to tell ‘fit-frame’ to ignore header lines when calculating the buffer width. The result is a better fit: a narrower frame with less empty space at the right – the long header lines are wrapped.

The remaining user options for frame-fitting are described in the doc string of command ‘fit-frame’. Widths are in characters; heights are in lines.

See Libraries:


OneOnOneEmacs CategoryFrames FrameModes CategoryDisplay