* bug#74561: [PATCH] Allow limiting the size of *Completions*
@ 2024-11-27 20:25 Spencer Baugh via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-11-27 23:23 ` Drew Adams via Bug reports for GNU Emacs, the Swiss army knife of text editors
0 siblings, 1 reply; 2+ messages in thread
From: Spencer Baugh via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2024-11-27 20:25 UTC (permalink / raw)
To: 74561; +Cc: dmitry, juri
[-- Attachment #1: Type: text/plain, Size: 1754 bytes --]
Tags: patch
From profiling, the main bottleneck in completion over large
completion sets is display-completion-list, when there are many
available candidates. For example, in my large monorepo, when
completing over the 589196 files or the 73897 branches, even with the
candidates narrowed down by typing some prefix to complete, TAB (when
it shows *Completions*) or ? is slow, mostly in
display-completion-list.
By adding completions-list-max with a very large default, performance
is greatly improved in these situations without impacting the normal
case of completion on reasonably sized sets.
Limiting the work done by display-completion-list is also important
for packages which auto-update *Completions* inside while-no-input:
since display-completion-list doesn't do anything which reads input,
while-no-input won't interrupt it. Such packages can instead just
bind completions-list-max to a smaller value.
* lisp/minibuffer.el (display-completion-list): Add FULL-COUNT
argument.
(completions-list-max): Add.
(minibuffer-completion-help): Truncate completions based on
completions-list-max.
In GNU Emacs 29.2.50 (build 9, x86_64-pc-linux-gnu, X toolkit, cairo
version 1.15.12, Xaw scroll bars) of 2024-11-20 built on
igm-qws-u22796a
Repository revision: 28dc0b6f9987e0def7dff4deaa23aa60f021d2a7
Repository branch: emacs-29
Windowing system distributor 'The X.Org Foundation', version 11.0.12011000
System Description: Rocky Linux 8.10 (Green Obsidian)
Configured using:
'configure --with-x-toolkit=lucid --without-gpm --without-gconf
--without-selinux --without-imagemagick --with-modules --with-gif=no
--with-tree-sitter --with-native-compilation=aot
PKG_CONFIG_PATH=/usr/local/home/garnish/libtree-sitter/0.22.6-1/lib/pkgconfig/'
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-Allow-limiting-the-size-of-Completions.patch --]
[-- Type: text/patch, Size: 6047 bytes --]
From 808b1a6d01fcd2d2cc03324aa9826b3160047653 Mon Sep 17 00:00:00 2001
From: Spencer Baugh <sbaugh@janestreet.com>
Date: Thu, 14 Nov 2024 17:14:10 -0500
Subject: [PATCH] Allow limiting the size of *Completions*
From profiling, the main bottleneck in completion over large
completion sets is display-completion-list, when there are many
available candidates. For example, in my large monorepo, when
completing over the 589196 files or the 73897 branches, even with the
candidates narrowed down by typing some prefix to complete, TAB (when
it shows *Completions*) or ? is slow, mostly in
display-completion-list.
By adding completions-list-max with a very large default, performance
is greatly improved in these situations without impacting the normal
case of completion on reasonably sized sets.
Limiting the work done by display-completion-list is also important
for packages which auto-update *Completions* inside while-no-input:
since display-completion-list doesn't do anything which reads input,
while-no-input won't interrupt it. Such packages can instead just
bind completions-list-max to a smaller value.
* lisp/minibuffer.el (display-completion-list): Add FULL-COUNT
argument.
(completions-list-max): Add.
(minibuffer-completion-help): Truncate completions based on
completions-list-max.
---
lisp/minibuffer.el | 38 +++++++++++++++++++++++++++++++-------
1 file changed, 31 insertions(+), 7 deletions(-)
diff --git a/lisp/minibuffer.el b/lisp/minibuffer.el
index 5d11064d900..8078e1603ae 100644
--- a/lisp/minibuffer.el
+++ b/lisp/minibuffer.el
@@ -2354,7 +2354,7 @@ completion-hilit-commonality
completions)
base-size))))
-(defun display-completion-list (completions &optional common-substring group-fun)
+(defun display-completion-list (completions &optional common-substring group-fun full-count)
"Display the list of completions, COMPLETIONS, using `standard-output'.
Each element may be just a symbol or string
or may be a list of two strings to be printed as if concatenated.
@@ -2366,7 +2366,9 @@ display-completion-list
At the end, this runs the normal hook `completion-setup-hook'.
It can find the completion buffer in `standard-output'.
GROUP-FUN is a `group-function' used for grouping the completion
-candidates."
+candidates.
+If FULL-COUNT is non-nil, it's used as the total number of
+completions."
(declare (advertised-calling-convention (completions) "24.4"))
(if common-substring
(setq completions (completion-hilit-commonality
@@ -2379,17 +2381,24 @@ display-completion-list
(let ((standard-output (current-buffer))
(completion-setup-hook nil))
(with-suppressed-warnings ((callargs display-completion-list))
- (display-completion-list completions common-substring group-fun)))
+ (display-completion-list completions common-substring group-fun full-count)))
(princ (buffer-string)))
(with-current-buffer standard-output
(goto-char (point-max))
(if completions-header-format
- (insert (format completions-header-format (length completions)))
+ (insert (format completions-header-format (or full-count (length completions))))
(unless completion-show-help
;; Ensure beginning-of-buffer isn't a completion.
(insert (propertize "\n" 'face '(:height 0)))))
- (completion--insert-strings completions group-fun)))
+ (completion--insert-strings completions group-fun)
+ (when (and full-count (/= full-count (length completions)))
+ (newline)
+ (insert (propertize
+ (format "Displaying %s of %s possible completions.\n"
+ (length completions) full-count)
+ 'face
+ 'shadow)))))
(run-hooks 'completion-setup-hook)
nil)
@@ -2455,6 +2464,15 @@ completions--fit-window-to-buffer
(resize-temp-buffer-window win))
(fit-window-to-buffer win completions-max-height)))
+(defcustom completions-list-max 10000
+ "Maximum number of completions for `minibuffer-completion-help' to list.
+
+After the completions are sorted, any beyond this amount are
+discarded and a message about truncation is inserted. This can
+improve performance when displaying large numbers of completions."
+ :type 'number
+ :version "31.1")
+
(defcustom completion-auto-deselect t
"If non-nil, deselect current completion candidate when you type in minibuffer.
@@ -2554,7 +2572,8 @@ minibuffer-completion-help
;; window, mark it as softly-dedicated, so bury-buffer in
;; minibuffer-hide-completions will know whether to
;; delete the window or not.
- (display-buffer-mark-dedicated 'soft))
+ (display-buffer-mark-dedicated 'soft)
+ full-count)
(with-current-buffer-window
"*Completions*"
;; This is a copy of `display-buffer-fallback-action'
@@ -2610,6 +2629,11 @@ minibuffer-completion-help
(_ completions-group-sort))
completions)))
+ (when completions-list-max
+ (setq full-count (length completions))
+ (when (< completions-list-max full-count)
+ (setq completions (take completions-list-max completions))))
+
(cond
(aff-fun
(setq completions
@@ -2661,7 +2685,7 @@ minibuffer-completion-help
(if (eq (car bounds) (length result))
'exact 'finished))))))
- (display-completion-list completions nil group-fun)
+ (display-completion-list completions nil group-fun full-count)
(when current-candidate-and-offset
(with-current-buffer standard-output
(when-let* ((match (text-property-search-forward
--
2.39.3
^ permalink raw reply related [flat|nested] 2+ messages in thread
* bug#74561: [PATCH] Allow limiting the size of *Completions*
2024-11-27 20:25 bug#74561: [PATCH] Allow limiting the size of *Completions* Spencer Baugh via Bug reports for GNU Emacs, the Swiss army knife of text editors
@ 2024-11-27 23:23 ` Drew Adams via Bug reports for GNU Emacs, the Swiss army knife of text editors
0 siblings, 0 replies; 2+ messages in thread
From: Drew Adams via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2024-11-27 23:23 UTC (permalink / raw)
To: Spencer Baugh, 74561@debbugs.gnu.org; +Cc: dmitry@gutov.dev, juri@linkov.net
FWIW, Icicles has had this since 2010.
`C-h v icicle-max-candidates':
icicle-max-candidates is a variable defined in `icicles-opt.el'.
Its value is nil
Documentation:
Non-nil means truncate completion candidates to at most this many.
If you use library `doremi.el' then you can use `C-x #' during
completion to increment or decrement the option value using the
vertical arrow keys or the mouse wheel. A numeric prefix argument for
`C-x #' sets the increment size. A plain prefix argument (`C-u')
resets `icicle-max-candidates' to nil, meaning no truncation.
If the value is an integer and you use Do Re Mi (library `doremi.el')
then you can use multi-command `icicle-increment-option' anytime to
change the option value incrementally.
You can customize this variable.
If the list of candidates shown in `*Completions*' is truncated
because of `icicle-max-candidates' then:
1. Mode-line minor-mode lighter `Icy' is suffixed by `...'. If you
see `...' you know that if you increase `icicle-max-candidates'
(e.g. by using `C-x #') then more candidates will be available.
2. The mode-line of buffer *Completions*' shows the number of
candidates - e.g., `567 candidates'. If the display is truncated
then it shows the number displayed and the total number - e.g.,
`149/567 candidates shown'.
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2024-11-27 23:23 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-11-27 20:25 bug#74561: [PATCH] Allow limiting the size of *Completions* Spencer Baugh via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-11-27 23:23 ` Drew Adams via Bug reports for GNU Emacs, the Swiss army knife of text editors
Code repositories for project(s) associated with this public inbox
https://git.savannah.gnu.org/cgit/emacs.git
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).