The manual says the following.
Subskeletons are inserted recursively, not once, but as often as the user enters something at the subskeletons interactor. Thus there must be a str
in the subskeleton. They can also be used non-interactively, when prompt is a lisp-expression that returns successive list-elements.
(Emphasis is mine, see section Skeleton Language for more.)
Here's what this means:
By default it repeats until you hit RET
or C-g
:
(define-skeleton skeleton-repeat-until-tired "repeat until tired"
"" ; empty top-level interactor
("Enter something here, or press %s: " ; stops on empty input string
"You entered '" str "'.\n"))
To execute a subskeleton once, use ("")
as the interactor:
(define-skeleton skeleton-once "executes a subskeletons once"
"" ; empty top-level interactor
(("")
"insert stuff\n"))
This is just a special case of an interactor used to loop over several strings:
(define-skeleton skeleton-loop-1 "subskeletons as loops"
"" ; empty top-level interactor
(("a" "b" "c") ; list if strings, execute subskeleton once per element
"str is " str "\n"))
You can compute these strings based on the context, too:
(defun my-strings ()
(list (format "you were at line %d" (line-number-at-pos))))
(define-skeleton skeleton-loop-2 "subskeletons as loops"
"" ; empty top-level interactor
`(,(my-strings) ; list if strings, execute subskeleton once per element
"str is " str "\n"))
Here's one way to use this information to fix your skeleton:
(define-skeleton my-func-skeleton "func skeleton"
""
(if (looking-back "\n")
;; A function at left of screen is a top level function.
`((,(skeleton-read "Function name: "))
"// " str " ." \n
"func " str "(" @ ") {" \n
_ @ \n
-1 "}")
;; Otherwise it is an anonymous function.
'(("")
"func () {" \n
_ \n
-1 "}")))