|
84 | 84 | ;; or one further indent from that if either current line
|
85 | 85 | ;; begins with 'else', or previous line didn't end in
|
86 | 86 | ;; semi, comma or brace (other than whitespace and line
|
87 |
| - ;; comments) , and wasn't an attribute. But if we have |
| 87 | + ;; comments) , and wasn't an attribute. But if we have |
88 | 88 | ;; something after the open brace and ending with a comma,
|
89 | 89 | ;; treat it as fields and align them. PHEW.
|
90 | 90 | ((> level 0)
|
|
213 | 213 |
|
214 | 214 | (defun rust-fill-prefix-for-comment-start (line-start)
|
215 | 215 | "Determine what to use for `fill-prefix' based on what is at the beginning of a line."
|
216 |
| - (let ((result |
| 216 | + (let ((result |
217 | 217 | ;; Replace /* with same number of spaces
|
218 | 218 | (replace-regexp-in-string
|
219 |
| - "\\(?:/\\*+\\)[!*]" |
| 219 | + "\\(?:/\\*+\\)[!*]" |
220 | 220 | (lambda (s)
|
221 | 221 | ;; We want the * to line up with the first * of the comment start
|
222 | 222 | (concat (make-string (- (length s) 2) ?\x20) "*"))
|
223 | 223 | line-start)))
|
224 |
| - ;; Make sure we've got at least one space at the end |
| 224 | + ;; Make sure we've got at least one space at the end |
225 | 225 | (if (not (= (aref result (- (length result) 1)) ?\x20))
|
226 | 226 | (setq result (concat result " ")))
|
227 | 227 | result))
|
|
247 | 247 | ;; inferring it from the comment start.
|
248 | 248 | (let ((next-bol (line-beginning-position 2)))
|
249 | 249 | (while (save-excursion
|
250 |
| - (end-of-line) |
251 |
| - (syntax-ppss-flush-cache 1) |
252 |
| - (and (nth 4 (syntax-ppss)) |
253 |
| - (save-excursion |
254 |
| - (beginning-of-line) |
255 |
| - (looking-at paragraph-start)) |
256 |
| - (looking-at "[[:space:]]*$") |
257 |
| - (nth 4 (syntax-ppss next-bol)))) |
| 250 | + (end-of-line) |
| 251 | + (syntax-ppss-flush-cache 1) |
| 252 | + (and (nth 4 (syntax-ppss)) |
| 253 | + (save-excursion |
| 254 | + (beginning-of-line) |
| 255 | + (looking-at paragraph-start)) |
| 256 | + (looking-at "[[:space:]]*$") |
| 257 | + (nth 4 (syntax-ppss next-bol)))) |
258 | 258 | (goto-char next-bol)))
|
259 | 259 |
|
260 | 260 | (syntax-ppss-flush-cache 1)
|
|
269 | 269 |
|
270 | 270 | (defun rust-with-comment-fill-prefix (body)
|
271 | 271 | (let*
|
272 |
| - ((line-string (buffer-substring-no-properties |
| 272 | + ((line-string (buffer-substring-no-properties |
273 | 273 | (line-beginning-position) (line-end-position)))
|
274 | 274 | (line-comment-start
|
275 |
| - (when (nth 4 (syntax-ppss)) |
| 275 | + (when (nth 4 (syntax-ppss)) |
276 | 276 | (cond
|
277 | 277 | ;; If we're inside the comment and see a * prefix, use it
|
278 | 278 | ((string-match "^\\([[:space:]]*\\*+[[:space:]]*\\)"
|
|
281 | 281 | ;; If we're at the start of a comment, figure out what prefix
|
282 | 282 | ;; to use for the subsequent lines after it
|
283 | 283 | ((string-match (concat "[[:space:]]*" comment-start-skip) line-string)
|
284 |
| - (rust-fill-prefix-for-comment-start |
| 284 | + (rust-fill-prefix-for-comment-start |
285 | 285 | (match-string 0 line-string))))))
|
286 |
| - (fill-prefix |
| 286 | + (fill-prefix |
287 | 287 | (or line-comment-start
|
288 | 288 | fill-prefix)))
|
289 | 289 | (funcall body)))
|
|
294 | 294 | (defun rust-fill-paragraph (&rest args)
|
295 | 295 | "Special wrapping for `fill-paragraph' to handle multi-line comments with a * prefix on each line."
|
296 | 296 | (rust-in-comment-paragraph
|
297 |
| - (lambda () |
| 297 | + (lambda () |
298 | 298 | (rust-with-comment-fill-prefix
|
299 | 299 | (lambda ()
|
300 | 300 | (let
|
|
321 | 321 | (rust-with-comment-fill-prefix
|
322 | 322 | (lambda () (comment-indent-new-line arg))))
|
323 | 323 |
|
| 324 | +;;; Imenu support |
| 325 | +(defvar rust-imenu-generic-expression |
| 326 | + (append (loop for item in |
| 327 | + '("enum" "struct" "type" "mod" "fn") |
| 328 | + collect `(nil ,(rust-re-item-def item) 1)) |
| 329 | + `(("Impl" ,(rust-re-item-def "impl") 1))) |
| 330 | + "Value for `imenu-generic-expression' in Rust mode. |
| 331 | +
|
| 332 | +Create a flat index of the item definitions in a Rust file. |
| 333 | +
|
| 334 | +Imenu will show all the enums, structs, etc. at the same level. |
| 335 | +Implementations will be shown under the `Impl` subheading. |
| 336 | +Use idomenu (imenu with ido-mode) for best mileage.") |
| 337 | + |
324 | 338 | ;; For compatibility with Emacs < 24, derive conditionally
|
325 | 339 | (defalias 'rust-parent-mode
|
326 | 340 | (if (fboundp 'prog-mode) 'prog-mode 'fundamental-mode))
|
|
348 | 362 | (set (make-local-variable 'indent-tabs-mode) nil)
|
349 | 363 |
|
350 | 364 | ;; Allow paragraph fills for comments
|
351 |
| - (set (make-local-variable 'comment-start-skip) |
| 365 | + (set (make-local-variable 'comment-start-skip) |
352 | 366 | "\\(?://[/!]*\\|/\\*[*!]?\\)[[:space:]]*")
|
353 | 367 | (set (make-local-variable 'paragraph-start)
|
354 | 368 | (concat "[[:space:]]*\\(?:" comment-start-skip "\\|\\*/?[[:space:]]*\\|\\)$"))
|
|
359 | 373 | (set (make-local-variable 'adaptive-fill-function) 'rust-find-fill-prefix)
|
360 | 374 | (set (make-local-variable 'comment-multi-line) t)
|
361 | 375 | (set (make-local-variable 'comment-line-break-function) 'rust-comment-indent-new-line)
|
| 376 | + (set (make-local-variable 'imenu-generic-expression) rust-imenu-generic-expression) |
362 | 377 | )
|
363 | 378 |
|
364 | 379 |
|
|
0 commit comments