@@ -481,11 +481,84 @@ This is written mainly to be used as `end-of-defun-function' for Rust."
481
481
; ; There is no opening brace, so consider the whole buffer to be one "defun"
482
482
(goto-char (point-max ))))
483
483
484
+ ; ; Angle-bracket matching. This is kind of a hack designed to deal
485
+ ; ; with the fact that we can't add angle-brackets to the list of
486
+ ; ; matching characters unconditionally. Basically we just have some
487
+ ; ; special-case code such that whenever `>` is typed, we look
488
+ ; ; backwards to find a matching `<` and highlight it, whether or not
489
+ ; ; this is *actually* appropriate. This could be annoying so it is
490
+ ; ; configurable (but on by default because it's awesome).
491
+
492
+ (defcustom rust-blink-matching-angle-brackets t
493
+ " Blink matching `<` (if any) when `>` is typed"
494
+ :type 'boolean
495
+ :group 'rust-mode )
496
+
497
+ (defvar rust-point-before-matching-angle-bracket 0 )
498
+
499
+ (defvar rust-matching-angle-bracker-timer nil )
500
+
501
+ (defun rust-find-matching-angle-bracket ()
502
+ (save-excursion
503
+ (let ((angle-brackets 1 )
504
+ (start-point (point ))
505
+ (invalid nil ))
506
+ (while (and
507
+ ; ; didn't find a match
508
+ (> angle-brackets 0 )
509
+ ; ; we have no guarantee of a match, so give up eventually
510
+ (< (- start-point (point )) blink-matching-paren-distance)
511
+ ; ; didn't hit the top of the buffer
512
+ (> (point ) (point-min ))
513
+ ; ; didn't hit something else weird like a `;`
514
+ (not invalid))
515
+ (backward-char 1 )
516
+ (cond
517
+ ((looking-at " >" )
518
+ (setq angle-brackets (+ angle-brackets 1 )))
519
+ ((looking-at " <" )
520
+ (setq angle-brackets (- angle-brackets 1 )))
521
+ ((looking-at " [;{]" )
522
+ (setq invalid t ))))
523
+ (cond
524
+ ((= angle-brackets 0 ) (point ))
525
+ (t nil )))))
526
+
527
+ (defun rust-restore-point-after-angle-bracket ()
528
+ (goto-char rust-point-before-matching-angle-bracket)
529
+ (when rust-matching-angle-bracker-timer
530
+ (cancel-timer rust-matching-angle-bracker-timer))
531
+ (setq rust-matching-angle-bracker-timer nil )
532
+ (remove-hook 'pre-command-hook 'rust-restore-point-after-angle-bracket ))
533
+
534
+ (defun rust-match-angle-bracket-hook ()
535
+ " If the most recently inserted character is a `>`, briefly moves point to matching `<` (if any)."
536
+ (interactive )
537
+ (when (and rust-blink-matching-angle-brackets
538
+ (looking-back " >" ))
539
+ (let ((matching-angle-bracket-point (save-excursion
540
+ (backward-char 1 )
541
+ (rust-find-matching-angle-bracket))))
542
+ (when matching-angle-bracket-point
543
+ (progn
544
+ (setq rust-point-before-matching-angle-bracket (point ))
545
+ (goto-char matching-angle-bracket-point)
546
+ (add-hook 'pre-command-hook 'rust-restore-point-after-angle-bracket )
547
+ (setq rust-matching-angle-bracker-timer
548
+ (run-at-time blink-matching-delay nil 'rust-restore-point-after-angle-bracket )))))))
549
+
550
+ (defun rust-match-angle-bracket ()
551
+ " The point should be placed on a `>`. Finds the matching `<` and moves point there."
552
+ (interactive )
553
+ (let ((matching-angle-bracket-point (rust-find-matching-angle-bracket)))
554
+ (if matching-angle-bracket-point
555
+ (goto-char matching-angle-bracket-point)
556
+ (message " no matching angle bracket found " ))))
557
+
484
558
; ; For compatibility with Emacs < 24, derive conditionally
485
559
(defalias 'rust-parent-mode
486
560
(if (fboundp 'prog-mode ) 'prog-mode 'fundamental-mode ))
487
561
488
-
489
562
;;;### autoload
490
563
(define-derived-mode rust-mode rust-parent-mode " Rust"
491
564
" Major mode for Rust code."
@@ -519,6 +592,7 @@ This is written mainly to be used as `end-of-defun-function' for Rust."
519
592
(setq-local end-of-defun-function 'rust-end-of-defun )
520
593
(setq-local parse-sexp-lookup-properties t )
521
594
(add-hook 'syntax-propertize-extend-region-functions 'rust-syntax-propertize-extend-region )
595
+ (add-hook 'post-self-insert-hook 'rust-match-angle-bracket-hook )
522
596
(setq-local syntax-propertize-function 'rust-syntax-propertize ))
523
597
524
598
(defun rust-syntax-propertize-extend-region (start end )
0 commit comments