|
12 | 12 | (defconst raku-smie-grammar
|
13 | 13 | (smie-prec2->grammar
|
14 | 14 | (smie-precs->prec2
|
15 |
| - '((assoc ";") (assoc "=") (assoc ",") (left ":"))))) |
| 15 | + '((assoc ";") (assoc "=") (assoc ",") (left ":") (left "."))))) |
16 | 16 |
|
17 | 17 | (defcustom raku-indent-offset 4
|
18 | 18 | "Basic size of one indentation step."
|
|
33 | 33 | ;; if this does NOT match, we are not in an interpolation
|
34 | 34 | (not (looking-back "#{\\$" (- (point) 3))))))
|
35 | 35 |
|
| 36 | +(defun raku-smie--method-chain-p () |
| 37 | + "Check if current line starts with a method call (dot operator)." |
| 38 | + (save-excursion |
| 39 | + (beginning-of-line) |
| 40 | + (skip-chars-forward " \t") |
| 41 | + (eq (char-after) ?\.))) |
| 42 | + |
| 43 | +(defun raku-smie--find-chain-root-indentation () |
| 44 | + "Find the indentation of the root line in a method chain." |
| 45 | + (save-excursion |
| 46 | + ;; Move to previous line and scan backward to find the chain root |
| 47 | + (forward-line -1) |
| 48 | + (end-of-line) |
| 49 | + ;; Keep going back while we see lines starting with dots |
| 50 | + (while (and (not (bobp)) |
| 51 | + (save-excursion |
| 52 | + (beginning-of-line) |
| 53 | + (skip-chars-forward " \t") |
| 54 | + (eq (char-after) ?\.))) |
| 55 | + (forward-line -1) |
| 56 | + (end-of-line)) |
| 57 | + ;; Now we're at the root line, return its indentation |
| 58 | + (beginning-of-line) |
| 59 | + (current-indentation))) |
| 60 | + |
36 | 61 | (defun raku-smie--forward-token ()
|
37 |
| - (cond |
| 62 | + (cond |
38 | 63 | ;; Return `;` to fudge end-of-block indentation (I think), as ; is optional after a block
|
39 | 64 | ((and (eq (char-before) ?\}) ;; Character immediately prior to point is `}`
|
40 | 65 | (raku-smie--not-interpolation-p) ;; And, not in an interpolation
|
|
51 | 76 | "=")
|
52 | 77 |
|
53 | 78 | ((progn (forward-comment (point-max)) ;; Read past ALL comments
|
54 |
| - (looking-at "[;,:]")) ;; Are we looking at ; , or : |
| 79 | + (looking-at "[;,:.])")) ;; Are we looking at ; , : or . |
55 | 80 |
|
56 | 81 | (forward-char 1) ;; If so, advance one character
|
57 | 82 | (match-string 0)) ;; And then return whatever looking-at found (?)
|
|
74 | 99 | (forward-char -1)
|
75 | 100 | "=")
|
76 | 101 |
|
77 |
| - ;; Cond #2 - Get whatever precedes [,:;] |
78 |
| - ((memq (char-before) '(?\; ?\, ?\:)) ;; Point is preceded immediately by `;`, `,`, or `:` |
| 102 | + ;; Cond #2 - Get whatever precedes [,:;.] |
| 103 | + ((memq (char-before) '(?\; ?\, ?\: ?\.)) ;; Point is preceded immediately by `;`, `,`, `:`, or `.` |
79 | 104 | (forward-char -1) ;; Retreat one char
|
80 | 105 | (string (char-after))) ;; Return char after point (the char we just retreated past)
|
81 | 106 |
|
|
103 | 128 |
|
104 | 129 | (`(:before . ,(or "{" "("))
|
105 | 130 | (if (smie-rule-hanging-p)
|
106 |
| - (smie-rule-parent 0))))) |
| 131 | + (smie-rule-parent 0))) |
| 132 | + |
| 133 | + ;; Method chaining indentation |
| 134 | + (`(:before . ".") |
| 135 | + (when (raku-smie--method-chain-p) |
| 136 | + (+ (raku-smie--find-chain-root-indentation) raku-indent-offset))))) |
107 | 137 |
|
108 | 138 | (provide 'raku-indent)
|
109 | 139 |
|
|
0 commit comments