More adventures in helm - more than one action

| categories: emacs | tags:

We continue our exploration of helm and now consider how to have more than one action for a selection. When you press enter, helm runs the default action defined, but you can define more than one action, and choose which one to run. How do you know if there are multiple actions? Press C-z in helm and you will get a new helm buffer showing the actions. The first action is the default, and you can select the the actions with function keys, e.g. f1 is the first action, f2 is the second action, or you can select the action and press enter.

The main difference in setting up multiple actions is that instead of a single function for action in the source definition, we provide a list of cons cells for the action element of the helm source. Each action cons cell should have a descriptive string as the car that identifies the action. This will be shown in the helm buffer. The cdr should be the function to run on the candidate. The function will be called with the selection, so the function must take one argument.

Here is an example where we have two actions. The default action will just show us the email address of the selected candidates in a message box. It will show as a list. The second action opens an email window and inserts the selected candidates in the To: field as a comma separated list. I use helm-selected-candidates in these functions instead of the just the current selected candidate so we can have multiple selections. I define the first function as a lambda function, and the second one as a defun to illustrate how to use both approaches. You can have as many actions as you want, so you could consider functions that open notes about the person, or open your contacts to look up a phone number, or functions with template emails you send often, etc…

Now, you have these options to run those actions.

  1. Make a selection and press enter. That runs the first (and default) action to show you a message box.
  2. Make a selection and press C-z to see what actions are available. Select the action you want, and press enter.
  3. Make a selection and press F1 to run the default action, or F2 to run the second action.

Here is our code.

(setq data '(("John" . "john@email.com")
             ("Jim" . "jim@email.com")
             ("Jane" . "jane@email.com")
             ("Jill" . "jill@email.com")))


(defun open-email (candidates)
  "Compose an email to the candidates. Fill in the addresses and
move point to the subject."
  (compose-mail)
  (message-goto-to)
  (insert
   (mapconcat
    'identity
    (helm-marked-candidates)
    ","))
  (message-goto-subject))

(setq some-helm-source
      `((name . "HELM at the Emacs")
        (candidates . ,data)
        (action . (("show email address" . (lambda (candidate)
                                             (message-box
                                              "selected: %s"
                                              (helm-marked-candidates))))
                   ("send email" . open-email)))))

(helm :sources '(some-helm-source))
t

Now, you can define multiple actions for your selection in helm!

Copyright (C) 2015 by John Kitchin. See the License for information about copying.

org-mode source

Org-mode version = 8.2.10

Discuss on Twitter