Interactively select multiple items - emacs

How can I let the user select multiple items from a list instead of just one? Like in the C-x b menu in helm.
Currently I can only select a single item instead of getting a complete list:
(defun test-main ()
(interactive)
(let ((choice (completing-read "Select: " '("item1 item2 item3"))))
(message choice)))

You can do that with completing-read-multiple:
(defun test-main ()
(interactive)
(let ((choice (completing-read-multiple "Select: " '("item1" "item2" "item3"))))
(message "%S" choice)))
It returns the selected items as a list, so if you type item2,item3 at the prompt, it returns ("item2" "item3").

Because that's what vanilla completing-read does. It reads and returns a single choice, providing completion to help you choose.
You can do what you are asking for with Icicles. It redefines function completing-read when Icicle mode is on.
Many Icicles commands are multi-commands, which means that you can make multiple input choices in a single command execution: a multiple-choice command. You can define your own multi-commands, using any actions.
And for any completion (not just for a multi-command), you can manipulate, save, and restore sets of completion candidates.
(You can also enter multiple inputs in the minibuffer. This is useful even for commands that read input without completion.)

Related

Emacs command history including commands called by keys and with arguments passed to them

Is there a way to show full command history with arguments?
repeat-complex-command which is bound to:
<again>, <redo>, C-x M-:, C-x M-ESC
does not show commands that are invoked from key bindings, and kmacro-edit-macro (which is bound to C-x C-k RET) does not show arguments passed to commands.
Motivation. It would make it faster to turn a keyboard macro into an elisp function. For now, I invoke kmacro-edit-macro to see names of commands to use and then work out what arguments to pass by reading documentation of commands one by one. (Example workflow: https://stackoverflow.com/a/24784563/1446335)
Note. It is possible to programmatically press key sequence from within an elisp function, but its usefulness is small.
Yes, to get what you want, use pre-command-hook to invoke a function that adds the given command to extended-command-history. For example, this is what the Icicles code does to add commands executed by menu to this history:
;; This is done when you turn on Icicle mode.
(if icicle-menu-items-to-history-flag
(add-hook 'pre-command-hook 'icicle-add-menu-item-to-cmd-history)
(remove-hook 'pre-command-hook 'icicle-add-menu-item-to-cmd-history))
(defun icicle-add-menu-item-to-cmd-history ()
"Add `this-command' to command history, if it is a menu item.
Menu items that are not associated with a command symbol are ignored.
Used on `pre-command-hook'."
(condition-case nil ; Just in case, since this is on `pre-command-hook'.
(when (and (> (length (this-command-keys-vector)) 0)
(equal '(menu-bar) (elt (this-command-keys-vector) 0))
;; Exclude uninterned symbols such as `menu-function-356'.
(symbolp this-command) (or (< emacs-major-version 21) (intern-soft this-command)))
(pushnew (symbol-name this-command) extended-command-history))
(error nil)))
It would be great to have a way to turn a keyboard-macro into a chunk of Elisp code, but for this chunk of Elisp code to be useful, it should be somewhat idiomatic, yet in many cases, the idiomatic Elisp code to do something is quite different from the keyboard-macro way to do it (e.g. idiomatic code should not use the mark and the kill ring just to extract and move text around).
So the transcription is not straightforward. I think the way to write such a thing is to "start small" and accept the fact that it will not be 100% reliable.

Tell ido to ignore all star buffers except for some

Normally I want ido to ignore all non-user buffers, i.e. all buffers which start with a *. I have achieved this using the following setting:
(setq ido-ignore-buffers '("\\` " "^\*"))
However, this poses a problem when working with a shell or an interpreter, e.g. ielm, where the interaction buffer is named *ielm*. Obviously adding all buffers to be ignored manually is not really an option because the list can get quite long with a lot of different emacs packages loaded. I know about C-a which disabled the ignore pattern from within ido, however, I don't want to hit C-a every time I switch to an ielm buffer.
My question is:
Is there some variable which allows to specify buffers which ido should not ignore (although they match the normal ignore list)? Or is there some other approach for solving this?
The list that the ido-ignore-buffers variable points to may contain not only regular expressions but also functions (any mix of them, actually). It's easy to provide a function to filter out all non-user buffers except *ielm*:
(defun ido-ignore-non-user-except-ielm (name)
"Ignore all non-user (a.k.a. *starred*) buffers except *ielm*."
(and (string-match "^\*" name)
(not (string= name "*ielm*"))))
(setq ido-ignore-buffers '("\\` " ido-ignore-non-user-except-ielm))
Here's an example of having multiple unignored buffer names:
(setq my-unignored-buffers '("*ielm*" "*scratch*" "*foo*" "*bar*"))
(defun my-ido-ignore-func (name)
"Ignore all non-user (a.k.a. *starred*) buffers except those listed in `my-unignored-buffers'."
(and (string-match "^\*" name)
(not (member name my-unignored-buffers))))
(setq ido-ignore-buffers '("\\` " my-ido-ignore-func))
An interesting example of using ignore functions can be found among comments in the ido.el source code (I've removed ;; at the beginning of each line):
(defun ido-ignore-c-mode (name)
"Ignore all c mode buffers -- example function for ido."
(with-current-buffer name
(derived-mode-p 'c-mode)))
Basically, once you've got buffer name, you can do any checking/ignoring you want.

How to archive all the DONE tasks using a single command

To archive the DONE tasks i am using
C-c C-x a
command. The draw back is i have to manually move over the DONE tasks one by one and then archive it.
How to archive all the DONE tasks using a single command.
You can bulk archive (or refile/change todo etc) from within the Agenda view.
http://orgmode.org/manual/Agenda-commands.html#Agenda-commands
If you call Org-Agenda from within the buffer you want to archive you can temporarily restrict it to only that buffer and view only todo entries and filter for only DONE
C-c a < t
N r
Where N corresponds to the shortcut for your DONE state (with default states it would be 2)
Then you'd simply need to mark all the desired headlines and bulk archive
m (mark for bulk action)
B a (or B $ for arch->sibling)
Here's a corrected version of madalu's snippet. Note that this version also only operates on the current subtree (change 'tree back to 'file to operate over the entire file).
(defun org-archive-done-tasks ()
(interactive)
(org-map-entries
(lambda ()
(org-archive-subtree)
(setq org-map-continue-from (org-element-property :begin (org-element-at-point))))
"/DONE" 'tree))
You can write a function using org-map-entries:
(defun my-org-archive-done-tasks ()
(interactive)
(org-map-entries 'org-archive-subtree "/DONE" 'file))
Also from http://orgmode.org/manual/Moving-subtrees.html#Moving-subtrees
C-u C-c C-x C-s
Check if any direct children of the current headline could be moved to the archive. To do this, each subtree is checked for open TODO entries. If none are found, the command offers to move it to the archive location. If the cursor is not on a headline when this command is invoked, the level 1 trees will be checked.
There is now a command org-archive-all-done that is built into org-mode, and in org-archive.el.
If you want to do it in the source Org buffer (as opposed to in an Org agenda view), and if they are following each other, you can select all of them in a region, and apply a command (such as C-c C-t d).
Only setting needed:
;; Some commands act upon headlines in the active region.
(setq org-loop-over-headlines-in-active-region 'start-level)
I found the direct "org-map-entries" method in a couple of these answers to be a little "fragile" for some reason in situations with more varied nesting and TODOs at multiple levels.
This method - generating a list and then archiving in reverse (to avoid changes in positioning) seems to cover every use case I've thrown at it. Sharing it here for anyone else that runs into trouble.
Note the "TODO" string match on the last line needs to match how you have your TODOs defined exactly (for example in a vanilla case, the match may be: "TODO=\"DONE\"").
(defun org-archive-done-tasks ()
"Archive all tasks marked DONE in the file."
(interactive)
(mapc (lambda(entry)
(goto-char entry)
(org-archive-subtree))
(reverse (org-map-entries (lambda () (point)) "TODO=\"★ DONE\"" 'file))))
Based on Robert's Answer
(require 'org)
(require 'org-archive)
(add-hook 'org-mode-hook (lambda () (add-hook 'after-save-hook 'org-archive-all-done nil t)))

Emacs lisp - autocomplete bookmark names

I'm new to elisp. http://www.gnu.org/s/emacs/manual/html_node/elisp/Interactive-Codes.html#Interactive-Codes lists 'code characters' for interactive parameters, which AFAIK modifies the behaviour of the input mechanism when prompting the user for input (eg: if you specify that the input is a filename that exists, emacs' autocomplete functionality will look for file names that exists).
I'm trying to find a code for a bookmark name that already exists - ie: emacs will prompt the user for a bookmark name, and upon pressing tab emacs will show possible bookmark name completions.
Does such a code exist?
Use completing-read for that. You could write a function that prompts the user for a bookmark like so:
(defun my-function ()
(interactive)
(let ((bookmark (completing-read "Bookmark: " (bookmark-all-names))))
...))
If you prefer the prompting to be part of interactive (so that the result will be bound automatically to your function's arguments), you could use the following alternative:
(defun my-function (bookmark)
(interactive (list (completing-read "Bookmark: " (bookmark-all-names))))
...)
For Emacs to find the function bookmark-all-names you also have to add the following line to your .emacs file:
(require 'bookmark)
Function bookmark-completing-read is the standard way to complete a bookmark name. You do not need the lower-level function completing-read for this. Example:
(bookmark-completing-read "Bookmark" bookmark-current-bookmark)
If you use Bookmark+ then bookmark-completing-read accepts some optional arguments (similar to completing-read) that can help:
ALIST -- an alist of bookmarks to choose from (instead of all bookmarks: bookmark-alist)
PRED -- a predicate that filters the list of bookmark candidates
HIST -- an input history list
There is also a non-strict version of the function, bmkp-completing-read-lax, which is useful if you want to accept a new bookmark name or complete against existing names.

What does (interactive) mean in an Emacs Lisp function?

Emacs Lisp function often start like this:
(lambda () (interactive) ...
What does "(interactive)" do?
Just to clarify (it is in the quoted docs that Charlie cites) (interactive) is not just for key-bound functions, but for any function. Without (interactive), it can only be called programmatically, not from M-x (or via key-binding).
EDIT: Note that just adding "(interactive)" to a function won't necessarily make it work that way, either -- there could be many reasons functions are not interactive. Scoping, dependencies, parameters, etc.
I means that you're including some code for the things you need to make a function callable when bound to a key -- things like getting the argument from CTRL-u.
Have a look at CTRL-h f interactive for details:
interactive is a special form in `C source code'.
(interactive args)
Specify a way of parsing arguments for interactive use of a function.
For example, write
(defun foo (arg) "Doc string" (interactive "p") ...use arg...)
to make ARG be the prefix argument when `foo' is called as a command.
The "call" to `interactive' is actually a declaration rather than a function;
it tells `call-interactively' how to read arguments
to pass to the function.
When actually called, `interactive' just returns nil.
The argument of `interactive' is usually a string containing a code letter
followed by a prompt. (Some code letters do not use I/O to get
the argument and do not need prompts.) To prompt for multiple arguments,
give a code letter, its prompt, a newline, and another code letter, etc.
Prompts are passed to format, and may use % escapes to print the
arguments that have already been read.
Furthermore it’s worth mentioning that interactive's main purpose is, in an interactive context (e.g. when user calls function with key binding), let user specify function arguments that otherwise could be only given programmatically.
For instance, consider function sum returns sum of two numbers.
(defun sum (a b)
(+ a b))
You may call it by (sum 1 2) but you can do it only in a Lisp program (or in a REPL). If you use the interactive special form in your function, you can ask the user for the arguments.
(defun sum (a b)
(interactive
(list
(read-number "First num: ")
(read-number "Second num: ")))
(+ a b))
Now M-x sum will let you type two numbers in the minibuffer, and you can still do (sum 1 2) as well.
interactive should return a list that would be used as the argument list if function called interactively.
(interactive) is for functions meant to interact with the user, be it through M-x or through keybindings.
M-x describe-function RET interactive RET for detailed info on how to use it, including parameter to catch strings, integers, buffer names, etc.
One of the "gotchas" that this clarifies is that the argument to interactive is actually a kind of mini-formatting language (like for printf) that specifies the following (for the surrounding function's input):
schema (number of arguments and their type)
source (e.g., marked-region in buffer and/or user input, etc.)
For example,
'r'
Point and the mark, as two numeric arguments, smallest first.
means that the interactive-annotated function needs exactly two arguments.
e.g. this will work
(defun show-mark (start stop)
(interactive "r")
(print start)
(print stop))
This will break:
(defun show-mark (start)
(interactive "r")
(print start))
Wrong number of arguments: ((t) (start) (interactive "r") (print start)), 2