[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
bug#70217: [PATCH] Add substring-partial-completion style
From: |
Spencer Baugh |
Subject: |
bug#70217: [PATCH] Add substring-partial-completion style |
Date: |
Sun, 02 Jun 2024 08:16:01 -0400 |
User-agent: |
Gnus/5.13 (Gnus v5.13) |
It seems like we're almost ready to install this patch.
Stefan - it would be nice to know if you think this approach of
including dynamic variable bindings in completion-styles is a good idea,
or at least an acceptable idea. I can go back to the drawing board if
this clashes with your vision/design/theory for completion styles.
Eli Zaretskii <eliz@gnu.org> writes:
> Thanks, I think the first one is better.
Updated with the new docstring.
>From 9f90123afe89e64861d6dca6d4c39a6387e0e720 Mon Sep 17 00:00:00 2001
From: Spencer Baugh <sbaugh@janestreet.com>
Date: Sun, 26 May 2024 08:57:37 -0400
Subject: [PATCH] Allow customizing partial-completion to be more like
substring
The substring completion style completes "foo-bar" as "*foo-bar*". The
partial-completion completion style completes "foo-bar" as "foo*bar*".
Previously, it was not possible to get completion of "foo-bar" to act as
"*foo*bar*", e.g. combining the partial-completion and substring styles.
This would be especially useful for things like project-find-file.
Now it is possible by customizing the completion-pcm-anchored variable
to a non-nil value.
Furthermore, it's convenient to be able to run
regular (completion-pcm-anchored=t, non-substring) partial-completion
before running completion-pcm-anchored=nil partial-completion, since
the former provides more narrowly targeted completions.
It's possible to do this by customizing completion-styles. Just add
'(partial-completion ((completion-pcm-anchored t))) and
'(partial-completion ((completion-pcm-anchored nil))) in that order.
Then the completion machinery will first run partial-completion with
completion-pcm-anchored=t, and if that returns no completions, run
partial-completion with completion-pcm-anchored=nil.
* lisp/minibuffer.el (completion--nth-completion): Allow an element of
completion-styles to contain a list of bindings.
(completion-styles): Document that.
(completion-pcm-anchored): Add.
(completion-pcm--string->pattern): Check completion-pcm-anchored.
(bug#70217)
---
doc/emacs/mini.texi | 16 +++++++++++++--
etc/NEWS | 20 +++++++++++++++++++
lisp/minibuffer.el | 48 ++++++++++++++++++++++++++++++++++++++-------
3 files changed, 75 insertions(+), 9 deletions(-)
diff --git a/doc/emacs/mini.texi b/doc/emacs/mini.texi
index 4557f41c3f7..cfb5df4d586 100644
--- a/doc/emacs/mini.texi
+++ b/doc/emacs/mini.texi
@@ -535,8 +535,14 @@ Completion Styles
@vindex completion-styles
The list variable @code{completion-styles} specifies the completion
-styles to use. Each list element is the name of a completion style (a
-Lisp symbol). The available style symbols are stored in the variable
+styles to use. Each list element is either the name of a completion
+style (a Lisp symbol) or a list starting with the name of a completion
+style followed by @code{let}-style list of bindings which will be in
+effect for that completion style. Multiple elements of
+@code{completion-styles} can name the same completion style with
+different variable bindings.
+
+The available style symbols are stored in the variable
@code{completion-styles-alist} (@pxref{Completion Variables,,, elisp,
The Emacs Lisp Reference Manual}). The default completion styles are
(in order):
@@ -561,6 +567,12 @@ Completion Styles
@dfn{wildcard}---it matches any string of characters at the
corresponding position in the completion alternative.
+@vindex completion-pcm-leading-wildcard
+If @code{completion-pcm-leading-wildcard} is set to @code{t}, this style
+always acts as if a @dfn{wildcard} is present at the start of the
+minibuffer text, similar to the @code{substring} style. For example,
+@samp{l-m} will complete to @samp{emacs-lisp-mode}.
+
@item emacs22
@cindex @code{emacs22}, completion style
This completion style is similar to @code{basic}, except that it
diff --git a/etc/NEWS b/etc/NEWS
index 3c672ffed8f..db1582b86f6 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -1868,6 +1868,26 @@ customization group control exactly when Emacs displays
this preview.
'completion-preview-mode' is buffer-local, to enable it globally use
'global-completion-preview-mode'.
++++
+*** New user option 'completion-pcm-leading-wildcard'.
+This option configures how the partial-completion style does completion.
+It defaults to nil, which preserves the existing behavior. When it is set
+to t, the partial-completion style behaves more like the substring
+style, in that a string being completed can match against a candidate
+anywhere in the candidate string.
+
++++
+*** 'completion-styles' now can contain lists of bindings.
+In addition to being a symbol naming a completion style, an element of
+'completion-styles' can now be a list of the form '(STYLE ((VARIABLE
+VALUE) ...))' where STYLE is a symbol naming a completion style.
+VARIABLE will be bound to VALUE (without evaluating it) while the style
+is executing. This allows multiple references to the same style with
+different values for completion-affecting variables like
+'completion-pcm-leading-wildcard or 'completion-ignore-case'. This also
+applies for the styles configuration in 'completion-category-overrides'
+and 'completion-category-defaults'.
+
---
** The highly accessible Modus themes collection has eight items.
The 'modus-operandi' and 'modus-vivendi' are the main themes that have
diff --git a/lisp/minibuffer.el b/lisp/minibuffer.el
index f62cb2566b2..62d113499dd 100644
--- a/lisp/minibuffer.el
+++ b/lisp/minibuffer.el
@@ -1141,7 +1141,15 @@ completion-styles
;; and simply add "bar" to the end of the result.
emacs22)
"List of completion styles to use.
-The available styles are listed in `completion-styles-alist'.
+An element should be a symbol which is listed in
+`completion-styles-alist'.
+
+An element can also be a list of the form
+(STYLE ((VARIABLE VALUE) ...))
+STYLE must be a symbol listed in `completion-styles-alist', followed by
+a `let'-style list of variable/value pairs. VARIABLE will be bound to
+VALUE (without evaluating it) while the style is handling completion.
+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."
@@ -1284,11 +1292,18 @@ completion--nth-completion
(result-and-style
(seq-some
(lambda (style)
- (let ((probe (funcall
- (or (nth n (assq style completion-styles-alist))
- (error "Invalid completion style %s" style))
- string table pred point)))
- (and probe (cons probe style))))
+ (let (symbols values)
+ (when (consp style)
+ (dolist (binding (cadr style))
+ (push (car binding) symbols)
+ (push (cadr binding) values))
+ (setq style (car style)))
+ (cl-progv symbols values
+ (let ((probe (funcall
+ (or (nth n (assq style completion-styles-alist))
+ (error "Invalid completion style %s" style))
+ string table pred point)))
+ (and probe (cons probe style))))))
(completion--styles md)))
(adjust-fn (get (cdr result-and-style) 'completion--adjust-metadata)))
(when (and adjust-fn metadata)
@@ -3864,6 +3879,21 @@ completion-pcm--pattern-trivial-p
(setq trivial nil)))
trivial)))
+(defcustom completion-pcm-leading-wildcard nil
+ "If non-nil, partial-completion completes as if there's a leading wildcard.
+
+If nil (the default), partial-completion requires a matching completion
+alternative to have the same beginning as the first \"word\" in the
+minibuffer text, where \"word\" is determined by
+`completion-pcm-word-delimiters'.
+
+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"
+ :type 'boolean)
+
(defun completion-pcm--string->pattern (string &optional point)
"Split STRING into a pattern.
A pattern is a list where each element is either a string
@@ -3914,7 +3944,11 @@ completion-pcm--string->pattern
(when (> (length string) p0)
(if pending (push pending pattern))
(push (substring string p0) pattern))
- (nreverse pattern))))
+ (setq pattern (nreverse pattern))
+ (when completion-pcm-leading-wildcard
+ (when (stringp (car pattern))
+ (push 'prefix pattern)))
+ pattern)))
(defun completion-pcm--optimize-pattern (p)
;; Remove empty strings in a separate phase since otherwise a ""
--
2.39.3