Subject: [PATCH] Do not show obsolete options in customize

From: Stefan Kangas <[email-masked]>
Date: Thu, 12 Nov 2020 15:56:24 -0500

Severity: wishlist

In a recent discussion on emacs-devel,[1]

Eli Zaretskii <[email-masked]> wrote:

>> The obsolete options use a different face.  However, it's not obvious
>> that this is the meaning of that face.
>
> IMO, we shouldn't show obsolete options at all in a Custom buffer, for
> the same reason why we remove them from the manuals.

How about the attached patch?
From 66221f1d0f7ee4f2af0d6c65fe956cce711b48e2 Mon Sep 17 00:00:00 2001
From: Stefan Kangas <[email-masked]>
Date: Sat, 24 Oct 2020 19:44:20 +0200
Subject: [PATCH] Do not show obsolete options in customize

* lisp/cus-edit.el (custom-variable-obsolete): Delete face.
(custom--filter-obsolete-variables): New defun.
(custom-variable-documentation, custom-variable-value-create)
(custom-group-value-create): Do not show obsolete user options.
* test/lisp/cus-edit-tests.el: New file.
---
 etc/NEWS                    |  4 +++
 lisp/cus-edit.el            | 61 ++++++++++++-------------------------
 test/lisp/cus-edit-tests.el | 46 ++++++++++++++++++++++++++++
 3 files changed, 69 insertions(+), 42 deletions(-)
 create mode 100644 test/lisp/cus-edit-tests.el

diff --git a/etc/NEWS b/etc/NEWS
index f21c4cb02c..7d064c0c11 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -706,6 +706,10 @@ This file was a compatibility kludge which is no longer needed.
 To revert to the previous behavior,
 '(setq lisp-indent-function 'lisp-indent-function)' from 'lisp-mode-hook'.
 
+** Customize
+
+*** Customize will no longer show obsolete user options.
+
 ** Edebug
 
 +++
diff --git a/lisp/cus-edit.el b/lisp/cus-edit.el
index d1077d367d..b249b7ef42 100644
--- a/lisp/cus-edit.el
+++ b/lisp/cus-edit.el
@@ -2505,18 +2505,6 @@ custom-comment-invisible-p
 
 ;;; The `custom-variable' Widget.
 
-(defface custom-variable-obsolete
-  '((((class color) (background dark))
-     :foreground "light blue")
-    (((min-colors 88) (class color) (background light))
-     :foreground "blue1")
-    (((class color) (background light))
-     :foreground "blue")
-    (t :slant italic))
-  "Face used for obsolete variables."
-  :version "27.1"
-  :group 'custom-faces)
-
 (defface custom-variable-tag
   '((((class color) (background dark))
      :foreground "light blue" :weight bold)
@@ -2544,7 +2532,7 @@ custom-variable-documentation
 Normally just return the docstring.  But if VARIABLE automatically
 becomes buffer local when set, append a message to that effect.
 Also append any obsolescence information."
-  (format "%s%s%s" (documentation-property variable 'variable-documentation t)
+  (format "%s%s" (documentation-property variable 'variable-documentation t)
 	  (if (and (local-variable-if-set-p variable)
 		   (or (not (local-variable-p variable))
 		       (with-temp-buffer
@@ -2552,21 +2540,7 @@ custom-variable-documentation
 	      "\n
 This variable automatically becomes buffer-local when set outside Custom.
 However, setting it through Custom sets the default value."
-	    "")
-	  ;; This duplicates some code from describe-variable.
-	  ;; TODO extract to separate utility function?
-	  (let* ((obsolete (get variable 'byte-obsolete-variable))
-		 (use (car obsolete)))
-	    (if obsolete
-		(concat "\n
-This variable is obsolete"
-			(if (nth 2 obsolete)
-			    (format " since %s" (nth 2 obsolete)))
-			(cond ((stringp use) (concat ";\n" use))
-			      (use (format-message ";\nuse `%s' instead."
-						   (car obsolete)))
-			      (t ".")))
-	      ""))))
+            "")))
 
 (define-widget 'custom-variable 'custom
   "A widget for displaying a Custom variable.
@@ -2650,8 +2624,7 @@ custom-variable-value-create
 	 (state (or (widget-get widget :custom-state)
 		    (if (memq (custom-variable-state symbol value)
 			      (widget-get widget :hidden-states))
-			'hidden)))
-	 (obsolete (get symbol 'byte-obsolete-variable)))
+			'hidden))))
 
     ;; If we don't know the state, see if we need to edit it in lisp form.
     (unless state
@@ -2684,9 +2657,7 @@ custom-variable-value-create
 	   (push (widget-create-child-and-convert
 		  widget 'item
 		  :format "%{%t%} "
-		  :sample-face (if obsolete
-				   'custom-variable-obsolete
-				 'custom-variable-tag)
+		  :sample-face 'custom-variable-tag
 		  :tag tag
 		  :parent widget)
 		 buttons))
@@ -2744,9 +2715,7 @@ custom-variable-value-create
 		    :help-echo "Change value of this option."
 		    :mouse-down-action 'custom-tag-mouse-down-action
 		    :button-face 'custom-variable-button
-		    :sample-face (if obsolete
-				     'custom-variable-obsolete
-				   'custom-variable-tag)
+		    :sample-face 'custom-variable-tag
 		    :tag tag)
 		   buttons)
 	     (push (widget-create-child-and-convert
@@ -4232,6 +4201,13 @@ custom-group-visibility-create
 	(insert "--------")))
   (widget-default-create widget))
 
+(defun custom--filter-obsolete-variables (items)
+  "Filter obsolete variables from ITEMS."
+  (seq-filter (lambda (item)
+                (not (and (eq (nth 1 item) 'custom-variable)
+                          (get (nth 0 item) 'byte-obsolete-variable))))
+              items))
+
 (defun custom-group-members (symbol groups-only)
   "Return SYMBOL's custom group members.
 If GROUPS-ONLY is non-nil, return only those members that are groups."
@@ -4437,12 +4413,13 @@ custom-group-value-create
 					     ?\s))
 	   ;; Members.
 	   (message "Creating group...")
-	   (let* ((members (custom-sort-items
-			    members
-			    ;; Never sort the top-level custom group.
-			    (unless (eq symbol 'emacs)
-			      custom-buffer-sort-alphabetically)
-			    custom-buffer-order-groups))
+           (let* ((members (custom--filter-obsolete-variables
+                            (custom-sort-items
+                             members
+                             ;; Never sort the top-level custom group.
+                             (unless (eq symbol 'emacs)
+                               custom-buffer-sort-alphabetically)
+                             custom-buffer-order-groups)))
 		  (prefixes (widget-get widget :custom-prefixes))
 		  (custom-prefix-list (custom-prefix-add symbol prefixes))
 		  (have-subtitle (and (not (eq symbol 'emacs))
diff --git a/test/lisp/cus-edit-tests.el b/test/lisp/cus-edit-tests.el
new file mode 100644
index 0000000000..6fe1ce4a11
--- /dev/null
+++ b/test/lisp/cus-edit-tests.el
@@ -0,0 +1,46 @@
+;;; cus-edit-tests.el --- Tests for cus-edit.el  -*- lexical-binding: t -*-
+
+;; Copyright (C) 2020 Free Software Foundation, Inc.
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs.  If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;;; Code:
+
+(require 'ert)
+(require 'ert-x)
+(require 'cus-edit)
+
+(defgroup cus-edit-tests nil "test"
+  :group 'test-group)
+
+(defcustom cus-edit--testvar-obsolete nil "test"
+  :type 'boolean)
+(make-obsolete-variable 'cus-edit--testvar-obsolete nil "X.X-test")
+
+(ert-deftest cus-edit-tests-customize-group/no-obsolete ()
+  "Check that obsolete variables do not show up."
+  (save-window-excursion
+    (unwind-protect
+        (progn
+          (customize-group 'cus-edit-tests)
+          (should-not (search-forward "Cus Edit Testvar Obsolete" nil t)))
+      (when-let ((buf (get-buffer "*Customize Group: Cus Edit Tests*")))
+        (kill-buffer buf)))))
+
+(provide 'cus-edit-tests)
+;;; cus-edit-tests.el ends here
-- 
2.28.0