+buffer. If `tempo-interactive' is nil, the current point is placed on
+`tempo-mark'.
+
+PROMPT is the prompt string, SAVE-NAME is a name to save the inserted
+text under. If the optional argument NO-INSERT is non-nil, no text is
+inserted. This can be useful when there is a SAVE-NAME.
+
+If there already is a value for SAVE-NAME, it is used and the user is
+never prompted."
+ (let (insertion
+ (previous (and save-name
+ (tempo-lookup-named save-name))))
+ (cond
+ ;; Insert previous value, unless no-insert is non-nil
+ ((and previous
+ (not no-insert))
+ (tempo-insert-named save-name)) ; A double lookup here, but who
+ ; cares
+ ;; If no-insert is non-nil, don't insert the previous value. Just
+ ;; keep it
+ (previous
+ nil)
+ ;; No previous value. Prompt or insert mark
+ (tempo-interactive
+ (if (not (stringp prompt))
+ (error "tempo: The prompt (%s) is not a string" prompt))
+ (setq insertion (read-string prompt))
+ (or no-insert
+ (insert insertion))
+ (if save-name
+ (tempo-save-named save-name insertion)))
+ (t
+ (tempo-insert-mark (point-marker))))))
+
+;;;
+;;; tempo-is-user-element
+
+(defun tempo-is-user-element (element)
+ "Tries all the user-defined element handlers in `tempo-user-elements'."
+ ;; Sigh... I need (some list)
+ (catch 'found
+ (mapcar (function (lambda (handler)
+ (let ((result (funcall handler element)))
+ (if result (throw 'found result)))))
+ tempo-user-elements)
+ (throw 'found nil)))
+
+;;;
+;;; tempo-forget-insertions
+
+(defun tempo-forget-insertions ()
+ "Forget all the saved named insertions."
+ (setq tempo-named-insertions nil))
+
+;;;
+;;; tempo-save-named
+
+(defun tempo-save-named (name data) ; Had an optional prompt for 'v
+ "Save some data for later insertion
+The contents of DATA is saved under the name NAME.
+
+The data can later be retrieved with `tempo-lookup-named'.
+
+This function returns nil, so it can be used in a template without
+inserting anything."
+ (setq tempo-named-insertions
+ (cons (cons name data)
+ tempo-named-insertions))
+ nil)
+
+;;;
+;;; tempo-lookup-named
+
+(defun tempo-lookup-named (name)
+ "Lookup some saved data under the name NAME.
+Returns the data if NAME was found, and nil otherwise."
+ (cdr (assq name tempo-named-insertions)))
+
+;;;
+;;; tempo-insert-named
+
+(defun tempo-insert-named (name)
+ "Insert the previous insertion saved under a named specified in NAME.
+If there is no such name saved, a tempo mark is inserted.
+
+Note that if the data is a string, it will not be run through the string
+processor."
+ (let* ((insertion (tempo-lookup-named name)))
+ (cond ((null insertion)
+ (tempo-insert-mark (point-marker)))
+ ((stringp insertion)
+ (insert insertion))
+ (t
+ (tempo-insert insertion nil)))))