Repository: rust-lang/rust-mode (language: rust)

Issue:
electric-pair-mode work incorrect with `<>`
I started Emacs and opened rust file as below,

```
emacs -q
M-x package-initialize
M-x electric-pair-mode
(require 'rust-mode)
```

If I type `tmp(x)` it works correctly and results in `tmp(x)`
However if I type `tmp<T>` it would result in `tmp<T>>`

It seems like this has to do with `rust-ordinary-lt-gt-p`.
I found `tmp<T>` works fine with `(defun rust-ordinary-lt-gt-p () nil)`
(although it ruins the other bracket processes).

So I guess `rust-ordinary-lt-gt-p` should be updated to return `nil` properly in the specific case.

Please correct me if I'm missing something.

Thanks.


Discussion / hints:

Fix patch:
diff --git a/rust-mode.el b/rust-mode.el
index b361749e..f681b053 100644
--- a/rust-mode.el
+++ b/rust-mode.el
@@ -21,6 +21,7 @@
 (require 'json)
 
 (defvar electric-pair-inhibit-predicate)
+(defvar electric-pair-skip-self)
 (defvar electric-indent-chars)
 
 (defvar rust-buffer-project)
@@ -1044,6 +1045,13 @@ This wraps the default defined by `electric-pair-inhibit-predicate'."
        (rust-is-lt-char-operator)))
    (funcall (default-value 'electric-pair-inhibit-predicate) char)))
 
+(defun rust-electric-pair-skip-self-wrap (char)
+  "Skip CHAR instead of inserting a second closing character.
+This wraps the default defined by `electric-pair-skip-self'."
+  (or
+   (= ?> char)
+   (funcall (default-value 'electric-pair-skip-self) char)))
+
 (defun rust-ordinary-lt-gt-p ()
   "Test whether the `<' or `>' at point is an ordinary operator of some kind.
 
@@ -1610,6 +1618,7 @@ Return the created process."
   (setq-local end-of-defun-function 'rust-end-of-defun)
   (setq-local parse-sexp-lookup-properties t)
   (setq-local electric-pair-inhibit-predicate 'rust-electric-pair-inhibit-predicate-wrap)
+  (setq-local electric-pair-skip-self 'rust-electric-pair-skip-self-wrap)
 
   (add-hook 'before-save-hook 'rust-before-save-hook nil t)
   (add-hook 'after-save-hook 'rust-after-save-hook nil t)


Test patch:
diff --git a/rust-mode-tests.el b/rust-mode-tests.el
index 9d4e6b6c..4fcb5bde 100644
--- a/rust-mode-tests.el
+++ b/rust-mode-tests.el
@@ -3220,4 +3220,18 @@ impl Two<'a> {
 
   (ert-deftest rust-test-electric-pair-lt-expression-capitalized-keyword ()
     (test-electric-pair-insert "fn foo() -> Box" 16 ?< ?>))
-  )
+
+  (ert-deftest rust-test-electric-pair-<-> ()
+    (let ((old-electric-pair-mode electric-pair-mode))
+      (electric-pair-mode 1)
+      (unwind-protect
+          (with-temp-buffer
+            (electric-pair-mode 1)
+            (rust-mode)
+            (mapc (lambda (c)
+                    (let ((last-command-event c)) (self-insert-command 1)))
+                  "tmp<T>")
+            (should
+             (equal "tmp<T>" (buffer-substring-no-properties (point-min)
+                                                             (point-max)))))
+        (electric-pair-mode (or old-electric-pair-mode 1))))))