Sets of Completion Candidates

Whereas ‘C-RET’ (see Icicles - Multi-Commands) acts on individual objects, `C-!’ acts on an entire set of objects at once, via their names: the set of all current completion candidates. There are additional Iciclescommands that also act, not on individual completion candidates, but on one or more sets of completion candidates.

One of these is ‘M-*’ or ‘S-SPC’, which effectively narrows the set of completion candidates by taking the intersection of the candidate sets defined by various input regexps.

This page presents some more Icicles commands that act on sets of completion candidates. The basic idea is that you can perform set operations using the current set of completion candidates, changing it into a different set. You can, then, for example, use `C-!’ to act on everything in a custom-defined set. Or you can define a custom set that you want to use often (for example, a list of project files), save it persistently, and then retrieve it later to use for completion.

Another way of acting on a set of candidates is to insert them into the minibuffer and then use ‘M-R’ – see Icicles - Multi-Inputs.

Saving and Retrieving Completion Candidates

Set operations such as union and difference act on two sets. The current set of completion candidates is always one of these sets. If an operation, such as set complement, acts on a single set, then it acts on the current set.

When two sets are involved, the other set is called the “saved set”. This just means that at some previous time in your sesssion you saved some completion candidates as the value of variable‘icicle-saved-completion-candidates’.

In buffer‘*Completions*’, candidates that have been saved are highlighted using face‘icicle-saved-candidate’. Here is a screenshot showing this:

By default, the saved set is not persistent; it is saved only until the next save in the same Emacs session overwrites it or adds to it. See Icicles - Persistent Completions for ways to save candidates persistently.

In addition to persistently saving a candidate set in a file, if you also use library Bookmark+ then you can save a set of Icicles search candidates as a bookmark. You “jump” to the bookmark to restore those search results during another Icicles search.

One way you can save candidates is to use ‘icicle-candidate-set-save’, bound to `C-M->’. This saves all of the current candidates.

Gotcha:

If you use progressive completion and you have not yet typed anything after ‘M-*’ or ‘S-SPC’, then there is not yet a set of candidates to save. If you use `C-M->’ at that point, you will reset the saved candidates to none. To define the current candidates, either type something or use ‘S-TAB’.

Another way to save candidates, besides `C-M->’, is to select candidates in buffer ‘*Completions*’ using the (active) region, and then use ‘icicle-candidate-set-save-selected’, bound to `C-M-)’. This saves any candidates that are at least partially in the region.

Command ‘icicle-mouse-candidate-set-save’, bound to ‘M-S-mouse-3’ in ‘*Completions*’ combines these two: if the region is active, then the selected candidates become the saved set; otherwise, all candidates are saved. This binding makes it easy to save candidates using the mouse: select them (e.g. drag or double-click ‘mouse-1’, or click ‘mouse-1’ then ‘mouse-3’), then use ‘M-S-mouse-3’ to save. *

You can also use `C-M-)’ to unsave all candidates: just select no candidates before you hit `C-M-)’, to reset the set of saved completions to none. Think of this as replacing the saved set with the empty set (no candidates). And you need not use ‘TAB’ or ‘S-TAB’ first to use this, since the current set of candidates is not used in any way when you reset the saved set.

You can process the list of saved candidates in any way you like using Emacs Lisp. For example, you can save a list of file names that match a regexp, then print the list or process the individual files in some way. Here, for instance, is how to save the set of file names that contain either ‘dir’ or ‘ici’:

C-x C-f \(dir\|ici\) S-TAB C-M-> C-g

You can retrieve a set of saved candidates with command ‘icicle-candidate-set-retrieve’, bound to `C-M-<’. This replaces the current set of candidates with those retrieved. It also acts like ‘M-*’ by entering a recursive minibuffer, which removes any saved-candidates highlighting. Using ‘TAB’ or ‘S-TAB’ restores the highlighting.

What if you have defined the saved set and you later decide to narrow it by excluding some of its members? First, if the saved candidates are not current then use `C-M-<’ to make them so. Then use progressive completion to narrow the current candidates. Then use `C-M->’ to define (only) them as the saved candidates. For example, if you hit `C-M->’ after narrowing to the files matching prefix ‘ici’, you can narrow that saved set to only those files that also match ‘m’, by using `S-SPC m C-M->’.

Saving or Retrieving Additional Candidates

You can use `C-<’ to retrieve a set of saved candidates and add them to the current candidates, instead of replacing those candidates. This way, you can build up the current set of candidates by retrieving (combining) several saved sets.

In the other direction, you can save additional candidates, adding them to a set of candidates already saved, in these ways:

`C->’ (‘icicle-candidate-set-save-more’) adds all of the current candidates.

`C-)’ (‘icicle-candidate-set-save-more-selected’) adds any candidates that you have selected using the region in ‘*Completions*’.

‘M-mouse-3’ (‘icicle-mouse-candidate-set-save-more’) acts the same as `C-)’ or `C->’, depending on whether or not the region is active in ‘*Completions*’: it adds selected or all candidates.

Extending the region with ‘mouse-3’, and then clicking ‘mouse-3’ again in the same place, acts the same as `C-)’. That is, click ‘mouse-1’, then click ‘mouse-3’ twice in another location, to save all candidates between the ‘mouse-1’ and ‘mouse-3’ positions. *

The ‘insert’key (‘icicle-save/unsave-candidate’) adds just the current completion candidate (e.g. during cycling). Clicking a candidate in buffer ‘*Completions*’ with ‘M-S-mouse-2’ (‘icicle-mouse-save/unsave-candidate’) does the same thing. If you do this to a candidate that has already been saved, then it is unsaved (no longer saved).

Note that the ‘insert’ key and ‘M-S-mouse-2’ are toggles for a given candidate, saving or unsaving it. In this sense each is its own opposite. In another sense, the opposite operation of saving is simply removing a candidate from the current set of candidates. You do that using the ‘delete’ key or ‘S-mouse-2’.

Another way to add to the list of saved candidates is to use ‘M-S’ (‘icicle-multi-inputs-save’). This is available for any minibuffer input, not just during completion. It adds all of the multi-inputs currently in in the minibuffer to the set of saved candidates. So you can, for instance, use ‘M-S’ on a minibuffer containing the following input, to add its three file names to the current saved set of candidates in variable ‘icicle-saved-completion-candidates’.

icicles-mac.el "my file.txt" bookmark+.el

Matching, saving, and retrieving candidates is a powerful way to interact with completion. One important use is to prepare a list of candidates on which to act, and then act on them all at once using `C-!’. This is a good way to proceed when you want to double-check what to act on, before you actually act. This is the same idea behind marking files in Dired and then operating on the marked files, using ‘x’. It corresponds to what is represented in some user interfaces by filling out a checklist followed by clicking ‘OK’.

[* If you click ‘mouse-1’ on a candidate and (starting with Emacs 22) ‘mouse-1-click-follows-link’ is an integer, then you will need to hold the mouse button depressed longer than that many seconds, or else that candidate will simply by chosen. If the value is ‘t’, then this will not work at all. Any other value presents no problem. (Personally, I use ‘nil’.)]

Different Places for Saving and Retrieving Candidates

You can save completion candidates to a different variable from ‘icicle-saved-completion-candidates’ by using a numeric prefix argument to command ‘icicle-candidate-set-save’; that is, use `C-u N C-M->’where N is an integer. Alternatively, use `C-M-}’, which is bound to command ‘icicle-candidate-set-save-to-variable’.

You are prompted for the name of the variable, and you can use completion when inputting it. During this completion, the only available candidates are variables that you have used for saved candidates (but completion is lax, so you can type a new variable name). The same behavior works also for `C->’, `C-M-)’, and `C-)’.

To retrieve completion candidates that were previously saved to a variable other than ‘icicle-saved-completion-candidates’, so that they become the current set of candidates, use `C-u N C-M-<’, where N is an integer, or `C-M-{’ (‘icicle-candidate-set-retrieve’ or ‘icicle-candidate-set-retrieve-from-variable’).

When you save candidates to a different variable from ‘icicle-saved-completion-candidates’, they are not shown in buffer ‘*Completions*’ using face ‘icicle-saved-candidate’. When you save candidates to a cache file, they are also saved to ‘icicle-saved-completion-candidates’, so they are shown in ‘*Completions*’ using face ‘icicle-saved-candidate’.

`C->’ and `C-<’ accept the same prefix arguments as `C-M->’ and `C-M-<’ , letting you specify the source or destination (variable, cache file) when you save or retrieve additional candidates.

Note: Use the right type of saved candidates (persistent or not) for a given command. It is the particular command that determines whether or not a given type of saved candidate is appropriate. For example, you can save search hits when you use ‘icicle-search-file’ (same as ‘icicle-search’ with a negative prefix argument), and those saved search-hit candidates effectively reference files and positions in those files. And you can later retrieve and reuse such saved candidates to visit the search positions. But those candidates are not merely file names, so they cannot be used with a command such as as ‘find-file’ or ‘icicle-file’ that expects a file name. Conversely, you cannot use a saved set of file names with a command such as ‘icicle-search-file’ that expects ‘icicle-search’ candidates.

Saving Marked Files and Dirs in Dired

Besides saving file and directory names that are completion candidates on the fly, You can create or add to a saved set of names using the names that are marked in Dired. The same keys (e.g., `C-M->’) that save candidates in the minibuffer during completion save the marked names in Dired.

If you use library Dired+ then you can also use the same keys, but with the prefix key `M-+’ (e.g. `M-+ C-M->’) to save not only the names that are marked in the current Dired buffer but also those that are marked in any marked subdirectories, recursively. See Save Marked Names Here and Below.

Set Operations

The other available set-operation commands for use with completion candidates, besides saving and retrieving, are these:

‘icicle-candidate-set-save’, bound to `C-M->’. Save the current set of completion candidates, for use in a subsequent set operation (see below). The saved set is not persistent; it is saved only until the next `C-M->’ in the same Emacs session.

‘icicle-candidate-set-retrieve’, bound to `C-M-<’. Retrieve the saved set of completion candidates, making it the current set.

‘icicle-candidate-set-swap’, bound to `C-%’. Swap the saved and current sets of completion candidates.

‘icicle-candidate-set-define’, bound to `C-:’. Define the current set of completion candidates by evaluating an input sexp. The sexp must evaluate to a list of strings, such as is returned by ‘all-completions’. You can use this to substitute any list of strings, and then operate on them as completions, using any Icicles functionalities. Keep in mind, however, that the completions must be of the proper type for the context in which they are used. For example, if you are executing a command, they must be command names.

‘icicle-candidate-set-complement’, bound to `C-~’. Complement the current set of candidates: replace the current candidate set with its set complement. This means all possible completions of the appropriate type that do not match the current input. You can combine this with progressive completion (‘M-*’ or ‘S-SPC’) to progressively eliminate candidates that match different inputs. This process-of-elimination matching is a common Icicles usage idiom.

‘icicle-candidate-set-union’, bound to `C-+’. Replace the current candidate set by its union with the saved set of candidates.

‘icicle-candidate-set-difference’, bound to ‘C--’. Replace the current candidate set by its set difference with the saved set of candidates. That is, the saved candidates are subtracted from the current candidates, and the result becomes the current candidate set. To obtain the opposite set difference, subtracting the current candidates from the saved candidates, just use ‘icicle-candidate-set-swap’ followed by ‘icicle-candidate-set-difference’.

‘icicle-candidate-set-intersection’, bound to ‘C-*’. Replace the current candidate set by its intersection with the saved set of candidates. Unlike the set intersection provided by ‘M-*’ (or ‘S-SPC’), ‘C-*’ is, in itself, a one-time operation. ‘M-*’ (or ‘S-SPC’) can be repeated, using the previous intersection as one of the sets to be intersected in a new operation. Both ‘C-*’ and ‘M-*’ use the current set of matching candidates as one of the sets being intersected. But ‘M-*’ reads another input regexp to define the other set to be intersected, whereas ‘C-*’ uses the saved candidates set as the other set. ‘M-*’ (or ‘S-SPC’) is useful for chaining, to achieve progressive approximation. ‘C-*’ is useful to perform an intersection on a set from a previous input reading.

You can operate on or choose from all input values in the set that results from any of these set operations. For example, you can use `C-~’ to see the list of objects that do not match the current input, to cycle among those objects, or to operate on any or all of them. Use `C-~’ at any time to switch to the complement of the current set of candidates.

Example: To cycle through all files whose names do not end in ‘el’, you can do the following:

1. Use ‘C-f’ to read a file name.

2. Type `el$’ to match all file names that end in ‘el’.

3. Use ‘S-TAB’ to show the matching files.

4. Use `C-~’ to flip to the complement: files not ending in ‘el’.

5. Use ‘next’ or ‘prior’ to cycle among the new set of candidates.

A minibuffer message briefly confirms each of the set operations.

When buffer ‘*Completions*’ is displayed, the union, difference, and intersection commands scroll the buffer when repeated. Repeating ‘icicle-candidate-set-complement’ complements the complement, of course, giving the original set.

Once you have established a set of completion candidates using any of the candidate-set commands, you can cycle among the candidates of that set using either prefix or apropos cycling (‘down’, ‘up’, ‘next’, ‘prior’, ‘end’, or ‘home’). However, switching from prefix to apropos cycling (or completion), or vice versa, establishes a new completion set of the appropriate type, as usual. Switching completion type signifies that you are finished with the specially defined completion set, and you want to redefine it using apropos or prefix cycling or completion.

Note: You might have noticed that, as a mnemonic device, the keys bound to the various set operations use the corresponding binary arithmetic or Boolean operators: `~’ (unary negation) for complement (not); ‘*’ (multiplication) for intersection (and); `+’ (addition) for union (or); and ‘-’ (subtraction) for difference. Note too that the ‘C--’ and `C-+’ bindings mean that you cannot use these key sequences for prefix arguments – you must use ‘C-u ’’N ‘, or ‘M-’’N ‘ instead, where N is a possibly signed integer.

Recompleting Using the Original Domain

Sometimes you want to perform an operation using a saved set of candidates, and then you want to do something using the original set of candidates provided by the command’s completion domain. For example, you might want to perform an action on selected files from a saved candidate set, and then act on files that are not necessarily in that set.

That is what ‘C-x C-0’ (‘icicle-recomplete-from-original-domain’) does: during completion, it forgets about the current set of candidates and completes your input from scratch, using the original domain of candidates.

This means that you can also use it after progressive completion, to pop up to the shallowest minibuffer level (1) and start over, completing your current input from scratch.

This work is licensed to you under version 2 of the
GNUGeneral Public License.
Alternatively, you may choose to receive this work under any other
license that grants the right to use, copy, modify, and/or distribute
the work, as long as that license imposes the restriction that
derivative works have to grant the same rights and impose the same
restriction. For example, you may choose to receive this work under
the
GNUFree Documentation License, the
CreativeCommonsShareAlike
License, the XEmacs manual license, or
similar licenses.