A negated name counts as the name an arm's pattern binds, and a comment belongs to the form or block whose column it sits at

This commit is contained in:
Joseph Ferano 2026-09-25 21:02:19 +07:00
parent 4d3688a519
commit 095701b29b
2 changed files with 51 additions and 9 deletions

View File

@ -680,6 +680,10 @@ a `(' -- a pattern's constructor, which binds nothing."
(let (names)
(while (re-search-forward "\\(?:\\sw\\|\\s_\\)+" nil t)
(let ((n (match-string-no-properties 0)))
;; A `-' glued to a letter, `$', `_' or `*' is negation, not part
;; of the name (`is_neg_char' in lib/indent_reader.ml): `-n' is n.
(when (string-match "\\`-[a-zA-Z$_*]" n)
(setq n (substring n 1)))
(unless (and skip-heads (eq (char-after) ?\())
(push n names)
(dolist (part (split-string n "\\." t))
@ -1563,14 +1567,25 @@ that says so and otherwise is its own."
(and (flan-fln--blank-p pos) (not (flan-fln--empty-line-p pos))))
(defun flan-fln--with-comments (b)
"Whole lines B, and the comment lines directly above them: a comment block
with no blank line under it belongs to what it sits on."
"Whole lines B, and the comments that belong to them.
Above: a comment block at B's own column with no blank line under it.
Below: comment lines deeper than B's column straight after it, which close
its block. A comment at another column belongs to the block it lines up
with."
(and b (save-excursion
(goto-char (car b))
(while (and (zerop (forward-line -1))
(flan-fln--comment-line-p (point)))
(setq b (cons (point) (cdr b))))
b)))
(let ((col (flan-fln--indent-at (car b))))
(goto-char (car b))
(while (and (zerop (forward-line -1))
(flan-fln--comment-line-p (point))
(= (current-indentation) col))
(setq b (cons (point) (cdr b))))
(goto-char (cdr b))
(while (and (not (eobp))
(flan-fln--comment-line-p (point))
(> (current-indentation) col))
(forward-line 1)
(setq b (cons (car b) (point))))
b))))
(defun flan-fln--commented-toplevel (pos)
"The top-level form at POS, whole lines with its comment block.
@ -1579,6 +1594,7 @@ On a comment block that sits directly on a form, that form."
(goto-char pos)
(beginning-of-line)
(while (and (flan-fln--comment-line-p (point))
(zerop (current-indentation))
(zerop (forward-line 1))))
(if (flan-fln--toplevel-start-p (point)) (point) pos))))
(flan-fln--with-comments

View File

@ -533,7 +533,9 @@ comment:
(dolist (c '(("Some(_v) -> _v + 1" "a name starting with _")
("Some(éé) -> éé" "a name that is not ASCII")
("Some(N) -> N" "a capitalised name")
("Some(p) -> p.x" "a name used as a field's base")))
("Some(p) -> p.x" "a name used as a field's base")
("Some(n) -> -n" "a name its value negates")
("Some(p) -> -p.x" "a name whose field its value negates")))
(test-flan-fln--in (concat "fn f(o: Option(i64)) -> i64\n match o\n " (car c) "\n")
(goto-char (point-max))
(skip-chars-backward "\n")
@ -888,7 +890,31 @@ comment:
"; loose\n\n; on f\nfn f() -> ()\n a()\n; after f\n\n; on g\nfn g() -> ()\n")))
(test-flan-fln--is (format "under Evil, %s on %s keeps comments with their forms"
(car c) (nth 1 c))
(funcall deleted (car c) (nth 1 c)) (nth 2 c))))
(funcall deleted (car c) (nth 1 c)) (nth 2 c)))
;; A comment deeper than a form, at the end of its block, is
;; that block's, not the next form's.
(dolist (c '(("dad" "fn a" "fn a() -> i64\n 1\n ; end of a\nfn b() -> i64\n 2\n"
"fn b() -> i64\n 2\n")
("dad" "fn b" "fn a() -> i64\n 1\n ; end of a\nfn b() -> i64\n 2\n"
"fn a() -> i64\n 1\n ; end of a\n")
("das" "let y"
"fn a(x: i64) -> i64\n if x > 0\n 1\n ; end of the if\n let y = 2\n y\n"
"fn a(x: i64) -> i64\n if x > 0\n 1\n ; end of the if\n y\n")))
(let ((b (generate-new-buffer "owned.fln")))
(switch-to-buffer b)
(insert (nth 2 c))
(flan-fln-mode)
(evil-initialize-state)
(evil-normal-state)
(goto-char (point-min))
(search-forward (nth 1 c))
(goto-char (match-beginning 0))
(execute-kbd-macro (car c))
(test-flan-fln--is (format "under Evil, %s on %s: a deeper comment stays with the block above"
(car c) (nth 1 c))
(buffer-string) (nth 3 c))
(set-buffer-modified-p nil)
(kill-buffer b))))
(let ((b (generate-new-buffer "keys.fln")))
(switch-to-buffer b)
(insert "fn f() -> i32 = 1\n")