Skip to content

Commit 1ef3ce5

Browse files
author
Keith Pinson
committed
Augh, try to fix a bunch of cases without breaking others
There are more still that aren't right.
1 parent c8a7bba commit 1ef3ce5

File tree

1 file changed

+52
-13
lines changed

1 file changed

+52
-13
lines changed

scala-mode-indent.el

Lines changed: 52 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -282,6 +282,8 @@ and are in fact a sign of run-on. Reserved-symbols not included.")
282282
nil)
283283
;; NO: this line is the start of value body
284284
;; ((scala-indent:body-p) ;; TODO did I delete this function when I shouldn't have?
285+
;; TODO or even if I did, maybe it just doesn't matter because the
286+
;; heuristics that union this algorithm with the other will compensate?
285287
;; nil)
286288
;; YES: eager strategy can stop here, everything is a run-on if no
287289
;; counter evidence
@@ -422,6 +424,7 @@ Returns point or (point-min) if not inside a block."
422424
"A kind of tokenize step of the hand-wavy parse"
423425
(pcase stack
424426
;; <hitting the beginning of a block when starting in the middle> { (
427+
(`(?\{) 'left-boundary) ;; too aggressive?
425428
(`(?\{ ,_ . ,_) 'left-boundary)
426429
(`(?\( ,_ . ,_) 'left-boundary)
427430
;; <dot chaining>
@@ -430,7 +433,7 @@ Returns point or (point-min) if not inside a block."
430433
;; =
431434
(`(= ?\n . ,_) 'decl-lhs)
432435
((and `(= ,_ . ,tail) (guard (memq ?\n tail))) 'after-decl)
433-
(`(= ,_ . ,_) 'decl-lhs)
436+
(`(= ,_ . ,_) 'decl-inline-lhs)
434437
;; =>
435438
(`(=> ?\n . ,_) 'arrow-lhs)
436439
((and `(=> ,_ . ,tail) (guard (memq ?\n tail))) 'after-arrow)
@@ -479,6 +482,8 @@ Returns point or (point-min) if not inside a block."
479482
(`(override) 'decl)
480483
;; package
481484
(`(package . ,_) 'decl)
485+
;; sealed
486+
(`(sealed) 'decl)
482487
;; then
483488
(`(then ?\n . ,_) 'then-conseq)
484489
(`(then) 'then)
@@ -520,6 +525,7 @@ Returns point or (point-min) if not inside a block."
520525
(`(case ,_) 2)
521526
;; decl
522527
(`(decl decl) 0)
528+
(`(decl decl decl-inline-lhs) 0)
523529
(`(decl else) -2)
524530
(`(decl . ,_) 2)
525531
;; decl-lhs
@@ -589,10 +595,19 @@ Returns point or (point-min) if not inside a block."
589595
(setq stack (cons ?\n stack)))
590596
;; (beginning-of-thing 'sexp) gets confused by `.'
591597
(unless (looking-at-p "\\.")
592-
;; Avoid double-reading curent symbol
598+
;; Avoid double-reading current symbol
593599
(beginning-of-thing 'sexp)))
594-
(list (point)
595-
stack))))
600+
;; handle the occurence of case in various contexts
601+
(or (save-excursion
602+
(when-let ((_ (looking-at-p (concat "case *"
603+
scala-syntax:class-or-object-re)))
604+
(point (progn (forward-to-word 1) (point)))
605+
(class-or-object (sexp-at-point)))
606+
;; This throws away the stack we've built up above. The assumption
607+
;; here is that this case is mutually exclusive with those above.
608+
(scala-indent:skip-back-over-modifiers point
609+
(list class-or-object))))
610+
(list (point) stack)))))
596611

597612
(defun scala-indent:analyze-context (point &optional init-stack)
598613
"TODO document"
@@ -629,13 +644,19 @@ Returns point or (point-min) if not inside a block."
629644
(unless result
630645
(setq last-indentation (current-indentation))
631646
(while (looking-at-p "\\.") (backward-char))
647+
;; ")." is a funny case where we actually do want to be on the dot
648+
(if (looking-at-p ")") (forwar-char))
632649
(scala-syntax:backward-sexp-forcing)))
633-
(list result
634-
(line-number-at-pos)
635-
(current-indentation)
636-
last-indentation
637-
(point)
638-
stack))))
650+
(let* ((x (or (scala-indent:skip-back-over-modifiers (point) stack)
651+
(list (point) stack)))
652+
(point (nth 0 x))
653+
(stack (nth 1 x)))
654+
(list result
655+
(line-number-at-pos)
656+
(current-indentation)
657+
last-indentation
658+
point
659+
stack)))))
639660

640661
(defun scala-indent:full-stmt-less-than-line (syntax-elem stopped-point)
641662
(and
@@ -657,7 +678,7 @@ Returns point or (point-min) if not inside a block."
657678
(or (and (= ctxt-line line-no) (> line-no 1)
658679
;; If we keep reading for this reason, we've accepted the
659680
;; existing tokens and so need to clear the stack
660-
(list nil ;; syntax-elem
681+
(list syntax-elem ;; syntax-elem
661682
nil ;; stack
662683
(save-excursion ;; point
663684
(goto-char stopped-point)
@@ -675,11 +696,29 @@ Returns point or (point-min) if not inside a block."
675696
;; We know we have a dot-chain, but we need to get more context to know
676697
;; how to position it
677698
(when (equal syntax-elem '(dot-chain))
678-
(list nil ;; syntax-elem
699+
(list syntax-elem ;; syntax-elem
679700
nil ;; stack
680701
stopped-point ;; point
681702
))))
682703

704+
(defun scala-indent:skip-back-over-modifiers (point stack)
705+
(if-let* ((head (car stack))
706+
(_ (memq head '(trait class object)))
707+
(new-point point)
708+
(new-sexp t)
709+
(new-stack stack))
710+
(save-excursion
711+
(goto-char new-point)
712+
(scala-syntax:backward-sexp-forcing)
713+
(setq new-sexp (sexp-at-point))
714+
(while (memq new-sexp
715+
'(final sealed case open abstract implicit private))
716+
(setq new-point (point))
717+
(setq new-stack (cons new-sexp new-stack))
718+
(scala-syntax:backward-sexp-forcing)
719+
(setq new-sexp (sexp-at-point)))
720+
(list new-point new-stack))))
721+
683722
(defun scala-indent:whitespace-biased-indent (&optional point)
684723
"Whitespace-syntax-friendly heuristic indentation engine.
685724
@@ -704,7 +743,7 @@ certain amount of incorrect or in-progress syntactic forms."
704743
(message "analysis: %s" analysis)
705744
(while (when-let ((x (scala-indent:continue-lookback?
706745
syntax-elem ctxt-line line-no stopped-point end-stack)))
707-
(setq syntax-elem (or (nth 0 x) syntax-elem))
746+
(setq syntax-elem (nth 0 x))
708747
(setq stack (nth 1 x))
709748
(setq point (nth 2 x))
710749
t)

0 commit comments

Comments
 (0)