Every tracked .flan file reindents to itself
This commit is contained in:
commit
5214343251
13
TODO.org
13
TODO.org
@ -1821,10 +1821,15 @@ pass. Deriving from clojure-mode at runtime stays rejected: it would add an
|
|||||||
external dependency to a mode that ships in this repository and needs nothing
|
external dependency to a mode that ships in this repository and needs nothing
|
||||||
beyond stock Emacs, and that community is mid-transition to a tree-sitter mode.
|
beyond stock Emacs, and that community is mid-transition to a tree-sitter mode.
|
||||||
|
|
||||||
** TODO 373 lines in 20 files still reindent differently
|
** DONE Every tracked .flan file reindents to itself
|
||||||
Concentrated in four files, untouched by the Emacs pass and untouched before it.
|
CLOSED: [2026-09-25]
|
||||||
The indenter and the hand-formatting there disagree about shapes nothing has
|
clojure-mode decided each shape. The indenter was wrong on one: a =with-= head,
|
||||||
looked at.
|
and a qualified =def…= or =with-= head, now indents as a body, and a qualified
|
||||||
|
name finds its unqualified part's spec. The rest was hand formatting and was
|
||||||
|
reindented: a =cond= or =match= result on its own line sits under its test, and
|
||||||
|
an ordinary call's later arguments align under its first. A lone =;= comment
|
||||||
|
line goes to =comment-column= in every Lisp mode, so continuation comments are
|
||||||
|
written as =;;= lines above the code instead.
|
||||||
|
|
||||||
** DONE C-c C-i inspects the expression at point
|
** DONE C-c C-i inspects the expression at point
|
||||||
No prompt, because the expression is already written in the buffer. =C-u= opens
|
No prompt, because the expression is already written in the buffer. =C-u= opens
|
||||||
|
|||||||
@ -585,8 +585,22 @@ Anything not named here that begins with `def' is treated as `:defn' by
|
|||||||
`flan-indent-function'; anything else indents as a function call.")
|
`flan-indent-function'; anything else indents as a function call.")
|
||||||
|
|
||||||
(defun flan--indent-spec (name)
|
(defun flan--indent-spec (name)
|
||||||
"The indent spec for the form called NAME, or nil."
|
"The indent spec for the form called NAME, or nil.
|
||||||
(and name (cdr (assoc name flan-indent-specs))))
|
A qualified name falls back to its unqualified part, so `rl/when' would find
|
||||||
|
the entry for `when' — `clojure--get-indent-method' does the same."
|
||||||
|
(and name
|
||||||
|
(cdr (or (assoc name flan-indent-specs)
|
||||||
|
(and (string-match "/\\([^/]+\\)\\'" name)
|
||||||
|
(assoc (match-string 1 name) flan-indent-specs))))))
|
||||||
|
|
||||||
|
(defun flan--definer-p (name)
|
||||||
|
"Non-nil if NAME indents as a definition or a `with-' form.
|
||||||
|
Either may be qualified: `rl/with-drawing' is a `with-' form. This is
|
||||||
|
`clojure-indent-function''s fallback for a head with no spec, regexp and all;
|
||||||
|
`default…' is excluded there because it is not a definer, and here too."
|
||||||
|
(and name
|
||||||
|
(string-match "\\`\\(?:\\S +/\\)?\\(def[a-z]*\\|with-\\)" name)
|
||||||
|
(not (string-match-p "\\`default" (match-string 1 name)))))
|
||||||
|
|
||||||
(defconst flan--labelled-forms '("dotimes" "while" "until")
|
(defconst flan--labelled-forms '("dotimes" "while" "until")
|
||||||
"Loops that may carry a label, which `break' and `continue' name.
|
"Loops that may carry a label, which `break' and `continue' name.
|
||||||
@ -755,8 +769,9 @@ decision to `calculate-lisp-indent'."
|
|||||||
;; No spec. Anything else spelled `def…' is a definition and indents
|
;; No spec. Anything else spelled `def…' is a definition and indents
|
||||||
;; like one, which covers `defstruct', `defdata', `defunion',
|
;; like one, which covers `defstruct', `defdata', `defunion',
|
||||||
;; `defenum', `defonce', `defconst' and `defalias' without naming
|
;; `defenum', `defonce', `defconst' and `defalias' without naming
|
||||||
;; them.
|
;; them. A `with-' form is a body too — `rl/with-drawing',
|
||||||
((and name (string-match-p "\\`def" name))
|
;; `rl/with-mode-2d camera' — whatever it takes before the body.
|
||||||
|
((flan--definer-p name)
|
||||||
(+ lisp-body-indent head-column))
|
(+ lisp-body-indent head-column))
|
||||||
;; A clause: `(name [params] body…)'. `handler-bind', `handler-case'
|
;; A clause: `(name [params] body…)'. `handler-bind', `handler-case'
|
||||||
;; and `restart-case' all write their clauses this way, and the head is
|
;; and `restart-case' all write their clauses this way, and the head is
|
||||||
|
|||||||
@ -326,6 +326,54 @@
|
|||||||
y 2.0]
|
y 2.0]
|
||||||
(print y))")
|
(print y))")
|
||||||
|
|
||||||
|
;; A `with-' form is a body, qualified or not, whatever it takes on the head's
|
||||||
|
;; line — `clojure-indent-function''s fallback. From `examples/core-2d-camera.flan'.
|
||||||
|
(test-flan-mode--check
|
||||||
|
"a qualified with- form indents its body by two past an argument"
|
||||||
|
"(rl/with-mode-2d camera
|
||||||
|
(rl/draw-rectangle-rec player rl/red)
|
||||||
|
(rl/draw-grid 10 1.0))")
|
||||||
|
|
||||||
|
(test-flan-mode--check
|
||||||
|
"a qualified def form indents its body by two"
|
||||||
|
"(m/defthing name
|
||||||
|
(body))")
|
||||||
|
|
||||||
|
;; A qualified name finds the spec of its unqualified part.
|
||||||
|
(test-flan-mode--check
|
||||||
|
"a qualified when keeps when's spec"
|
||||||
|
"(rl/when (ready?)
|
||||||
|
(go))")
|
||||||
|
|
||||||
|
;; `default…' begins with `def' and is not a definer.
|
||||||
|
(test-flan-mode--check
|
||||||
|
"a default-prefixed call aligns its arguments"
|
||||||
|
"(default-color a
|
||||||
|
b)")
|
||||||
|
|
||||||
|
;; A cond result on its own line sits under its test, not deeper.
|
||||||
|
(test-flan-mode--check
|
||||||
|
"a cond result on its own line aligns with its test"
|
||||||
|
"(cond
|
||||||
|
(= k 1)
|
||||||
|
(one)
|
||||||
|
:else
|
||||||
|
(other))")
|
||||||
|
|
||||||
|
(test-flan-mode--check
|
||||||
|
"a match result on its own line aligns with its pattern"
|
||||||
|
"(match v
|
||||||
|
(Int n) n
|
||||||
|
(List items)
|
||||||
|
(length items))")
|
||||||
|
|
||||||
|
;; A trailing argument of an ordinary call aligns under the first argument,
|
||||||
|
;; even when it is long; only a `with-', `def' or specced head gives a body.
|
||||||
|
(test-flan-mode--check
|
||||||
|
"an ordinary call's arguments align under the first one"
|
||||||
|
"(push missing
|
||||||
|
`(when (ok) (go)))")
|
||||||
|
|
||||||
|
|
||||||
;;; Font lock
|
;;; Font lock
|
||||||
|
|
||||||
|
|||||||
@ -13,8 +13,8 @@
|
|||||||
;; Normative references: spec-memory.md (ownership, containers, places,
|
;; Normative references: spec-memory.md (ownership, containers, places,
|
||||||
;; generics, function values) and spec-conditions.md (restart semantics).
|
;; generics, function values) and spec-conditions.md (restart semantics).
|
||||||
|
|
||||||
(import rl "vendor:raylib") ; directory = package, declaration optional;
|
;; Imports are always qualified: rl/foo.
|
||||||
; imports are always qualified rl/foo
|
(import rl "vendor:raylib") ; directory = package, declaration optional
|
||||||
|
|
||||||
;; ── Type notation ─────────────────────────────────────────────────────
|
;; ── Type notation ─────────────────────────────────────────────────────
|
||||||
;; [4 f32] fixed array — a value, copies on assignment
|
;; [4 f32] fixed array — a value, copies on assignment
|
||||||
|
|||||||
@ -213,8 +213,9 @@
|
|||||||
|
|
||||||
;; ── The refusals, each asserted on its own reason ─────────────────
|
;; ── The refusals, each asserted on its own reason ─────────────────
|
||||||
(refusal "\"a\\nb\"") ; an escape inside a string
|
(refusal "\"a\\nb\"") ; an escape inside a string
|
||||||
(refusal "\"a\\\"b\"") ; an escaped quote — the case where a wrong
|
;; An escaped quote is the case where a wrong version returns `a\` and
|
||||||
; version returns `a\` and leaves `b"` behind
|
;; leaves `b"` behind.
|
||||||
|
(refusal "\"a\\\"b\"") ; an escaped quote
|
||||||
(refusal "\"unterminated") ; not a refusal, but the other string failure
|
(refusal "\"unterminated") ; not a refusal, but the other string failure
|
||||||
;; A set is read now, so what is left to refuse about one is its balance. A
|
;; A set is read now, so what is left to refuse about one is its balance. A
|
||||||
;; `#{` that pushed nothing would answer "no error" for both of these.
|
;; `#{` that pushed nothing would answer "no error" for both of these.
|
||||||
@ -228,8 +229,8 @@
|
|||||||
(refusal "\\a") ; a character literal
|
(refusal "\\a") ; a character literal
|
||||||
(refusal "12x") ; starts like a number, is not one
|
(refusal "12x") ; starts like a number, is not one
|
||||||
(refusal "[1 :]") ; a colon with no name
|
(refusal "[1 :]") ; a colon with no name
|
||||||
(refusal "@") ; not the start of any value — and the case a
|
;; `@` is the case a scan-to-delimiter reads as a one-byte symbol.
|
||||||
; scan-to-delimiter reads as a one-byte symbol
|
(refusal "@") ; not the start of any value
|
||||||
(refusal "`x") ; a Clojure reader macro, not EDN
|
(refusal "`x") ; a Clojure reader macro, not EDN
|
||||||
(refusal "[1 2}") ; the wrong closer
|
(refusal "[1 2}") ; the wrong closer
|
||||||
(refusal "]") ; a closer with nothing open
|
(refusal "]") ; a closer with nothing open
|
||||||
|
|||||||
@ -102,9 +102,9 @@
|
|||||||
(show-dec (slice lone-cont 0 1)) ; a continuation byte leading
|
(show-dec (slice lone-cont 0 1)) ; a continuation byte leading
|
||||||
(show-dec (slice overlong2 0 2)) ; overlong "/"
|
(show-dec (slice overlong2 0 2)) ; overlong "/"
|
||||||
(show-dec (slice overlong3 0 3)) ; overlong "/" again, three bytes
|
(show-dec (slice overlong3 0 3)) ; overlong "/" again, three bytes
|
||||||
(show-dec (slice overlong4 0 4)) ; and four. Added after a mutation run:
|
;; Added after a mutation run: relaxing 0xf0's floor to 0x80 left the
|
||||||
; relaxing 0xf0's floor to 0x80 left the
|
;; whole suite green without this line.
|
||||||
; whole suite green without this line.
|
(show-dec (slice overlong4 0 4)) ; and four
|
||||||
(show-dec (slice surrogate 0 3)) ; U+D800
|
(show-dec (slice surrogate 0 3)) ; U+D800
|
||||||
(show-dec (slice above-max 0 4)) ; U+110000
|
(show-dec (slice above-max 0 4)) ; U+110000
|
||||||
(show-dec (slice lead-f5 0 4)) ; 0xf5 leads nothing
|
(show-dec (slice lead-f5 0 4)) ; 0xf5 leads nothing
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user