Subject: bug#6830: widget-complete bad completions in :type 'file

From: Stefan Monnier <[email-masked]>
Date: Wed, 07 Mar 2012 17:09:56 -0500

> The value of `field' on MS-Windows is neither `boundary' nor nil.
> It is the value of the widget itself.  Here's just its beginning, as an
> illustration:

Oh, I think I see, now.
There are 2 overlays defining a field: one if the setup by the
completion code, the other by the widget code.  both cover the same text
area, so using either would be fine.
Now since both overlays cover the exact same area, and have no
`priority', none has priority over the other, so which of the two is
used depends on arbitrary details, e.g. implementation of the
`sort' function.

Now, until here, there's still no bug because indeed it doesn't matter
which overlay we use to determine the field.

The bug comes up because one overlay is used to get `field' and the
other is used to get `before_field'.  I.e. the "arbitrary details" end
up making a different choice.

This is probably due to the presence of the boundary overlay, so
`before_field' is computed based on the two main overlays only (because
at that position, the boundary overlay is absent), whereas for `field',
we take the overlays at the end pos, where we have the two main overlays
plus the boundary overlay, so the sort is applied to a different list of
overlays, resulting in a different ordering of the two overlays we
care about.

Does the patch below fix the problem?

        Stefan

=== modified file 'src/buffer.c'
--- src/buffer.c	2012-03-02 15:57:16 +0000
+++ src/buffer.c	2012-03-07 22:08:13 +0000
@@ -2864,7 +2864,11 @@
     return s1->beg < s2->beg ? -1 : 1;
   if (s1->end != s2->end)
     return s2->end < s1->end ? -1 : 1;
-  return 0;
+  /* Avoid the non-determinism of qsort by choosing an arbitrary ordering
+     between "equal" overlays.  The result can still change between
+     invocations of Emacs, but it won't change in the middle of
+     `find_field' (bug#6830).  */
+  return XHASH (s1->overlay) < XHASH (s2->overlay) ? -1 : 1;
 }
 
 /* Sort an array of overlays by priority.  The array is modified in place.