summaryrefslogtreecommitdiff
path: root/orderless.el
diff options
context:
space:
mode:
authorDaniel Mendler <mail@daniel-mendler.de>2024-09-05 11:13:00 +0200
committerDaniel Mendler <mail@daniel-mendler.de>2024-09-05 11:13:00 +0200
commit860a10222a1a6be3ea87a77d34d09cd0e2dfd422 (patch)
treeb2ce8693608ef948ea2b1e3bdd321df690bd8997 /orderless.el
parenta2eaed8f465a329c61421668f8168d6aaa2a5ebd (diff)
orderless-expand-prefix: Support the values `prefix`, `substring` and `nil`
Using `completion-substring-try-completion` can be costly in comparison to prefix completion only via `try-completion`, in particular in the context of timer-based auto completion. As a compromise, default to `prefix` completion only. Performance should not be affected, while expansion is still provided. Depending on preference the expansion setting can be escalated to `substring` or even disabled, in case the restrictive Orderless (non-)expansion behavior is preferred.
Diffstat (limited to 'orderless.el')
-rw-r--r--orderless.el86
1 files changed, 46 insertions, 40 deletions
diff --git a/orderless.el b/orderless.el
index 187fd38..4e731fb 100644
--- a/orderless.el
+++ b/orderless.el
@@ -212,14 +212,17 @@ is determined by the values of `completion-ignore-case',
`read-buffer-completion-ignore-case', as usual for completion."
:type 'boolean)
-(defcustom orderless-expand-substring t
+(defcustom orderless-expand-substring 'prefix
"Whether to perform literal substring expansion.
-If enabled, `orderless-try-completion' will first attempt literal
-substring expansion via `completion-substring-try-completion'.
-Otherwise expansion is only performed for single unique matches.
This configuration option affects the behavior of some completion
-interfaces when pressing TAB."
- :type 'boolean)
+interfaces when pressing TAB. If enabled `orderless-try-completion'
+will first attempt literal substring expansion. If disabled,
+expansion is only performed for single unique matches. For
+performance reasons only `prefix' expansion is enabled by default.
+Set the variable to `substring' for full substring expansion."
+ :type '(choice (const :tag "No expansion" nil)
+ (const :tag "Substring" substring)
+ (const :tag "Prefix (efficient)" prefix)))
;;; Matching styles
@@ -563,40 +566,43 @@ match, it completes to that match. If there are no matches, it
returns nil. In any other case it \"completes\" STRING to
itself, without moving POINT.
This function is part of the `orderless' completion style."
- (or (and orderless-expand-substring
- (completion-substring-try-completion string table pred point))
- (catch 'orderless--many
- (pcase-let ((`(,prefix ,regexps ,ignore-case ,pred)
- (orderless--compile string table pred))
- (one nil))
- ;; Abuse all-completions/orderless--filter as a fast search loop.
- ;; Should be almost allocation-free since our "predicate" is not
- ;; called more than two times.
- (orderless--filter
- prefix regexps ignore-case table
- (orderless--predicate-normalized-and
- pred
- (lambda (arg)
- ;; Check if there is more than a single match (= many).
- (when (and one (not (equal one arg)))
- (throw 'orderless--many (cons string point)))
- (setq one arg)
- t)))
- (when one
- ;; Prepend prefix if the candidate does not already have the same
- ;; prefix. This workaround is needed since the predicate may either
- ;; receive an unprefixed or a prefixed candidate as argument. Most
- ;; completion tables consistently call the predicate with unprefixed
- ;; candidates, for example `completion-file-name-table'. In contrast,
- ;; `completion-table-with-context' calls the predicate with prefixed
- ;; candidates. This could be an unintended bug or oversight in
- ;; `completion-table-with-context'.
- (unless (or (equal prefix "")
- (and (string-prefix-p prefix one)
- (test-completion one table pred)))
- (setq one (concat prefix one)))
- (or (equal string one) ;; Return t for unique exact match
- (cons one (length one))))))))
+ (or
+ (pcase orderless-expand-substring
+ ('nil nil)
+ ('prefix (completion-emacs21-try-completion string table pred point))
+ (_ (completion-substring-try-completion string table pred point)))
+ (catch 'orderless--many
+ (pcase-let ((`(,prefix ,regexps ,ignore-case ,pred)
+ (orderless--compile string table pred))
+ (one nil))
+ ;; Abuse all-completions/orderless--filter as a fast search loop.
+ ;; Should be almost allocation-free since our "predicate" is not
+ ;; called more than two times.
+ (orderless--filter
+ prefix regexps ignore-case table
+ (orderless--predicate-normalized-and
+ pred
+ (lambda (arg)
+ ;; Check if there is more than a single match (= many).
+ (when (and one (not (equal one arg)))
+ (throw 'orderless--many (cons string point)))
+ (setq one arg)
+ t)))
+ (when one
+ ;; Prepend prefix if the candidate does not already have the same
+ ;; prefix. This workaround is needed since the predicate may either
+ ;; receive an unprefixed or a prefixed candidate as argument. Most
+ ;; completion tables consistently call the predicate with unprefixed
+ ;; candidates, for example `completion-file-name-table'. In contrast,
+ ;; `completion-table-with-context' calls the predicate with prefixed
+ ;; candidates. This could be an unintended bug or oversight in
+ ;; `completion-table-with-context'.
+ (unless (or (equal prefix "")
+ (and (string-prefix-p prefix one)
+ (test-completion one table pred)))
+ (setq one (concat prefix one)))
+ (or (equal string one) ;; Return t for unique exact match
+ (cons one (length one))))))))
;;;###autoload
(add-to-list 'completion-styles-alist