7 Developing Template Functions

You can develop your own custom template insertion functions. Doing so is relatively simple, and requires that you write an Emacs Lisp command.

If the built in commands don’t provide enough options, you will need to write your own function in order to provide your dictionaries with the values needed for custom templates.

In this way, you can build your own code generator for any language based on a set of predefined macros whose values you need to derive from Emacs Lisp code yourself.

For example:

(defun my-srecode-insert (template-name)
  "Insert the template TEMPLATE-NAME into the current buffer at point."

  ;; Read in a template name.
  (interactive (list (srecode-read-template-name "Template Name: ")))
  (if (not (srecode-table))
      (error "No template table found for mode %s" major-mode))
  (let ((temp (srecode-template-get-table (srecode-table) template-name))

       ;; Create a new dictionary
	(newdict (srecode-create-dictionary)))

    (if (not temp)
        (error "No Template named %s" template-name))

    ;; Add some values into the dictionary!
    (srecode-dictionary-set-value newdict "FOO" (my-get-value-of-foo))
    ;; Optionally show a section
    (srecode-dictionary-show-section newdict "BLARG")

    ;; Add in several items over a loop
    (let ((my-stuff (get-my-stuff-list)))
       (while my-stuff
          (let ((subdict (srecode-dictionary-add-section-dictionary
                             newdict "LOOP")))
             (srecode-dictionary-set-value subdict "NAME" (nth 0 my-stuff))
             (srecode-dictionary-set-value subdict "ARG" (nth 1 my-stuff))
             (srecode-dictionary-set-value subdict "MOOSE" (nth 2 my-stuff))
             )
          (setq my-stuff (cdr my-stuff)))

    ;; Some templates have arguments that need to be resolved.
    (srecode-resolve-arguments temp newdict)

    ;; Do the expansion
    (srecode-insert-fcn temp newdict)
    ))

Lets look at the key functions involved above:

7.1 Interactive Completion:

Function: srecode-read-template-name prompt

Completing read for Semantic Recoder template names. prompt is used to query for the name of the template desired.

7.2 Template Lookup

Even if your program does not query the user for a template name, you will need to locate a template. First, you need to locate the table to look the template up in.

Function: srecode-table &optional mode

Return the currently active Semantic Recoder table for this buffer. Optional argument MODE specifies the mode table to use.

Function: srecode-template-get-table tab template-name &optional context application

Find in the template in mode table TAB, the template with TEMPLATE-NAME. Optional argument CONTEXT specifies a context a particular template would belong to. Optional argument APPLICATION restricts searches to only template tables belonging to a specific application. If APPLICATION is nil, then only tables that do not belong to an application will be searched.

For purposes of an SRecode application, it is important to decide what to call your application, and use that with this method call.

7.3 Creating dictionaries

Several dictionary calls are made in this example, including:

srecode-create-dictionary
srecode-dictionary-set-value
srecode-dictionary-show-section
srecode-dictionary-add-section-dictionary

These are documented more fully Dictionaries.

Also used is srecode-resolve-arguments. To learn more about that, see Argument Resolution.

7.4 Template Insertion Commands

There are several ways to insert a template. It is easiest to just start with the main entry point.

Function: srecode-insert-fcn template dictionary &optional stream

Insert template using dictionary into stream. If stream is nil, then use the current buffer.