Subject: Re: bug#6000: describe-text-sexp does not know window-width

From: martin rudalics <[email-masked]>
Date: Sun, 6 Jun 2021 09:42:22 +0200

>> Does anybody have a test case that displays the problem (in case it's
 >> still in place after all these years)?
 >
 > Indeed a test case would be needed, but I have none.

With emacs -Q evaluate

(progn
   (split-window nil -20 t)
   (put-text-property 1 2 'foo "This is a very long text property")
   (describe-char 1))

or

(progn
   (setq split-height-threshold nil)
   (setq split-width-threshold 20)
   (put-text-property 1 2 'foo "This is a very long text property")
   (describe-char 1))

Here these show a *Help* window on the right where not the entire text
property string is visible.  Depending on your settings it won't matter
much because the rest of that buffer is only partially visible too.

To show the inverse effect, again with emacs -Q, evaluate

(progn
   (split-window nil 20 t)
   (put-text-property 1 2 'foo t)
   (describe-char 1))

Here this shows *Help* in the window on the right with a line

   foo                  [Show]

where clicking on [Show] will show "t" in the window on the left.
This is embarrassingly silly.

Obviously, there are many more scenarios but most of them require to
customize `display-buffer-alist'.  Presumably, most people don't notice
the behavior - they just got used to it.

We could

- Do nothing: If, in the earlier scenarios, we'd insert a "Show" button
   instead of the text, clicking that button might again pop up a too
   narrow *Pp Eval Output* window and nothing has been gained.  As for
   the last scenario, we could tell users that they are on their own when
   they invoke `describe-char' in a too narrow window.

- Skip the `window-width' check in `describe-text-sexp' and maybe
   recommend using `temp-buffer-resize-mode' with a few tweaks like

(progn
   (temp-buffer-resize-mode)
   (setq temp-buffer-max-width 100)
   (setq fit-window-to-buffer-horizontally t)
   (setq split-height-threshold nil)
   (setq split-width-threshold 20)
   (put-text-property 1 2 'foo "This is a very long text property")
   (describe-char 1))

   But some people don't like `temp-buffer-resize-mode'.

- Calculate the maximum width of text in the buffer preceding the line
   where to insert the property with a function like

(defun max-column-in-frame ()
   "Return maximum column of current buffer in selected frame.
The return value is the longest column from the beginning of the
buffer to the line specified by the selected frame's height."
   (save-excursion
     (goto-char (point-min))
     (let ((width (frame-width))
	  (height (frame-height))
	  (line 0)
	  (max-column 0)
	  column)
       (while (and (< line height) (< (point) (point-max)))
	(setq column (move-to-column width))
	(when (> column max-column)
	  (setq max-column column))
	(forward-line 1)
	(setq line (1+ line)))
       max-column)))

and use that instead of `window-width' in `describe-text-sexp' as

     	     (<= (length pp) (- (max-column-in-frame) (current-column))))

This will delegate the problem to those who inserted text earlier into
that buffer.  If they were right, `describe-text-sexp' won't do anything
wrong.

martin