1

So I'm using Emacs in Windows (Emacs 24.5.1, Windows 10). I've set a default margin width of 20 on both sides for text-mode, but occasionally I like to resize the window in half (Windows+left or right arrow) so that I can quote something from a browser window or the like.

What would be a good way to have Emacs detect this behavior and adjust the margins appropriately (as it is, there's just a thin slit of text when the window is halved), maybe to 5 or 3 characters on each side?

Alternatively, how could I program a function I could issue that would do this manually? I can't even work out how to do it by issuing setq left-margin-width xx from within a running instance. Heeelp.

Here are the relevant parts of my current .emacs:

(add-hook 'text-mode-hook 'visual-line-mode)

(defun margins ()
(setq left-margin-width 20)
(setq right-margin-width 20))

(add-hook 'text-mode-hook 'margins)
  • When you say "window" do you perhaps mean frame? When you "halve" the window are you doing, in effect, C-x 2 or C-x 3, or something else? – Drew May 4 '16 at 13:46
  • Hi @Drew! I mean vertically splitting the Emacs window using the Windows window management functionality. Hitting the Windows key and either of the arrow keys cuts your current window neatly in half vertically so you can do two things side by side. I mean, you could do the same in any windowing system, I just happen to be using Windows right now. – Eirik S. May 4 '16 at 14:56
  • To @Drew's question, what you are doing here is resizing the frame. (In Emacs terminology frame and window are distinct: a frame can display multiple windows.) Two options for what you want: write Emacs commands that resize the frame to the left/right half of the screen and also set the margin. Or you can use the window-configuration-change-hook with a function that checks for e.g. the current frame size and sets the margins accordingly. That hook gets called for any window/frame change. – glucas May 4 '16 at 20:10
0

sublimity-attractive in the sublimity package tries to keep the window width to a specified width, by managing margins.

(require 'sublimity-attractive) (setq sublimity-attractive-centering-width 110) (sublimity-mode 1)

0

There may be more elegant solutions, but here's a function that sets the margins based on the width of the frame:

(defun reset-margins (&optional arg)
  "Reset the buffer margins based on the width of the frame.
  Has no effect when the frame contains multiple windows. By
  default, only adjust the margins if they are already
  non-zero. Use a prefix ARG to force the resize."
  (interactive "P")
  (unless (window-parent)
(when (or arg (> left-margin-width 0))
  (let ((width (if (< (frame-width) 100) 5 20)))
    (unless (= left-margin-width width)
      (setq left-margin-width width)
      (setq right-margin-width width)
      (set-window-buffer nil (current-buffer)))))))

The left/right margin variables are buffer-local and are not actually applied until you set the window buffer, so here I'm calling set-window-buffer with the current buffer to pick up the change.

To simplify things this function checks that the frame has exactly one window (i.e. there is no window-parent). It's using margins of 5 and 20 depending on whether the frame is wider or narrow than 100.

You can call this function automatically when the frame is resized using this hook:

(add-hook 'window-configuration-change-hook 'reset-margins)

By default this function only sets the margins if they are already non-zero. It can be called with an argument to force the change, so that you can also use it from a mode hook:

(add-hook 'text-mode-hook (lambda () (reset-margins t)))

That way when you first enable text-mode the margins will be adjusted from 0 to either 5 or 20, and then when you resize the frame they will automatically narrow or widen accordingly.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.