[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

RE: should locate-file-completion filter out "./" and "../"?

From: Drew Adams
Subject: RE: should locate-file-completion filter out "./" and "../"?
Date: Mon, 10 Jul 2006 11:17:32 -0700

    > Thankfully (!!!!), duplicates are *not* being removed from
    > the result of `all-completions', because I rely upon that
    > fact to give me an unordered set of completions, with
    > duplicates if they are available. I have code that lets
    > users take advantage of completion candidates that might be identical
    > strings but have different meanings (e.g. occurrences of the
    > same string in a buffer).

    Could you expand on this? I have a hard time imagining why it
    would be useful to have duplicates if they are truly identical.
    And if they're not really identical, how does the user know
    the difference?

It shouldn't be important for this bug report - `all-completions' works just
fine as is.

The real question is why not fix callers of `completing-read', so they pass
a TABLE arg that doesn't have duplicates (unless they want duplicates)? It
makes sense for a calling program to do any duplicate removal or sorting of
completion candidates, as it deems appropriate; only the caller knows what
it needs. `all-completions' should not get involved with sorting or
duplicate removal (which it doesn't, thank goodness).

FYI, if you're just curious (though I'm sure this is TMI) -

It's true that the completion candidates themselves are just strings, but
the completion alist passed to completing-read or read-file-name can have
key-value pairs, and those values can be exploited. I track which candidate
is chosen, so I can tell which of any duplicate candidate strings is picked.
Then I can use the associated value.

For this to be helpful to the user, s?he generally needs to be able to see
more than just the candidates in *Completions*. For this kind of
functionality, I display whatever is appropriate at the same time.

An example: I have a search functionality that lets you input a regexp to
search for in some buffer. That regexp determines the matching occurrences
in the buffer being searched (like `occur', but not limited to searches
within a line). Each match is also used as a completion candidate, in
*Completions*. And each match is highlighted in the buffer searched. IOW,
searching determines a set of matching hits, and those are treated as
completion candidates. You can complete to any candidate and hit RET to go
to it. Or, you can cycle among candidates, browsing the hits in context (in
the buffer searched); that is, cycling can navigate to each candidate in
turn (or to specific candidates).

After entering the original regexp, which determines the set of completion
candidates, you can type another string (possibly another regexp) in the
minibuffer. This matches only within each candidate - i.e. within each of
the original hits. This match is also highlighted (in a different color)
within the hits in the buffer searched.

That second search string refines the search - it typically means that fewer
of the original candidate set match (i.e. match also the second regexp). All
of the original candidates remain highlighted in the buffer searched, but
the set of completion candidates is reduced to those that match also the
second regexp. When you complete, it is to one of these candidates. When you
cycle among candidates, you browse among these candidates that match both
regexps. You can dynamically change the second search string - a la isearch;
whatever you type is reflected in an updated *Completions*. If you delete
the second input altogether, so the minibuffer is empty again, then
*Completions* is back to the original set of candidates.

You browse among candidate hits by using C-next and C-prior. This moves you
around the buffer among the various hits, so you can see them in context.
The order of candidates is the order of the hits in the buffer - candidates
are not sorted (another reason for, say, all-completions not to impose
sorting). There are also ways to move around among selected candidates; you
need not cycle through each one, in order.

Of course, some of the original hits might be identical candidate strings.
If there are multiple hits for the same original input, those hits might not
be identical (the regexp might match them each differently), but some of
them might be identical.

The user might thus see some duplicates in *Completions*. When s?he
navigates, the hits are in order in the buffer (and they are in order in
*Completions*), and the navigation to each hit shows you its context (where
it is in the buffer). So there is no disorientation, even though the strings
in *Completions* are the same. If I had more control over the *Completions*
display (e.g. from Lisp), then I might try to put an indicator next to each
candidate in *Completions* - perhaps the position of the hit (point) or the
line number (though hits need not be lines, because the inital regexp can
match anything).

I have several features that exploit the order (or lack of it) of
*Completions* candidates and their possible multiple occurrence; search is
one of them. Here is an explanation of the search, with screenshots:
earchCommands. It's easier to see it than it is to explain it.

The search itself has some variants that provide browsing for:

 - matching lines (similar to occur) - this is just the same
   search feature, with an implicit initial regexp of .*
 - matching grep hits (used with, e.g. `grep')
 - matching definitions (an Imenu browser)

The essential difference between these is the initial regexp, which
determines the set of candidates that you can then match further and browse
among. For the occur browser, the regexp matches lines; for the Imenu
browser, the regexp is `imenu-generic-expression'. For the grep browser, a
hook opens the source file to the target hit when you cycle or complete.

Again, I'm not suggesting that Emacs should do anything like this, or that
Emacs should or ever will make any use of either unsorted or duplicate
completion candidates in *Completions*. My request is just that the
responsibility for removing duplicates and sorting be put on the functions
that call `completing-read' and `read-file-name'. They should pass in an
appropriate TABLE arg that DTRT for them, that is, does what they expect.
And, again, if Emacs wants to (also) have `minibuffer-completion-help' sort
and remove duplicates, I have no problem with that (since I don't use it).

For this bug, if `locate-file-completion' simply didn't add duplicates, I
would be happy.

Thx - Drew

reply via email to

[Prev in Thread] Current Thread [Next in Thread]