unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
From: sbaugh@catern.com
To: emacs-devel@gnu.org
Subject: Re: Updating *Completions* as you type
Date: Sat, 14 Oct 2023 16:05:11 -0400	[thread overview]
Message-ID: <87sf6dx954.fsf@catern.com> (raw)
In-Reply-To: 86r0lxm7um.fsf@mail.linkov.net

[-- Attachment #1: Type: text/plain, Size: 816 bytes --]

Juri Linkov <juri@linkov.net> writes:

>>>> It would be nice if there was a built-in customization which caused
>>>> *Completions* to update as you type, as long as that buffer is visible.
>>>> I imagine such a request has been made before, so what is the obstacle
>>>> to adding it?
>>>
>>> I don't remember what was the obstacle, but here is the previous patch
>>> that implements the behavior of zsh and is based on icomplete-mode.
>>
>> Nice! Although again this is more features than I want - I just want
>> *Completions* to automatically update after it opens.
>
> Probably it's possible to pare it down to less code with less features
> that could basically do the same after toggling a new option.

Yes, agreed.  Taking inspiration from zcomplete, I wrote this patch to
provide just this feature, thoughts?


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-Add-completions-auto-update.patch --]
[-- Type: text/x-patch, Size: 3402 bytes --]

From fef547ece1d5cd3eebbc2fb7f51e51f15cfc2b4a Mon Sep 17 00:00:00 2001
From: Spencer Baugh <sbaugh@catern.com>
Date: Sat, 14 Oct 2023 14:27:23 -0400
Subject: [PATCH] Add completions-auto-update

It can be useful for the *Completions* buffer to automatically update
as you type.  That way you can see immediately what the next
completion operation will do, even if you've changed text in the
buffer since triggering completion.

* lisp/minibuffer.el (completions-auto-update): Add.
(completions-no-auto-update-commands): Add.
(completions--post-command): Add.
(minibuffer-completion-help): Add completions--post-command to
post-command-hook.
---
 lisp/minibuffer.el | 38 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 38 insertions(+)

diff --git a/lisp/minibuffer.el b/lisp/minibuffer.el
index 3e30b68d5e9..9995da9e4b7 100644
--- a/lisp/minibuffer.el
+++ b/lisp/minibuffer.el
@@ -2376,6 +2376,40 @@ completions--fit-window-to-buffer
         (resize-temp-buffer-window win))
     (fit-window-to-buffer win completions-max-height)))
 
+(defcustom completions-auto-update t
+  "If non-nil, update the *Completions* buffer as you type.
+
+This only affects the *Completions* buffer if it is already
+displayed."
+  :type '(choice (const :tag "*Completions* doesn't change as you type" nil)
+                 (const :tag "*Completions* updates as you type" t))
+  :version "30.1")
+
+(defconst completions-no-auto-update-commands
+  '(previous-history-element
+    next-history-element
+    previous-line-or-history-element
+    next-line-or-history-element
+    completion-at-point
+    minibuffer-complete-and-exit
+    minibuffer-force-complete-and-exit
+    minibuffer-next-completion
+    minibuffer-previous-completion
+    minibuffer-choose-completion)
+  "Commands to skip updating *Completions*")
+
+(defun completions--post-command ()
+  "Update a displayed *Completions* buffer after a change"
+  (when completions-auto-update
+    (while-no-input
+      (let ((non-essential t))
+        (when (and (get-buffer-window "*Completions*" 0)
+                   (not (memq this-command completions-no-auto-update-commands)))
+          (redisplay)
+          (if completion-in-region-mode
+              (completion-help-at-point)
+            (minibuffer-completion-help)))))))
+
 (defun minibuffer-completion-help (&optional start end)
   "Display a list of possible completions of the current minibuffer contents."
   (interactive)
@@ -2398,6 +2432,7 @@ minibuffer-completion-help
           ;; If there are no completions, or if the current input is already
           ;; the sole completion, then hide (previous&stale) completions.
           (minibuffer-hide-completions)
+          (remove-hook 'post-command-hook #'completions--post-command t)
           (if completions
               (completion--message "Sole completion")
             (unless completion-fail-discreetly
@@ -2449,6 +2484,9 @@ minibuffer-completion-help
             (body-function
              . ,#'(lambda (_window)
                     (with-current-buffer mainbuf
+                      (when completions-auto-update
+                        (add-hook 'post-command-hook #'completions--post-command nil t))
+
                       ;; Remove the base-size tail because `sort' requires a properly
                       ;; nil-terminated list.
                       (when last (setcdr last nil))
-- 
2.41.0


[-- Attachment #3: Type: text/plain, Size: 2714 bytes --]


>> That being said, yes this may be nice.  But minibuffer-completion-help
>> already does sort the completions using display-sort-function, just like
>> completion-all-sorted-completions, so what's causing the difference in
>> behavior?
>
> It seems this is implementable in minibuffer-completion-help
> by copying this code from completion-all-sorted-completions:
>
>               (setq all (minibuffer--sort-by-position
>                          (minibuffer--sort-preprocess-history
>                           (substring string 0 base-size))
>                          all))

Oh, very interesting!  Maybe completions-sort should accept a new symbol
'history to behave this way?

I already think this would be very nice for project-switch-project, for
example, since I'm often switching between a few related projects.

Perhaps 'history should break ties by alphabetizing, otherwise
e.g. filenames you haven't visited before would be unsorted randomly.

Hmm, actually the case of filenames is a bit complex.  Because for
filenames, the strings we're completing over don't appear verbatim in
the history.  So perhaps read-file-name would need its own specialized
sorting function, which whenever you're completing in some directory,
sorts to the front any files in that directory whose full path appears
in file-name-history.

>> Honestly the main place I find myself wanting different sorting of
>> completions is for buffer completion - I'd prefer buffers to be sorted
>> by most-recently-used.  Maybe we can just add such an option?
>
> Such an option would be nice.  Maybe the right way to support it
> is to add a new sort function with the code above.  Then the caller
> could provide such a function in the completion metadata.

Oh, that's also interesting.  So there would be a function that the
completion metadata could specify as display-sort-function, which would
have the behavior of sorting based on history?

That also makes a lot of sense, and would allow commands like
project-switch-project and read-buffer to opt in on a command-by-command
basis, which might be more sensible.

So maybe adding 'history as a new option for completions-sort isn't a
good idea.  Instead we should just add user options for enabling history
sorting for files and buffers.  (And perhaps we could just enable
history sorting by default for project-switch-project.)

Also: it might be nice to switch between history-sorting and
alphabetized-sorting during the course of completion, both for files and
buffers.  Maybe we could do that by making a command which puts
completion into a mode where it just ignores the display-sort-function
specified by the completion metadata, and just always uses
completions-sort.


  reply	other threads:[~2023-10-14 20:05 UTC|newest]

Thread overview: 107+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-10-12 23:53 Updating *Completions* as you type sbaugh
2023-10-13  6:31 ` Eli Zaretskii
2023-10-13 18:01   ` Spencer Baugh
2023-10-14  7:09     ` Eli Zaretskii
2023-10-14 19:26       ` Björn Bidar
     [not found]       ` <874jit2ef7.fsf@>
2023-10-14 19:38         ` Eli Zaretskii
2023-10-14 16:51     ` Juri Linkov
2023-10-14 17:56       ` sbaugh
2023-10-14 19:51       ` Dmitry Gutov
2023-10-13  6:34 ` Juri Linkov
2023-10-13 19:04   ` Spencer Baugh
2023-10-14 16:58     ` Juri Linkov
2023-10-14 20:05       ` sbaugh [this message]
2023-10-15  6:06         ` Eli Zaretskii
2023-10-15 15:55           ` sbaugh
2023-10-16 11:38             ` Eli Zaretskii
2023-10-16 14:50               ` Michael Albinus
2023-10-16 15:58                 ` [External] : " Drew Adams
2023-10-16 12:16             ` sbaugh
2023-10-17 18:23               ` Juri Linkov
2023-10-18 23:27                 ` Spencer Baugh
2023-10-15  7:32         ` Juri Linkov
2023-10-16 19:28           ` Rudolf Adamkovič
2023-10-17 18:38             ` Juri Linkov
2023-10-15 20:31         ` Eshel Yaron
2023-10-16  3:18           ` [External] : " Drew Adams
2023-10-16 16:54           ` Juri Linkov
2023-10-17 13:48         ` sbaugh
2023-10-17 18:35           ` Juri Linkov
2023-10-17 22:57             ` Spencer Baugh
2023-10-18  3:04               ` [External] : " Drew Adams
2023-10-18  6:56               ` Juri Linkov
2023-10-18 12:25                 ` Spencer Baugh
2023-10-18 17:32                   ` Juri Linkov
2023-10-18 23:33                     ` Spencer Baugh
2023-10-19  2:29                       ` Spencer Baugh
2023-10-19  6:55                         ` Juri Linkov
2023-11-19 19:22                           ` sbaugh
2023-11-20  7:51                             ` Juri Linkov
2023-11-20 15:24                               ` Spencer Baugh
2023-11-20 17:47                                 ` Juri Linkov
2023-11-20 18:50                                   ` Spencer Baugh
2023-11-21  7:58                                     ` Juri Linkov
2023-11-21 12:40                                       ` sbaugh
2023-11-21 17:09                                         ` Juri Linkov
2023-11-21 20:45                                           ` Spencer Baugh
2023-11-22  7:51                                             ` Juri Linkov
2023-11-22 16:11                                               ` Spencer Baugh
2023-11-23  7:58                                                 ` Juri Linkov
2023-11-23 12:36                                                   ` sbaugh
2023-11-24  7:58                                                     ` Juri Linkov
2023-11-25 16:44                                                       ` Spencer Baugh
2023-11-25 18:31                                                         ` Juri Linkov
2023-11-26 13:33                                                           ` sbaugh
2023-11-27  7:28                                                             ` Juri Linkov
2023-11-28 14:38                                                               ` Spencer Baugh
2023-11-28 15:03                                                                 ` Eli Zaretskii
2023-11-28 17:13                                                                   ` Juri Linkov
2023-11-28 17:36                                                                     ` Eli Zaretskii
2023-11-29  7:11                                                                       ` Juri Linkov
2023-11-29 13:09                                                                         ` Eli Zaretskii
2023-11-29 14:14                                                                           ` Spencer Baugh
2023-11-29 14:54                                                                             ` Eli Zaretskii
2023-11-29 15:21                                                                               ` Spencer Baugh
2023-11-29 15:52                                                                                 ` Eli Zaretskii
2023-11-29 19:17                                                                                   ` Spencer Baugh
2023-11-30  6:12                                                                                     ` Eli Zaretskii
2023-11-30 12:33                                                                                       ` Spencer Baugh
2023-11-30 14:10                                                                                         ` Eli Zaretskii
2023-11-28 23:56                                                                   ` Spencer Baugh
2023-11-29  3:33                                                                     ` Eli Zaretskii
2023-12-03 17:25                                                                     ` Juri Linkov
2023-12-03 17:56                                                                       ` Eli Zaretskii
2023-12-06 17:17                                                                         ` Juri Linkov
2023-11-28 17:16                                                                 ` Juri Linkov
2023-11-28 23:36                                                                   ` Turning completion table lambdas into symbols Spencer Baugh
2023-11-28 23:51                                                                     ` Dmitry Gutov
2023-11-29 19:26                                                                       ` Spencer Baugh
2023-12-01  0:36                                                                         ` Dmitry Gutov
2023-11-29  7:18                                                                     ` Juri Linkov
2023-11-21 12:54                                       ` Updating *Completions* as you type John Yates
2023-11-21 17:03                                         ` Juri Linkov
2023-11-21 22:27                                           ` John Yates
2023-10-20  6:49         ` Juri Linkov
2023-10-17 15:01       ` sbaugh
2023-10-17 18:20         ` Juri Linkov
2023-10-17 23:37           ` Spencer Baugh
2023-10-17 23:44             ` Spencer Baugh
2023-10-18  6:51             ` Juri Linkov
2023-10-18 12:47               ` Spencer Baugh
2023-10-18 17:28                 ` Juri Linkov
2023-10-18 23:32                   ` Spencer Baugh
2023-10-16  3:19   ` [External] : " Drew Adams
2023-10-20  9:35   ` zcomplete Philip Kaludercic
2023-10-22 17:28     ` zcomplete Juri Linkov
2023-10-23  5:00       ` zcomplete Protesilaos Stavrou
2023-10-23  6:45         ` zcomplete Juri Linkov
2023-10-13 18:11 ` Updating *Completions* as you type Daniel Semyonov
2023-10-13 18:48   ` Spencer Baugh
2023-10-16  3:16     ` [External] : " Drew Adams
2023-10-16  9:25       ` Philip Kaludercic
2023-10-16 16:03         ` Drew Adams
2023-10-20  7:45           ` Philip Kaludercic
2023-10-20 16:10             ` Drew Adams
2023-10-16 22:55         ` Emanuel Berg
2023-10-17  6:09           ` Emanuel Berg
2023-10-17  0:44 ` Michael Heerdegen

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.gnu.org/software/emacs/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=87sf6dx954.fsf@catern.com \
    --to=sbaugh@catern.com \
    --cc=emacs-devel@gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).