From 7c767ec781fdba02d073b79113b1d8d89548bb08 Mon Sep 17 00:00:00 2001 From: Spencer Baugh Date: Fri, 6 Sep 2024 13:12:52 -0400 Subject: [PATCH] Update completion-styles defcustom for variable overrides In 69ec333eab0b801949d33ef5ae505addc9061793 I allowed completion-styles to contain a list of bindings. Now the 'defcustom' type also supports this. Since the type is somewhat unusual (a value in the list can be either a symbol or a list) I had to add a new widget to support it. * lisp/minibuffer.el (completion--styles-type): Update to allow setting variable overrides. (completion-styles, completion-category-overrides) (completion-pcm-leading-wildcard): Update :version. * lisp/wid-edit.el (widget-single-or-list-to-internal) (single-or-list): Add. --- lisp/minibuffer.el | 12 +++++++----- lisp/wid-edit.el | 24 ++++++++++++++++++++++++ 2 files changed, 31 insertions(+), 5 deletions(-) diff --git a/lisp/minibuffer.el b/lisp/minibuffer.el index 6fae62b3904..cd59b108a7e 100644 --- a/lisp/minibuffer.el +++ b/lisp/minibuffer.el @@ -1119,8 +1119,10 @@ and DOC describes the way this style of completion works.") widget)) (defconst completion--styles-type - `(repeat :tag "insert a new menu to add more styles" - (choice :convert-widget completion--update-styles-options))) + '(repeat :tag "insert a new menu to add more styles" + (single-or-list + (choice :convert-widget completion--update-styles-options) + (repeat :tag "Variable overrides" (group variable sexp))))) (defconst completion--cycling-threshold-type '(choice (const :tag "No cycling" nil) @@ -1154,7 +1156,7 @@ This allows repeating the same style with different configurations. Note that `completion-category-overrides' may override these styles for specific categories, such as files, buffers, etc." :type completion--styles-type - :version "23.1") + :version "31.1") (defvar completion-category-defaults '((buffer (styles . (basic substring))) @@ -1205,7 +1207,7 @@ completing buffer and file names, respectively. If a property in a category is specified by this variable, it overrides the default specified in `completion-category-defaults'." - :version "25.1" + :version "31.1" :type `(alist :key-type (choice :tag "Category" (const buffer) (const file) @@ -3895,7 +3897,7 @@ If non-nil, partial-completion allows any string of characters to occur at the beginning of a completion alternative, as if a wildcard such as \"*\" was present at the beginning of the minibuffer text. This makes partial-completion behave more like the substring completion style." - :version "30.1" + :version "31.1" :type 'boolean) (defun completion-pcm--string->pattern (string &optional point) diff --git a/lisp/wid-edit.el b/lisp/wid-edit.el index e7e6351fcab..05c3f412bf6 100644 --- a/lisp/wid-edit.el +++ b/lisp/wid-edit.el @@ -3891,6 +3891,30 @@ or a list with the default value of each component of the list WIDGET." (and (consp value) (widget-group-match widget (widget-apply widget :value-to-internal value)))) + +(defun widget-single-or-list-to-internal (widget val) + (if (listp val) val + (cons val (make-list (1- (length (widget-get widget :args))) nil)))) + +(define-widget 'single-or-list 'group + "Either a single value (`nlistp') or a list of values (`listp'). + +If the initial value is `nlistp', the first child widget gets +that value and the other children get nil. + +If the first child's value is `nlistp' and the other children are +nil, then `widget-value' just returns the first child's value." + ;; The internal value is always a list; only :value-to-internal and + ;; :match ever get called with the external value, which might be + ;; `nlistp'. + :value-to-external (lambda (_ val) + (if (and (nlistp (car val)) + (cl-every #'null (cdr val))) + (car val) val)) + :value-to-internal #'widget-single-or-list-to-internal + :match (lambda (widget val) + (widget-group-match widget (widget-single-or-list-to-internal widget val)))) + ;;; The `lazy' Widget. ;;