Subject: bug#23169: 24.5; Inconsistent text reflow in man pages depending on window configuration

From: Lluís <[email-masked]>
Date: Sat, 02 Apr 2016 13:30:38 +0200

Eli Zaretskii writes:

>> From: Lluís <[email-masked]>
>> Cc: [email-masked]
>> Date: Fri, 01 Apr 2016 17:13:55 +0200
>> 
>> > The usual way to fix these problems is to set Man-width to a non-nil
>> > value, as appropriate for your frame/window dimensions.  Would that
>> > solve the problem for you?
>> 
>> Thing is I don't know the width of the window that will be used, since in some
>> cases it does not exist yet:
>> 
>> +-----+                   +--+--+
>> |     |                   |  |  |
>> |     | -> M-x man man -> |  |  |
>> |     |                   |  |  |
>> +-----+                   +--+--+

> Isn't the window that man will use half of the window before the
> command?  Then you know the width in advance, because you are familiar
> with your window and frame configurations

That's only one case. Maybe display-buffer ends up creating a smaller window
(depending on its configuration hooks), or maybe it ends up reusing some other
window.

>> The ideal without breaking the asynchronicity would be to somehow display the
>> new buffer on a window before populating it (display-buffer might or might not
>> reuse a window here), calculate its window's width, set COLUMNS, asynchronously
>> call man to populate the buffer, and then really show the buffer on the previous
>> window.
>> 
>> The only problem is that creating a temporary window just to calculate its width
>> could annoy people because the contents won't be shown yet.

> Yes, that's the problem.

Martin's "pretend" argument to display-buffer could be a way out of this
conundrum. Also, here's a patch for an alternative fix.

Thanks,
  Lluis

--- /tmp/old/man.el	2016-04-02 13:09:14.588221106 +0200
+++ /tmp/man.el	2016-04-02 13:28:07.580237516 +0200
@@ -1001,7 +1001,16 @@
       (error "No item under point")
     (man man-args)))
 
-(defmacro Man-start-calling (&rest body)
+(defun Man-buffer-or-window-width (buffer-or-window)
+  "Get width of window used after BUFFER-OR-WINDOW is displayed."
+  (if (windowp buffer-or-window)
+      (window-width buffer-or-window)
+    (save-window-excursion
+      (window-width (display-buffer buffer-or-window
+                                    ;; As used by `Man-notify-when-ready'.
+                                    'not-this-window)))))
+
+(defmacro Man-start-calling (buffer-or-window &rest body)
   "Start the man command in `body' after setting up the environment"
   `(let ((process-environment (copy-sequence process-environment))
 	;; The following is so Awk script gets \n intact
@@ -1040,7 +1049,7 @@
 			  ((and (integerp Man-width) (> Man-width 0))
 			   Man-width)
 			  (Man-width (frame-width))
-			  ((window-width))))))
+			  ((Man-buffer-or-window-width ,buffer-or-window))))))
     ;; Since man-db 2.4.3-1, man writes plain text with no escape
     ;; sequences when stdout is not a tty.	In 2.5.0, the following
     ;; env-var was added to allow control of this (see Debian Bug#340673).
@@ -1062,7 +1071,7 @@
 	(setq buffer-undo-list t)
 	(setq Man-original-frame (selected-frame))
 	(setq Man-arguments man-args))
-      (Man-start-calling
+      (Man-start-calling buffer
        (if (fboundp 'start-process)
 	    (set-process-sentinel
 	     (start-process manual-program buffer
@@ -1099,7 +1108,7 @@
 	(inhibit-read-only t)
 	(buffer-read-only nil))
      (erase-buffer)
-     (Man-start-calling
+     (Man-start-calling (frame-selected-window)
       (call-process shell-file-name nil (list (current-buffer) nil) nil
 		    shell-command-switch
 		    (format (Man-build-man-command) Man-arguments)))