Subject: bug#43300: [PATCH] Make M-x show new commands for obsolete aliases

From: Stefan Kangas <[email-masked]>
Date: Wed, 9 Sep 2020 16:59:33 -0700

Severity: wishlist

Please find attached two patches that tweaks how M-x
(execute-extended-command) works:

1. Show obsolete commands, and give their new name as an annotation.

M-x recently got the capability to show the keybindings for commands in
an annotation (in parenthesis after the command name).  This patch makes
it show new names for obsolete aliases in the same way, instead of just
refusing to show them.  This should help users ease into the new name
less abruptly and disruptively, instead of having it just disappearing
from M-x and be nowhere to be found.

As an added bonus, we could more confidently mark an alias such as
`display-time-world' obsolete (without worrying that it will just be
gone in the next release).

(Yes, if you type out the full name, you can still call it, but chances
are that many users are very reliant on tab completion and will assume
that it's just gone if it doesn't show up.)

2. Show the function that aliases point to in the same way.
From 870e392fc31da0f1c8a84c3196b16441908a3455 Mon Sep 17 00:00:00 2001
From: Stefan Kangas <[email-masked]>
Date: Thu, 10 Sep 2020 01:32:24 +0200
Subject: [PATCH 1/2] Make M-x show obsolete commands

* lisp/simple.el (read-extended-command): Don't hide obsolete
commands.
(read-extended-command--annotation): Show an annotation for obsolete
commands that says what their new name is.
---
 lisp/simple.el | 21 ++++++++-------------
 1 file changed, 8 insertions(+), 13 deletions(-)

diff --git a/lisp/simple.el b/lisp/simple.el
index 3b2b5c92e9..37e9a95bad 100644
--- a/lisp/simple.el
+++ b/lisp/simple.el
@@ -1881,22 +1881,17 @@ read-extended-command
 	   '(metadata
 	     (annotation-function . read-extended-command--annotation)
 	     (category . command))
-         (let ((pred
-                (if (memq action '(nil t))
-                    ;; Exclude obsolete commands from completions.
-                    (lambda (sym)
-                      (and (funcall pred sym)
-                           (or (equal string (symbol-name sym))
-                               (not (get sym 'byte-obsolete-info)))))
-                  pred)))
-           (complete-with-action action obarray string pred))))
+         (complete-with-action action obarray string pred)))
      #'commandp t nil 'extended-command-history)))
 
 (defun read-extended-command--annotation (command-name)
-  (let* ((function (and (stringp command-name) (intern-soft command-name)))
-         (binding (where-is-internal function overriding-local-map t)))
-    (when (and binding (not (stringp binding)))
-      (format " (%s)" (key-description binding)))))
+  (let* ((fun (and (stringp command-name) (intern-soft command-name)))
+         (binding (where-is-internal fun overriding-local-map t))
+         (obsolete (get fun 'byte-obsolete-info)))
+    (cond (obsolete
+           (format " (%s)" (car obsolete)))
+          ((and binding (not (stringp binding)))
+           (format " (%s)" (key-description binding))))))
 
 (defcustom suggest-key-bindings t
   "Non-nil means show the equivalent key-binding when M-x command has one.
-- 
2.28.0

From c6a60a657f52712d40a80b115484904dc88e4629 Mon Sep 17 00:00:00 2001
From: Stefan Kangas <[email-masked]>
Date: Thu, 10 Sep 2020 01:42:53 +0200
Subject: [PATCH 2/2] Make M-x show what aliases point to

* lisp/simple.el (read-extended-command--annotation): Show an
annotation for aliases saying what it points to.
---
 lisp/simple.el | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/lisp/simple.el b/lisp/simple.el
index 37e9a95bad..73dd938e63 100644
--- a/lisp/simple.el
+++ b/lisp/simple.el
@@ -1887,8 +1887,11 @@ read-extended-command
 (defun read-extended-command--annotation (command-name)
   (let* ((fun (and (stringp command-name) (intern-soft command-name)))
          (binding (where-is-internal fun overriding-local-map t))
-         (obsolete (get fun 'byte-obsolete-info)))
-    (cond (obsolete
+         (obsolete (get fun 'byte-obsolete-info))
+         (alias (symbol-function fun)))
+    (cond ((symbolp alias)
+           (format " (%s)" alias))
+          (obsolete
            (format " (%s)" (car obsolete)))
           ((and binding (not (stringp binding)))
            (format " (%s)" (key-description binding))))))
-- 
2.28.0