2

I'm helping a visually impaired user make viewing documentation in Emacs easier. He sets his font size such that he has about 40 columns of text in a full-screen frame with no splits (and he has configured Emacs never to split the window). At that size, line-wrapping (either the default or visual-line-mode) results in awkward gaps that make the text more difficult to read. Setting and appropriate fill-column and running fill-paragraph results in much more readable formatting, and so I tried to write some functions to do this automatically.

;; function to set the fill
(defun my-auto-set-fill-column ()
  "Always set fill-column to window width."
  (let ((inhibit-message 1)
        (width (/ (window-body-width nil t)
                     (window-font-width))))
    (set-fill-column width)
    (set-default 'fill-column width)))

this utility seems pretty straight-forward, but I'm happy for any suggested improvements.

 Function to format help pages.
;; You can call this with `M-x
;; my-format-doc-width' if you find
;; a help page that has wrapped
;; badly. With the hook below this
;; should be automatic.
(defun my-format-doc-width ()
  "Format documentation to window width."
  (interactive)
  (with-selected-window
      (get-buffer-window "*Help*")
    (read-only-mode -1)
    (my-auto-set-fill-column)
    (mark-whole-buffer)
    (call-interactively 'fill-region)
    (read-only-mode 1)))

I think this is also straight-forward, but happy for any suggestions.

(add-hook 'help-mode-hook
          '(lambda()
             (run-at-time
              (if (get-buffer-window "*Help*")
                  0 0.5) nil
              'my-format-doc-width)))

This feels pretty bad. Since the hook apparently runs before the window is actually created I have to put it on a timer. But of course I don't want to wait if the *Help* window exists already... Again, suggestions are welcome.

As you can see, my Emacs lisp is not strong and I suspect there are some obvious improvements that could be made to the implementation. More fundamentally, is this a reasonable general approach, or is there a better way to go about it? Something like (setq help-buffer-reformat-automagic 1) that I missed?

2

temp-buffer-show-hook should help. That's where help-mode-finish is called, for instance. It is used in with-help-window and with-temp-buffer-window, which are used to display Help windows.

  • Thanks, this does help. I couldn't get it to work directly, but it led me to help-mode-finish. In the end I advised this function and it works well. – Ista May 24 '18 at 1:29
1

Based on @Drew's answer, I ended up doing this:

;; function to get window width
(defun my-get-window-width ()
  "Get width of current window in."
  (/ (window-body-width nil t)
     (window-font-width)))

;; function to set the fill column
(defun my-auto-set-fill-column ()
  "Set fill-column to window width."
  (let ((inhibit-message 1))
    (set-fill-column
     (my-get-window-width))))

(set-default 'fill-column
             (my-get-window-width))

;; Function to format help pages.
;; With the hook below this
;; should be automatic.
(defun my-fill-buffer ()
  "Fill to window width."
  (interactive)
    (read-only-mode -1)
    (my-auto-set-fill-column)
    (mark-whole-buffer)
    (call-interactively 'fill-region)
    (read-only-mode 1))

(advice-add
 'help-mode-finish
 :after
 #'my-fill-buffer)

It works well and avoids the run-at-time kludge.

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.