|
209 | 209 |
|
210 | 210 | collect `(,(rust-re-item-def item) 1 ,face))))
|
211 | 211 |
|
| 212 | +(defun rust-fill-prefix-for-comment-start (line-start) |
| 213 | + "Determine what to use for `fill-prefix' based on what is at the beginning of a line." |
| 214 | + (let ((result |
| 215 | + ;; Replace /* with same number of spaces |
| 216 | + (replace-regexp-in-string |
| 217 | + "\\(?:/\\*+\\)[!*]" |
| 218 | + (lambda (s) |
| 219 | + ;; We want the * to line up with the first * of the comment start |
| 220 | + (concat (make-string (- (length s) 2) ?\x20) "*")) |
| 221 | + line-start))) |
| 222 | + ;; Make sure we've got at least one space at the end |
| 223 | + (if (not (= (aref result (- (length result) 1)) ?\x20)) |
| 224 | + (setq result (concat result " "))) |
| 225 | + result)) |
| 226 | + |
| 227 | +(defun rust-in-comment-paragraph (body) |
| 228 | + ;; We might move the point to fill the next comment, but we don't want it |
| 229 | + ;; seeming to jump around on the user |
| 230 | + (save-excursion |
| 231 | + ;; If we're outside of a comment, with only whitespace and then a comment |
| 232 | + ;; in front, jump to the comment and prepare to fill it. |
| 233 | + (when (not (nth 4 (syntax-ppss))) |
| 234 | + (beginning-of-line) |
| 235 | + (when (looking-at (concat "[[:space:]\n]*" comment-start-skip)) |
| 236 | + (goto-char (match-end 0)))) |
| 237 | + |
| 238 | + ;; We need this when we're moving the point around and then checking syntax |
| 239 | + ;; while doing paragraph fills, because the cache it uses isn't always |
| 240 | + ;; invalidated during this. |
| 241 | + (syntax-ppss-flush-cache 1) |
| 242 | + ;; If we're at the beginning of a comment paragraph with nothing but |
| 243 | + ;; whitespace til the next line, jump to the next line so that we use the |
| 244 | + ;; existing prefix to figure out what the new prefix should be, rather than |
| 245 | + ;; inferring it from the comment start. |
| 246 | + (let ((next-bol (line-beginning-position 2))) |
| 247 | + (while (save-excursion |
| 248 | + (end-of-line) |
| 249 | + (syntax-ppss-flush-cache 1) |
| 250 | + (and (nth 4 (syntax-ppss)) |
| 251 | + (save-excursion |
| 252 | + (beginning-of-line) |
| 253 | + (looking-at paragraph-start)) |
| 254 | + (looking-at "[[:space:]]*$") |
| 255 | + (nth 4 (syntax-ppss next-bol)))) |
| 256 | + (goto-char next-bol))) |
| 257 | + |
| 258 | + (syntax-ppss-flush-cache 1) |
| 259 | + ;; If we're on the last line of a multiline-style comment that started |
| 260 | + ;; above, back up one line so we don't mistake the * of the */ that ends |
| 261 | + ;; the comment for a prefix. |
| 262 | + (when (save-excursion |
| 263 | + (and (nth 4 (syntax-ppss (line-beginning-position 1))) |
| 264 | + (looking-at "[[:space:]]*\\*/"))) |
| 265 | + (goto-char (line-end-position 0))) |
| 266 | + (funcall body))) |
| 267 | + |
| 268 | +(defun rust-with-comment-fill-prefix (body) |
| 269 | + (let* |
| 270 | + ((line-string (buffer-substring-no-properties |
| 271 | + (line-beginning-position) (line-end-position))) |
| 272 | + (line-comment-start |
| 273 | + (when (nth 4 (syntax-ppss)) |
| 274 | + (cond |
| 275 | + ;; If we're inside the comment and see a * prefix, use it |
| 276 | + ((string-match "^\\([[:space:]]*\\*+[[:space:]]*\\)" |
| 277 | + line-string) |
| 278 | + (match-string 1 line-string)) |
| 279 | + ;; If we're at the start of a comment, figure out what prefix |
| 280 | + ;; to use for the subsequent lines after it |
| 281 | + ((string-match (concat "[[:space:]]*" comment-start-skip) line-string) |
| 282 | + (rust-fill-prefix-for-comment-start |
| 283 | + (match-string 0 line-string)))))) |
| 284 | + (fill-prefix |
| 285 | + (or line-comment-start |
| 286 | + fill-prefix))) |
| 287 | + (funcall body))) |
| 288 | + |
| 289 | +(defun rust-find-fill-prefix () |
| 290 | + (rust-with-comment-fill-prefix (lambda () fill-prefix))) |
| 291 | + |
| 292 | +(defun rust-fill-paragraph (&rest args) |
| 293 | + "Special wrapping for `fill-paragraph' to handle multi-line comments with a * prefix on each line." |
| 294 | + (rust-in-comment-paragraph |
| 295 | + (lambda () |
| 296 | + (rust-with-comment-fill-prefix |
| 297 | + (lambda () |
| 298 | + (let |
| 299 | + ((fill-paragraph-function |
| 300 | + (if (not (eq fill-paragraph-function 'rust-fill-paragraph)) |
| 301 | + fill-paragraph-function))) |
| 302 | + (apply 'fill-paragraph args) |
| 303 | + t)))))) |
| 304 | + |
| 305 | +(defun rust-do-auto-fill (&rest args) |
| 306 | + "Special wrapping for `do-auto-fill' to handle multi-line comments with a * prefix on each line." |
| 307 | + (rust-with-comment-fill-prefix |
| 308 | + (lambda () |
| 309 | + (apply 'do-auto-fill args) |
| 310 | + t))) |
| 311 | + |
| 312 | +(defun rust-fill-forward-paragraph (arg) |
| 313 | + ;; This is to work around some funny behavior when a paragraph separator is |
| 314 | + ;; at the very top of the file and there is a fill prefix. |
| 315 | + (let ((fill-prefix nil)) (forward-paragraph arg))) |
| 316 | + |
| 317 | +(defun rust-comment-indent-new-line (&optional arg) |
| 318 | + (rust-with-comment-fill-prefix |
| 319 | + (lambda () (comment-indent-new-line arg)))) |
212 | 320 |
|
213 | 321 | ;; For compatibility with Emacs < 24, derive conditionally
|
214 | 322 | (defalias 'rust-parent-mode
|
|
234 | 342 | ;; Misc
|
235 | 343 | (set (make-local-variable 'comment-start) "// ")
|
236 | 344 | (set (make-local-variable 'comment-end) "")
|
237 |
| - (set (make-local-variable 'indent-tabs-mode) nil)) |
| 345 | + (set (make-local-variable 'indent-tabs-mode) nil) |
| 346 | + |
| 347 | + ;; Allow paragraph fills for comments |
| 348 | + (set (make-local-variable 'comment-start-skip) |
| 349 | + "\\(?://[/!]*\\|/\\*[*!]?\\)[[:space:]]*") |
| 350 | + (set (make-local-variable 'paragraph-start) |
| 351 | + (concat "[[:space:]]*\\(?:" comment-start-skip "\\|\\*/?[[:space:]]*\\|\\)$")) |
| 352 | + (set (make-local-variable 'paragraph-separate) paragraph-start) |
| 353 | + (set (make-local-variable 'normal-auto-fill-function) 'rust-do-auto-fill) |
| 354 | + (set (make-local-variable 'fill-paragraph-function) 'rust-fill-paragraph) |
| 355 | + (set (make-local-variable 'fill-forward-paragraph-function) 'rust-fill-forward-paragraph) |
| 356 | + (set (make-local-variable 'adaptive-fill-function) 'rust-find-fill-prefix) |
| 357 | + (set (make-local-variable 'comment-multi-line) t) |
| 358 | + (set (make-local-variable 'comment-line-break-function) 'rust-comment-indent-new-line) |
| 359 | + ) |
238 | 360 |
|
239 | 361 |
|
240 | 362 | ;;;###autoload
|
|
0 commit comments