unofficial mirror of help-gnu-emacs@gnu.org
 help / color / mirror / Atom feed
From: Drew Adams <drew.adams@oracle.com>
To: Kaushal Modi <kaushal.modi@gmail.com>,
	Help Gnu Emacs mailing list <help-gnu-emacs@gnu.org>
Subject: RE: Canonical way to add a pre-filter to completing-read
Date: Thu, 10 May 2018 07:10:05 -0700 (PDT)	[thread overview]
Message-ID: <bc515c5a-7ffd-4f37-b163-b6afdc0cfa13@default> (raw)
In-Reply-To: <CAFyQvY3gomT-G=oGhYsReZ4O1vdJ09a9OpYYtvyoTsaaSmG0Qw@mail.gmail.com>

> I want to use completing-read to provide a "pre-filter" to
> narrow down the completion list.

Possibilities:

1. Filter the list of completions before passing it.
   IOW, pass '("abc" "bcd"), not '("abc" "bcd" "cde").
   (Or if COMPLETIONS is a function, have it also filter,
   as and when needed.)

2. Provide a PREDICATE arg that filters as needed.  E.g.,
   (lambda (xx) (string-match-p "bc" xx)).

With vanilla Emacs:

If you use a non-function COMPLETIONS arg then you need
to establish that list of candidates before completing.
You have only PREDICATE to play with.  The candidates
are determined independently of whatever input might be
in the minibuffer

If you use a function COMPLETIONS arg then the function
can take into account the current minibuffer input.
The function can do anything you want, to come up with
the (current, dynamically computed) set of candidates.

----

Wrt INITIAL-INPUT: It should not be considered deprecated.
There was never any need for that.  It should have been
enough for the manual or doc string to just explain the
difference between DEF and INITIAL-INPUT, and to suggest
that in many (most?) cases it can be more user-friendly
or more useful to use only DEF.  The "deprecation" of
this arg was uncalled for, IMHO.

----

If you use Icicles:

1. There are 3 possibilities for filtering with a predicate:

   a. Use argument PREDICATE.  As usual, it filters raw
      COMPLETIONS, e.g., alist elements or obarray symbols,
      and it does so before you type anything in the
      minibuffer.  Nothing new here.

   b. Bind variable `icicle-must-pass-after-match-predicate'
      around the `completing-read' call.  It filters the
      _displayed_ candidates (strings - what you see in
      `*Completions*'), and it does so _after_ matching your
      minibuffer input.

   c. Bind variable `icicle-must-pass-predicate': same as
      `icicle-must-pass-after-match-predicate', but before
      matching your current input.

   These can be used in combination.  PREDICATE filters all
   initial candidates, even when that might be wasteful (not
   so performant) because you've typed some text that would
   more quickly rule out many of them, if matched first.

   Different use cases call for different matching orders.
   Sometimes it makes sense to use only PREDICATE, filtering
   all raw candidates ahead of time.  Sometimes it makes
   sense to do input-matching first, before applying a
   given predicate.

2. Option `icicle-default-value' controls arg DEF: whether
   it is shown in the prompt, gets substituted for an empty
   INITIAL-INPUT, and so on.  In particular, 4 of the 6
   values insert the default value into the minibuffer:

   `insert-start'    - Insert DEF and leave cursor at start.
   `insert-end'      - Insert DEF and leave cursor at end.
   `preselect-start' - Insert & preselect DEF; cursor at start.
   `preselect-end'   - Insert & preselect DEF; cursor at end.

> Below works exactly as I want.. but the docs and manual
> say that INITIAL-INPUT is deprecated.
>
> (completing-read "Entry: " '("abc" "bcd" "cde") nil
>                  :require-match "bc")
>
> So, what would be the right way, i.e. not using the
> deprecated INITIAL-INPUT?

Ignore the docs.  Emacs was wrong to proclaim INITIAL-INPUT
deprecated.  It can be useful.  It never hurt anyone for
Emacs to make it available.  It is enough to suggest to
users that it is more conventional, and typically more
user-friendly, to use only DEF.

With luck, this silly uber-control will be removed from
the docs someday.  Don't be scared away from using it
when it suits your purpose.

(Just one opinion.)



  reply	other threads:[~2018-05-10 14:10 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-05-10 13:09 Canonical way to add a pre-filter to completing-read Kaushal Modi
2018-05-10 14:10 ` Drew Adams [this message]
2018-05-10 17:36   ` Kaushal Modi
2018-05-10 15:21 ` Stefan Monnier
2018-05-10 17:19   ` Kaushal Modi
2018-05-10 22:05     ` Stefan Monnier

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.gnu.org/software/emacs/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=bc515c5a-7ffd-4f37-b163-b6afdc0cfa13@default \
    --to=drew.adams@oracle.com \
    --cc=help-gnu-emacs@gnu.org \
    --cc=kaushal.modi@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).