: [[image:iciclesimage]]

|| *Previous:*  [[Icicles - Multi-Commands the Hard Way]] || '''[[Icicles]]''' || IciclesIndex || *Next:* [[Icicles - Specifying Match Functions for Commands]] ||

----

== Global Filters ==

This section is for EmacsLisp programmers.

Which [[completion]] candidates get displayed?  To review:

'''1.''' The domain of discourse, that is, all possible candidates, is
determined by the arguments to `completing-read',
`read-file-name', or `M-x'.

'''2.''' A user types something in the [[minibuffer]].  This narrows the
possible candidates to those that match the input.  Matching
can be [[prefix completion|prefix-matching]] or [[apropos completion|apropos-matching]].

Wouldn't it sometimes be useful to filter '''#1''' in a global way,
before filtering it with the user input ('''#2''')?  Functions `completing-read' and
`read-file-name' take a predicate argument, so that can be used
for global filtering.  However, those functions are usually called
from some [[command]], and it would also be useful to give ''end users'',
not just programmers, some way to globally filter candidates.

For example, if you have a command, such as `icicle-buffer', that
reads a [[buffer]] name and displays the buffer, some users might
always be interested only in buffers that are associated with
files.  They do not want to see possible candidates such as
`*scratch*' and `*Messages*'.  What they need is a way to apply a
global predicate that limits candidates to file-buffer names -- but
they do not have access to the call to `completing-read' that is
inside the command definition.

For this reason, some global filtering [[variable]]s are provided by '''Icicles''':

  `icicle-must-match-regexp', `icicle-must-not-match-regexp',
  `icicle-must-pass-predicate', `icicle-must-pass-after-match-predicate',
  `icicle-extra-candidates'.

The first and second of these are ''[[regexp]]s'' that candidates ''must
match'' and ''must not match'', respectively, in order for them to be
displayed.  The third and fourth are ''predicates'' that candidates must satisfy.
The fifth is a list of ''extra candidates'' to display.  Any of the
filters can be `nil', in which case it has no effect.

Each of these except `icicle-extra-candidates' filters not only completion candidates but also the default values passed to `completing-read' and `read-file-name'.

Variable `icicle-must-match-regexp' is similar to the standard variable
`completion-regexp-list', except:

* `completion-regexp-list' is a list of regexps, not just one.
* `icicle-must-match-regexp' is used after filtering using [[option]] '''`<tt>[[Icicles - Customization and General Tips#icicle-transform-function|icicle-transform-function]]</tt>''''.

Variables `icicle-must-pass-predicate' and
`icicle-must-pass-after-match-predicate' act the same: they filter
display candidates.  The former filters before the current user
input is matched.  The latter filters after matching -- it is
applied only to candidates that match.

Neither is like the
##PREDICATE## argument to `completing-read' in that they do not act on
full candidates (e.g. alist entries) -- they apply only to display
candidates (strings).

For apropos completion, the `completing-read' ##PREDICATE## is applied
to all ##COLLECTION## entries before matching those entries that
satisfy it against the user input.  If the ##PREDICATE## argument uses
only the candidate name (it does not make any use of the full
candidate) then it can sometimes be more efficient to pass `nil' as
the ##PREDICATE## and use `icicle-must-pass-after-match-predicate'
instead.

Here is something to keep in mind about
`icicle-must-pass-after-match-predicate':

It is often a good idea to use this predicate rather than pass a
##PREDICATE## argument to `completing-read' or `read-file-name',
especially when the initial domain of candidates is large and the
predicate is complex (costly).  It makes little sense to test each
such candidate using the predicate, rather than test only those
that match the current minibuffer input.

However, sometimes the ##PREDICATE## argument to `completing-read' or
`read-file-name', is also used for something else, and in such a
context you will need to provide it.  In particular, IcompleteMode
uses it to compute the completions it displays.

For this reason, the '''Icicles''' predefined functions that use
`icicle-must-pass-after-match-predicate' also test for
`icomplete-mode'. When that is turned on they use a
##PREDICATE## argument instead of
`icicle-must-pass-after-match-predicate'.  You might want to do
the same in your code.  Just look at the '''Icicles''' code for 
examples.

[:icicle-execute-extended-command]
An example of this is `M-x', which by default in ''Icicle'' mode is
`icicle-execute-extended-command'.  If IcompleteMode is turned on
then the predicate `commandp' first filters all of the available
[[symbol]]s, before you type any input to be matched.  If Icomplete mode is off, then this predicate is used as
`icicle-must-pass-after-match-predicate':

  (lambda (c)
    (unless (symbolp c) (setq c  (intern-soft c)))
    (commandp c))

That does about the same thing as `commandp', but its argument is
a completion candidate as displayed, that is, a string, not a symbol in the `[[obarray]]'.  See
[[Icicles - Expanded-Common-Match Completion]].

And here's a gotcha to keep in mind if you use either
'''`icicle-must-pass-predicate'''' or
'''`icicle-must-pass-after-match-predicate'''' with (non-absolute)
file-name candidates: Since the candidate file names have no
directory part, in many cases you will want to test the candidate
expanded relative to the directory shown in the minibuffer.  One
way to do this is as follows:

    (setq file  (expand-file-name file
                 (icicle-file-name-directory-w-default
                   (icicle-input-from-minibuffer))))

This gotcha is nothing new -- the same applies for standard Emacs function
`read-file-name', but it is still worth pointing out.

Variable `icicle-extra-candidates' is not really a "filter".  It
does not ''restrict'' the set of possible candidates -- rather, it
''extends'' that set.  The other filters do not act on the candidates
in `icicle-extra-candidates' -- they are always added.   Extra
candidates are displayed in buffer `*Completions*' using face
`<tt>[[#icicle-extra-candidate]]</tt>'.

Note that an extra candidate need not have anything in common with
the normal (non-extra) candidates.  In particular, because it is
provided explicitly, it does not follow the restrictions implied
by the current candidate-generation method.  

In this, extra candidates are similar to [[proxy candidate]]s.
For example, when
option '''`<tt>[[Icicles - Customization and General Tips#icicle-guess-cmds-in-path-flag|icicle-guess-cmds-in-path-flag]]</tt>'''' is non-`nil', the proxy
shell-command candidates provided have no connection with the
file-name completion that is used to generate the other candidates
(see [[Icicles - Shell-Command Enhancements]]).


Note too that if an extra candidate is already a candidate anyway then it will be present twice in the list of all candidates (that is,
unless `icicle-transform-function' removes duplicate candidates).

These global variables are ''internal'' variables, even though they
are defined as user options -- they are not really meant
to be customized.  If you are not an Emacs-Lisp programmer, you
will ''not'' use these variables, but some commands that you use might
provide corresponding global-filter ''user options''.  '''Icicles'''
provides customizable user options for '''Icicles''' buffer commands, such as `icicle-buffer'.  For example:

[:icicle-buffer-match-regexp]
[:icicle-buffer-no-match-regexp]
[:icicle-buffer-predicate]
[:icicle-buffer-extras]
*  '''`<tt>[[Icicles - Customization and General Tips#icicle-buffer-match-regexp|icicle-buffer-match-regexp]]</tt>''''    -- Regexp that buffer names must match
*  '''`<tt>[[Icicles - Customization and General Tips#icicle-buffer-no-match-regexp|icicle-buffer-no-match-regexp]]</tt>'''' -- Regexp buffer names must ''not'' match
*  '''`<tt>[[Icicles - Customization and General Tips#icicle-buffer-predicate|icicle-buffer-predicate]]</tt>''''       -- Predicate buffers must satisfy
*  '''`<tt>[[Icicles - Customization and General Tips#icicle-buffer-extras|icicle-buffer-extras]]</tt>''''          -- Extra buffer names to display

You might, for instance, customize `icicle-buffer-no-match-regexp'
to not display file-buffers whose names end in `<code>.elc</code>', and
customize `icicle-buffer-predicate' to show only buffers that are
associated with files.  The former would use a value of <code>"\\.elc$"</code>,
and the latter would use a value such as this:

   (lambda (bufname) (buffer-file-name (get-buffer bufname)))

Similarly, '''Icicles''' provides user options for filtering and sorting
file names during completion:

[:icicle-file-match-regexp]
[:icicle-file-no-match-regexp]
[:icicle-file-predicate]
[:icicle-file-extras]
*  '''`<tt>[[Icicles - Customization and General Tips#icicle-file-match-regexp|icicle-file-match-regexp]]</tt>''' -- Regexp file names must match
*  '''`<tt>[[Icicles - Customization and General Tips#icicle-file-no-match-regexp|icicle-file-no-match-regexp]]</tt>''' -- Regexp file names must not match
*  '''`<tt>[[Icicles - Customization and General Tips#icicle-file-predicate|icicle-file-predicate]]</tt>''' -- Predicate files must satisfy
*  '''`<tt>[[Icicles - Customization and General Tips#icicle-file-extras|icicle-file-extras]]</tt>''' -- Extra file names to display

Note that `icicle-buffer-predicate' and `icicle-file-predicate'
correspond to `icicle-must-pass-after-match-predicate', not to
`icicle-must-pass-predicate'.  They are applied after your current
input filters the candidates.

If you as a programmer write a command, and you want to expose
global filters to users of the command, you should:

'''1.''' Create corresponding user options that can be customized.

'''2.''' Bind the user options to the corresponding filtering variables.

If you use `icicle-define-command' or `icicle-define-file-command'
to define a command (recommended), then you can simply pass the
filter-variable bindings as part of the `BINDINGS' argument.

For convenience you can use macros '''`icicle-buffer-bindings'''' and
'''`icicle-file-bindings'''' to provide bindings that are appropriate
for buffer-name and file-name completion, respectively.  For
example, macro `icicle-buffer-bindings' expands to include these
bindings, among others:

  (icicle-must-match-regexp                icicle-buffer-match-regexp)
  (icicle-must-not-match-regexp            icicle-buffer-no-match-regexp)
  (icicle-must-pass-after-match-predicate  icicle-buffer-predicate)
  (icicle-require-match-flag               icicle-buffer-require-match-flag)
  (icicle-extra-candidates                 icicle-buffer-extras)
  (icicle-delete-candidate-object          'icicle-kill-a-buffer)


As an example of using this macro, here is the core definition of `icicle-buffer':

 (icicle-define-command
  icicle-buffer                          ; Command name
  "Switch to a different buffer."        ; Doc string
  switch-to-buffer                       ; Action function
  "Switch to buffer: "                   ; `completing-read' args
  (mapcar (lambda (buf) (list (buffer-name buf))) (buffer-list))
  nil nil nil 'buffer-name-history
  (icicle-default-buffer-names current-prefix-arg) nil
  ;; Filter bindings
  (icicle-buffer-bindings))       ; Macro provides buffer bindings

If you define a command that uses completion, but you do not use
`icicle-define-command' or `icicle-define-file-command', then you
can just bind appropriate variables individually around a call to `completing-read' or
`read-file-name'.

Another way that users can apply predicates to completion
candidates is to use `##M-&##' while completing.  These predicates
apply to the full [[alist]]-entry candidates that are supplied to
`completing-read' or `read-file-name', not just to the textual
candidates that are displayed in buffer `*Completions*'.
See [[Icicles - Progressive Completion]].




----


|| *Previous:*  [[Icicles - Multi-Commands the Hard Way]] || '''[[Icicles]]''' || IciclesIndex || *Next:* [[Icicles - Specifying Match Functions for Commands]] ||



DrewsElispLibraries referenced here: Lisp:icicles.el


CategoryCommands 
CategoryBufferSwitching
CategoryCompletion
CategoryRegexp
CategoryProgrammerUtils
CategoryCode




