Recently Written · git

tmpl

Insanely simple templates

git clone https://github.com/equwal/tmpl

Log | Files | Refs


README.md (3928 bytes)

1 ![template jump <++> on a transparent background](https://therealtruex.com/static/tmpl.webp)
2 
3 Templates for all kinds of things. Read a file into your editor at the cursor
4 and jump to the `<++>` locations.
5 
6 A [therealtruex.com](https://therealtruex.com) project.
7 
8 Here is one such template:
9 ```
10 (defpackage :<++>-system (:use :cl :asdf))
11 (in-package :<++>-system)
12 (defsystem <++>
13   :name "<++>"
14   :author "<++> <<++>@<++>.<++>>"
15   :version "<++>"
16   :maintainer "<++> <<++>@<++>.<++>>"
17   :license "GNU GPLv3.0"
18   :description "<++>"
19   ;; put the most general files first to minimize the "depends on" use
20   ;; and in that case you'll need :serial t
21   :serial <++>
22   :components ((:file "packages")
23                (:file "<++>" :depends-on ("<++>")))
24   :weakly-depends-on (<++>)
25   :depends-on (<++>))
26 ```
27 
28 # Layout
29 
30 One directory per language: `c`, `cl` (Common Lisp), `sh` (POSIX shell),
31 `sed`, `awk`, `make`, `vim`, `html`. A few loose templates sit at the root
32 (`openrc.init`, `git-config-branch`, `uad.json`).
33 
34 Two kinds of file live here:
35 
36 - **Templates** contain `<++>`. Read them in and fill the gaps.
37 - **Cheat sheets** contain no `<++>` (for example `sed/TLDR`, `vim/use-g-v`,
38   most of `sh/`). They are notes to read or `:read` in whole. The snippet
39   converter skips them.
40 
41 # Conventions
42 
43 - The first line of a template is a one-line summary in the language's
44   comment syntax (`#`, `;;`, `//` or `<!-- -->`). Tools read it as the
45   description. A `#!` line may come before it.
46 - `<++>` marks a spot to fill. `<+name+>` does the same and names the spot,
47   for example `<+remote+>`. The snippet converter turns the name into the
48   placeholder text. Use the plain form unless a name helps.
49 
50 # Finding a template
51 
52 `bin/tmpl` lists and prints templates. Put it on your `PATH` or call it by
53 path.
54 
55 ```sh
56 tmpl -l                    # list every file with its summary
57 tmpl -f                    # pick one with fzf and print it
58 tmpl sh for-find           # print sh/for-find
59 tmpl sh/trap/cleanup-temp  # the same, as one path
60 ```
61 
62 In Vim, `:r !tmpl sh for-find` reads a template in at the cursor.
63 
64 [INDEX.md](INDEX.md) is the same list as a table. `make index` regenerates it.
65 
66 # Using with Vim
67 
68 ```vim
69 :read /path/to/tmpl/thing
70 ```
71 
72 Add a shortcut on your leader key that jumps to the next placeholder, deletes
73 it, and leaves you in insert mode. The pattern matches both `<++>` and
74 `<+name+>`.
75 
76 Vimscript:
77 ```vim
78 map <leader><Space> /<+.\{-}+><CR>dt>a<BS>
79 ```
80 
81 Lua:
82 ```lua
83 map("n", "<leader><Space>", "/<+.\\{-}+><CR>dt>a<BS>", { desc = "Jump to next template placeholder" })
84 ```
85 
86 # Using with Neovim and LuaSnip
87 
88 `convert_to_luasnip.py` turns every template into a VSCode-format snippet.
89 Each language becomes one JSON file, and a `package.json` lists them for the
90 LuaSnip loader.
91 
92 ```sh
93 python3 convert_to_luasnip.py --dry-run          # list what would be written
94 python3 convert_to_luasnip.py                    # write to ~/.config/nvim/snippets
95 python3 convert_to_luasnip.py --output some/dir  # write elsewhere
96 ```
97 
98 Load the output in your Neovim config:
99 ```lua
100 require("luasnip.loaders.from_vscode").lazy_load({
101     paths = { vim.fn.stdpath("config") .. "/snippets" }
102 })
103 ```
104 
105 The snippet prefix is the path with dashes: `c/main.c` is `c-main`,
106 `sh/trap/cleanup-temp` is `sh-trap-cleanup-temp`. The description is the
107 template's summary comment. Type the prefix, press Tab, and Tab again to move
108 between the placeholders.
109 
110 # Checks
111 
112 ```sh
113 python3 -m pip install pytest hypothesis
114 make check
115 ```
116 
117 `make check` parses the shell templates with `sh -n` and `shellcheck`,
118 compiles the C templates, reads the Lisp templates with `sbcl` when it is
119 installed, runs the Python tests, and confirms `INDEX.md` is current. The
120 GitHub Actions workflow runs the same target.
121 
122 # POSIX shell tricks
123 
124 Many of the shell tricks come from https://www.etalabs.net/sh_tricks.html,
125 especially `sh/for-find`, a nightmare fixed-point solution.