Icicles - More About Multi-Commands

Previous: Icicles - Dot, Dot, DotIciclesIciclesIndexNext: Icicles - Multi-Inputs

More about Multi-Commands

A multi-command is any command that uses input completion and lets you perform actions on any number of individual completion candidates without exiting completion. See Icicles - Multi-Commands.

The default action is invoked on the current candidate by ‘C-RET’ (‘icicle-candidate-action’). There are three other kinds of actions on individual candidates:

A given command can define any combination of these four kinds of actions: none of them, any one of them, any two of them, any three of them, or all four kinds.

This page provides information about alternative actions and deletion actions. See also:

Alternative Actions

Just as you can use ‘C-RET’, ‘C-mouse-2’, ‘C-next’, and so on to invoke a command’s default action on multiple completion candidates individually, so you can use ‘C-S-RET’ (‘icicle-candidate-alt-action’), ‘C-S-mouse-2’, ‘C-S-next’, and so on to invoke an alternative action that is associated with the command. If the main action of a command ‘my-find-file’ is to visit a file, and the alternative action is to print a file, then you can use ‘C-S-RET’ to print one or more files on the fly, even as you are completing the name of a file to be visited.

Keys `C-|’ and `M-|’ apply the alternative action defined for a given multi-command to all matching candidates at once. (In the same way, `C-!’ and `M-!’ apply the main action defined for it to all candidates. — see Icicles - Choose All Candidates.)

For example, in Icicles search (e.g. `C-c `’), the alternative action (e.g. ‘C-S-RET’) replaces all or part of the current search hit, and `M-|’ does the same for all search hits.

It is the particular command that defines its alternative action. Some commands define no such action. Some commands, as their alternative action, prompt you to choose (using completion) a function to be applied to the current completion candidate. In this case, a single alternative action effectively provides a set of possible actions.

To achieve this, such commands use the value of user option `icicle-type-actions-alist’, which associates lists of possible functions with specific candidate types. For example, for file-name candidates, you can choose among functions that act on file names.

Choosing such a function to apply is itself a multi-command operation. You can thus apply any number of functions to any number of candidates.

For example, while you are using ‘C-x C-f’, you can, say, print one or more candidate files on the fly, or invoke a shell command on selected files, or byte-compile them… This is a particularly handy feature, especially if you customize ‘icicle-type-actions-alist’ for your own particular use.

Some such functions you can choose produce no side effect; they simply return a value. But if you use ‘C-u’ before ‘C-S-RET’, then the result of applying the function is pretty-printed (in the echo area or buffer ‘*Pp Eval Output*’). For example, if you use ‘C-x C-f’, you hit ‘C-u C-S-RET’ on the candidate file name `icicles-doc1.el’, and you choose the function candidate ‘file-attributes’ at the completion prompt `How (action): ’, then the properties of the candidate file (`icicles-doc1.el’) are displayed. With just ‘C-S-RET’ (no prefix argument), the list of properties is computed, but not displayed.

Be aware of this gotcha: The alternative action for commands that use ‘icicle-type-actions-alist’ prompts for a function. If you want to apply that function to all current completion candidates, then you must use `M-|’, not `C-|’, because `C-|’ prompts you for each candidate. `M-|’ is designed to do the right thing here: it prompts you once for the function to apply, and then applies it to each of the current candidates. And you can filter the set of current candidates (progressive completion and so on), or retrieve a saved set of candidates to operate on.

Note that completion while you choose a function to apply is lax. This means that you can really enter any function, including a lambda expression that you invent on the fly. Of course, the function must accept an object of the appropriate type, (but it need not actually use that argument).

Using a lambda expression here is a good way to curry a function that requires multiple arguments, so that it adapts to expect just a single argument of the appropriate object type. For example, (lambda (sym-name) (get (intern sym-name) 'invisible)) transforms function ‘get’, which takes a symbol and a property as arguments, to a function that takes a symbol name and looks up the ‘invisible’ property of the symbol.

Option ‘icicle-type-actions-alist’ is predefined with a number of candidate types (buffer, color, command, face, file, frame, function, option, process, variable, and window) and their associated action functions, but you can add new types or modify their associated function lists. Any EmacsLisp functions can be used, including lambda expressions. But each function must accept a value of the appropriate type as its sole required argument (additional, optional arguments are OK).

Sometimes, you might want to define your own alternative action function for some command. Do this if you always want the same alternative action, and it is not the predefined one. To do this, just customize option `icicle-alternative-actions-alist’. The associations defined by this option always override any predefined alternative actions for the corresponding commands.

An alternative to using option ‘icicle-alternative-actions-alist’ is to define a new command, wrapping an existing command with a ‘let’ binding that defines the action you want. I recommend using the option instead, but you might sometimes prefer this approach. For example:

  (defun my-icicle-find-file (f)
    "`icicle-find-file', but with `w32-browser' as the alt action."
      (let ((icicle-candidate-alt-action-fn  'w32-browser))
        (list (read-file-name "File: "))))
    (icicle-find-file f))

If you are familiar with Icicles object-action commands (see Icicles - Object-Action Interaction), then this idea of choosing an object (completion candidate) and then choosing a function to act on it will ring a bell. And just as for the object-action commands, here too Icicles exploits any object-action associations (“sources” and “types”) defined by library Anything (anything.el), if you happen to use that, in addition to the associations defined by ‘icicle-type-actions-alist’. And when you do use the Icicles object-action commands, the same behavior is available as for alternative actions.

You might have noticed, above, that a type/actions association is predefined for type ‘function’. Since the actions you can choose are themselves functions, you can even use ‘C-S-RET’ on one of them, to apply a function-for-functions (e.g. ‘find-function’ or ‘symbol-function’) to it. This is a curiosity, but it can sometimes be useful.

Finally, note that the completion candidate to which you apply an alternative action is in most cases a string. In some cases, the alternative action functions expect a non-string object, and they will raise an error if applied to a string. Icicles takes care of this in the case of buffer-name candidates. It assumes that you really want to operate on a buffer, not its name (a string), so it automatically calls ‘get-buffer’ before applying the alternative action function.

See Also:

Deleting Objects

When it is defined for a particular command, minibuffer command ‘icicle-delete-candidate-object’, bound to ‘S-delete’ (that’s the ‘delete’ key, Shifted) deletes the object or objects named by the completion candidate on which it operates. (At least that is the default behavior – if you customize ‘icicle-deletion-action-flag’ to nil, then ‘S-delete’ has no effect.)

Which objects are thus targeted by a given candidate (name) is something that must be defined by the particular command. The doc string of a command should always indicate the effect of using ‘S-delete’, if a deletion action is defined.

As an example of a deletion action, Icicles command ‘icicle-buffer-other-window’, bound to ‘C-x 4 b’, opens buffers named by the individual candidates you act on, using ‘C-RET’. But it also lets you kill any buffer that you act on, using ‘S-delete’. This is not the alternative action for the command (which is bound to ‘C-S-RET’); it is the deletion action. Similarly, command ‘icicle-bookmark’ jumps to a bookmark, but you can also use ‘S-delete’ with it to delete individual bookmarks.

When you use ‘S-delete’ with a command that allow duplicate candidate names that represent different candidate objects, it deletes only the object associated with the current candidate (name).

Some multi-commands define a deletion action, so that ‘S-delete’ works; some do not. Consult the doc for any given command to see if it does. Whenever it is defined, the meaning of “delete” depends on the particular command you use.

‘S-delete’ deletes only the objects named by the current completion candidate. However, with a prefix argument, it deletes ALL objects named by the current set of completion candidates, after you confirm that this is really what you want to do. This is a quick way to delete things whenever ‘S-delete’ is available: Use input patterns, with progressive completion, chipping away , and so on, to define the candidates to delete, then use ‘C-u S-delete’ and confirm their deletion. Bye-bye.

Do not confuse the unshifted ‘delete’ key with ‘S-delete’. ‘delete’ does not delete any objects; it just removes a completion candidate so that you cannot complete to it. ‘S-delete’ deletes an object and removes its name as a completion candidate.

If you are an EmacsLisp programmer, then you can define your own multi-commands that provide a deletion action via ‘S-delete’. There are two ways to do this. Both involve binding ‘icicle-delete-candidate-object’:

For more information about using this feature in EmacsLisp code, see the doc of function ‘icicle-delete-current-candidate-object’ (‘S-delete’) and variable ‘icicle-delete-candidate-object’.

Option `icicle-use-C-for-actions-flag'

In some contexts, you end up using ‘C-next’ more than ‘next’, and likewise for the other keys that combine candidate action and cycling. This is especially true for Icicles multi-commands that act like a browser, such as ‘icicle-search’, ‘icicle-imenu’, ‘icicle-find-tag’, ‘icicle-Info-goto-node’, and ‘icicle-compilation-search’. In these cases, you use the action keys to navigate among the locations indicated by the completion candidates.

If you set user option `icicle-use-C-for-actions-flag’ to ‘nil’, then the keys that cycle are swapped with the keys that both cycle and act on a candidate. You can then use ‘down’, ‘up’, ‘next’, ‘prior’, ‘end’, and ‘home’ to both cycle and act (e.g. navigate), and ‘C-down’, ‘C-up’, ‘C-next’, ‘C-prior’ ‘C-end’, and ‘C-home’ to merely cycle, without acting. The option has no effect on other keys.

You can toggle ‘icicle-use-C-for-actions-flag’ at any time using ‘M-g’ (‘icicle-toggle-C-for-actions’) in the minibuffer.

Accessing Saved Locations (Bookmarks) on the Fly

When you complete the names of some kinds of objects, you can use ‘C-x m’ to follow bookmarks to objects of that type. This is available only if you use library Bookmark+ (bookmark+.el).

For example, when you invoke a command that completes file names, you can use ‘C-x m’ to interrupt that operation and complete against the names of file bookmarks. This is a multi-command, so you can actually visit any number of file bookmarks. When finished, you can continue with non-bookmark file-name completion.

The same thing holds for Info bookmarks when you use ‘icicle-Info-goto-node’ (‘g’ in Info mode); for buffer (non-file) bookmarks when you use ‘icicle-buffer’ (‘C-x b’); and for Dired bookmarks when you use ‘icicle-dired’ (‘C-x d’).

See Also: Icicles - Bookmark Enhancements

Previous: Icicles - Dot, Dot, DotIciclesIciclesIndexNext: Icicles - Multi-Inputs

DrewsElispLibraries referenced here: Lisp:doremi.el, Lisp:doremi-cmd.el, Lisp:doremi-frm.el, Lisp:icicles.el

CategoryMenus CategoryCommands CategoryBufferSwitching CategoryCompletion CategoryDocumentation CategoryHelp CategoryProgrammerUtils CategoryCode