summaryrefslogtreecommitdiff
path: root/lisp/cedet/srecode/insert.el
diff options
context:
space:
mode:
Diffstat (limited to 'lisp/cedet/srecode/insert.el')
-rw-r--r--lisp/cedet/srecode/insert.el162
1 files changed, 101 insertions, 61 deletions
diff --git a/lisp/cedet/srecode/insert.el b/lisp/cedet/srecode/insert.el
index 4ee6d467009..843b577e1eb 100644
--- a/lisp/cedet/srecode/insert.el
+++ b/lisp/cedet/srecode/insert.el
@@ -26,6 +26,9 @@
;; Manage the insertion process for a template.
;;
+(eval-when-compile
+ (require 'cl)) ;; for `lexical-let'
+
(require 'srecode/compile)
(require 'srecode/find)
(require 'srecode/dictionary)
@@ -49,7 +52,7 @@ Possible values are:
NOTE: The field feature does not yet work with XEmacs."
:group 'srecode
:type '(choice (const :tag "Ask" ask)
- (cons :tag "Field" field)))
+ (const :tag "Field" field)))
(defvar srecode-insert-with-fields-in-progress nil
"Non-nil means that we are actively inserting a template with fields.")
@@ -86,7 +89,6 @@ DICT-ENTRIES are additional dictionary values to add."
(car dict-entries)
(car (cdr dict-entries)))
(setq dict-entries (cdr (cdr dict-entries))))
- ;;(srecode-resolve-arguments temp newdict)
(srecode-insert-fcn temp newdict)
;; Don't put code here. We need to return the end-mark
;; for this insertion step.
@@ -100,6 +102,10 @@ has set everything up already."
;; Perform the insertion.
(let ((standard-output (or stream (current-buffer)))
(end-mark nil))
+ ;; Merge any template entries into the input dictionary.
+ (when (slot-boundp template 'dictionary)
+ (srecode-dictionary-merge dictionary (oref template dictionary)))
+
(unless skipresolver
;; Make sure the semantic tags are up to date.
(semantic-fetch-tags)
@@ -110,7 +116,7 @@ has set everything up already."
;; If there is a buffer, turn off various hooks. This will cause
;; the mod hooks to be buffered up during the insert, but
;; prevent tools like font-lock from fontifying mid-template.
- ;; Especialy important during insertion of complex comments that
+ ;; Especially important during insertion of complex comments that
;; cause the new font-lock to comment-color stuff after the inserted
;; comment.
;;
@@ -239,6 +245,9 @@ ST can be a class, or an object."
(defmethod srecode-insert-method ((st srecode-template) dictionary)
"Insert the srecoder template ST."
;; Merge any template entries into the input dictionary.
+ ;; This may happen twice since some templates arguments need
+ ;; these dictionary values earlier, but these values always
+ ;; need merging for template inserting in other templates.
(when (slot-boundp st 'dictionary)
(srecode-dictionary-merge dictionary (oref st dictionary)))
;; Do an insertion.
@@ -264,7 +273,7 @@ Use DICTIONARY to resolve any macros."
;; Specific srecode inserters.
;; The base class is from srecode-compile.
;;
-;; Each inserter handles various macro codes from the temlate.
+;; Each inserter handles various macro codes from the template.
;; The `code' slot specifies a character used to identify which
;; inserter is to be created.
;;
@@ -471,7 +480,7 @@ If SECONDNAME is nil, return VALUE."
;; (setq val (format "%S" val))))
))
;; Output the dumb thing unless the type of thing specifically
- ;; did the inserting forus.
+ ;; did the inserting for us.
(when do-princ
(princ val))))
@@ -498,7 +507,8 @@ If there is no entry, prompt the user for the value to use.
The prompt text used is derived from the previous PROMPT command in the
template file.")
-(defmethod srecode-inserter-apply-state ((ins srecode-template-inserter-ask) STATE)
+(defmethod srecode-inserter-apply-state
+ ((ins srecode-template-inserter-ask) STATE)
"For the template inserter INS, apply information from STATE.
Loop over the prompts to see if we have a match."
(let ((prompts (oref STATE prompts))
@@ -669,7 +679,13 @@ Arguments ESCAPE-START and ESCAPE-END are the current escape sequences in use."
)
(defvar srecode-template-inserter-point-override nil
- "When non-nil, the point inserter will do this function instead.")
+ "Point-positioning method for the SRecode template inserter.
+When nil, perform normal point-positioning behavior.
+When the value is a cons cell (DEPTH . FUNCTION), call FUNCTION
+instead, unless the template nesting depth, measured
+by (length (oref srecode-template active)), is greater than
+DEPTH.")
+
(defclass srecode-template-inserter-point (srecode-template-inserter)
((key :initform ?^
@@ -702,15 +718,20 @@ Arguments ESCAPE-START and ESCAPE-END are the current escape sequences in use."
dictionary)
"Insert the STI inserter.
Save point in the class allocated 'point' slot.
-If `srecode-template-inserter-point-override' then this generalized
-marker will do something else. See `srecode-template-inserter-include-wrap'
-as an example."
- (if srecode-template-inserter-point-override
+If `srecode-template-inserter-point-override' non-nil then this
+generalized marker will do something else. See
+`srecode-template-inserter-include-wrap' as an example."
+ ;; If `srecode-template-inserter-point-override' is non-nil, its car
+ ;; is the maximum template nesting depth for which the override is
+ ;; valid. Compare this to the actual template nesting depth and
+ ;; maybe use the override function which is stored in the cdr.
+ (if (and srecode-template-inserter-point-override
+ (<= (length (oref srecode-template active))
+ (car srecode-template-inserter-point-override)))
;; Disable the old override while we do this.
- (let ((over srecode-template-inserter-point-override)
+ (let ((over (cdr srecode-template-inserter-point-override))
(srecode-template-inserter-point-override nil))
- (funcall over dictionary)
- )
+ (funcall over dictionary))
(oset sti point (point-marker))
))
@@ -751,9 +772,15 @@ Loops over the embedded CODE which was saved here during compilation.
The template to insert is stored in SLOT."
(let ((dicts (srecode-dictionary-lookup-name
dictionary (oref sti :object-name))))
+ (when (not (listp dicts))
+ (error "Cannot insert section %S from non-section variable."
+ (oref sti :object-name)))
;; If there is no section dictionary, then don't output anything
;; from this section.
(while dicts
+ (when (not (srecode-dictionary-p (car dicts)))
+ (error "Cannot insert section %S from non-section variable."
+ (oref sti :object-name)))
(srecode-insert-subtemplate sti (car dicts) slot)
(setq dicts (cdr dicts)))))
@@ -853,39 +880,44 @@ this template instance."
;; If there was no template name, throw an error
(if (not templatenamepart)
(error "Include macro %s needs a template name" (oref sti :object-name)))
- ;; Find the template by name, and save it.
- (if (or (not (slot-boundp sti 'includedtemplate))
- (not (oref sti includedtemplate)))
- (let ((tmpl (srecode-template-get-table (srecode-table)
- templatenamepart))
- (active (oref srecode-template active))
- ctxt)
+
+ ;; NOTE: We used to cache the template and not look it up a second time,
+ ;; but changes in the template tables can change which template is
+ ;; eventually discovered, so now we always lookup that template.
+
+ ;; Calculate and store the discovered template
+ (let ((tmpl (srecode-template-get-table (srecode-table)
+ templatenamepart))
+ (active (oref srecode-template active))
+ ctxt)
+ (when (not tmpl)
+ ;; If it isn't just available, scan back through
+ ;; the active template stack, searching for a matching
+ ;; context.
+ (while (and (not tmpl) active)
+ (setq ctxt (oref (car active) context))
+ (setq tmpl (srecode-template-get-table (srecode-table)
+ templatenamepart
+ ctxt))
(when (not tmpl)
- ;; If it isn't just available, scan back through
- ;; the active template stack, searching for a matching
- ;; context.
- (while (and (not tmpl) active)
- (setq ctxt (oref (car active) context))
- (setq tmpl (srecode-template-get-table (srecode-table)
- templatenamepart
- ctxt))
- (when (not tmpl)
- (when (slot-boundp (car active) 'table)
- (let ((app (oref (oref (car active) table) application)))
- (when app
- (setq tmpl (srecode-template-get-table
- (srecode-table)
- templatenamepart
- ctxt app)))
- )))
- (setq active (cdr active)))
- (when (not tmpl)
- ;; If it wasn't in this context, look to see if it
- ;; defines its own context
- (setq tmpl (srecode-template-get-table (srecode-table)
- templatenamepart)))
- )
- (oset sti :includedtemplate tmpl)))
+ (when (slot-boundp (car active) 'table)
+ (let ((app (oref (oref (car active) table) application)))
+ (when app
+ (setq tmpl (srecode-template-get-table
+ (srecode-table)
+ templatenamepart
+ ctxt app)))
+ )))
+ (setq active (cdr active)))
+ (when (not tmpl)
+ ;; If it wasn't in this context, look to see if it
+ ;; defines it's own context
+ (setq tmpl (srecode-template-get-table (srecode-table)
+ templatenamepart)))
+ )
+
+ ;; Store the found template into this object for later use.
+ (oset sti :includedtemplate tmpl))
(if (not (oref sti includedtemplate))
;; @todo - Call into a debugger to help find the template in question.
@@ -955,23 +987,31 @@ insert the section it wraps into the location in the included
template where a ^ inserter occurs."
;; Step 1: Look up the included inserter
(srecode-insert-include-lookup sti dictionary)
- ;; Step 2: Temporarilly override the point inserter.
- (let* ((vaguely-unique-name sti)
- (srecode-template-inserter-point-override
- (lambda (dict2)
- (if (srecode-dictionary-lookup-name
- dict2 (oref vaguely-unique-name :object-name))
- ;; Insert our sectional part with looping.
- (srecode-insert-method-helper
- vaguely-unique-name dict2 'template)
- ;; Insert our sectional part just once.
- (srecode-insert-subtemplate vaguely-unique-name
- dict2 'template))
- )))
+ ;; Step 2: Temporarily override the point inserter.
+ ;; We bind `srecode-template-inserter-point-override' to a cons cell
+ ;; (DEPTH . FUNCTION) that has the maximum template nesting depth,
+ ;; for which the override is valid, in DEPTH and a lambda function
+ ;; which implements the wrap insertion behavior in FUNCTION. The
+ ;; maximum valid nesting depth is just the current depth + 1.
+ (let ((srecode-template-inserter-point-override
+ (lexical-let ((inserter1 sti))
+ (cons
+ ;; DEPTH
+ (+ (length (oref srecode-template active)) 1)
+ ;; FUNCTION
+ (lambda (dict)
+ (let ((srecode-template-inserter-point-override nil))
+ (if (srecode-dictionary-lookup-name
+ dict (oref inserter1 :object-name))
+ ;; Insert our sectional part with looping.
+ (srecode-insert-method-helper
+ inserter1 dict 'template)
+ ;; Insert our sectional part just once.
+ (srecode-insert-subtemplate
+ inserter1 dict 'template))))))))
;; Do a regular insertion for an include, but with our override in
;; place.
- (call-next-method)
- ))
+ (call-next-method)))
(provide 'srecode/insert)