Skip to content

Conversation

garlic0x1
Copy link
Collaborator

lem-template

A templating extension to generate boilerplate in new files.

Usage

Here is an example template file that generates a simple .asd to help get you started.

(asdf:defsystem "<%= (pathname-name (@ path)) %>"
  :author ""
  :license "MIT"
  :depends-on ()
  :components ((:module "src"
                :components ((:file "core")))))

Assuming this file exists in ~/.config/lem/templates/asd.clt, you can register it like this:

(lem-template:register-template
 :pattern ".*\.asd"
 :file (merge-pathnames "templates/asd.clt" (lem-home)))

You can create any kind of template you want in the cl-template format, buffer and path are passed to the template and you can read it with (@ buffer) etc.

Examples

See my templates for more examples, I used the plural register-templates to register them like this:

(register-templates
  (:pattern ".*\.asd"  :file (merge-pathnames "templates/asd.clt"      (lem-home)))
  (:pattern ".*\.lisp" :file (merge-pathnames "templates/lisp.clt"     (lem-home)))
  (:pattern ".*\.go"   :file (merge-pathnames "templates/go.clt"       (lem-home)))
  (:pattern "Makefile" :file (merge-pathnames "templates/Makefile.clt" (lem-home))))

@garlic0x1
Copy link
Collaborator Author

I am not sure if depending on cl-template in an extension asd file is okay, however I think it might be worth adding it in the qlfile because it will be useful if we want to add snippets as well.

@vindarel
Copy link
Collaborator

vindarel commented Jan 29, 2024

Wow, I like the possibilities very much.

code:

  • I personally am not a fan of line-up-first, which is the -> arrow macro with a weird name (first time used in Lem)

I tried quickly:

  • using the command the first time, with no registered template, it does and says nothing. It should inform of something.
  • "(@ buffer) etc." document better the variables we can access. It's best to document cl-template here and avoid that the user has to read cl-template's README… like in Stack Overflow, it's best to have the doc self-contained IMO. Or… copy its README and ship it? At least as a user I'd appreciate more examples.
  • minor: I was expecting the template to be inserted at the current point. If I am at the end of an existing .asd file and I call M-x insert-template, it is inserted at the top and I don't see it.
  • also message the user that the template was inserted? (I was puzzled, did not see it)

more feedback:

  • definitely ship ready-to-use templates, at least for CL.
  • what about a project skeleton? Create the .asd, and src/, and packages.lisp, and more.
  • can we have several templates per file type, give them a name and a description?

if we want to add snippets as well.

definitely IMO. (cl-template has 0 dependencies)

@garlic0x1
Copy link
Collaborator Author

  • Insert location and messages
    I removed the command so this shouldn't be much of an issue, I really only intend for this to be used in an automatic fashion, a snippets package with an M-x command would be better for some of this.
  • Arrow macros
    We already have alexandria, I don't want to add more dependencies unless there are already arrow macros somewhere I didn't notice.
  • Default templates
    Feel free to add some, I will keep my collection linked in the readme for examples, but I don't have a collection I am sure everyone will benefit from yet. It also might be better to put them in the lisp-mode, c-mode, &rest extensions.
  • Project skeleton
    This is a really good idea, perhaps I could make it so you could register a directory of templates that recursively create files.
  • Named templates
    Again, I think this would be better suited to a snippets extension that is more interactive, instead of automatic.

I think the next thing I will make will be a snippets system, which hopefully will cover most of the other features you want.

@vindarel
Copy link
Collaborator

vindarel commented Jan 29, 2024

Oh, I found the interactive command useful. I think it just needed one or two checks and "message"s more.

(yes no need to pull an arrow macro dependency; maybe not use line-up-first ? : D )

@garlic0x1
Copy link
Collaborator Author

Okay, I have added the option to use named templates, if there are multiple templates registered for a pattern, it prompts the user to choose one, otherwise it automatically uses the only one there is.

(lem-template:register-templates
    (:pattern ".*\.asd"
     :name "Basic ASD"
     :file (merge-pathnames "templates/asd.clt" (lem-home)))
    (:pattern ".*\.asd"
     :name "Test ASD"
     :file (merge-pathnames "templates/test.asd.clt" (lem-home)))
    (:pattern ".*\.lisp"
     :file (merge-pathnames "templates/lisp.clt" (lem-home))))

Here there are two named options for .asd files, and one unnamed template for .lisp files. This is what it looks like to use:

Screencast.from.2024-01-29.18-27-33.webm

I will spend some time cleaning up and testing more today.

@garlic0x1
Copy link
Collaborator Author

Added register-snippet, register-snippets, and insert-snippet

You can use a file, like with templates, or just a string if its small.

(register-snippets
  (:mode 'lem-lisp-mode:lisp-mode
   :name "test"
   :string "(message \"testing\")")
  (:mode 'lem-lisp-mode:lisp-mode
   :name "hi"
   :string "(message \"hi\")")
  (:mode 'lem-go-mode:go-mode
   :name "loop"
   :file (merge-pathnames "snippets/loop.go.clt" (lem-home)))
  (:mode 'lem-go-mode:go-mode
   :name "err"
   :file (merge-pathnames "snippets/if-err.go.clt" (lem-home))))
snippets.webm

@vindarel
Copy link
Collaborator

Awesome.

minor:

  • str:empty? is "deprecated", we prefer emptyp.
  • your utils could probably benefit to the Lem package. Maybe buffer/file.lisp is a good place, not sure.

@ryukinix
Copy link
Contributor

This is very interesting. I'd like to see this getting merged to lem main branch someday.

@cianoc
Copy link
Contributor

cianoc commented Aug 6, 2025

What prevents this from being merged? Are you still planning to work on this @garlic0x1 ? And if not, what would be required for this to be of mergable quality?

@garlic0x1
Copy link
Collaborator Author

I use Emacs these days and will not be working on this PR. Anyone else is free to take over.

@cianoc
Copy link
Contributor

cianoc commented Aug 7, 2025

I'm happy to take this over.

Possibly easier if I create a new pull request. Let me know @vindarel

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants