1
votes

I'm trying to define a function which will keep my fixed width body in Emacs centered in the buffer rather than aligned to the left side. In particular I want this to be buffer-local, and I'm trying to do this by locally setting left- and right-margin-width.

This works fine by itself, but I also want a hook to adjust the margins when the window size changes, and this is causing problems for me. Here's the code (adapted from https://stackoverflow.com/a/23731757/3822233):

(defun center-body ()
  (let* ((max-text-width 70)
         (margin (max 0 (/ (- (window-width) max-text-width) 2))))
    (setq-local left-margin-width margin)
    (setq-local right-margin-width margin)
    (set-window-buffer nil (current-buffer))))

(defun uncenter-body ()
  (setq-local left-margin-width 0)
  (setq-local right-margin-width 0)
  (set-window-buffer nil (current-buffer)))

(defun body-center-mode ()
  (interactive)
  (if (= left-margin-width 0)
      (progn
        (center-body))
        (add-hook 'window-configuration-change-hook 'center-body nil 1))                                                        
    (uncenter-body)
    (remove-hook 'window-configuration-change-hook 'center-body 1)))  

When the add-hook and remove-hook lines are removed, everthing's ok. But as soon as I call the add-hook I get a nesting exceeds max-lisp-eval-depth error.

I don't really understand lisp so I'm having trouble debugging this.

1

1 Answers

2
votes

Most likely set-window-buffer will end up running window-configuration-change-hook. So I'd recommend you only call set-window-buffer when left-margin-width or right-margin-width actually changes.

But in any case you'll get into trouble as soon as your buffer gets displayed in 2 or more windows of different width. So the better answer is to not use left-margin-width and right-margin-width but instead to use set-window-margins. Not only this will not call window-configuration-change-hook and hence won't suffer from this infinite recursion problem, but on top of that, it will happily adjust the margins differently for every window that displays the buffer, depending on those windows's widths.