The manual says how a form is indented, and NEXT loses what landed
The indentation rules were written and tested but never described anywhere a user would look. MANUAL.md had no section on editing at all — it starts at `C-c C-c' and assumes the file is already written — so the rule that cost the friction, a binding vector lining up name under name, was only visible by trying it. What is written down is what was checked, not what the port was aimed at: the call fallback, the `handler-bind' clause vector, `defn' parameter alignment with a return type after it, and `restart-case' clause bodies were each reindented from scratch and the manual quotes the result. NEXT.md keeps the half of the field-label handover that is still open. The printer in render.ml has to move in the same commit as the inspector that parses it, and that is the inspector lane's; the font-lock half is done here, so only that half is struck.
This commit is contained in:
parent
c9e9d93a91
commit
64342c406e
17
NEXT.md
17
NEXT.md
@ -286,9 +286,11 @@ BUILT.md, "The colon belongs to keys".
|
|||||||
|
|
||||||
**What it left for the Emacs lane, both verified.** `render.ml` still *prints* a struct with colons, deliberately:
|
**What it left for the Emacs lane, both verified.** `render.ml` still *prints* a struct with colons, deliberately:
|
||||||
`emacs/flan-inspect.el:165` parses that output and hard-codes the colon when it reads a field out, so the printer
|
`emacs/flan-inspect.el:165` parses that output and hard-codes the colon when it reads a field out, so the printer
|
||||||
has to move in the same commit as its reader. And `flan-mode.el:61` font-locks `:name` as a constant with nothing
|
has to move in the same commit as its reader. That half is still open and belongs with whoever next opens the
|
||||||
matching `.name`, so a field label is now unfontified where it used to be coloured. Neither is urgent; both belong
|
inspector. ~~And `flan-mode.el:61` font-locks `:name` as a constant with nothing matching `.name`, so a field label
|
||||||
with whoever next opens `emacs/`.
|
is now unfontified where it used to be coloured.~~ **The font-lock half is done:** a field is drawn as a constant in
|
||||||
|
both of the spellings that exist while the corpus moves, so `{.x 1}` and the accessor `(.x v)` read alike, and the
|
||||||
|
keyword rule stayed where it was because the colon still means an enum member and a map key.
|
||||||
|
|
||||||
**7. `Map` follows Odin's implementation.** Read `base/runtime/dynamic_map_internal.odin` before writing any of it;
|
**7. `Map` follows Odin's implementation.** Read `base/runtime/dynamic_map_internal.odin` before writing any of it;
|
||||||
the checkout is at `~/Repositories/Odin`. Three properties are the ones worth copying, and they are stated in its own
|
the checkout is at `~/Repositories/Odin`. Three properties are the ones worth copying, and they are stated in its own
|
||||||
@ -423,9 +425,12 @@ run one lane at a time; item 4 is disjoint and runs alongside any of them.
|
|||||||
whole of the resource-cleanup answer.
|
whole of the resource-cleanup answer.
|
||||||
|
|
||||||
4. **The Emacs batch. Disjoint from the compiler, so it runs in parallel with anything above.** Globals in the break
|
4. **The Emacs batch. Disjoint from the compiler, so it runs in parallel with anything above.** Globals in the break
|
||||||
buffer; the buffer opening itself when the program stops; the indentation rewrite with `clojure-mode` as the
|
buffer; the buffer opening itself when the program stops; ~~the indentation rewrite with `clojure-mode` as the
|
||||||
reference; `#_`; hex, binary and addresses on primitives in the inspector. The indentation one is worth doing first
|
reference~~; ~~`#_`~~; hex, binary and addresses on primitives in the inspector. **The indentation rewrite and `#_`
|
||||||
within this batch — it costs friction on every keystroke today.
|
are done.** The indenter is ported from `clojure-mode`'s source rather than derived from it — `flan-mode` still
|
||||||
|
requires nothing outside stock Emacs — and it aligns a binding vector name-under-name, which is the bug that cost
|
||||||
|
friction on every keystroke. `defn` parameter lists and `restart-case` clause parameters were the same shape and
|
||||||
|
came with it. What remains in this batch is the break buffer and the inspector, and they are independent.
|
||||||
|
|
||||||
5. **Union values, then the macro expander, then `Result`/`try`.** Promoted above `Handle` on the author's call —
|
5. **Union values, then the macro expander, then `Result`/`try`.** Promoted above `Handle` on the author's call —
|
||||||
macros are the thing most worth wanting, and unions are the only thing between here and them.
|
macros are the thing most worth wanting, and unions are the only thing between here and them.
|
||||||
|
|||||||
@ -263,6 +263,49 @@ the inner binding.
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
## Writing it
|
||||||
|
|
||||||
|
`TAB` indents the line, and `C-M-q` the form under point. The rules are ported
|
||||||
|
from `clojure-mode`'s, because Clojure has the shapes Flan has and Emacs Lisp
|
||||||
|
does not — vectors that bind, bracket variety, and keys inside braces.
|
||||||
|
|
||||||
|
**A binding vector lines up name under name.** The second and later bindings of a
|
||||||
|
`let` sit under the first one's *name*, not under its value:
|
||||||
|
|
||||||
|
```
|
||||||
|
(let [vel (+ gravity (at velocity row col))
|
||||||
|
y (min (- rows 1) (+ row (i32 vel)))]
|
||||||
|
…)
|
||||||
|
```
|
||||||
|
|
||||||
|
The same rule draws `defn` parameter lists, `restart-case` and `handler-bind`
|
||||||
|
clause parameters, and both spellings of a struct literal — they are all a vector
|
||||||
|
or a brace read in pairs, so they are all indented as one.
|
||||||
|
|
||||||
|
**A body indents two.** `let`, `if`, `when`, `while`, `match`, `restart-case`,
|
||||||
|
`handler-bind`, `defn` and the `def…` forms all put their body two columns in
|
||||||
|
from the head. What differs between them is only how many forms come *before*
|
||||||
|
the body and stay on the head's line — a `let`'s binding vector, an `if`'s test,
|
||||||
|
a `restart-case`'s protected form — and the indenter knows that count per form.
|
||||||
|
|
||||||
|
A form it has no entry for is treated as a call: the arguments line up under the
|
||||||
|
first argument, not two in. That is the fallback, and it is what you want for
|
||||||
|
`(rl/draw-rectangle x y w h)` and for every function you write.
|
||||||
|
|
||||||
|
`defn` carries a return type between the parameter vector and the body, and it is
|
||||||
|
optional. The indenter does not need to know which — everything after the head
|
||||||
|
indents two, which is the right answer for the name, the parameters, a return type
|
||||||
|
if one is written, and the body alike.
|
||||||
|
|
||||||
|
**A field is drawn as a constant**, in the accessor `(.x v)` and as a label in
|
||||||
|
`{.x 1.0}`. The colon is still a constant too; it means an enum member, `:green`,
|
||||||
|
and a key in a map.
|
||||||
|
|
||||||
|
Nothing here needs a running program. Indentation and colouring are the major
|
||||||
|
mode's, so they work in a file you have only opened.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## Getting around
|
## Getting around
|
||||||
|
|
||||||
| Key | Does |
|
| Key | Does |
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user