Subject: Re: bug#19661: wrapping before window-width (new wrap-column text property?)

From: Ivan Shmakov <[email-masked]>
Date: Fri, 23 Jan 2015 19:45:31 +0000

>>>>> Eli Zaretskii <[email-masked]> writes:

 >> From: Ivan Shmakov  Date: Fri, 23 Jan 2015 13:17:08 +0000

 >> Please provide support for window-width-independent wrapping in the
 >> Emacs display engine; possibly by the means of a new wrap-column
 >> text property (and still perhaps complemented by a eponymous
 >> buffer-local variable), treated similarly to the likes of
 >> wrap-prefix.

	… Or that could rather be wrap-width, given that Emacs supports
	pixelwise resize now (not to mention variable-width fonts, etc…)

 >> This feature could be used to display format=flowed (RFC 3676) MIME
 >> parts, as well as enriched-mode documents, documents using MediaWiki
 >> markup, SHR-rendered HTML documents, and pretty much any other kind
 >> of text which allows for /both/ wrappable and preformatted parts at
 >> the same time.

 > format=flowed etc. is already supported by word-wrap, isn't it?

	Not in its entirety; consider, e. g. (section 4.1 of RFC 3676):

   If the line ends in a space, the line is flowed.  Otherwise it is
   fixed.  The exception to this rule is a signature separator line,
   described in Section 4.3.  Such lines end in a space but are neither
   flowed nor fixed.

	I know of no way to make the Emacs display engine wrap one line
	but not the other in the very same buffer.

 >> I admit that I know very little of the current Emacs display
 >> implementation.

 > How about biting the bullet and trying to do this yourself?  I can
 > provide guidance and advice, if needed.

	I guess I can, but most probably /not/ in the next few months.

	(The biggest problem for me would be the change of the tools and
	the workflow.  Say, nothing like eval-defun is going to be
	available while working on the C code.  Also, I’m not really
	keen when it comes to non-tty Emacs frames, – never felt those
	as of being of much value for my tasks.)

[…]

 > The fundamental problem here is that the Emacs display engine is
 > based on an "iterator" object that basically walks a buffer and
 > generates "glyph" objects that are then given to the display back-end
 > for actual display.  The iterator object has only a very myopic view
 > of the text it walks through.  Before Emacs 24, that view was
 > one-character long -- we only looked at the next character in the
 > logical order.  With Emacs 24's bidirectional display, the field of
 > view became slightly wider, but it is still limited to a single
 > physical line, and most of the display doesn't even know about that,
 > the single exception being bidi.c.

	“Physical” as in “display” or “buffer”?

 > With your suggestion, once the width of the laid out glyphs reaches
 > some pixel value, the next display element will need to come from a
 > different part of the buffer.  But how to know where in the buffer is
 > that?  You cannot know that until you are done with layout of the
 > entire visible portion of the left-side pane, the one that in the
 > above example ends with "set to 23."

 > So either we need a deep surgery of display_line, so that it acquires
 > the ability to produce layout of each screen line in several parts,
 > or we write some tricky code that would perform all the necessary
 > calculations to find the buffer position of "This yet another
 > example" when we are done producing "This is an example" and want to
 > continue with the same screen line.

	Basically, yes, I thought about the display engine keeping track
	of the latest “wasted” rectangular chunk of screen space, and
	allowing for it to be occupied by the text coming later in the
	“buffer” order.  (Or perhaps up to two such chunks: one to the
	right and one to the left of the text being drawn.)

	IIUC, display_line would potentially have to be called several
	times to draw a single display line.

	And all this behavior only triggered when the text being drawn
	has some specific property; once the property value changes, —
	the state is reset.

 > The former alternative means significant changes all over the display
 > engine, the latter means redisplay will be slower (not sure by how
 > much).  So both are highly non-trivial.

	ACK; thanks for the detailed explanation.

 >> As already imagined in the preceding discussion, forward- and
 >> backward-char commands would then still follow the logical order of
 >> text in the buffer (that is: the “23” sentence, then the “25” one),
 >> while left-char, etc. would follow the visual order (assuming
 >> visual-order-cursor-movement.)

 > That's the least of our trouble: the function that finds the place to
 > put the cursor (set_cursor_from_row) already thoroughly analyzes the
 > window display, and in Emacs 24 was rewritten to make it independent
 > of many assumptions that were broken by bidirectional display.

 > Perhaps you think that Emacs moves cursor visually, in which case it
 > would have had problems when the logical flow of text is broken like
 > that.  But that's not what Emacs does to move cursor: it moves point,
 > updates the display, and then figures out where in the new display to
 > put the cursor.

	That was a pure UI consideration.  (And not even one I’ve
	personally thought of.)

-- 
FSF associate member #7257  http://boycottsystemd.org/  … 3013 B6A0 230E 334A