lem
lem copied to clipboard
Templates
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))))
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.
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)
- 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.
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 )
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.
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))))
Awesome.
minor:
-
str:empty?
is "deprecated", we preferemptyp
. - your utils could probably benefit to the Lem package. Maybe
buffer/file.lisp
is a good place, not sure.