lem icon indicating copy to clipboard operation
lem copied to clipboard

Templates

Open garlic0x1 opened this issue 1 year ago • 7 comments

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 avatar Jan 28 '24 22:01 garlic0x1

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.

garlic0x1 avatar Jan 28 '24 22:01 garlic0x1

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)

vindarel avatar Jan 29 '24 00:01 vindarel

  • 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.

garlic0x1 avatar Jan 29 '24 01:01 garlic0x1

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 )

vindarel avatar Jan 29 '24 11:01 vindarel

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 avatar Jan 30 '24 00:01 garlic0x1

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

garlic0x1 avatar Jan 30 '24 07:01 garlic0x1

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.

vindarel avatar Jan 30 '24 12:01 vindarel