bug-gnu-emacs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

bug#36516: Wrong dynamic abbrev expansion after space


From: Juri Linkov
Subject: bug#36516: Wrong dynamic abbrev expansion after space
Date: Sun, 28 Jul 2019 23:47:53 +0300
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/27.0.50 (x86_64-pc-linux-gnu)

>> 0. emacs -Q
>> 1. Type these two lines:
>> str 1
>> str 2
>> 2. On the third line type:
>>  s                      ;; self-insert-command
>>  M-/                    ;; dabbrev-expand
>>  SPC                    ;; self-insert-command
>>  C-M-/                  ;; dabbrev-completion
>>
>> This correctly displays all available completions
>> “str 1” and “str 2”.  But ‘s M-/ SPC M-/ M-/’ doesn't get
>> the second completion.
>
> ’s M-/ SPC M-/’ doesn’t do a normal completion, it does this (from 
> the manual):
>
>     After you have expanded a dynamic abbrev, you can copy additional
>     words that follow the expansion in its original context. Simply type
>     <SPC> M-/ for each additional word you want to copy. The spacing and
>     punctuation between words is copied along with the words.

Oh, this special-casing unfortunately breaks the natural workflow.

> I suppose that subsequent M-/’s are undocumented, but the current
> behaviour is, IMO, definitely confusing as it seems to search other
> buffers for completions even though there are valid completions in the
> current buffer.

Maybe it's possible to break out of the vicious cycle of ‘SPC M-/’
repetitions by making ‘SPC M-/’ look like a normal expansion, e.g.:

diff --git a/test/lisp/dabbrev-tests.el b/test/lisp/dabbrev-tests.el
index a6ab2e7201..39fd37db1d 100644
--- a/test/lisp/dabbrev-tests.el
+++ b/test/lisp/dabbrev-tests.el
@@ -40,3 +40,27 @@
      ;; M-/ SPC M-/ M-/
      (execute-kbd-macro "\257 \257\257"))
    (should (string= (buffer-string) "ab  x\nab y\nab  y"))))
+
+(ert-deftest dabbrev-with-space-word ()
+  "Test for bug#36516.
+Check that the ‘<SPC> M-/’ feature still works as documented
+in `(emacs) Dynamic Abbrevs'."
+  (with-temp-buffer
+   (insert "sub a b\nstr a c\ns")
+   (save-window-excursion
+     (set-window-buffer nil (current-buffer))
+     ;; M-/ M-/ SPC M-/ SPC M-/
+     (execute-kbd-macro "\257\257 \257 \257"))
+   (should (string= (buffer-string) "sub a b\nstr a c\nsub a b"))))
+
+(ert-deftest dabbrev-without-space-word ()
+  "Test for bug#36516.
+Check that ‘<SPC> M-/ M-/’ doesn't conflict with the ‘<SPC> M-/’ feature
+documented in `(emacs) Dynamic Abbrevs'."
+  (with-temp-buffer
+   (insert "str 1\nstr 2\ns")
+   (save-window-excursion
+     (set-window-buffer nil (current-buffer))
+     ;; M-/ SPC M-/ M-/
+     (execute-kbd-macro "\257 \257\257"))
+   (should (string= (buffer-string) "str 1\nstr 2\nstr 1"))))
diff --git a/lisp/dabbrev.el b/lisp/dabbrev.el
index 23abe7ae16..ffb1b7d819 100644
--- a/lisp/dabbrev.el
+++ b/lisp/dabbrev.el
@@ -472,43 +472,35 @@ dabbrev-expand
                 (markerp dabbrev--last-abbrev-location)
                 (marker-position dabbrev--last-abbrev-location)
                 (= (point) (1+ dabbrev--last-abbrev-location)))
-           (progn
-             ;; The "abbrev" to expand is just the space.
-             (setq abbrev " ")
-             (save-excursion
-               (save-restriction
-                 (widen)
-                 (if dabbrev--last-buffer
-                     (set-buffer dabbrev--last-buffer))
-                 ;; Find the end of the last "expansion" word.
-                 (if (or (eq dabbrev--last-direction 1)
-                         (and (eq dabbrev--last-direction 0)
-                              (< dabbrev--last-expansion-location (point))))
-                     (setq dabbrev--last-expansion-location
-                           (+ dabbrev--last-expansion-location
-                              (length dabbrev--last-expansion))))
-                 (goto-char dabbrev--last-expansion-location)
-                 ;; Take the following word, with intermediate separators,
-                 ;; as our expansion this time.
-                 (re-search-forward
-                  (concat "\\(?:" dabbrev--abbrev-char-regexp "\\)+"))
-                 (setq expansion (buffer-substring-no-properties
-                                  dabbrev--last-expansion-location (point)))
-
-                 ;; Record the end of this expansion, in case we repeat this.
-                 (setq dabbrev--last-expansion-location (point))))
-             ;; Indicate that dabbrev--last-expansion-location is
-             ;; at the end of the expansion.
-             (setq dabbrev--last-direction -1))
+            (save-excursion
+             (save-restriction
+               (widen)
+               (if dabbrev--last-buffer
+                   (set-buffer dabbrev--last-buffer))
+               ;; Find the end of the last "expansion" word.
+               (if (or (eq dabbrev--last-direction 1)
+                       (and (eq dabbrev--last-direction 0)
+                            (< dabbrev--last-expansion-location (point))))
+                   (setq dabbrev--last-expansion-location
+                         (+ dabbrev--last-expansion-location
+                            (length dabbrev--last-expansion))))
+               (goto-char dabbrev--last-expansion-location)
+               ;; Take the following word, with intermediate separators,
+               ;; as our expansion this time.
+               (re-search-forward
+                (concat "\\(?:" dabbrev--abbrev-char-regexp "\\)+"))
 
+               ;; Record the end of this expansion, in case we repeat this.
+               (setq dabbrev--last-expansion-location (point))))
          ;; We have a different abbrev to expand.
-         (dabbrev--reset-global-variables)
-         (setq direction (if (null arg)
-                             (if dabbrev-backward-only 1 0)
-                           (prefix-numeric-value arg)))
-         (setq abbrev (dabbrev--abbrev-at-point))
-         (setq record-case-pattern t)
-         (setq old nil)))
+          (dabbrev--reset-global-variables))
+
+       (setq direction (if (null arg)
+                           (if dabbrev-backward-only 1 0)
+                         (prefix-numeric-value arg)))
+       (setq abbrev (dabbrev--abbrev-at-point))
+       (setq record-case-pattern t)
+       (setq old nil))
 
       ;;--------------------------------
       ;; Find the expansion

reply via email to

[Prev in Thread] Current Thread [Next in Thread]