Icicles - Defining Tripping Commands

iciclesimage
Previous: Icicles - Defining Icicles CommandsIciclesIciclesIndexNext: Icicles - Multiple-Choice Menus

Defining Icicles Tripping Commands

Icicles - Tripping describes the use of Icicles tripping (aka navigation or browsing) multi-commands. This page tells you how to define your own such commands for custom trips – it is thus for EmacsLisp programmers.

The best way to learn how to do this is to look at how the existing tripping commands are defined. Some of them use macro ‘icicle-define-command’; others do not. Some use building-block function ‘icicle-explore’ or ‘icicle-apply’; others do not. Several use ‘icicle-search’ as a building block.

Using `icicle-define-command'

Those that use ‘icicle-define-command’ take advantage of some extraneous way to obtain trip location information from a display candidate, which is just a string. For example, ‘icicle-bookmark’ ultimately uses the display string to look up location information in a bookmarks file. Those that use ‘icicle-explore’ or ‘icicle-apply’ make use of location information stored in the alist COLLECTION argument to ‘completing-read’.

You can also use ‘icicle-define-command’, ‘icicle-explore’, and ‘icicle-apply’ to define multi-commands other than browsing commands – the action function can do anything you like.

Using `icicle-explore'

‘icicle-explore’ is a higher-order function that takes as arguments the following functions, in addition to accepting the optional ‘completing-read’ arguments.

If you also bind ‘icicle-candidate-action-fn’ to a function that takes a display candidate (string) as argument and navigates to the corresponding location, then ‘icicle-explore’ does everything you need for an Icicles trip. You can use function ‘icicle-get-alist-candidate’ to get the location information for a given display candidate.

Note: ‘icicle-explore’ binds user option `icicle-incremental-completion’ `to ‘always’, because I think you typically want to start it out with incremental completion turned on. Functions that call ‘icicle-explore’ thus also turn on incremental completion. This includes the predefined Icicles commands ‘icicle-find-tag’ and ‘icicle-search’, and the many specialized Icicles search commands derived from ‘icicle-search’. Remember that you can use `C-#’ (once or twice) to turn incremental completion off.

Using `icicle-apply'

‘icicle-apply’ binds ‘icicle-candidate-action-fn’ appropriately and calls ‘icicle-explore’. It applies its function argument to completion candidates the user acts on (using ‘C-RET’ etc.). It applies the function to the full alist entry, that is, the display candidate car plus any additional information in the cdr. For a tripping command, the additional information provides a location and the function applied takes you there.

This use of an alist that stores location information in the cdrs is what makes ‘icicle-apply’ and ‘icicle-explore’ particularly suitable for defining navigation multi-commands. The Icicles macros ‘icicle-define-command’ and ‘icicle-define-file-command’ make no such provision, but with suitable arguments you can use them too to define tripping commands.

Note: ‘icicle-apply’ binds user option `icicle-incremental-completion’ `to ‘always’, because I think you typically want to start it out with incremental completion turned on. Functions that call ‘icicle-apply’ thus also turn on incremental completion. This includes the predefined Icicles commands ‘icicle-goto-marker’, ‘icicle-goto-any-marker’, and ‘icicle-goto-global-marker’. Remember that you can use `C-#’ (once or twice) to turn incremental completion off.

See Also: Icicles Commands to Go To a Marker

Using `icicle-search'

‘icicle-search’ is another high-level function for defining tripping commands. Like ‘icicle-apply’, it calls ‘icicle-explore’, but it also provides features for searching bookmarks, buffers, and files. It takes as arguments the search limits (region), if any, and either a regexp or a function that determines the unfiltered search hits. It does everything else needed to define a trip command that uses search hits as completion candidates. Several predefined Icicles tripping commands were defined using ‘icicle-search’.

Note: ‘icicle-search’ effectively binds user option `icicle-incremental-completion’ `to ‘always’, because I think you typically want to start it out with incremental completion turned on. Other Icicles search commands are defined using ‘icicle-search’, so they also effectively turn on incremental completion. Remember that you can use `C-#’ (once or twice) to turn incremental completion off.

Tripping on Foot

You should be able to define any tripping commands you need using ‘icicle-explore’, ‘icicle-apply’, or ‘icicle-search’.

If, however, for some reason you decide to define one at a lower, pedestrian level (that is, without using any of those building blocks), then bind ‘icicle-whole-candidate-as-text-prop-p’ to ‘t’ around the call to ‘completing-read’. You can then use ‘icicle-get-alist-candidate’ to retrieve the candidate cdr (e.g. location) information from the completion result.

However, if the action or alternative action function that you need modifies the existing set of completion candidates on the fly, as a side effect, then bind ‘icicle-whole-candidate-as-text-prop-p’ to ‘nil’ in the action function. Then modify both ‘minibuffer-completion-table’ and ‘icicle-candidates-alist’ as needed to perform the side effect.

Icicles search-and-replace provides an example of this. When you replace text, the original domain of search-hit candidates (with their associated location information) is altered, so that you can continue replacing coherently. (See the code for ‘icicle-search-action’ and ‘icicle-search-highlight-and-maybe-replace’.)

Because such side effects can change the meaning of cycling state information such as the current candidate number, Icicles does not automatically save such state information before a candidate action and then restore it afterward.

For example, search-and-replace removes a search-hit candidate, as a side effect, if the replacement text no longer matches your input. In that case, a current candidate number recorded before the action would no longer correspond to the same candidate.

For this reason, if your action function does not perform any such side effects on the candidates, and you want to restore the cycling state as it was before a candidate action, then you might want your action function to save and then restore the values of Icicles variables such as ‘icicle-candidate-nb’, ‘icicle-last-completion-candidate’, and ‘icicle-completion-candidates’.

See Also:


Previous: Icicles - Defining Icicles CommandsIciclesIciclesIndexNext: Icicles - Multiple-Choice Menus

DrewsElispLibraries referenced here: Lisp:icicles.el

CategoryCommands CategoryBufferSwitching CategoryCompletion CategoryRegexp CategoryDirectories CategoryFiles CategoryProgrammerUtils CategoryCode