Emacs offers no binding column after a binding's else block, and offers one after a first binding whose bracketed lambda has closed
This commit is contained in:
parent
349e2d7e72
commit
f7781dbb78
@ -1357,6 +1357,24 @@ block lambda inside brackets, whose block closes with them."
|
|||||||
(= (car (save-excursion (syntax-ppss (flan-fln--code-end last))))
|
(= (car (save-excursion (syntax-ppss (flan-fln--code-end last))))
|
||||||
(car (save-excursion (syntax-ppss (flan-fln--first-char l))))))))
|
(car (save-excursion (syntax-ppss (flan-fln--first-char l))))))))
|
||||||
|
|
||||||
|
(defun flan-fln--bindings-ended-p (l)
|
||||||
|
"Non-nil if the line L, on a block column above, is a let's binding whose
|
||||||
|
value ended in an open block, so no binding and no clause may follow at its
|
||||||
|
column. An `if', `handler-case', `handler-bind' or `restart-case' value
|
||||||
|
still takes a clause there, and so does the line after an `elif', `on' or
|
||||||
|
`restart'; after an `else', nothing does."
|
||||||
|
(save-excursion
|
||||||
|
(goto-char (flan-fln--first-char l))
|
||||||
|
(cond
|
||||||
|
((flan-fln--clause-line-p l)
|
||||||
|
(and (looking-at "else\\_>")
|
||||||
|
(let ((h (flan-fln--clause-header l)))
|
||||||
|
(and (not (eq h l)) (flan-fln--binding-let h) (flan-fln--open-ended-p h)))))
|
||||||
|
(t (and (flan-fln--binding-let l) (flan-fln--open-ended-p l)
|
||||||
|
(let ((v (flan-fln--value-start l)))
|
||||||
|
(not (and v (progn (goto-char v)
|
||||||
|
(looking-at "\\(?:if\\|handler-case\\|handler-bind\\|restart-case\\)\\_>"))))))))))
|
||||||
|
|
||||||
(defun flan-fln--levels (pos)
|
(defun flan-fln--levels (pos)
|
||||||
"Columns TAB offers POS's line outside brackets, deepest first.
|
"Columns TAB offers POS's line outside brackets, deepest first.
|
||||||
Not the column of a let's binding whose value ended in an open block: that
|
Not the column of a let's binding whose value ended in an open block: that
|
||||||
@ -1365,9 +1383,9 @@ the reader refuses any line there."
|
|||||||
(let* ((prev (flan-fln--prev-code pos))
|
(let* ((prev (flan-fln--prev-code pos))
|
||||||
(stack (mapcar #'car
|
(stack (mapcar #'car
|
||||||
(seq-remove (lambda (e)
|
(seq-remove (lambda (e)
|
||||||
(and (cdr e) (flan-fln--binding-let (cdr e))
|
(and (cdr e) (flan-fln--bindings-ended-p (cdr e))))
|
||||||
(flan-fln--open-ended-p (cdr e))))
|
(flan-fln--stack pos))))
|
||||||
(flan-fln--stack pos)))))
|
(owner (and prev (flan-fln--outside-block (flan-fln--logical-start prev) pos))))
|
||||||
(cond
|
(cond
|
||||||
;; A lambda's block goes under the line its `=>' ends, which may be a
|
;; A lambda's block goes under the line its `=>' ends, which may be a
|
||||||
;; line of a call wrapped inside its brackets.
|
;; line of a call wrapped inside its brackets.
|
||||||
@ -1380,8 +1398,10 @@ the reader refuses any line there."
|
|||||||
;; After a let's line, its next binding's column too, lined up with
|
;; After a let's line, its next binding's column too, lined up with
|
||||||
;; its first name -- second, so RET after a let stays at its column.
|
;; its first name -- second, so RET after a let stays at its column.
|
||||||
;; After a binding line, that column is on the stack, first.
|
;; After a binding line, that column is on the stack, first.
|
||||||
((and prev (flan-fln--let-line-p (flan-fln--logical-start prev)))
|
;; A block lambda whose brackets closed on the line above counts as
|
||||||
(let ((b (flan-fln--binding-column (flan-fln--logical-start prev))))
|
;; that let's line: its block is shut, and a binding may follow.
|
||||||
|
((and owner (flan-fln--let-line-p owner) (not (flan-fln--open-ended-p owner)))
|
||||||
|
(let ((b (flan-fln--binding-column owner)))
|
||||||
(if (or (null b) (memq b stack)) stack
|
(if (or (null b) (memq b stack)) stack
|
||||||
(cons (car stack) (cons b (cdr stack))))))
|
(cons (car stack) (cons b (cdr stack))))))
|
||||||
(t stack))))
|
(t stack))))
|
||||||
|
|||||||
@ -943,7 +943,15 @@ defconst(k, 3)
|
|||||||
("fn f()\n let a = 1\n b = match a\n 1 -> 2\n|" (8 2 0) "a match's arms")
|
("fn f()\n let a = 1\n b = match a\n 1 -> 2\n|" (8 2 0) "a match's arms")
|
||||||
("let a = 0\n g = fn(x) =>\n x + 1\n|" (6 0) "a global's lambda block")
|
("let a = 0\n g = fn(x) =>\n x + 1\n|" (6 0) "a global's lambda block")
|
||||||
("fn f()\n let a = 1\n g = map(xs, fn(x) =>\n x + 1)\n|" (6 2 0)
|
("fn f()\n let a = 1\n g = map(xs, fn(x) =>\n x + 1)\n|" (6 2 0)
|
||||||
"but a lambda's brackets closed, where the column stays")))
|
"but a lambda's brackets closed, where the column stays")
|
||||||
|
("fn f(c)\n let a = 1\n b = if c\n 1\n else\n 2\n|" (8 2 0)
|
||||||
|
"an if's else block")
|
||||||
|
("fn f(c)\n let a = 1\n b = if c\n 1\n|" (8 6 2 0)
|
||||||
|
"but an if's block, where its else may go")
|
||||||
|
("fn f(c, d)\n let a = 1\n b = if c\n 1\n elif d\n 2\n|" (8 6 2 0)
|
||||||
|
"and an elif's block, where another clause may go")
|
||||||
|
("fn f()\n let g = map(xs, fn(x) =>\n x + 1)\n|" (2 6 0)
|
||||||
|
"a first binding's bracketed lambda offers the column")))
|
||||||
(test-flan-fln--is (format "no binding column after a binding's open block: %s" (nth 2 c))
|
(test-flan-fln--is (format "no binding column after a binding's open block: %s" (nth 2 c))
|
||||||
(test-flan-fln--in (car c) (flan-fln--block-levels (point)))
|
(test-flan-fln--in (car c) (flan-fln--block-levels (point)))
|
||||||
(cadr c)))
|
(cadr c)))
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user