Last edit
Alterado:
< nil t nil 'buffer-name-history (icicle-default-buffer-names) nil)
para
> nil t nil 'buffer-name-history
> (icicle-default-buffer-names current-prefix-arg) nil)
| Previous: Icicles - Candidates with Text Properties | Icicles | IciclesIndex | Next: Icicles - Defining Tripping Commands |
This section is for EmacsLisp programmers.
Defining a command that uses Icicles completion and cycling is simple: just call ‘completing-read’ or ‘read-file-name’ to read input, then act on that input.
Nothing could be simpler – just use ‘completing-read’ or ‘read-file-name’! Icicles does the rest. This is the most important thing to learn about defining Icicles commands: you do not need to do anything except call ‘completing-read’ or ‘read-file-name’ as you would normally anyway.
Or at least as I hope you would normally. I fear that many Emacs-Lisp programmers do not take sufficient advantage of ‘completing-read’ when they could, using instead a function such as (quel horreur !) ‘read-string’ to read user input.
If defining an Icicles command is trivial, so is defining an Icicles multi-command. For the same effort it takes to define a command that acts on a single input choice, you can have a command that acts on any number of input choices. A multi-command takes advantage of one or more action functions when cycling candidates, as described in Icicles - Multi-Commands, Icicles - More About Multi-Commands, and Icicles - Choose All Candidates.
In fact, there is no reason not to define your commands as multi-commands – you lose nothing, and you gain a lot. Whenever it is appropriate for a user to possibly want to act on multiple objects, define a multi-command that does that.
An anecdote, to make the point. An Icicles user sent me an email saying how much he appreciated Icicles multi-commands, and asking if I would add a multi-command version of ‘insert-buffer’. I did so, but I replied to him that the definition is trivial: it is identical to the definition of ‘icicle-buffer’, except that the action function is ‘insert-buffer’ instead of ‘switch-to-buffer’.
The point is to not be afraid of defining multi-commands yourself. You do not really need to have me add a multi-command to Icicles in most cases; you can easily define it yourself. Here is a simple definition of ‘icicle-insert-buffer’. You will understand it in detail after reading the next section.
(icicle-define-command icicle-insert-buffer
"Multi-command version of `insert-buffer'." ; Doc string
insert-buffer ; Action function
"Buffer: " ; `completing-read' args
(mapcar #'(lambda (buf) (list (buffer-name buf))) (buffer-list))
nil t nil 'buffer-name-history
(icicle-default-buffer-names current-prefix-arg) nil)Macros ‘icicle-define-command’ and ‘icicle-define-file-command’ make it easy to define a multi-command. Without them, it is sometimes not so easy, depending on the complexity of your action functions. See Icicles - Multi-Commands the Hard Way for a taste of what is involved. If you read that page first, make sure you come back here to see how easy things can be.
Here is how you might define a multi-command to delete one or more files or directories:
1. Define the multi-command, ‘my-delete-file’:
(icicle-define-file-command my-delete-file ; Command name "Delete a file or directory." ; Doc string my-delete-file-or-directory ; Function to perform the action "Delete file or directory: " ; `read-file-name' arguments... default-directory nil t)
2. Define the action function that deletes a single file:
(defun my-delete-file-or-directory (file)
"Delete file (or directory) FILE."
(condition-case i-delete-file
(if (eq t (car (file-attributes file)))
(delete-directory file)
(delete-file file))
(error (message "%s" (error-message-string i-delete-file))
(error "%s" (error-message-string i-delete-file)))))There are two parts to the definition of ‘my-delete-file’:
1. The definition of the command itself, using ‘icicle-define-file-command’.
2. The definition of an action function, ‘my-delete-file-or-directory’, which deletes a single file (or directory), given its name.
It is #1 that is of interest here, because that is essentially what you do to define any multi-command.
The details of #2 are less interesting, even if more complex in this case: ‘my-delete-file-or-directory’ checks whether its argument is a file or directory, and then tries to delete it. If an error occurs, it prints the error message and then returns the message, so that the calling command can report on all deletion errors.
In #1, the arguments to ‘icicle-define-file-command’ are straightforward:
‘my-delete-file’.‘my-delete-file-or-directory’.‘read-file-name’ to read a single file name.These are the same things you would need if you were defining a simple command to delete a single file or directory. The only differences here are that you:
‘icicle-define-file-command’ instead of ‘defun’ with an ‘interactive’ spec.‘my-delete-file-or-directory’) that acts on a single object (here, a file).When you use ‘icicle-define-file-command’, the action function is called on the result of ‘read-file-name’, and it is also bound to ‘icicle-candidate-action-fn’, so that it will be applied to the current candidate via ‘C-RET’ or ‘C-mouse-2’.
Command ‘icicle-all-candidates-action’ (`C-!' – see Icicles - Choose All Candidates) can report in buffer ‘*Help*’ on the objects that it did not act upon successfully. For this reporting to work, the function bound to ‘icicle-candidate-action-fn’ (e.g. ‘my-delete-file-or-directory’, above) should return ‘nil’ for “success” and non-‘nil’ (for example, an error message) for “failure”, whatever “success” and “failure” might mean in the particular context of use. This is not a requirement, except if you want to take advantage of such reporting. For a command that deletes files, it is important to let the user know which deletions failed when s?he tries to delete all matching candidates at once.
If the command you want to define acts on objects other than files, then use ‘icicle-define-command’ instead of ‘icicle-define-file-command’ – the only difference is that you then supply the arguments for ‘completing-read’ instead of those for ‘read-file-name’.
To let users know that a command is a multi-command, and how to use it as such, ‘icicle-define-command’ and ‘icicle-define-file-command’ automatically add this explanation to the doc string you provide for the multi-command:
Read input, then call `<your action function name>' to act on it.
Input-candidate completion and cycling are available. While cycling, these keys with prefix `C-' are active:
`C-mouse-2, `C-RET' - Act on current completion candidate only `C-down', `C-wheel-down' - Move to next completion candidate and act `C-up', `C-wheel-up' - Move to previous completion candidate and act `C-next' - Move to next apropos-completion candidate and act `C-prior' - Move to previous apropos-completion candidate and act `C-end' - Move to next prefix-completion candidate and act `C-home' - Move to previous prefix-completion candidate and act `C-!' - Act on *all* candidates, successively (careful!)
When candidate action and cycling are combined (e.g. `C-next'), user option `icicle-act-before-cycle-flag' determines which occurs first.
With prefix `C-M-' instead of `C-', the same keys (`C-M-mouse-2', `C-M-RET', `C-M-down', and so on) provide help about candidates.
Use `mouse-2', `RET' or `S-RET' to finally choose a candidate, or `C-g' to quit.
This is an Icicles command - see `icicle-mode'.
Notice that the doc string of your new multi-command references your action function (e.g. ‘my-delete-file-or-directory’). The doc string you provide for the multi-command can thus be a little more abstract, leaving any detailed explanation of the action to the doc string of your action function.
To provide more flexibility, ‘icicle-define-command’ and ‘icicle-define-file-command’ provide some predefined key bindings and allow for additional arguments.
Here is a definition of a multi-command, ‘change-font’, that reads a font name and changes the selected frame to use that font.
1 (icicle-define-command 2 change-font "Change font of current frame." 3 (lambda (font) 4 (modify-frame-parameters orig-frame 5 (list (cons 'font font)))) 6 "Font: " (mapcar #'list (x-list-fonts "*")) 7 nil t nil nil nil nil 8 ((orig-frame (selected-frame)) 9 (orig-font (frame-parameter nil 'font))) 10 nil 11 (modify-frame-parameters orig-frame 12 (list (cons 'font orig-font))) 13 nil)
The arguments to ‘icicle-define-command’ here are as follows:
‘completing-read’ (lines 6-7)The following bindings are predefined – you can refer to them in the command body:
‘icicle-orig-buff’ is bound to (current-buffer)‘icicle-orig-window’ is bound to (selected-window)Before running any “undo” code that you supply, the original buffer is restored, in case of error or user quit (‘C-g’).
Most of the arguments to ‘icicle-define-command’ are optional. In this case, optional arguments were provided to save (lines 8-9) and then restore (lines 11-12) the original font and frame.
Several top-level Icicles commands have been defined using ‘icicle-define-command’ and ‘icicle-define-file-command’. You can use their definitions as models for your own multi-commands.
‘clear-option’ (alias) – Set value of a binary option to ‘nil’‘icicle-add-buffer-candidate’ – Add buffer to those always shown for completion‘icicle-add-buffer-config’ – Add config to ‘icicle-buffer-configs’‘icicle-bookmark’ – Jump to a bookmark‘icicle-bookmark-all-tags’ – Jump: bookmark with all of its tags matching a given set‘icicle-bookmark-all-tags-regexp’ – Jump: bookmark with all of its tags matching a given regexp‘icicle-bookmark-bookmark-list’ – Jump to a bookmark-list bookmark‘icicle-bookmark-desktop’ – Jump to a bookmarked DeskTop‘icicle-bookmark-dired’ – Jump to a bookmarked Dired state‘icicle-bookmark-file’ – Jump to a bookmarked file‘icicle-bookmark-gnus’ – Jump to a bookmarked Gnus message‘icicle-bookmark-info’ – Jump to a bookmarked Info node‘icicle-bookmark-list’ – Choose a list of bookmarks or their names‘icicle-bookmark-local-file’ – Jump to a bookmarked local file‘icicle-bookmark-man’ – Jump to a bookmarked ‘man’ page‘icicle-bookmark-non-file’ – Jump to a bookmarked non-file buffer‘icicle-bookmark-region’ – Jump to a bookmarked region‘icicle-bookmark-remote-file’ – Jump to a bookmarked remote file‘icicle-bookmark-some-tags’ – Jump: bookmark with some of its tags matching a given set‘icicle-bookmark-some-tags-regexp’ – Jump: bookmark with some of its tags matching a given regexp‘icicle-bookmark-specific-buffers’ – Jump: specific-buffer bookmark‘icicle-bookmark-specific-files’ – Jump: specific-file bookmark‘icicle-bookmark-this-buffer’ – Jump: bookmark for this buffer‘icicle-bookmark-url’ – Jump to a bookmarked URL‘icicle-bookmark-w3m’ – Jump to a w3m bookmark‘icicle-buffer’ – Switch to another buffer‘icicle-buffer-config’ – Choose a config of options for Icicles buffer commands‘icicle-buffer-list’ – Choose a list of buffer names‘icicle-choose-faces’ – Choose a list of face names‘icicle-choose-invisible-faces’ – Choose list of invisible faces‘icicle-choose-visible-faces’ – Choose list of visible faces‘icicle-clear-history’ – Clear entries from minibuffer histories‘icicle-clear-current-history’ – Clear current history entries‘icicle-color-theme’ – Change color theme‘icicle-comint-command’ – Reuse a previous command in ComintMode‘icicle-command-abbrev’ – Execute command or command abbreviation‘icicle-command-abbrev-command’ – Execute command from abbreviation‘icicle-completing-yank’ – Yank text using completion‘icicle-delete-file’ – Delete a file or directory‘icicle-delete-windows’ – Delete windows showing a buffer anywhere‘icicle-describe-option-of-type’ – Describe option of a given type‘icicle-directory-list’ – Choose a list of directory names‘icicle-dired’ – Visit a directory in Dired mode‘icicle-doc’ – Display doc of function, variable, or face‘icicle-execute-extended-command’ – A multi-command version of ‘M-x’‘icicle-execute-named-keyboard-macro’ – Execute a named keyboard macro‘icicle-face-list’ – Choose a list of face names‘icicle-file-list’ – Choose a list of file names‘icicle-file’ – Visit a file or directory‘icicle-find-file’ – Visit a file or directory (relative)‘icicle-find-file-absolute’ – Visit a file (absolute)‘icicle-find-file-all-tags’ – Visit a file with all of its tags matching a given set‘icicle-find-file-all-tags-regexp’ – Visit a file with all of its tags matching a given regexp‘icicle-find-file-in-tags-table’ – Visit a file in a tags table‘icicle-find-file-read-only’ – Visit a file in read-only mode‘icicle-find-file-some-tags’ – Visit a file with some tags matching a given set‘icicle-find-file-some-tags-regexp’ – Visit a file with some of its tags matching a given regexp‘icicle-find-file-tagged’ – Visit a file with file name or tags matching minibuffer input‘icicle-find-first-tag’ – Visit source-code definition with tag‘icicle-font’ – Change the frame font‘icicle-frame-bg’ – Change the frame background color‘icicle-frame-fg’ – Change the frame foreground color‘icicle-fundoc’ – Display the doc of a function‘icicle-Info-menu’ – Go to an Info menu node‘icicle-increment-option’ – Increment an option value using arrows‘icicle-increment-variable’ – Increment a variable value using arrows‘icicle-insert-buffer’ – Insert a buffer‘icicle-insert-thesaurus-entry’ – Insert an entry from a thesaurus‘icicle-keyword-list’ – Choose a list of keywords ([[regexps?]])‘icicle-kill-buffer’ – Kill a buffer‘icicle-kmacro’ – Execute a keyboard macro (Emacs 22+)‘icicle-locate-file’ – Open a file located anywhere‘icicle-pick-color-by-name’ – Set highlighting color to one you name‘icicle-plist’ – Choose a symbol and its property list‘icicle-recent-file’ – Open a recently used file‘icicle-remove-buffer-candidate’ – Remove buffer from those always shown for completion‘icicle-remove-buffer-config’ – Remove config from ‘icicle-buffer-configs’‘icicle-remove-file-from-recentf-list’ – Remove files from recent-files list‘icicle-remove-saved-completion-set’ – Remove a set from ‘icicle-saved-completion-sets’‘icicle-reset-option-to-nil’ – Set the value of a binary option to ‘nil’‘icicle-search-all-tags-bookmark’ – Search a bookmark that has all of a given set of tags‘icicle-search-all-tags-regexp-bookmark’ – Search a bookmark all of whose tags match a regexp‘icicle-search-autofile-bookmark’ – Search an autofile bookmark‘icicle-search-bookmark’ – Search a bookmark‘icicle-search-bookmark-list-bookmark’ – Search a bookmark-list bookmark‘icicle-search-dired-bookmark’ – Search a Dired bookmark‘icicle-search-file-bookmark’ – Search a bookmarked file‘icicle-search-gnus-bookmark’ – Search a bookmarked Gnus message‘icicle-search-info-bookmark’ – Search a bookmarked Info node‘icicle-search-local-file-bookmark’ – Search a local-file bookmark‘icicle-search-man-bookmark’ – Search a bookmarked ‘man’ page‘icicle-search-non-file-bookmark’ – Search a bookmarked buffer‘icicle-search-region-bookmark’ – Search a bookmarked region‘icicle-search-remote-file-bookmark’ – Search a remote bookmark‘icicle-search-some-tags-bookmark’ – Search a bookmark that has some of a given set of tags‘icicle-search-some-tags-regexp-bookmark’ – Search a bookmark some of whose tags match a regexp‘icicle-search-specific-buffers-bookmark’ – Search a bookmark to specific buffers‘icicle-search-specific-files-bookmark’ – Search a bookmark to specific files‘icicle-search-this-buffer-bookmark’ – Search a bookmark to the current buffer‘icicle-search-url-bookmark’ – Search a bookmarked URL‘icicle-search-w3m-bookmark’ – Search a w3m bookmark‘icicle-select-frame’ – Select frame by name and raise it‘icicle-select-window’ – Select window by its buffer name‘icicle-send-signal-to-process’ – Send a signal to a process‘icicle-set-option-to-t’ – Set the value of a binary option to ‘t’‘icicle-synonyms’ – Show synonyms that match a regexp‘icicle-tag-a-file’ – Add one or more tags to a file‘icicle-toggle-option’ – Toggle the value of a binary option‘icicle-untag-a-file’ – Remove one or more tags from a file‘icicle-vardoc’ – Display the doc of a variable‘icicle-where-is’ – Show key sequences that invoke a commandFor simplicity, the descriptions of most of these commands are singular actions (e.g. “kill a buffer”), but each of them can be used to act on any number of items any number of times (e.g. kill one or more buffers). I recommend that you follow a similar naming convention – remember that the doc string will let users know that the command can be used on multiple objects.
Macros ‘icicle-define-command’ and ‘icicle-define-file-command’ define a multi-command in a simple way. Sometimes you will need a little more flexibility. In that case, you can use higher-order functions ‘icicle-explore’ and ‘icicle-apply’ to define a multi-command. See Icicles - Defining Tripping Commands.
For users to be able to take advantage of the Icicles features that your multi-command provides, they must load Icicles. You can do this for them, by adding (require 'icicles nil t) to your code. The last two arguments mean that no error will be raised if for some reason Icicles cannot be found or successfully loaded.
But that brings up another question: What happens to your multi-command if Icicles is not available for a user, or s?he does not want to load it? No problem – your multi-command then automatically turns into a normal, single-choice command -- graceful degradation.
Similarly, users can always turn off ‘icicle-mode’ at any time, to return to the standard Emacs behavior.
Users will, in any case, need to load Icicles at compile time, in order to byte-compile your library that calls macro ‘icicle-define-command’ or ‘icicle-define-file-command’ – either that, or you can duplicate the definitions of the macros in your library. To let users load Icicles at (only) compile time, add this to your library that defines multi-commands:
(eval-when-compile '(require icicles))
See also:
‘icicle-apply’ and ‘icicle-explore’ to define browsing commands.‘icicle-define-command’ and ‘icicle-define-file-command’, if you need to.‘icicle-define-command’ to define command ‘synonyms’. This command lets you use Icicles completion on input regexps when you search a thesaurus.| Previous: Icicles - Candidates with Text Properties | Icicles | IciclesIndex | Next: Icicles - Defining Tripping Commands |
DrewsElispLibraries referenced here: Lisp:icicles.el, Lisp:synonyms.el
CategoryCommands CategoryBufferSwitching CategoryCompletion CategoryRegexp CategoryDirectories CategoryFiles CategoryProgrammerUtils CategoryCode