#+title: The Helm Developer's Guide
# #+subtitle:  Release {{{version}}}
#+subtitle:  Release 3.6.2
#+author:    The Helm Developers
# #+date:      {{{modification-time}}}
#+language:  en

# #+texinfo: @insertcopying

* Table Of Contents                                                   :TOC_3:
- [[#introduction][Introduction]]
- [[#creating-a-helm-buffer][Creating a Helm buffer]]
- [[#helm-attributes][Helm attributes]]
  - [[#looking-up-helm-attributes][Looking up Helm attributes]]
  - [[#mandatory-attributes][Mandatory attributes]]
  - [[#optional-but-important-attributes][Optional, but important attributes]]
  - [[#helm-keywords][~helm~ keywords]]
    - [[#sources][~:sources~]]
    - [[#buffer][~:buffer~]]
    - [[#input][~:input~]]
- [[#customizing-action-lists][Customizing Action Lists]]
- [[#creating-a-source][Creating a Source]]
  - [[#helm-source-sync][~helm-source-sync~]]
  - [[#helm-source-in-buffer][~helm-source-in-buffer~]]
  - [[#helm-source-async][~helm-source-async~]]
  - [[#helm-source-dummy][~helm-source-dummy~]]
  - [[#helm-source-in-file][~helm-source-in-file~]]
  - [[#help][Help]]
  - [[#pre-filtering-lines-in-a-buffer][Pre-filtering lines in a buffer]]
- [[#creating-a-class][Creating a Class]]
  - [[#create-your-own-class-inheriting-from-one-of-the-main-classes][Create your own class inheriting from one of the main classes]]
  - [[#create-your-own-class-and-inherit-from-one-of-helm-type-classes][Create your own class and Inherit from one of helm-type classes]]
    - [[#creating-a-new-class-using-as-parent-a-class-inheriting-itself-from-a-helm-type--class][Creating a new class using as parent a class inheriting itself from a ~helm-type-*~ class]]
  - [[#create-your-source-from-your-own-class][Create your source from your own class]]
  - [[#write-your-own-helm-type-class][Write your own helm-type class]]
- [[#writing-actions][Writing actions]]
- [[#writing-persistent-actions][Writing persistent actions]]
- [[#footnotes][Footnotes]]

* Introduction

The best way to learn how to create a custom Helm command is to  read
the source code[fn:1] and look at examples.

A good place to start is the source file =helm-info.el=[fn:2].  This
source file is fairly short and straightforward.

That being said, we'll try to go over some basic ideas in this manual.

* Creating a Helm buffer

The ~helm~ function creates a Helm buffer with candidates to select
and/or take action on. The list of candidates is provided by one or
more *sources*.

An example usage of ~helm~ is below:

#+begin_src emacs-lisp
  (defun my-first-helm-command ()
    (interactive)
    (helm :sources 'my-source
	  :buffer "*helm my command*"))
#+end_src

~helm~ must be called with several keywords arguments, called
*attributes*.

* Helm attributes

An *attribute* determines Helm behavior.

There are a large number of attributes in Helm; some are mandatory,
while others are optional.

NOTE: When creating sources you are using slots which are keywords
describing how to build attributes, they have generally the same name
as attributes but not always e.g the slot ~:data~ exists, but there is
no such attribute.

** Looking up Helm attributes

To learn about /a single/ Helm attribute, use the documentation of the
class you are using where all slots are documented.

** Mandatory attributes

You have to give at least a name to your source and a list of
candidates.  The list of candidates is given with a variable
containing candidates, a function returning candidates or a list, the
attribute depend on which class you are using, e.g candidates for sync
sources, for in-buffer sources you have to build a buffer using
~helm-init-candidates-in-buffer~ or for conveniency you can use the
~:data~ slot which will build the candidate buffer for you.  In async
sources the candidates-process attribute is used which is a function
with no arg that returns a process.

** Optional, but important attributes

** ~helm~ keywords

*** ~:sources~

Expects a source of the form:

- Single source (alist)

- Symbol naming the source

- List of sources (alist or symbol)

Where alists are the resulting value of functions building sources,
that is all the ~helm-build-*~ function or the ~helm-make-source~
function, don't use directly alists when writing sources.  See
examples in next section.

*** ~:buffer~

*Optional but important*.

The value for the ~:buffer~ keyword helps the ~helm-resume~ command
retrieve the Helm session.

The name of the buffer should be prefixed with =helm= (e.g. =*helm
Info*=). This is not mandatory, but it is good practice. It will,
among other things, allow Helm to automatically hide the buffer.

*** ~:input~

The value for the ~:input~ keyword is used to pre-fill the input of
the helm window.

E.g. if the user is using helm to autocomplete and runs the
autocomplete command, you could get the word at point and set ~:input~
to that word. That word will then be pre-filled in the minibuffer.

#+begin_src emacs-lisp
  (defun my-autocomplete-command ()
    (interactive)
    (helm :sources 'my-source
	  :input (word-at-point)
	  :buffer "*helm my autocomplete command*"))
#+end_src

* Customizing Action Lists

It's possible to change the default list of actions for various
existing Helm commands. The actions are typically held in variables
called ~helm-type-foo-actions~, for instance ~helm-type-file-actions~,
so search apropos for those. Each action in the list is the usual cons
of action label and action function.

Another higher-level approach is to use a pre-defined function such as
~helm-add-action-to-source~ or ~helm-add-action-to-source-if~. These
functions accept an action label, action function, the source to
modify (as a class symbol name, such as 'helm-source-ffiles), and for
the latter, a predicate which determines if the action should be made
available for the candidate under point.

Also see ~helm-delete-action-from-source~, and
~helm-source-add-action-to-source-if~.

* Creating a Source

Even if you can still create source with alists, helm provides
convenient basic classes to build sources, and allow you to create
your own classes that inherit from these basics classes.

Here are the basic classes for creating a Helm source:

- ~helm-source-sync~ ::   Put candidates in a list

- ~helm-source-in-buffer~ ::  Put candidates in a buffer

- ~helm-source-async~ ::  Get candidates asynchronously using the
  output of a process.

- ~helm-source-dummy~ ::  Use ~helm-pattern~ as candidate.

- ~helm-source-in-file~ ::  Get candidates from the lines of a named
  file using ~helm-source-in-buffer~.

For consistency, prefix your source names with =helm-source-=
(e.g. ~helm-source-info-emacs~).

For convenience, ~helm~ provide macros prefixed by =helm-build-= to
build your sources quickly, see examples below.

All the different slots are documented in docstring of each classes.

** ~helm-source-sync~

Put candidates in a list

#+begin_src emacs-lisp
  (helm-build-sync-source "test"
    :candidates '(a b c d e))

  (helm :sources (helm-build-sync-source "test"
		   :candidates '(a b c d e))
	:buffer "*helm sync source*")
#+end_src

** ~helm-source-in-buffer~

Put candidates in a buffer

#+begin_src emacs-lisp
  (helm-build-in-buffer-source "test1"
    :data '(a b c d e))

  (helm :sources (helm-build-in-buffer-source "test1"
		   :data '(a b c d e))
	:buffer "*helm buffer source*")
#+end_src

** ~helm-source-async~

Get candidates asynchronously using the output of a process.

#+begin_src emacs-lisp
  (helm :sources (helm-build-async-source "test2"
		   :candidates-process
		   (lambda ()
		     (start-process "echo" nil "echo" "a\nb\nc\nd\ne")))
	:buffer "*helm async source*")
#+end_src

** ~helm-source-dummy~

Use ~helm-pattern~ as candidate

#+begin_src emacs-lisp
  (defun helm/test-default-action (candidate)
    (browse-url (format
		 "http://www.google.com/search?q=%s"
		 (url-hexify-string candidate))))

  (helm :sources (helm-build-dummy-source "test"
		   :action '(("Google" . helm/test-default-action)))
	:buffer "*helm test*")
#+end_src

** ~helm-source-in-file~

Get candidates from the lines of a named file using
~helm-source-in-buffer~.

#+begin_src emacs-lisp
  (helm :sources (helm-build-in-file-source
		     "test" "~/.emacs.d/init.el"
		   :action (lambda (candidate)
			     (let ((linum (with-helm-buffer
					    (get-text-property
					     1 'helm-linum
					     (helm-get-selection nil 'withprop)))))
			       (find-file (with-helm-buffer
					    (helm-attr 'candidates-file)))
			       (goto-line linum))))
	:buffer "*helm test*")

#+end_src

** Help

To give a specific help to your Helm source, create a variable
~helm-<my-source>-help-string~ and bind it in your source with the
~helm-message~ slot. It will then appear when you use {{{kbd(C-h m)}}} or
{{{kbd(C-c ?=)}}}.

** Pre-filtering lines in a buffer

Here's an example of an in-buffer source that pre-filters lines to
those matching a certain regular expression.  Then the pre-filtered
lines are narrowed as the user types.  This uses
[[https://github.com/tarsius/hl-todo][hl-todo-mode]] which provide
=hl-todo-regexp= but you could use any regexp to do the same thing.
The =:init= function switches to the automatically created buffer,
which is returned by ~(helm-candidate-buffer 'global)~, then it
deletes uninteresting lines, after which Helm presents the remaining
lines to the user.  The =:get-line= function is changed to
=buffer-substring= so that the properties are preserved in the
=helm-buffer=.

#+begin_src emacs-lisp
  (defun helm-hl-todo-items ()
    "Show `hl-todo'-keyword items in buffer."
    (helm :sources (helm-build-in-buffer-source "hl-todo items"
		     :init (lambda ()
			     (with-current-buffer (helm-candidate-buffer 'global)
			       (insert (with-helm-current-buffer (buffer-string)))
			       (goto-char (point-min))
			       (delete-non-matching-lines hl-todo-regexp)))
		     :get-line #'buffer-substring)
	  :buffer "*helm hl-todo*"))
#+end_src

And it could be also written using the =:data= slot:

#+begin_src emacs-lisp
  (defun helm-hl-todo-items ()
    "Show `hl-todo'-keyword items in buffer."
    (helm :sources (helm-build-in-buffer-source "hl-todo items"
		     :data (current-buffer)
		     :candidate-transformer (lambda (candidates)
					      (cl-loop for c in candidates
						       when (string-match hl-todo-regexp c)
						       collect c))
		     :get-line #'buffer-substring)
	  :buffer "*helm hl-todo*"))
#+end_src

* Creating a Class

** Create your own class inheriting from one of the main classes

#+begin_src emacs-lisp
  (defclass my-helm-class (helm-source-sync)
    ((candidates :initform '("foo" "bar" "baz"))))

  (helm :sources (helm-make-source "test" 'my-helm-class)
	:buffer "*helm test*")

#+end_src

This is same as creating your source with:

#+begin_src emacs-lisp
  (helm :sources (helm-build-sync-source "test"
		   :candidates '("foo" "bar" "baz"))
	:buffer "*helm test*")

#+end_src

** Create your own class and Inherit from one of helm-type classes

Here an example from a helm user that store a list of favorite files
in a file =~/.fav= to retrieve them quickly:

#+begin_src emacs-lisp
  (defclass helm-test-fav (helm-source-in-file helm-type-file)
    ((candidates-file :initform "~/.fav")))

  (helm :sources (helm-make-source "test" 'helm-test-fav)
	:buffer "*helm test*")

#+end_src

*** Creating a new class using as parent a class inheriting itself from a ~helm-type-*~ class

Sometimes, you may want to inherit from a class using itself a
~helm-type-*~ class but with one or more attributes of this class
slightly modified for your needs.  You may think that you only need to
create your new class inheriting from the class inheriting itself from
the ~helm-type-*~ class, but this is not enough.

Here how to do, reusing the example above we modify
the actions predefined by helm-type-file:

1. Create a fake class:

  #+begin_src emacs-lisp
    (defclass helm-override-test-fav (helm-source) ())
  #+end_src

2. Create a method for this class

   This method is used as a ~:PRIMARY~ method, which mean that the
   similar parent method, if some will not be used, in particular the
   ~helm-source-in-file~ method which calls itself the
   ~helm-source-in-buffer~ method, so to be sure these important
   methods are used, use ~call-next-method~, see below.

  #+begin_src emacs-lisp
    (defmethod helm--setup-source ((source helm-override-test-fav))
      (call-next-method)
      (let ((actions (slot-value source 'action)))
	(setf (slot-value source 'action)
	      (helm-append-at-nth (symbol-value actions)
				  '(("test" . ignore)) 1))))

  #+end_src

3. Create now your main class inheriting from your new overriding
   class

   #+begin_src emacs-lisp
     (defclass helm-test-fav (helm-source-in-file helm-type-file helm-override-test-fav)
       ((candidates-file :initform "~/.fav")))
   #+end_src

   Now when running helm with a source built from your new class you
   should see the new action you have added in second position to the
   other file action.

** Create your source from your own class

Once your class is created, you have to use ~helm-make-source~ to
build your source.

#+begin_src emacs-lisp
  (helm-make-source "test" 'my-class :action 'foo [...other slots])
#+end_src

** Write your own helm-type class

You will find several examples in the =helm-types.el=[fn:3] file.

The main thing to remember is to create an empty class and fill it
using two =defmethod= s, one empty which should be a primary method and
one which is a before method, use for this the slots ~:primary~ and
~:before~ of ~defmethod~. This allows you to override different slots
of the inheriting type class in your new class.

* Writing actions

Actions are specified in the ~:action~ slot of your class, it is an
alist composed of (ACTION_NAME . FUNCTION), it can be also a symbol
defining a customizable action alist.

#+begin_src elisp
  (defcustom helm-source-foo
    '(("Do this" . foo)
      ("Do that" . bar))
    "A customizable action list."
    :group 'helm
    :type '(alist :key-type string :value-type function))

#+end_src

It is recommended however to use ~helm-make-actions~ to define your
actions easily, it allow also to create actions with condition, e.g

#+begin_src emacs-lisp
  (helm-make-actions "Do this"
		     'foo
		     (lambda ()
		       (when (featurep 'something)
			 "Do that"))
		     'bar)
#+end_src

* Writing persistent actions

The way to specify persistent-action is to use the slot
~:persistent-action~ to specify the function Helm will run when using
{{{kbd(C-j)}}} or {{{kbd(C-z)}}}. If you don't specify this helm will
run the first action of the action.

You can also specify additional persistent actions, which must be
bound to keys other than {{{kbd(C-j)}}} or {{{kbd(C-z)}}}.

#+begin_src emacs-lisp
  (defun helm-foo-persistent-action ()
    "Bind a new persistent action 'foo-action to foo function.
  foo function is an action function called with one arg candidate."
    (interactive)
    (with-helm-alive-p
      ;; never split means to not split the helm window when executing
      ;; this persistent action. If your source is using full frame you
      ;; will want your helm buffer to split to display a buffer for the
      ;; persistent action (if it needs one to display something).
      (helm-attrset 'foo-action '(foo . never-split))
      (helm-execute-persistent-action 'foo-action)))
#+end_src

Then you bind your new persistent action to something else than
{{{kbd(C-j)}}} or {{{kbd(C-z)}}}.

* COMMENT Conventions

** TODO Class names

Class names are currently a mess. Need to come up with a better
convention.

* Export Setup                                                          :noexport:

#+setupfile: doc-setup.org
# #+options: H:4

#+export_file_name: helm-devel.texi

#+texinfo_dir_category: Emacs Add-ons
#+texinfo_dir_title: Helm Developer's Guide: (helm-devel)
#+texinfo_dir_desc: Helm Developer's Guide

* Footnotes

[fn:1] http://blog.codinghorror.com/learn-to-read-the-source-luke/

[fn:2] https://github.com/emacs-helm/helm/blob/master/helm-info.el

[fn:3] https://github.com/emacs-helm/helm/blob/master/helm-types.el

#+EXCLUDE_TAGS: TOC_3
