|
59 | 59 | (backward-word 1))
|
60 | 60 | (current-column))))
|
61 | 61 |
|
| 62 | +(defun rust-rewind-to-beginning-of-current-level-expr () |
| 63 | + (let ((current-level (rust-paren-level))) |
| 64 | + (back-to-indentation) |
| 65 | + (while (> (rust-paren-level) current-level) |
| 66 | + (backward-up-list) |
| 67 | + (back-to-indentation)))) |
| 68 | + |
62 | 69 | (defun rust-mode-indent-line ()
|
63 | 70 | (interactive)
|
64 | 71 | (let ((indent
|
65 | 72 | (save-excursion
|
66 | 73 | (back-to-indentation)
|
67 |
| - (let ((level (rust-paren-level))) |
| 74 | + ;; Point is now at beginning of current line |
| 75 | + (let* ((level (rust-paren-level)) |
| 76 | + (baseline |
| 77 | + ;; Our "baseline" is one level out from the indentation of the expression |
| 78 | + ;; containing the innermost enclosing opening bracket. That |
| 79 | + ;; way if we are within a block that has a different |
| 80 | + ;; indentation than this mode would give it, we still indent |
| 81 | + ;; the inside of it correctly relative to the outside. |
| 82 | + (if (= 0 level) |
| 83 | + 0 |
| 84 | + (save-excursion |
| 85 | + (backward-up-list) |
| 86 | + (rust-rewind-to-beginning-of-current-level-expr) |
| 87 | + (+ (current-column) rust-indent-offset))))) |
68 | 88 | (cond
|
69 | 89 | ;; A function return type is indented to the corresponding function arguments
|
70 | 90 | ((looking-at "->")
|
71 | 91 | (save-excursion
|
72 | 92 | (backward-list)
|
73 | 93 | (or (rust-align-to-expr-after-brace)
|
74 |
| - (* rust-indent-offset (+ 1 level))))) |
| 94 | + (+ baseline rust-indent-offset)))) |
75 | 95 |
|
76 | 96 | ;; A closing brace is 1 level unindended
|
77 |
| - ((looking-at "}") (* rust-indent-offset (- level 1))) |
| 97 | + ((looking-at "}") (- baseline rust-indent-offset)) |
78 | 98 |
|
79 | 99 | ;; Doc comments in /** style with leading * indent to line up the *s
|
80 | 100 | ((and (nth 4 (syntax-ppss)) (looking-at "*"))
|
81 |
| - (+ 1 (* rust-indent-offset level))) |
| 101 | + (+ 1 baseline)) |
82 | 102 |
|
83 | 103 | ;; If we're in any other token-tree / sexp, then:
|
84 |
| - ;; - [ or ( means line up with the opening token |
85 |
| - ;; - { means indent to either nesting-level * rust-indent-offset, |
86 |
| - ;; or one further indent from that if either current line |
87 |
| - ;; begins with 'else', or previous line didn't end in |
88 |
| - ;; semi, comma or brace (other than whitespace and line |
89 |
| - ;; comments) , and wasn't an attribute. But if we have |
90 |
| - ;; something after the open brace and ending with a comma, |
91 |
| - ;; treat it as fields and align them. PHEW. |
92 |
| - ((> level 0) |
93 |
| - (let ((pt (point))) |
94 |
| - (rust-rewind-irrelevant) |
95 |
| - (backward-up-list) |
96 |
| - (or (and (looking-at "[[({]") |
97 |
| - (rust-align-to-expr-after-brace)) |
98 |
| - (progn |
99 |
| - (goto-char pt) |
100 |
| - (back-to-indentation) |
101 |
| - (if (looking-at "\\<else\\>") |
102 |
| - (* rust-indent-offset (+ 1 level)) |
103 |
| - (progn |
104 |
| - (goto-char pt) |
105 |
| - (beginning-of-line) |
106 |
| - (rust-rewind-irrelevant) |
107 |
| - (end-of-line) |
108 |
| - (if (looking-back |
109 |
| - "[[,;{}(][[:space:]]*\\(?://.*\\)?") |
110 |
| - (* rust-indent-offset level) |
111 |
| - (back-to-indentation) |
112 |
| - (if (looking-at "#") |
113 |
| - (* rust-indent-offset level) |
114 |
| - (* rust-indent-offset (+ 1 level)))))))))) |
115 |
| - |
116 |
| - ;; Otherwise we're in a column-zero definition |
117 |
| - (t 0)))))) |
118 |
| - (cond |
119 |
| - ;; If we're to the left of the indentation, reindent and jump to it. |
120 |
| - ((<= (current-column) indent) |
121 |
| - (indent-line-to indent)) |
122 |
| - |
123 |
| - ;; We're to the right; if it needs indent, do so but save excursion. |
124 |
| - ((not (eq (current-indentation) indent)) |
125 |
| - (save-excursion (indent-line-to indent)))))) |
| 104 | + (t |
| 105 | + (or |
| 106 | + ;; If we are inside a pair of braces, with something after the |
| 107 | + ;; open brace on the same line and ending with a comma, treat |
| 108 | + ;; it as fields and align them. |
| 109 | + (when (> level 0) |
| 110 | + (save-excursion |
| 111 | + (rust-rewind-irrelevant) |
| 112 | + (backward-up-list) |
| 113 | + ;; Point is now at the beginning of the containing set of braces |
| 114 | + (rust-align-to-expr-after-brace))) |
| 115 | + |
| 116 | + (progn |
| 117 | + (back-to-indentation) |
| 118 | + ;; Point is now at the beginning of the current line |
| 119 | + (if (or |
| 120 | + ;; If this line begins with "else" or "{", stay on the |
| 121 | + ;; baseline as well (we are continuing an expression, |
| 122 | + ;; but the "else" or "{" should align with the beginning |
| 123 | + ;; of the expression it's in.) |
| 124 | + (looking-at "\\<else\\>\\|{") |
| 125 | + |
| 126 | + (save-excursion |
| 127 | + (rust-rewind-irrelevant) |
| 128 | + ;; Point is now at the end of the previous ine |
| 129 | + (or |
| 130 | + ;; If we are at the first line, no indentation is needed, so stay at baseline... |
| 131 | + (= 1 (line-number-at-pos (point))) |
| 132 | + ;; ..or if the previous line ends with any of these: |
| 133 | + ;; { ? : ( , ; [ } |
| 134 | + ;; then we are at the beginning of an expression, so stay on the baseline... |
| 135 | + (looking-back "[(,:;?[{}]\\|[^|]|") |
| 136 | + ;; or if the previous line is the end of an attribute, stay at the baseline... |
| 137 | + (progn (rust-rewind-to-beginning-of-current-level-expr) (looking-at "#"))))) |
| 138 | + baseline |
| 139 | + |
| 140 | + ;; Otherwise, we are continuing the same expression from the previous line, |
| 141 | + ;; so add one additional indent level |
| 142 | + (+ baseline rust-indent-offset)))))))))) |
| 143 | + (when (not (eq (current-indentation) indent)) |
| 144 | + ;; If we're at the beginning of the line (before or at the current |
| 145 | + ;; indentation), jump with the indentation change. Otherwise, save the |
| 146 | + ;; excursion so that adding the indentations will leave us at the |
| 147 | + ;; equivalent position within the line to where we were before. |
| 148 | + (if (<= (current-column) (current-indentation)) |
| 149 | + (indent-line-to indent) |
| 150 | + (save-excursion (indent-line-to indent)))))) |
126 | 151 |
|
127 | 152 |
|
128 | 153 | ;; Font-locking definitions and helpers
|
|
0 commit comments