As the title suggests, I essentially implemented a small, BNF-like mini-language on top of the skeleton language which allows otherwise very simple partial templates to expand into expressions of arbitrary complexity. With a bit of generalizing this approach can easily generate skeletons for other DSLs from the syntax of the DSL. The main reason I'm bringing it up is because I could use some input regarding whether it would be worth breaking this package apart into two separate ones (I could imagine using the same code to write an rx skeleton for example, could be neat) or whether this package is a product of overengineering and I'd be better off trying to simplify rather than generalize. (I'll try to explain my thought process below, but for those who prefer to get the bigger picture from the code itself can just skip straight to the Elisp.) Maybe I should first explain *why* I did this. This whole thing started with me trying to come up with a small typing aid to help me remember the syntax of the loop facility. Since I always liked the way features like auto-insert worked I decided I would like it to be based on an expansion mechanism with only minor completion features. I quickly realized that trying to generate an appropriate skeleton for this boiled down to basically rewrite the syntax specification, so that's exactly what I did. Here's an excerpt of CL's LOOP macro syntax taken from the CLHS: loop [name-clause] {variable-clause}* {main-clause}* => result* name-clause::= named name variable-clause::= with-clause | initial-final | for-as-clause with-clause::= with var1 [type-spec] [= form1] {and var2 [type-spec] [= form2]}* This structure translated quite naturally into an alist (with some minor additions for formatting and inlining options to make selection less tedious), where each element is either another keyword of the alist or a complex expression in my mini language (described in the docstring of `loopy-syntax-alist'): ((loop (list (symbol loop) (optional name-clause) (* variable-clause) (* main-clause))) ;; variable-clause::= with-clause | initial-final | for-as-clause (variable-clause (choose for as with initially finally) (newline)) ;; with-clause::= with var1 [type-spec] [= form1] (with (symbol with) variable type-spec (optional assignment) ;; {and var2 [type-spec] [= form2]}* (* (symbol and) variable type-spec (optional assignment))) ...) All that is left at that point to obtain a skeleton is to recursively expand the syntax into subskeletons and skeleton elements, prompting the user whenever a decision needs to be made or some arbitrary sexp needs to be inserted (lists to be iterated over, bodies of do statements, etc). (define-skeleton loopy-insert "Insert a LOOP macro interactively." ;;; long docstring nil ;; This command generates the above alist with some parameters to ;; account for both Common Lisp's LOOP and Emacs Lisp's cl-loop. '(loopy--init-alist) (loopy--expand 'loop) -1) Obviously the main complexity of the package rests in the implementation of loopy--expand, and to generalize this package would mean to provide a way to define one's own syntax elements (so some kind of defsyntax) to provide things like `arithmetic-clause', see loopy-syntax-alist (docstring), loopy--expand and for example loopy--expand-arithmetic. As a consequence loopy.el would shrink by quite a bit and whatever-package-name.el could be utilized for other projects more easily.. if it is worth reusing.