[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
bug#6830: widget-complete bad completions in :type 'file
From: |
Eli Zaretskii |
Subject: |
bug#6830: widget-complete bad completions in :type 'file |
Date: |
Fri, 24 Feb 2012 21:35:15 +0200 |
> From: Glenn Morris <rgm@gnu.org>
> Date: Wed, 22 Feb 2012 16:33:56 -0500
>
> Chong Yidong wrote:
>
> > If I enter "~/aaa" in the widget field and there is no file starting
> > with "aaa" in my home directory, M-TAB does nothing except for
> > displaying "No match" in the echo area.
> >
> > This is with the latest trunk, on GNU/Linux.
>
> I also cannot reproduce this.
> If no-one can reproduce this using stock Emacs on MS Windows, I suggest
> closing this.
Please don't close it. IIUC (and I'm not at all sure, as the
complexity of wid-edit.el and minibuffer.el is above my pay-grade),
the fact that it works on GNU/Linux is sheer luck.
What seems to happen is this:
. widget-complete calls completion-in-region, which in turn calls
minibuffer-complete, after let-binding the necessary variables:
(let ((minibuffer-completion-table collection)
(minibuffer-completion-predicate predicate)
(ol (make-overlay start end nil nil t)))
(overlay-put ol 'field 'completion)
(when completion-in-region-mode-predicate
(completion-in-region-mode 1)
(setq completion-in-region--data
(list (current-buffer) start end collection)))
(unwind-protect
(call-interactively 'minibuffer-complete)
. minibuffer-complete calls completion--do-completion, which does
this at its very beginning:
(let* ((beg (field-beginning))
(end (field-end))
(string (buffer-substring beg end))
(md (completion--field-metadata beg))
On GNU/Linux, field-beginning is correctly computed to be at the
beginning of the field, and thus buffer-substring correctly
extracts whatever you typed into the field, and that substring is
thereafter correctly completed.
In contrast, on Windows, field-beginning returns the position of
point, so if point is at the end of whatever you typed (as it
usually is when one hits M-TAB), buffer-substring extracts an empty
string, which is then "completed" to the files in the
default-directory.
The difference between the two system is, so it seems, that
find_field, which is the workhorse of field-beginning, looks at
overlays at point and before point which have the `field' property.
The problem is that we have 2 such overlays before point: one whose
`field' value is `completion' (as can be seen above, this overlay is
put there by completion-in-region), and another whose `field' value is
identical to the `field' text property at point. Both of these
overlays have nil as their priority, so when
get_char_property_and_overlay sorts the overlays by priority, the
resulting order is arbitrary. On GNU/Linux, the first overlay in the
sorted array happens to be the one whose `field' value is equal to the
text property, so find_field works. On MS-Windows, the first overlay
is the one whose value is `completion', so find_field decides that the
field begins and ends at the same position. The rest, as they say, is
history.
I hope that this analysis (if it is correct) will allow someone
smarter than myself to figure out how to fix this.
bug#6830: widget-complete bad completions in :type 'file,
Eli Zaretskii <=