unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
* Suggestions for improvements to the *Completions* buffer
@ 2021-12-09 17:22 Philip Kaludercic
  2021-12-09 17:49 ` [External] : " Drew Adams
                   ` (3 more replies)
  0 siblings, 4 replies; 32+ messages in thread
From: Philip Kaludercic @ 2021-12-09 17:22 UTC (permalink / raw)
  To: emacs-devel

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


Hi,

I'd like to suggest a few modifications to the default behaviour of
the *Completions* buffer.  These are mostly conservative extensions of
the current defaults.

Currently, next-completion (and previous-completion) stops at either the
end or the beginning of a buffer.  This patch would allow for the
command to also wrap around, and if the end has been reached to jump
back to the beginning.  In my experience, the improvement is most
noticeable when choosing between a small number choices, and pressing
tab twice is easier than shift-tab.

Optionally, this could also be extended to only enable cycling when
there are less than n options to select from.


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-Allow-for-next-completion-to-wrap-around-the-complet.patch --]
[-- Type: text/x-patch, Size: 2725 bytes --]

From 250d743cf53002b4c696ad33eb76a4454c4d254c Mon Sep 17 00:00:00 2001
From: Philip Kaludercic <philipk@posteo.net>
Date: Thu, 9 Dec 2021 17:26:14 +0100
Subject: [PATCH 1/4] Allow for next-completion to wrap around the completion
 buffer

* lisp/simple.el (completion-wrap-movement): Add new option.
(previous-completion): Update docstring.
(next-completion): Respect completion-wrap-movement.
---
 lisp/simple.el | 23 +++++++++++++++++++----
 1 file changed, 19 insertions(+), 4 deletions(-)

diff --git a/lisp/simple.el b/lisp/simple.el
index 94a459b779..5183a7e053 100644
--- a/lisp/simple.el
+++ b/lisp/simple.el
@@ -9013,25 +9013,38 @@ delete-completion-window
       (if (get-buffer-window buf)
 	  (select-window (get-buffer-window buf))))))
 
+(defcustom completion-wrap-movement t
+  "Non-nil means to wrap around when selecting completion options.
+This affects the commands `next-completion' and
+`previous-completion'."
+  :type 'boolean
+  :version "29.1"
+  :group 'completion)
+
 (defun previous-completion (n)
-  "Move to the previous item in the completion list."
+  "Move to the previous item in the completion list.
+With prefix argument N, move back N items (negative N means move
+forward)."
   (interactive "p")
   (next-completion (- n)))
 
 (defun next-completion (n)
   "Move to the next item in the completion list.
-With prefix argument N, move N items (negative N means move backward)."
+With prefix argument N, move N items (negative N means move
+backward)."
   (interactive "p")
   (let ((beg (point-min)) (end (point-max)))
-    (while (and (> n 0) (not (eobp)))
+    (while (> n 0)
       ;; If in a completion, move to the end of it.
       (when (get-text-property (point) 'mouse-face)
 	(goto-char (next-single-property-change (point) 'mouse-face nil end)))
+      (when (and (eobp) completion-wrap-movement)
+        (goto-char (point-min)))
       ;; Move to start of next one.
       (unless (get-text-property (point) 'mouse-face)
 	(goto-char (next-single-property-change (point) 'mouse-face nil end)))
       (setq n (1- n)))
-    (while (and (< n 0) (not (bobp)))
+    (while (< n 0)
       (let ((prop (get-text-property (1- (point)) 'mouse-face)))
 	;; If in a completion, move to the start of it.
 	(when (and prop (eq prop (get-text-property (point) 'mouse-face)))
@@ -9041,6 +9054,8 @@ next-completion
 	(unless (or (bobp) (get-text-property (1- (point)) 'mouse-face))
 	  (goto-char (previous-single-property-change
 		      (point) 'mouse-face nil beg)))
+        (when (and (bobp) completion-wrap-movement)
+          (goto-char (point-max)))
 	;; Move to the start of that one.
 	(goto-char (previous-single-property-change
 		    (point) 'mouse-face nil beg))
-- 
2.34.0


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


Currently, as soon as the minibuffer cannot expand the completion any
further, tab becomes a noop and the user is caught in a state that they
have to exit with some other command (M-v, C-g, ...).  Again, just like
above, I prefer to stay on the same key, so this patch introduces a user
option to automatically switch to the completion buffer, as soon as it
pops up, to just "tab on".


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #4: 0002-Allow-for-the-completion-buffer-to-be-automatically-.patch --]
[-- Type: text/x-patch, Size: 1412 bytes --]

From 4bc0d69c00cc650ec2be437ac7d45ccad7926ea1 Mon Sep 17 00:00:00 2001
From: Philip Kaludercic <philipk@posteo.net>
Date: Thu, 9 Dec 2021 17:34:54 +0100
Subject: [PATCH 2/4] Allow for the completion buffer to be automatically
 selected

* lisp/simple.el (completion-auto-select): Add new option.
(completion-setup-function): Respect completion-auto-select.
---
 lisp/simple.el | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/lisp/simple.el b/lisp/simple.el
index 5183a7e053..b5f5122153 100644
--- a/lisp/simple.el
+++ b/lisp/simple.el
@@ -9227,6 +9227,12 @@ completion-show-help
   :version "22.1"
   :group 'completion)
 
+(defcustom completion-auto-select t
+  "Non-nil means to automatically select the completions buffer."
+  :type 'boolean
+  :version "29.1"
+  :group 'completion)
+
 ;; This function goes in completion-setup-hook, so that it is called
 ;; after the text of the completion list buffer is written.
 (defun completion-setup-function ()
@@ -9263,7 +9269,9 @@ completion-setup-function
 	    (insert "Click on a completion to select it.\n"))
 	(insert (substitute-command-keys
 		 "In this buffer, type \\[choose-completion] to \
-select the completion near point.\n\n"))))))
+select the completion near point.\n\n")))))
+  (when completion-auto-select
+    (switch-to-completions)))
 
 (add-hook 'completion-setup-hook #'completion-setup-function)
 
-- 
2.34.0


[-- Attachment #5: Type: text/plain, Size: 438 bytes --]


When exiting the *Completions* buffer, C-g and q seem not to send the
user back to minibuffer.  This introduces friction via uncertainty,
because you don't know where the active point will land, so you have to
manually switch back.  This command adds and binds command that ensure
the minibuffer is always selected once it is closed or unfocused.  I
think this is an absolute improvement, so there is no option to reset
this behaviour.


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #6: 0003-Switch-back-to-minibuffer-when-quitting-completion-b.patch --]
[-- Type: text/x-patch, Size: 1822 bytes --]

From 8f2433d70eadef47772b01b71ff44f5010c0935b Mon Sep 17 00:00:00 2001
From: Philip Kaludercic <philipk@posteo.net>
Date: Thu, 9 Dec 2021 17:36:14 +0100
Subject: [PATCH 3/4] Switch back to minibuffer when quitting  completion
 buffer

* lisp/simple.el (completion-quit): Add new command
(completion-kill-buffer): Add new command
(completion-list-mode-map): Bind completion-quit and
rebind kill-current-buffer to completion-kill-buffer
---
 lisp/simple.el | 16 +++++++++++++++-
 1 file changed, 15 insertions(+), 1 deletion(-)

diff --git a/lisp/simple.el b/lisp/simple.el
index b5f5122153..5ca8142548 100644
--- a/lisp/simple.el
+++ b/lisp/simple.el
@@ -8957,6 +8957,18 @@ set-variable
 \f
 ;; Define the major mode for lists of completions.
 
+(defun completion-quit ()
+  "Close the completion buffer and return to the minibuffer."
+  (interactive)
+  (quit-window)
+  (switch-to-minibuffer))
+
+(defun completion-kill-buffer ()
+  "Close the completion buffer and return to the minibuffer."
+  (interactive)
+  (kill-buffer "*Completions*")
+  (switch-to-minibuffer))
+
 (defvar completion-list-mode-map
   (let ((map (make-sparse-keymap)))
     (set-keymap-parent map special-mode-map)
@@ -8970,10 +8982,12 @@ completion-list-mode-map
     (define-key map [right] 'next-completion)
     (define-key map [?\t] 'next-completion)
     (define-key map [backtab] 'previous-completion)
-    (define-key map "z" 'kill-current-buffer)
     (define-key map "n" 'next-completion)
     (define-key map "p" 'previous-completion)
     (define-key map "\M-g\M-c" 'switch-to-minibuffer)
+    (define-key map "z" #'completion-kill-buffer)
+    (define-key map [remap keyboard-quit] #'completion-quit)
+    (define-key map [remap quit-window] #'switch-to-minibuffer)
     map)
   "Local map for completion list buffers.")
 
-- 
2.34.0


[-- Attachment #7: Type: text/plain, Size: 409 bytes --]


In the *Completions*, self-insert-command is not bound so that "q", "n",
"p", "z", ... can be used.  This patch would add "s" (for
isearch-forward) and "S" (for isearch-forward-regexp) to the default
bunch.  This is my most recent change, that I am least certain about.
If I played around with it for a bit longer, maybe this could also be
extended to an interactive narrowing along the lines of icomplete.


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #8: 0004-Bind-modifier-less-isearch-commands-in-the-completio.patch --]
[-- Type: text/x-patch, Size: 958 bytes --]

From 4f311034fac33698534090c35fb7e662f1cef47a Mon Sep 17 00:00:00 2001
From: Philip Kaludercic <philipk@posteo.net>
Date: Thu, 9 Dec 2021 17:37:44 +0100
Subject: [PATCH 4/4] Bind modifier-less isearch commands in the completion
 buffer

* lisp/simple.el (completion-list-mode-map): Bind isearch-forward and
isearch-forward-regexp
---
 lisp/simple.el | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/lisp/simple.el b/lisp/simple.el
index 5ca8142548..cb2d4cd7f4 100644
--- a/lisp/simple.el
+++ b/lisp/simple.el
@@ -8982,6 +8982,8 @@ completion-list-mode-map
     (define-key map [right] 'next-completion)
     (define-key map [?\t] 'next-completion)
     (define-key map [backtab] 'previous-completion)
+    (define-key map "s" #'isearch-forward)
+    (define-key map "S" #'isearch-forward-regexp)
     (define-key map "n" 'next-completion)
     (define-key map "p" 'previous-completion)
     (define-key map "\M-g\M-c" 'switch-to-minibuffer)
-- 
2.34.0


[-- Attachment #9: Type: text/plain, Size: 453 bytes --]


So, any opinions on these suggestions?  I get the impression that many
people avoid the default completion system because of small
peculiarities such as the ones I describe above.  Protesilaos Stavrou's
recent library MCT (https://gitlab.com/protesilaos/mct) demonstrates
that it doesn't take much to fix these issues, but I think that the
above already does a lot, with a lot less code (mostly because this is
not a package).

-- 
	Philip Kaludercic


^ permalink raw reply related	[flat|nested] 32+ messages in thread

* RE: [External] : Suggestions for improvements to the *Completions* buffer
  2021-12-09 17:22 Suggestions for improvements to the *Completions* buffer Philip Kaludercic
@ 2021-12-09 17:49 ` Drew Adams
  2021-12-09 18:05   ` Philip Kaludercic
  2021-12-09 18:27 ` Manuel Uberti
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 32+ messages in thread
From: Drew Adams @ 2021-12-09 17:49 UTC (permalink / raw)
  To: Philip Kaludercic, emacs-devel@gnu.org

> Currently, next-completion (and previous-completion) stops at either the
> end or the beginning of a buffer.  This patch would allow for the
> command to also wrap around, and if the end has been reached to jump
> back to the beginning.  In my experience, the improvement is most
> noticeable when choosing between a small number choices, and pressing
> tab twice is easier than shift-tab.

Yet another feature introduced by Icicles, back in 2006.




^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: [External] : Suggestions for improvements to the *Completions* buffer
  2021-12-09 17:49 ` [External] : " Drew Adams
@ 2021-12-09 18:05   ` Philip Kaludercic
  2021-12-09 19:21     ` Stefan Monnier
  0 siblings, 1 reply; 32+ messages in thread
From: Philip Kaludercic @ 2021-12-09 18:05 UTC (permalink / raw)
  To: Drew Adams; +Cc: emacs-devel@gnu.org

Drew Adams <drew.adams@oracle.com> writes:

>> Currently, next-completion (and previous-completion) stops at either the
>> end or the beginning of a buffer.  This patch would allow for the
>> command to also wrap around, and if the end has been reached to jump
>> back to the beginning.  In my experience, the improvement is most
>> noticeable when choosing between a small number choices, and pressing
>> tab twice is easier than shift-tab.
>
> Yet another feature introduced by Icicles, back in 2006.

To clarify, I am not claiming any of this is new, all I am doing it
preparing these changes as patches that could be applied to Emacs
itself.

-- 
	Philip Kaludercic



^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: Suggestions for improvements to the *Completions* buffer
  2021-12-09 17:22 Suggestions for improvements to the *Completions* buffer Philip Kaludercic
  2021-12-09 17:49 ` [External] : " Drew Adams
@ 2021-12-09 18:27 ` Manuel Uberti
  2021-12-09 19:49 ` Juri Linkov
  2021-12-13 21:36 ` Philip Kaludercic
  3 siblings, 0 replies; 32+ messages in thread
From: Manuel Uberti @ 2021-12-09 18:27 UTC (permalink / raw)
  To: emacs-devel

On 09/12/21 18:22, Philip Kaludercic wrote:
> When exiting the *Completions* buffer, C-g and q seem not to send the
> user back to minibuffer.  This introduces friction via uncertainty,
> because you don't know where the active point will land, so you have to
> manually switch back.  This command adds and binds command that ensure
> the minibuffer is always selected once it is closed or unfocused.  I
> think this is an absolute improvement, so there is no option to reset
> this behaviour.

IMO, this would be a welcome improvement. But of course, about this and the rest 
of your patches I'll let more experienced developers chime in.

-- 
Manuel Uberti
www.manueluberti.eu



^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: [External] : Suggestions for improvements to the *Completions* buffer
  2021-12-09 18:05   ` Philip Kaludercic
@ 2021-12-09 19:21     ` Stefan Monnier
  0 siblings, 0 replies; 32+ messages in thread
From: Stefan Monnier @ 2021-12-09 19:21 UTC (permalink / raw)
  To: Philip Kaludercic; +Cc: Drew Adams, emacs-devel@gnu.org

> To clarify, I am not claiming any of this is new, all I am doing it
> preparing these changes as patches that could be applied to Emacs
> itself.

That would be great, indeed.


        Stefan




^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: Suggestions for improvements to the *Completions* buffer
  2021-12-09 17:22 Suggestions for improvements to the *Completions* buffer Philip Kaludercic
  2021-12-09 17:49 ` [External] : " Drew Adams
  2021-12-09 18:27 ` Manuel Uberti
@ 2021-12-09 19:49 ` Juri Linkov
  2021-12-09 20:07   ` Philip Kaludercic
  2021-12-13 21:36 ` Philip Kaludercic
  3 siblings, 1 reply; 32+ messages in thread
From: Juri Linkov @ 2021-12-09 19:49 UTC (permalink / raw)
  To: Philip Kaludercic; +Cc: emacs-devel

> I'd like to suggest a few modifications to the default behaviour of
> the *Completions* buffer.  These are mostly conservative extensions of
> the current defaults.

Thanks, all your patches is a nice improvement.  I have a question only
about the last patch.

> When exiting the *Completions* buffer, C-g and q seem not to send the
> user back to minibuffer.

This was just a plain bug.

> +(defun completion-quit ()
> +  "Close the completion buffer and return to the minibuffer."
> +  (interactive)
> +  (quit-window)
> +  (switch-to-minibuffer))
> +
> +(defun completion-kill-buffer ()
> +  "Close the completion buffer and return to the minibuffer."
> +  (interactive)
> +  (kill-buffer "*Completions*")
> +  (switch-to-minibuffer))
> @@ -8970,10 +8982,12 @@ completion-list-mode-map
> +    (define-key map "z" #'completion-kill-buffer)
> +    (define-key map [remap keyboard-quit] #'completion-quit)
> +    (define-key map [remap quit-window] #'switch-to-minibuffer)

So typing C-g in the *Completions* buffer will be the same as
typing C-g in the minibuffer?  This would provide more consistency.

> In the *Completions*, self-insert-command is not bound so that "q", "n",
> "p", "z", ... can be used.  This patch would add "s" (for
> isearch-forward) and "S" (for isearch-forward-regexp) to the default
> bunch.  This is my most recent change, that I am least certain about.
> If I played around with it for a bit longer, maybe this could also be
> extended to an interactive narrowing along the lines of icomplete.

I guess it's too late to allow all self-inserting keys in the *Completions*
buffer to be used either to add characters to the search string,
or to narrow completions interactively as if they were typed in the minibuffer,
because "q", "n", "p", "z" are already bound to other commands?



^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: Suggestions for improvements to the *Completions* buffer
  2021-12-09 19:49 ` Juri Linkov
@ 2021-12-09 20:07   ` Philip Kaludercic
  2021-12-09 20:21     ` Juri Linkov
  2021-12-09 21:16     ` Stefan Kangas
  0 siblings, 2 replies; 32+ messages in thread
From: Philip Kaludercic @ 2021-12-09 20:07 UTC (permalink / raw)
  To: Juri Linkov; +Cc: emacs-devel

Juri Linkov <juri@linkov.net> writes:

>> I'd like to suggest a few modifications to the default behaviour of
>> the *Completions* buffer.  These are mostly conservative extensions of
>> the current defaults.
>
> Thanks, all your patches is a nice improvement.  I have a question only
> about the last patch.
>
>> When exiting the *Completions* buffer, C-g and q seem not to send the
>> user back to minibuffer.
>
> This was just a plain bug.
>
>> +(defun completion-quit ()
>> +  "Close the completion buffer and return to the minibuffer."
>> +  (interactive)
>> +  (quit-window)
>> +  (switch-to-minibuffer))
>> +
>> +(defun completion-kill-buffer ()
>> +  "Close the completion buffer and return to the minibuffer."
>> +  (interactive)
>> +  (kill-buffer "*Completions*")
>> +  (switch-to-minibuffer))
>> @@ -8970,10 +8982,12 @@ completion-list-mode-map
>> +    (define-key map "z" #'completion-kill-buffer)
>> +    (define-key map [remap keyboard-quit] #'completion-quit)
>> +    (define-key map [remap quit-window] #'switch-to-minibuffer)
>
> So typing C-g in the *Completions* buffer will be the same as
> typing C-g in the minibuffer?  This would provide more consistency.

No, currently not: C-g will close the completions buffer, "reverting" a
change so to say, and another C-g in the minibuffer will cancel the
completion.

>> In the *Completions*, self-insert-command is not bound so that "q", "n",
>> "p", "z", ... can be used.  This patch would add "s" (for
>> isearch-forward) and "S" (for isearch-forward-regexp) to the default
>> bunch.  This is my most recent change, that I am least certain about.
>> If I played around with it for a bit longer, maybe this could also be
>> extended to an interactive narrowing along the lines of icomplete.
>
> I guess it's too late to allow all self-inserting keys in the *Completions*
> buffer to be used either to add characters to the search string,
> or to narrow completions interactively as if they were typed in the minibuffer,
> because "q", "n", "p", "z" are already bound to other commands?

True, so immediate narrowing (at least with the default bindings)
couldn't be done, but that doesn't mean that narrowing couldn't be
enabled by binding an activation command to conventional keys like "s"
and "/".

-- 
	Philip Kaludercic



^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: Suggestions for improvements to the *Completions* buffer
  2021-12-09 20:07   ` Philip Kaludercic
@ 2021-12-09 20:21     ` Juri Linkov
  2021-12-13 19:16       ` Philip Kaludercic
  2021-12-09 21:16     ` Stefan Kangas
  1 sibling, 1 reply; 32+ messages in thread
From: Juri Linkov @ 2021-12-09 20:21 UTC (permalink / raw)
  To: Philip Kaludercic; +Cc: emacs-devel

>>> +(defun completion-quit ()
>>> +  "Close the completion buffer and return to the minibuffer."
>>> +  (interactive)
>>> +  (quit-window)
>>> +  (switch-to-minibuffer))
>>> +
>>> +(defun completion-kill-buffer ()
>>> +  "Close the completion buffer and return to the minibuffer."
>>> +  (interactive)
>>> +  (kill-buffer "*Completions*")
>>> +  (switch-to-minibuffer))
>>> @@ -8970,10 +8982,12 @@ completion-list-mode-map
>>> +    (define-key map "z" #'completion-kill-buffer)
>>> +    (define-key map [remap keyboard-quit] #'completion-quit)
>>> +    (define-key map [remap quit-window] #'switch-to-minibuffer)
>>
>> So typing C-g in the *Completions* buffer will be the same as
>> typing C-g in the minibuffer?  This would provide more consistency.
>
> No, currently not: C-g will close the completions buffer, "reverting" a
> change so to say, and another C-g in the minibuffer will cancel the
> completion.

I misread the patch.  Then double C-g C-g will be like in Isearch where
the first C-g cancels wrong characters, and another C-g cancels the search.

>>> In the *Completions*, self-insert-command is not bound so that "q", "n",
>>> "p", "z", ... can be used.  This patch would add "s" (for
>>> isearch-forward) and "S" (for isearch-forward-regexp) to the default
>>> bunch.  This is my most recent change, that I am least certain about.
>>> If I played around with it for a bit longer, maybe this could also be
>>> extended to an interactive narrowing along the lines of icomplete.
>>
>> I guess it's too late to allow all self-inserting keys in the *Completions*
>> buffer to be used either to add characters to the search string,
>> or to narrow completions interactively as if they were typed in the minibuffer,
>> because "q", "n", "p", "z" are already bound to other commands?
>
> True, so immediate narrowing (at least with the default bindings)
> couldn't be done, but that doesn't mean that narrowing couldn't be
> enabled by binding an activation command to conventional keys like "s"
> and "/".

Wouldn't it be easier just to switch to the minibuffer (with e.g. 'q')
and continue narrowing by typing more characters in the minibuffer?



^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: Suggestions for improvements to the *Completions* buffer
  2021-12-09 20:07   ` Philip Kaludercic
  2021-12-09 20:21     ` Juri Linkov
@ 2021-12-09 21:16     ` Stefan Kangas
  2021-12-13 19:13       ` Philip Kaludercic
  1 sibling, 1 reply; 32+ messages in thread
From: Stefan Kangas @ 2021-12-09 21:16 UTC (permalink / raw)
  To: Philip Kaludercic, Juri Linkov; +Cc: emacs-devel

Philip Kaludercic <philipk@posteo.net> writes:

>> I guess it's too late to allow all self-inserting keys in the *Completions*
>> buffer to be used either to add characters to the search string,
>> or to narrow completions interactively as if they were typed in the minibuffer,
>> because "q", "n", "p", "z" are already bound to other commands?

I'm not sure how useful "q" and "z" are.  I'd suggest just binding "C-g"
to quit-window instead.

I guess "n" and "p" has some use, but maybe that behavior could be
optional.  IIRC, they were introduced in Emacs 28, so we could just
revert that binding before the second pretest.

> True, so immediate narrowing (at least with the default bindings)
> couldn't be done, but that doesn't mean that narrowing couldn't be
> enabled by binding an activation command to conventional keys like "s"
> and "/".

Having an option would be a useful first step.



^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: Suggestions for improvements to the *Completions* buffer
  2021-12-09 21:16     ` Stefan Kangas
@ 2021-12-13 19:13       ` Philip Kaludercic
  0 siblings, 0 replies; 32+ messages in thread
From: Philip Kaludercic @ 2021-12-13 19:13 UTC (permalink / raw)
  To: Stefan Kangas; +Cc: emacs-devel, Juri Linkov

Stefan Kangas <stefankangas@gmail.com> writes:

> Philip Kaludercic <philipk@posteo.net> writes:
>
>>> I guess it's too late to allow all self-inserting keys in the *Completions*
>>> buffer to be used either to add characters to the search string,
>>> or to narrow completions interactively as if they were typed in the minibuffer,
>>> because "q", "n", "p", "z" are already bound to other commands?
>
> I'm not sure how useful "q" and "z" are.  I'd suggest just binding "C-g"
> to quit-window instead.

"q" via (quit-window) and "z" are already mapped, so I don't think it
makes sense to remove them.  My intention is just to provide a superset
of the current behaviour.

> I guess "n" and "p" has some use, but maybe that behavior could be
> optional.  IIRC, they were introduced in Emacs 28, so we could just
> revert that binding before the second pretest.

True, but "q" and "z" go back further, so enabling something like
narrowing would have to be disabled by default anyway.

>> True, so immediate narrowing (at least with the default bindings)
>> couldn't be done, but that doesn't mean that narrowing couldn't be
>> enabled by binding an activation command to conventional keys like "s"
>> and "/".
>
> Having an option would be a useful first step.

-- 
	Philip Kaludercic



^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: Suggestions for improvements to the *Completions* buffer
  2021-12-09 20:21     ` Juri Linkov
@ 2021-12-13 19:16       ` Philip Kaludercic
  0 siblings, 0 replies; 32+ messages in thread
From: Philip Kaludercic @ 2021-12-13 19:16 UTC (permalink / raw)
  To: Juri Linkov; +Cc: emacs-devel

Juri Linkov <juri@linkov.net> writes:

>>>> +(defun completion-quit ()
>>>> +  "Close the completion buffer and return to the minibuffer."
>>>> +  (interactive)
>>>> +  (quit-window)
>>>> +  (switch-to-minibuffer))
>>>> +
>>>> +(defun completion-kill-buffer ()
>>>> +  "Close the completion buffer and return to the minibuffer."
>>>> +  (interactive)
>>>> +  (kill-buffer "*Completions*")
>>>> +  (switch-to-minibuffer))
>>>> @@ -8970,10 +8982,12 @@ completion-list-mode-map
>>>> +    (define-key map "z" #'completion-kill-buffer)
>>>> +    (define-key map [remap keyboard-quit] #'completion-quit)
>>>> +    (define-key map [remap quit-window] #'switch-to-minibuffer)
>>>
>>> So typing C-g in the *Completions* buffer will be the same as
>>> typing C-g in the minibuffer?  This would provide more consistency.
>>
>> No, currently not: C-g will close the completions buffer, "reverting" a
>> change so to say, and another C-g in the minibuffer will cancel the
>> completion.
>
> I misread the patch.  Then double C-g C-g will be like in Isearch where
> the first C-g cancels wrong characters, and another C-g cancels the search.

Yes, didn't think of that but good to be reminded that there is already
a precedent for this kind of behaviour. 

>>>> In the *Completions*, self-insert-command is not bound so that "q", "n",
>>>> "p", "z", ... can be used.  This patch would add "s" (for
>>>> isearch-forward) and "S" (for isearch-forward-regexp) to the default
>>>> bunch.  This is my most recent change, that I am least certain about.
>>>> If I played around with it for a bit longer, maybe this could also be
>>>> extended to an interactive narrowing along the lines of icomplete.
>>>
>>> I guess it's too late to allow all self-inserting keys in the *Completions*
>>> buffer to be used either to add characters to the search string,
>>> or to narrow completions interactively as if they were typed in the minibuffer,
>>> because "q", "n", "p", "z" are already bound to other commands?
>>
>> True, so immediate narrowing (at least with the default bindings)
>> couldn't be done, but that doesn't mean that narrowing couldn't be
>> enabled by binding an activation command to conventional keys like "s"
>> and "/".
>
> Wouldn't it be easier just to switch to the minibuffer (with e.g. 'q')
> and continue narrowing by typing more characters in the minibuffer?

That is what it would basically boil down to.  The question is just
should "q" quit close the completion window or now.

-- 
	Philip Kaludercic



^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: Suggestions for improvements to the *Completions* buffer
  2021-12-09 17:22 Suggestions for improvements to the *Completions* buffer Philip Kaludercic
                   ` (2 preceding siblings ...)
  2021-12-09 19:49 ` Juri Linkov
@ 2021-12-13 21:36 ` Philip Kaludercic
  2021-12-14 21:13   ` Juri Linkov
  3 siblings, 1 reply; 32+ messages in thread
From: Philip Kaludercic @ 2021-12-13 21:36 UTC (permalink / raw)
  To: emacs-devel

Philip Kaludercic <philipk@posteo.net> writes:

> From 8f2433d70eadef47772b01b71ff44f5010c0935b Mon Sep 17 00:00:00 2001
> From: Philip Kaludercic <philipk@posteo.net>
> Date: Thu, 9 Dec 2021 17:36:14 +0100
> Subject: [PATCH 3/4] Switch back to minibuffer when quitting  completion
>  buffer
>
> * lisp/simple.el (completion-quit): Add new command
> (completion-kill-buffer): Add new command
> (completion-list-mode-map): Bind completion-quit and
> rebind kill-current-buffer to completion-kill-buffer
> ---
>  lisp/simple.el | 16 +++++++++++++++-
>  1 file changed, 15 insertions(+), 1 deletion(-)
>
> diff --git a/lisp/simple.el b/lisp/simple.el
> index b5f5122153..5ca8142548 100644
> --- a/lisp/simple.el
> +++ b/lisp/simple.el
> @@ -8957,6 +8957,18 @@ set-variable
>  \f
>  ;; Define the major mode for lists of completions.
>  
> +(defun completion-quit ()
> +  "Close the completion buffer and return to the minibuffer."
> +  (interactive)
> +  (quit-window)
> +  (switch-to-minibuffer))
> +
> +(defun completion-kill-buffer ()
> +  "Close the completion buffer and return to the minibuffer."
> +  (interactive)
> +  (kill-buffer "*Completions*")
> +  (switch-to-minibuffer))
> +
>  (defvar completion-list-mode-map
>    (let ((map (make-sparse-keymap)))
>      (set-keymap-parent map special-mode-map)
> @@ -8970,10 +8982,12 @@ completion-list-mode-map
>      (define-key map [right] 'next-completion)
>      (define-key map [?\t] 'next-completion)
>      (define-key map [backtab] 'previous-completion)
> -    (define-key map "z" 'kill-current-buffer)
>      (define-key map "n" 'next-completion)
>      (define-key map "p" 'previous-completion)
>      (define-key map "\M-g\M-c" 'switch-to-minibuffer)
> +    (define-key map "z" #'completion-kill-buffer)
> +    (define-key map [remap keyboard-quit] #'completion-quit)
> +    (define-key map [remap quit-window] #'switch-to-minibuffer)

It seems that remapping quit-window to switch-to-minibuffer creates
issues when the completion buffer is not invoked by the minibuffer, but
e.g. by complete-symbol.  Binding it to completion-quit (defined above)
instead, might actually be more natural, as "q"/quit-window is expected
to close a window.

The question is whether or not there is a need for a separate
switch-to-minibuffer binding (besides M-g M-c)?  Is keeping the
completions buffer active while returning to the minibuffer a real need?

>      map)
>    "Local map for completion list buffers.")

-- 
	Philip Kaludercic



^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: Suggestions for improvements to the *Completions* buffer
  2021-12-13 21:36 ` Philip Kaludercic
@ 2021-12-14 21:13   ` Juri Linkov
  2021-12-17 11:27     ` Philip Kaludercic
  0 siblings, 1 reply; 32+ messages in thread
From: Juri Linkov @ 2021-12-14 21:13 UTC (permalink / raw)
  To: Philip Kaludercic; +Cc: emacs-devel

>> -    (define-key map "z" 'kill-current-buffer)
>>      (define-key map "\M-g\M-c" 'switch-to-minibuffer)
>> +    (define-key map "z" #'completion-kill-buffer)
>> +    (define-key map [remap keyboard-quit] #'completion-quit)
>> +    (define-key map [remap quit-window] #'switch-to-minibuffer)
>
> It seems that remapping quit-window to switch-to-minibuffer creates
> issues when the completion buffer is not invoked by the minibuffer, but
> e.g. by complete-symbol.  Binding it to completion-quit (defined above)
> instead, might actually be more natural, as "q"/quit-window is expected
> to close a window.

Good point, so `q' should not be rebound from its standard command
`quit-window'.  Like you noticed, currently `quit-window' fails
to select the minibuffer window, but this is a bug, so this regression
was reported in bug#52491.

Then "z" could be bound to a variant of `quit-window'
that calls it with the argument KILL non-nil.

Like currently `ESC ESC ESC' can close the completion window
by the special command `delete-completion-window', then the same
command could be bound to `[remap keyboard-quit]' as well.

> The question is whether or not there is a need for a separate
> switch-to-minibuffer binding (besides M-g M-c)?  Is keeping the
> completions buffer active while returning to the minibuffer a real need?

Good question.  If four key bindings (q, z, C-g, ESC ESC ESC)
all will close the completions (first two using quit-window,
and last two using delete-completion-window), then maybe we should have
an easy-to-type keybinding that will switch to the minibuffer without
closing the completions window?

There is an easy-to-type keys <PgUp> and M-v to switch to the
completions window, but no an easy-to-type key to switch back.

It seems wrong for `q' to switch to the minibuffer without closing
the window because `quit-window' implies that window should quit.
But what key to use instead, I have no idea.



^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: Suggestions for improvements to the *Completions* buffer
  2021-12-14 21:13   ` Juri Linkov
@ 2021-12-17 11:27     ` Philip Kaludercic
  2021-12-17 15:00       ` Philip Kaludercic
                         ` (2 more replies)
  0 siblings, 3 replies; 32+ messages in thread
From: Philip Kaludercic @ 2021-12-17 11:27 UTC (permalink / raw)
  To: Juri Linkov; +Cc: emacs-devel

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

Juri Linkov <juri@linkov.net> writes:

>>> -    (define-key map "z" 'kill-current-buffer)
>>>      (define-key map "\M-g\M-c" 'switch-to-minibuffer)
>>> +    (define-key map "z" #'completion-kill-buffer)
>>> +    (define-key map [remap keyboard-quit] #'completion-quit)
>>> +    (define-key map [remap quit-window] #'switch-to-minibuffer)
>>
>> It seems that remapping quit-window to switch-to-minibuffer creates
>> issues when the completion buffer is not invoked by the minibuffer, but
>> e.g. by complete-symbol.  Binding it to completion-quit (defined above)
>> instead, might actually be more natural, as "q"/quit-window is expected
>> to close a window.
>
> Good point, so `q' should not be rebound from its standard command
> `quit-window'.  Like you noticed, currently `quit-window' fails
> to select the minibuffer window, but this is a bug, so this regression
> was reported in bug#52491.

Ok, great!

> Then "z" could be bound to a variant of `quit-window'
> that calls it with the argument KILL non-nil.

So something like this?


[-- Attachment #2: Type: text/plain, Size: 2662 bytes --]

diff --git a/lisp/mail/smtpmail.el b/lisp/mail/smtpmail.el
index bd8aa611e9..95e7abdeae 100644
--- a/lisp/mail/smtpmail.el
+++ b/lisp/mail/smtpmail.el
@@ -78,6 +78,19 @@ smtpmail-smtp-server
   "The name of the host running SMTP server."
   :type '(choice (const nil) string))
 
+(defcustom smtpmail-smtp-server-alist '()
+  "Alist of SMTP servers for different addresses."
+  :type '(alist :key-type
+                (string :tag "Sender")
+                :value-type
+                (list (string :tag "SMTP Server")
+                      (natnum :tag "Service")
+                      (choice :tag "Stream type"
+                              (const :tag "Possibly upgrade to STARTTLS" nil)
+                              (const :tag "Always use STARTTLS" starttls)
+                              (const :tag "Never use STARTTLS" plain)
+                              (const :tag "Use TLS/SSL" ssl)))))
+
 (defcustom smtpmail-smtp-service 25
   "SMTP service port number.
 The default value would be \"smtp\" or 25."
@@ -706,13 +719,9 @@ smtpmail-user-mail-address
 (defun smtpmail-via-smtp (recipient smtpmail-text-buffer
 				    &optional ask-for-password
                                     send-attempts)
-  (unless smtpmail-smtp-server
+  (unless (or smtpmail-smtp-server smtpmail-smtp-server-alist)
     (smtpmail-query-smtp-server))
-  (let ((process nil)
-        (send-attempts (or send-attempts 1))
-	(host (or smtpmail-smtp-server
-		  (error "`smtpmail-smtp-server' not defined")))
-	(port smtpmail-smtp-service)
+  (let* ((process nil)
         ;; `smtpmail-mail-address' should be set to the appropriate
         ;; buffer-local value by the caller, but in case not:
         (envelope-from
@@ -727,6 +736,14 @@ smtpmail-via-smtp
 	         (and from
 		      (cadr (mail-extract-address-components from))))
 	       (smtpmail-user-mail-address))))
+         (send-attempts (or send-attempts 1))
+         (server (alist-get envelope-from smtpmail-smtp-server-alist
+                            (list smtpmail-smtp-server)
+                            nil #'string=))
+         (host (or (car server)
+                   (error "No known SMTP Server for %S" envelope-from)))
+         (port (or (cadr server)
+                   smtpmail-smtp-service))
 	process-buffer
 	result
 	auth-mechanisms
@@ -757,7 +774,7 @@ smtpmail-via-smtp
 	    (setq result
 		  (open-network-stream
 		   "smtpmail" process-buffer host port
-		   :type smtpmail-stream-type
+		   :type (or (caddr server) smtpmail-stream-type)
 		   :return-list t
 		   :warn-unless-encrypted ask-for-password
 		   :capability-command (format "EHLO %s\r\n" (smtpmail-fqdn))

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


> Like currently `ESC ESC ESC' can close the completion window
> by the special command `delete-completion-window', then the same
> command could be bound to `[remap keyboard-quit]' as well.

Sure, but what noticeable difference does this make?  It seems to me
that quitting or killing the completion buffer doesn't amount to much of
a difference, as *Completion* is rarely selected manually.

The only case I can think of where the difference could matter, is when
*Completion* is so large that you need to kill it.  But considering that
even with "C-h o TAB" the difference appears to be indistinguishable.
Quitting a window and requesting the came completion doesn't even reuse
the existing buffer.

>> The question is whether or not there is a need for a separate
>> switch-to-minibuffer binding (besides M-g M-c)?  Is keeping the
>> completions buffer active while returning to the minibuffer a real need?
>
> Good question.  If four key bindings (q, z, C-g, ESC ESC ESC)
> all will close the completions (first two using quit-window,
> and last two using delete-completion-window), then maybe we should have
> an easy-to-type keybinding that will switch to the minibuffer without
> closing the completions window?
>
> There is an easy-to-type keys <PgUp> and M-v to switch to the
> completions window, but no an easy-to-type key to switch back.
>
> It seems wrong for `q' to switch to the minibuffer without closing
> the window because `quit-window' implies that window should quit.
> But what key to use instead, I have no idea.

Seeing as <left> and <right> are bound to previous-completion and
next-completion, maybe <up> and <down> could be used for
completion/minibuffer switching?

Or to take inspiration from Protesilaos's MCT package, that switches
back to the minibuffer once next-completion and previous-completion
reaches the end/beginning of the buffer, without quitting the window.
With next-completion bound to TAB while TAB also jumps back to the
completion buffer, it would behave to just by cycling.

-- 
	Philip Kaludercic

^ permalink raw reply related	[flat|nested] 32+ messages in thread

* Re: Suggestions for improvements to the *Completions* buffer
  2021-12-17 11:27     ` Philip Kaludercic
@ 2021-12-17 15:00       ` Philip Kaludercic
  2021-12-18 12:22       ` Philip Kaludercic
  2021-12-18 17:40       ` Juri Linkov
  2 siblings, 0 replies; 32+ messages in thread
From: Philip Kaludercic @ 2021-12-17 15:00 UTC (permalink / raw)
  To: Juri Linkov; +Cc: emacs-devel

Philip Kaludercic <philipk@posteo.net> writes:

>> Then "z" could be bound to a variant of `quit-window'
>> that calls it with the argument KILL non-nil.
>
> So something like this?

I inserted the wrong patch, here.  It was supposed to be

--8<---------------cut here---------------start------------->8---
diff --git a/lisp/simple.el b/lisp/simple.el
index a55df604c1..1521c325dc 100644
--- a/lisp/simple.el
+++ b/lisp/simple.el
@@ -8967,7 +8967,8 @@ completion-quit
 (defun completion-kill-buffer ()
   "Close the completion buffer and return to the minibuffer."
   (interactive)
-  (kill-buffer "*Completions*")
+  (let ((win (get-buffer-window "*Completions*")))
+    (when win (quit-window t win)))
   (switch-to-minibuffer))
 
 (defvar completion-list-mode-map
--8<---------------cut here---------------end--------------->8---

-- 
	Philip Kaludercic



^ permalink raw reply related	[flat|nested] 32+ messages in thread

* Re: Suggestions for improvements to the *Completions* buffer
  2021-12-17 11:27     ` Philip Kaludercic
  2021-12-17 15:00       ` Philip Kaludercic
@ 2021-12-18 12:22       ` Philip Kaludercic
  2021-12-18 12:31         ` Po Lu
  2021-12-18 17:41         ` Juri Linkov
  2021-12-18 17:40       ` Juri Linkov
  2 siblings, 2 replies; 32+ messages in thread
From: Philip Kaludercic @ 2021-12-18 12:22 UTC (permalink / raw)
  To: Juri Linkov; +Cc: emacs-devel

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

Philip Kaludercic <philipk@posteo.net> writes:

>>> The question is whether or not there is a need for a separate
>>> switch-to-minibuffer binding (besides M-g M-c)?  Is keeping the
>>> completions buffer active while returning to the minibuffer a real need?
>>
>> Good question.  If four key bindings (q, z, C-g, ESC ESC ESC)
>> all will close the completions (first two using quit-window,
>> and last two using delete-completion-window), then maybe we should have
>> an easy-to-type keybinding that will switch to the minibuffer without
>> closing the completions window?
>>
>> There is an easy-to-type keys <PgUp> and M-v to switch to the
>> completions window, but no an easy-to-type key to switch back.
>>
>> It seems wrong for `q' to switch to the minibuffer without closing
>> the window because `quit-window' implies that window should quit.
>> But what key to use instead, I have no idea.
>
> Or to take inspiration from Protesilaos's MCT package, that switches
> back to the minibuffer once next-completion and previous-completion
> reaches the end/beginning of the buffer, without quitting the window.
> With next-completion bound to TAB while TAB also jumps back to the
> completion buffer, it would behave to just by cycling.

Here are the patches that would implement this behaviour.  I have to use
it for a bit longer before I can say if it is preferable, but I guess if
something along these lines were to be applied, this could be an option.

The mechanism used to make backtab in the minibuffer switch to the last
completion option is not that nice as it uses this-command and
this-command-keys.


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-Allow-for-the-completion-buffer-to-be-automatically-.patch --]
[-- Type: text/x-diff, Size: 1412 bytes --]

From 0cc155ee3395fab376b06838a79c9a8b6fee6378 Mon Sep 17 00:00:00 2001
From: Philip Kaludercic <philipk@posteo.net>
Date: Thu, 9 Dec 2021 17:34:54 +0100
Subject: [PATCH 1/3] Allow for the completion buffer to be automatically
 selected

* lisp/simple.el (completion-auto-select): Add new option.
(completion-setup-function): Respect completion-auto-select.
---
 lisp/simple.el | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/lisp/simple.el b/lisp/simple.el
index 84928caa31..213720784c 100644
--- a/lisp/simple.el
+++ b/lisp/simple.el
@@ -9226,6 +9226,12 @@ completion-show-help
   :version "22.1"
   :group 'completion)
 
+(defcustom completion-auto-select t
+  "Non-nil means to automatically select the completions buffer."
+  :type 'boolean
+  :version "29.1"
+  :group 'completion)
+
 ;; This function goes in completion-setup-hook, so that it is called
 ;; after the text of the completion list buffer is written.
 (defun completion-setup-function ()
@@ -9262,7 +9268,9 @@ completion-setup-function
 	    (insert "Click on a completion to select it.\n"))
 	(insert (substitute-command-keys
 		 "In this buffer, type \\[choose-completion] to \
-select the completion near point.\n\n"))))))
+select the completion near point.\n\n")))))
+  (when completion-auto-select
+    (switch-to-completions)))
 
 (add-hook 'completion-setup-hook #'completion-setup-function)
 
-- 
2.30.2


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #3: 0002-Allow-for-next-completion-to-wrap-around-the-complet.patch --]
[-- Type: text/x-diff, Size: 5889 bytes --]

From 1b53b0c60c830c5e9173f143e4ed7e4719288ec9 Mon Sep 17 00:00:00 2001
From: Philip Kaludercic <philipk@posteo.net>
Date: Thu, 9 Dec 2021 17:26:14 +0100
Subject: [PATCH 2/3] Allow for next-completion to wrap around the completion
 buffer

* lisp/simple.el (completion-wrap-movement): Add new option.
(previous-completion): Update docstring.
(next-completion): Respect completion-wrap-movement.
(switch-to-completions): Handle backwards completion by jumping to the
end of the buffer.
* lisp/minibuffer.el: (minibuffer-local-completion-map): Bind
minibuffer-complete to backtab
---
 lisp/minibuffer.el |  1 +
 lisp/simple.el     | 81 ++++++++++++++++++++++++++++++----------------
 2 files changed, 54 insertions(+), 28 deletions(-)

diff --git a/lisp/minibuffer.el b/lisp/minibuffer.el
index 28bd1df59a..5f831665eb 100644
--- a/lisp/minibuffer.el
+++ b/lisp/minibuffer.el
@@ -2651,6 +2651,7 @@ minibuffer-local-completion-map
   (let ((map (make-sparse-keymap)))
     (set-keymap-parent map minibuffer-local-map)
     (define-key map "\t" 'minibuffer-complete)
+    (define-key map [backtab] 'minibuffer-complete)
     ;; M-TAB is already abused for many other purposes, so we should find
     ;; another binding for it.
     ;; (define-key map "\e\t" 'minibuffer-force-complete)
diff --git a/lisp/simple.el b/lisp/simple.el
index 213720784c..6a7d7ba918 100644
--- a/lisp/simple.el
+++ b/lisp/simple.el
@@ -9027,38 +9027,57 @@ delete-completion-window
       (if (get-buffer-window buf)
 	  (select-window (get-buffer-window buf))))))
 
+(defcustom completion-wrap-movement t
+  "Non-nil means to wrap around when selecting completion options.
+This affects the commands `next-completion' and
+`previous-completion'."
+  :type 'boolean
+  :version "29.1"
+  :group 'completion)
+
 (defun previous-completion (n)
-  "Move to the previous item in the completion list."
+  "Move to the previous item in the completion list.
+With prefix argument N, move back N items (negative N means move
+forward)."
   (interactive "p")
   (next-completion (- n)))
 
 (defun next-completion (n)
   "Move to the next item in the completion list.
-With prefix argument N, move N items (negative N means move backward)."
+With prefix argument N, move N items (negative N means move
+backward)."
   (interactive "p")
   (let ((beg (point-min)) (end (point-max)))
-    (while (and (> n 0) (not (eobp)))
-      ;; If in a completion, move to the end of it.
-      (when (get-text-property (point) 'mouse-face)
-	(goto-char (next-single-property-change (point) 'mouse-face nil end)))
-      ;; Move to start of next one.
-      (unless (get-text-property (point) 'mouse-face)
-	(goto-char (next-single-property-change (point) 'mouse-face nil end)))
-      (setq n (1- n)))
-    (while (and (< n 0) (not (bobp)))
-      (let ((prop (get-text-property (1- (point)) 'mouse-face)))
-	;; If in a completion, move to the start of it.
-	(when (and prop (eq prop (get-text-property (point) 'mouse-face)))
-	  (goto-char (previous-single-property-change
-		      (point) 'mouse-face nil beg)))
-	;; Move to end of the previous completion.
-	(unless (or (bobp) (get-text-property (1- (point)) 'mouse-face))
-	  (goto-char (previous-single-property-change
-		      (point) 'mouse-face nil beg)))
-	;; Move to the start of that one.
-	(goto-char (previous-single-property-change
-		    (point) 'mouse-face nil beg))
-	(setq n (1+ n))))))
+    (catch 'bound
+      (while (> n 0)
+        ;; If in a completion, move to the end of it.
+        (when (get-text-property (point) 'mouse-face)
+          (goto-char (next-single-property-change (point) 'mouse-face nil end)))
+        (when (and completion-wrap-movement (eobp))
+          (throw 'bound nil))
+        ;; Move to start of next one.
+        (unless (get-text-property (point) 'mouse-face)
+          (goto-char (next-single-property-change (point) 'mouse-face nil end)))
+        (setq n (1- n)))
+      (while (< n 0)
+        (let ((prop (get-text-property (1- (point)) 'mouse-face)))
+          ;; If in a completion, move to the start of it.
+          (when (and prop (eq prop (get-text-property (point) 'mouse-face)))
+            (goto-char (previous-single-property-change
+                        (point) 'mouse-face nil beg)))
+          ;; Move to end of the previous completion.
+          (unless (or (bobp) (get-text-property (1- (point)) 'mouse-face))
+            (goto-char (previous-single-property-change
+                        (point) 'mouse-face nil beg)))
+          (when (and completion-wrap-movement (bobp))
+            (goto-char (next-single-property-change (point) 'mouse-face nil end))
+            (throw 'bound nil))
+          ;; Move to the start of that one.
+          (goto-char (previous-single-property-change
+                      (point) 'mouse-face nil beg))
+          (setq n (1+ n)))))
+    (when (/= 0 n)
+      (switch-to-minibuffer))))
 
 (defun choose-completion (&optional event)
   "Choose the completion at point.
@@ -9283,10 +9302,16 @@ switch-to-completions
                            (get-buffer-window "*Completions*" 0)))))
     (when window
       (select-window window)
-      ;; In the new buffer, go to the first completion.
-      ;; FIXME: Perhaps this should be done in `minibuffer-completion-help'.
-      (when (bobp)
-	(next-completion 1)))))
+      (cond
+       ((and (memq this-command '(completion-at-point minibuffer-complete))
+             (equal (this-command-keys) [backtab])
+             (bobp))
+        (goto-char (point-max))
+        (previous-completion 1))
+       ;; In the new buffer, go to the first completion.
+       ;; FIXME: Perhaps this should be done in `minibuffer-completion-help'.
+       ((bobp)
+        (next-completion 1))))))
 
 (defun read-expression-switch-to-completions ()
   "Select the completion list window while reading an expression."
-- 
2.30.2


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #4: 0003-Switch-back-to-minibuffer-when-quitting-completion-b.patch --]
[-- Type: text/x-diff, Size: 1881 bytes --]

From 1612aa4f9a5c1d4afa9e0d97b959c9623c400ce2 Mon Sep 17 00:00:00 2001
From: Philip Kaludercic <philipk@posteo.net>
Date: Thu, 9 Dec 2021 17:36:14 +0100
Subject: [PATCH 3/3] Switch back to minibuffer when quitting completion buffer

* lisp/simple.el (completion-quit): Add new command
(completion-kill-buffer): Add new command
(completion-list-mode-map): Bind completion-quit and
rebind kill-current-buffer to completion-kill-buffer
---
 lisp/simple.el | 17 ++++++++++++++++-
 1 file changed, 16 insertions(+), 1 deletion(-)

diff --git a/lisp/simple.el b/lisp/simple.el
index 6a7d7ba918..c9ddca7b0a 100644
--- a/lisp/simple.el
+++ b/lisp/simple.el
@@ -8971,6 +8971,19 @@ set-variable
 \f
 ;; Define the major mode for lists of completions.
 
+(defun completion-quit ()
+  "Close the completion buffer and return to the minibuffer."
+  (interactive)
+  (quit-window)
+  (switch-to-minibuffer))
+
+(defun completion-kill-buffer ()
+  "Close the completion buffer and return to the minibuffer."
+  (interactive)
+  (let ((win (get-buffer-window "*Completions*")))
+    (when win (quit-window t win)))
+  (switch-to-minibuffer))
+
 (defvar completion-list-mode-map
   (let ((map (make-sparse-keymap)))
     (set-keymap-parent map special-mode-map)
@@ -8984,10 +8997,12 @@ completion-list-mode-map
     (define-key map [right] 'next-completion)
     (define-key map [?\t] 'next-completion)
     (define-key map [backtab] 'previous-completion)
-    (define-key map "z" 'kill-current-buffer)
     (define-key map "n" 'next-completion)
     (define-key map "p" 'previous-completion)
     (define-key map "\M-g\M-c" 'switch-to-minibuffer)
+    (define-key map "z" #'completion-kill-buffer)
+    (define-key map [remap keyboard-quit] #'delete-completion-window)
+    (define-key map [remap quit-window] #'completion-quit)
     map)
   "Local map for completion list buffers.")
 
-- 
2.30.2


[-- Attachment #5: Type: text/plain, Size: 24 bytes --]


-- 
	Philip Kaludercic

^ permalink raw reply related	[flat|nested] 32+ messages in thread

* Re: Suggestions for improvements to the *Completions* buffer
  2021-12-18 12:22       ` Philip Kaludercic
@ 2021-12-18 12:31         ` Po Lu
  2021-12-18 13:39           ` Philip Kaludercic
  2021-12-18 17:41         ` Juri Linkov
  1 sibling, 1 reply; 32+ messages in thread
From: Po Lu @ 2021-12-18 12:31 UTC (permalink / raw)
  To: Philip Kaludercic; +Cc: Juri Linkov, emacs-devel

Philip Kaludercic <philipk@posteo.net> writes:

> Here are the patches that would implement this behaviour.  I have to use
> it for a bit longer before I can say if it is preferable, but I guess if
> something along these lines were to be applied, this could be an option.

Could this part be made optional, at least for those of us with muscle
memory?  I actually expect the focus to return to the previous window
(not necessarily the minibuffer) when I press `z' in a completion
buffer.

Thanks.

> +(defun completion-quit ()
> +  "Close the completion buffer and return to the minibuffer."
> +  (interactive)
> +  (quit-window)
> +  (switch-to-minibuffer))
> +
> +(defun completion-kill-buffer ()
> +  "Close the completion buffer and return to the minibuffer."
> +  (interactive)
> +  (let ((win (get-buffer-window "*Completions*")))
> +    (when win (quit-window t win)))
> +  (switch-to-minibuffer))
> +
>  (defvar completion-list-mode-map
>    (let ((map (make-sparse-keymap)))
>      (set-keymap-parent map special-mode-map)
> @@ -8984,10 +8997,12 @@ completion-list-mode-map
>      (define-key map [right] 'next-completion)
>      (define-key map [?\t] 'next-completion)
>      (define-key map [backtab] 'previous-completion)
> -    (define-key map "z" 'kill-current-buffer)
>      (define-key map "n" 'next-completion)
>      (define-key map "p" 'previous-completion)
>      (define-key map "\M-g\M-c" 'switch-to-minibuffer)
> +    (define-key map "z" #'completion-kill-buffer)
> +    (define-key map [remap keyboard-quit] #'delete-completion-window)
> +    (define-key map [remap quit-window] #'completion-quit)
>      map)
>    "Local map for completion list buffers.")
>  
> -- 
> 2.30.2



^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: Suggestions for improvements to the *Completions* buffer
  2021-12-18 12:31         ` Po Lu
@ 2021-12-18 13:39           ` Philip Kaludercic
  2021-12-20  1:13             ` Po Lu
  0 siblings, 1 reply; 32+ messages in thread
From: Philip Kaludercic @ 2021-12-18 13:39 UTC (permalink / raw)
  To: Po Lu; +Cc: emacs-devel, Juri Linkov

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

Po Lu <luangruo@yahoo.com> writes:

> Philip Kaludercic <philipk@posteo.net> writes:
>
>> Here are the patches that would implement this behaviour.  I have to use
>> it for a bit longer before I can say if it is preferable, but I guess if
>> something along these lines were to be applied, this could be an option.
>
> Could this part be made optional, at least for those of us with muscle
> memory?  I actually expect the focus to return to the previous window
> (not necessarily the minibuffer) when I press `z' in a completion
> buffer.

Sure, that was a mistake on end.  I don't even think it needs an option,
so I just removed the code entirely:


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0003-Switch-back-to-minibuffer-when-quitting-completion-b.patch --]
[-- Type: text/x-diff, Size: 1349 bytes --]

From b1f2aa11bdad6f07baef54ac6db15ee714d3941e Mon Sep 17 00:00:00 2001
From: Philip Kaludercic <philipk@posteo.net>
Date: Thu, 9 Dec 2021 17:36:14 +0100
Subject: [PATCH 3/3] Switch back to minibuffer when quitting completion buffer

* lisp/simple.el (completion-quit): Add new command
(completion-list-mode-map): Rebind completion-quit over keyboard-quit
and delete-completion-window over keyboard-quit.
---
 lisp/simple.el | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/lisp/simple.el b/lisp/simple.el
index 6a7d7ba918..74deb4bdc4 100644
--- a/lisp/simple.el
+++ b/lisp/simple.el
@@ -8971,6 +8971,12 @@ set-variable
 \f
 ;; Define the major mode for lists of completions.
 
+(defun completion-quit ()
+  "Close the completion buffer and return to the minibuffer."
+  (interactive)
+  (quit-window)
+  (switch-to-minibuffer))
+
 (defvar completion-list-mode-map
   (let ((map (make-sparse-keymap)))
     (set-keymap-parent map special-mode-map)
@@ -8988,6 +8994,8 @@ completion-list-mode-map
     (define-key map "n" 'next-completion)
     (define-key map "p" 'previous-completion)
     (define-key map "\M-g\M-c" 'switch-to-minibuffer)
+    (define-key map [remap keyboard-quit] #'delete-completion-window)
+    (define-key map [remap quit-window] #'completion-quit)
     map)
   "Local map for completion list buffers.")
 
-- 
2.30.2


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


> Thanks.

-- 
	Philip Kaludercic

^ permalink raw reply related	[flat|nested] 32+ messages in thread

* Re: Suggestions for improvements to the *Completions* buffer
  2021-12-17 11:27     ` Philip Kaludercic
  2021-12-17 15:00       ` Philip Kaludercic
  2021-12-18 12:22       ` Philip Kaludercic
@ 2021-12-18 17:40       ` Juri Linkov
  2 siblings, 0 replies; 32+ messages in thread
From: Juri Linkov @ 2021-12-18 17:40 UTC (permalink / raw)
  To: Philip Kaludercic; +Cc: emacs-devel

> diff --git a/lisp/simple.el b/lisp/simple.el
> index a55df604c1..1521c325dc 100644
> --- a/lisp/simple.el
> +++ b/lisp/simple.el
> @@ -8967,7 +8967,8 @@ completion-quit
>  (defun completion-kill-buffer ()
>    "Close the completion buffer and return to the minibuffer."
>    (interactive)
> -  (kill-buffer "*Completions*")
> +  (let ((win (get-buffer-window "*Completions*")))
> +    (when win (quit-window t win)))
>    (switch-to-minibuffer))

After fixing bug#52491, no more commands using switch-to-minibuffer
would be needed, so `q' can remain round to `quit-window', thus
doing what `delete-window' is customized to do.

>> Like currently `ESC ESC ESC' can close the completion window
>> by the special command `delete-completion-window', then the same
>> command could be bound to `[remap keyboard-quit]' as well.
>
> Sure, but what noticeable difference does this make?  It seems to me
> that quitting or killing the completion buffer doesn't amount to much of
> a difference, as *Completion* is rarely selected manually.
>
> The only case I can think of where the difference could matter, is when
> *Completion* is so large that you need to kill it.  But considering that
> even with "C-h o TAB" the difference appears to be indistinguishable.
> Quitting a window and requesting the came completion doesn't even reuse
> the existing buffer.

I see no difference, but maybe someone might want to use different commands
for quit-window: with and without kill-buffer (this will require a new command
`quit-window-kill-buffer').

> Seeing as <left> and <right> are bound to previous-completion and
> next-completion, maybe <up> and <down> could be used for
> completion/minibuffer switching?

Both pairs <left>/<right> and <up>/<down> are useful in multi-column
completions buffer.

> Or to take inspiration from Protesilaos's MCT package, that switches
> back to the minibuffer once next-completion and previous-completion
> reaches the end/beginning of the buffer, without quitting the window.
> With next-completion bound to TAB while TAB also jumps back to the
> completion buffer, it would behave to just by cycling.

This means no wrapping?  Or maybe wrapping through the minibuffer?



^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: Suggestions for improvements to the *Completions* buffer
  2021-12-18 12:22       ` Philip Kaludercic
  2021-12-18 12:31         ` Po Lu
@ 2021-12-18 17:41         ` Juri Linkov
  2021-12-19 14:55           ` Philip Kaludercic
  1 sibling, 1 reply; 32+ messages in thread
From: Juri Linkov @ 2021-12-18 17:41 UTC (permalink / raw)
  To: Philip Kaludercic; +Cc: emacs-devel

> The mechanism used to make backtab in the minibuffer switch to the last
> completion option is not that nice as it uses this-command and
> this-command-keys.

When completion-auto-select is not enabled, TAB scrolls the completions buffer
forward.  So S-TAB (backtab) could scroll backward.

When completion-auto-select will be enabled, backtab could switch to
the completions as well, indeed.



^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: Suggestions for improvements to the *Completions* buffer
  2021-12-18 17:41         ` Juri Linkov
@ 2021-12-19 14:55           ` Philip Kaludercic
  2021-12-19 17:18             ` Juri Linkov
  0 siblings, 1 reply; 32+ messages in thread
From: Philip Kaludercic @ 2021-12-19 14:55 UTC (permalink / raw)
  To: Juri Linkov; +Cc: emacs-devel

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

Juri Linkov <juri@linkov.net> writes:

>> The mechanism used to make backtab in the minibuffer switch to the last
>> completion option is not that nice as it uses this-command and
>> this-command-keys.
>
> When completion-auto-select is not enabled, TAB scrolls the completions buffer
> forward.  So S-TAB (backtab) could scroll backward.
>
> When completion-auto-select will be enabled, backtab could switch to
> the completions as well, indeed.

How is this?


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-Allow-for-the-completion-buffer-to-be-automatically-.patch --]
[-- Type: text/x-diff, Size: 1412 bytes --]

From 6315289b47083c32ca28d2c582eb80b5c80345e0 Mon Sep 17 00:00:00 2001
From: Philip Kaludercic <philipk@posteo.net>
Date: Thu, 9 Dec 2021 17:34:54 +0100
Subject: [PATCH 1/3] Allow for the completion buffer to be automatically
 selected

* lisp/simple.el (completion-auto-select): Add new option.
(completion-setup-function): Respect completion-auto-select.
---
 lisp/simple.el | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/lisp/simple.el b/lisp/simple.el
index 26c3ff575e..d0e58575e1 100644
--- a/lisp/simple.el
+++ b/lisp/simple.el
@@ -9226,6 +9226,12 @@ completion-show-help
   :version "22.1"
   :group 'completion)
 
+(defcustom completion-auto-select t
+  "Non-nil means to automatically select the completions buffer."
+  :type 'boolean
+  :version "29.1"
+  :group 'completion)
+
 ;; This function goes in completion-setup-hook, so that it is called
 ;; after the text of the completion list buffer is written.
 (defun completion-setup-function ()
@@ -9262,7 +9268,9 @@ completion-setup-function
 	    (insert "Click on a completion to select it.\n"))
 	(insert (substitute-command-keys
 		 "In this buffer, type \\[choose-completion] to \
-select the completion near point.\n\n"))))))
+select the completion near point.\n\n")))))
+  (when completion-auto-select
+    (switch-to-completions)))
 
 (add-hook 'completion-setup-hook #'completion-setup-function)
 
-- 
2.30.2


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #3: 0002-Allow-for-next-completion-to-wrap-around-the-complet.patch --]
[-- Type: text/x-diff, Size: 6395 bytes --]

From 300b30423f1515d5d1b2fcc477185b79ac4bb832 Mon Sep 17 00:00:00 2001
From: Philip Kaludercic <philipk@posteo.net>
Date: Thu, 9 Dec 2021 17:26:14 +0100
Subject: [PATCH 2/3] Allow for next-completion to wrap around the completion
 buffer

* lisp/simple.el (completion-wrap-movement): Add new option.
(previous-completion): Update docstring.
(next-completion): Respect completion-wrap-movement.
(switch-to-completions): Handle backwards completion by jumping to the
end of the buffer.
* lisp/minibuffer.el: (minibuffer-local-completion-map): Bind
minibuffer-complete to backtab
(completion--in-region-1): Handle backtab to scroll backwards
---
 lisp/minibuffer.el |  5 ++-
 lisp/simple.el     | 81 ++++++++++++++++++++++++++++++----------------
 2 files changed, 57 insertions(+), 29 deletions(-)

diff --git a/lisp/minibuffer.el b/lisp/minibuffer.el
index 28bd1df59a..559e36e370 100644
--- a/lisp/minibuffer.el
+++ b/lisp/minibuffer.el
@@ -1386,7 +1386,9 @@ completion--in-region-1
             (set-window-start window (point-min) nil)
           ;; Else scroll down one screen.
           (with-selected-window window
-	    (scroll-up)))
+            (if (equal (this-command-keys) [backtab])
+                (scroll-down)
+              (scroll-up))))
         nil)))
    ;; If we're cycling, keep on cycling.
    ((and completion-cycling completion-all-sorted-completions)
@@ -2651,6 +2653,7 @@ minibuffer-local-completion-map
   (let ((map (make-sparse-keymap)))
     (set-keymap-parent map minibuffer-local-map)
     (define-key map "\t" 'minibuffer-complete)
+    (define-key map [backtab] 'minibuffer-complete)
     ;; M-TAB is already abused for many other purposes, so we should find
     ;; another binding for it.
     ;; (define-key map "\e\t" 'minibuffer-force-complete)
diff --git a/lisp/simple.el b/lisp/simple.el
index d0e58575e1..626c24e10d 100644
--- a/lisp/simple.el
+++ b/lisp/simple.el
@@ -9027,38 +9027,57 @@ delete-completion-window
       (if (get-buffer-window buf)
 	  (select-window (get-buffer-window buf))))))
 
+(defcustom completion-wrap-movement t
+  "Non-nil means to wrap around when selecting completion options.
+This affects the commands `next-completion' and
+`previous-completion'."
+  :type 'boolean
+  :version "29.1"
+  :group 'completion)
+
 (defun previous-completion (n)
-  "Move to the previous item in the completion list."
+  "Move to the previous item in the completion list.
+With prefix argument N, move back N items (negative N means move
+forward)."
   (interactive "p")
   (next-completion (- n)))
 
 (defun next-completion (n)
   "Move to the next item in the completion list.
-With prefix argument N, move N items (negative N means move backward)."
+With prefix argument N, move N items (negative N means move
+backward)."
   (interactive "p")
   (let ((beg (point-min)) (end (point-max)))
-    (while (and (> n 0) (not (eobp)))
-      ;; If in a completion, move to the end of it.
-      (when (get-text-property (point) 'mouse-face)
-	(goto-char (next-single-property-change (point) 'mouse-face nil end)))
-      ;; Move to start of next one.
-      (unless (get-text-property (point) 'mouse-face)
-	(goto-char (next-single-property-change (point) 'mouse-face nil end)))
-      (setq n (1- n)))
-    (while (and (< n 0) (not (bobp)))
-      (let ((prop (get-text-property (1- (point)) 'mouse-face)))
-	;; If in a completion, move to the start of it.
-	(when (and prop (eq prop (get-text-property (point) 'mouse-face)))
-	  (goto-char (previous-single-property-change
-		      (point) 'mouse-face nil beg)))
-	;; Move to end of the previous completion.
-	(unless (or (bobp) (get-text-property (1- (point)) 'mouse-face))
-	  (goto-char (previous-single-property-change
-		      (point) 'mouse-face nil beg)))
-	;; Move to the start of that one.
-	(goto-char (previous-single-property-change
-		    (point) 'mouse-face nil beg))
-	(setq n (1+ n))))))
+    (catch 'bound
+      (while (> n 0)
+        ;; If in a completion, move to the end of it.
+        (when (get-text-property (point) 'mouse-face)
+          (goto-char (next-single-property-change (point) 'mouse-face nil end)))
+        (when (and completion-wrap-movement (eobp))
+          (throw 'bound nil))
+        ;; Move to start of next one.
+        (unless (get-text-property (point) 'mouse-face)
+          (goto-char (next-single-property-change (point) 'mouse-face nil end)))
+        (setq n (1- n)))
+      (while (< n 0)
+        (let ((prop (get-text-property (1- (point)) 'mouse-face)))
+          ;; If in a completion, move to the start of it.
+          (when (and prop (eq prop (get-text-property (point) 'mouse-face)))
+            (goto-char (previous-single-property-change
+                        (point) 'mouse-face nil beg)))
+          ;; Move to end of the previous completion.
+          (unless (or (bobp) (get-text-property (1- (point)) 'mouse-face))
+            (goto-char (previous-single-property-change
+                        (point) 'mouse-face nil beg)))
+          (when (and completion-wrap-movement (bobp))
+            (goto-char (next-single-property-change (point) 'mouse-face nil end))
+            (throw 'bound nil))
+          ;; Move to the start of that one.
+          (goto-char (previous-single-property-change
+                      (point) 'mouse-face nil beg))
+          (setq n (1+ n)))))
+    (when (/= 0 n)
+      (switch-to-minibuffer))))
 
 (defun choose-completion (&optional event)
   "Choose the completion at point.
@@ -9283,10 +9302,16 @@ switch-to-completions
                            (get-buffer-window "*Completions*" 0)))))
     (when window
       (select-window window)
-      ;; In the new buffer, go to the first completion.
-      ;; FIXME: Perhaps this should be done in `minibuffer-completion-help'.
-      (when (bobp)
-	(next-completion 1)))))
+      (cond
+       ((and (memq this-command '(completion-at-point minibuffer-complete))
+             (equal (this-command-keys) [backtab])
+             (bobp))
+        (goto-char (point-max))
+        (previous-completion 1))
+       ;; In the new buffer, go to the first completion.
+       ;; FIXME: Perhaps this should be done in `minibuffer-completion-help'.
+       ((bobp)
+        (next-completion 1))))))
 
 (defun read-expression-switch-to-completions ()
   "Select the completion list window while reading an expression."
-- 
2.30.2


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #4: 0003-Delete-completion-window-on-quitting.patch --]
[-- Type: text/x-diff, Size: 909 bytes --]

From 37af745b2f97ea7f9a719b4ba4c488bb8df0d79a Mon Sep 17 00:00:00 2001
From: Philip Kaludercic <philipk@posteo.net>
Date: Thu, 9 Dec 2021 17:36:14 +0100
Subject: [PATCH 3/3] Delete completion window on quitting

* lisp/simple.el (completion-list-mode-map): Rebind
delete-completion-window over keyboard-quit.
---
 lisp/simple.el | 1 +
 1 file changed, 1 insertion(+)

diff --git a/lisp/simple.el b/lisp/simple.el
index 626c24e10d..d30b52e286 100644
--- a/lisp/simple.el
+++ b/lisp/simple.el
@@ -8980,6 +8980,7 @@ completion-list-mode-map
     (define-key map [down-mouse-2] nil)
     (define-key map "\C-m" 'choose-completion)
     (define-key map "\e\e\e" 'delete-completion-window)
+    (define-key map [remap keyboard-quit] #'delete-completion-window)
     (define-key map [left] 'previous-completion)
     (define-key map [right] 'next-completion)
     (define-key map [?\t] 'next-completion)
-- 
2.30.2


[-- Attachment #5: Type: text/plain, Size: 24 bytes --]


-- 
	Philip Kaludercic

^ permalink raw reply related	[flat|nested] 32+ messages in thread

* Re: Suggestions for improvements to the *Completions* buffer
  2021-12-19 14:55           ` Philip Kaludercic
@ 2021-12-19 17:18             ` Juri Linkov
  2021-12-19 23:58               ` Philip Kaludercic
  0 siblings, 1 reply; 32+ messages in thread
From: Juri Linkov @ 2021-12-19 17:18 UTC (permalink / raw)
  To: Philip Kaludercic; +Cc: emacs-devel

>>> The mechanism used to make backtab in the minibuffer switch to the last
>>> completion option is not that nice as it uses this-command and
>>> this-command-keys.
>>
>> When completion-auto-select is not enabled, TAB scrolls the completions buffer
>> forward.  So S-TAB (backtab) could scroll backward.
>>
>> When completion-auto-select will be enabled, backtab could switch to
>> the completions as well, indeed.
>
> How is this?

Thanks, this has now such a nice property that after typing TAB
that switches to the completions buffer, it's easy to switch back
to the minibuffer by typing S-TAB.  But this works only when
completion-wrap-movement is non-nil.

> +(defcustom completion-wrap-movement t
> +  "Non-nil means to wrap around when selecting completion options.
> +This affects the commands `next-completion' and
> +`previous-completion'."
> +  :type 'boolean
> +  :version "29.1"
> +  :group 'completion)

It seems now completion-wrap-movement has no effect:
typing n, p, <right> or <left> eventually switches to the minibuffer,
where continuing typing these keys uses other commands.

> (completion--in-region-1): Handle backtab to scroll backwards
> @@ -1386,7 +1386,9 @@ completion--in-region-1
>              (set-window-start window (point-min) nil)
>            ;; Else scroll down one screen.
>            (with-selected-window window
> -	    (scroll-up)))
> +            (if (equal (this-command-keys) [backtab])
> +                (scroll-down)
> +              (scroll-up))))

Using S-TAB to scroll backwards also works nice.
The only difference with TAB is that while typing
several TABs reaches the end of the completions buffer,
typing more TABs wraps to the beginning of the completions
buffer, but S-TAB doesn't wrap to the end of the buffer.



^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: Suggestions for improvements to the *Completions* buffer
  2021-12-19 17:18             ` Juri Linkov
@ 2021-12-19 23:58               ` Philip Kaludercic
  2021-12-20  9:03                 ` Philip Kaludercic
  2021-12-21 19:02                 ` Juri Linkov
  0 siblings, 2 replies; 32+ messages in thread
From: Philip Kaludercic @ 2021-12-19 23:58 UTC (permalink / raw)
  To: Juri Linkov; +Cc: emacs-devel

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

Juri Linkov <juri@linkov.net> writes:

>>>> The mechanism used to make backtab in the minibuffer switch to the last
>>>> completion option is not that nice as it uses this-command and
>>>> this-command-keys.
>>>
>>> When completion-auto-select is not enabled, TAB scrolls the completions buffer
>>> forward.  So S-TAB (backtab) could scroll backward.
>>>
>>> When completion-auto-select will be enabled, backtab could switch to
>>> the completions as well, indeed.
>>
>> How is this?
>
> Thanks, this has now such a nice property that after typing TAB
> that switches to the completions buffer, it's easy to switch back
> to the minibuffer by typing S-TAB.  But this works only when
> completion-wrap-movement is non-nil.

True, even that was not the primary intention.  I guess this also raises
the question of whether or not completion-wrap-movement and
completion-auto-select should be set to non-nil by default or not?  If
applied, maybe they could be enabled for a month or so, to gather
experiences and then decide how to continue on that basis.

>> +(defcustom completion-wrap-movement t
>> +  "Non-nil means to wrap around when selecting completion options.
>> +This affects the commands `next-completion' and
>> +`previous-completion'."
>> +  :type 'boolean
>> +  :version "29.1"
>> +  :group 'completion)
>
> It seems now completion-wrap-movement has no effect:
> typing n, p, <right> or <left> eventually switches to the minibuffer,
> where continuing typing these keys uses other commands.

True, the only way I see right now to avoid this would be to check if
tab/backtab was used before switching to the minibuffer, and otherwise
wrap within the completions buffer.

>> (completion--in-region-1): Handle backtab to scroll backwards
>> @@ -1386,7 +1386,9 @@ completion--in-region-1
>>              (set-window-start window (point-min) nil)
>>            ;; Else scroll down one screen.
>>            (with-selected-window window
>> -	    (scroll-up)))
>> +            (if (equal (this-command-keys) [backtab])
>> +                (scroll-down)
>> +              (scroll-up))))
>
> Using S-TAB to scroll backwards also works nice.
> The only difference with TAB is that while typing
> several TABs reaches the end of the completions buffer,
> typing more TABs wraps to the beginning of the completions
> buffer, but S-TAB doesn't wrap to the end of the buffer.

Good point, this should fix that:


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-Allow-for-next-completion-to-wrap-around-the-complet.patch --]
[-- Type: text/x-diff, Size: 7177 bytes --]

From 6155e4a3347a9f7d188eae125d71040b8c8dcdf2 Mon Sep 17 00:00:00 2001
From: Philip Kaludercic <philipk@posteo.net>
Date: Thu, 9 Dec 2021 17:26:14 +0100
Subject: [PATCH] Allow for next-completion to wrap around the completion
 buffer

* lisp/simple.el (completion-wrap-movement): Add new option.
(previous-completion): Update docstring.
(next-completion): Respect completion-wrap-movement.
(switch-to-completions): Handle backwards completion by jumping to the
end of the buffer.
* lisp/minibuffer.el: (minibuffer-local-completion-map): Bind
minibuffer-complete to backtab
(completion--in-region-1): Handle backtab to scroll backwards
---
 lisp/minibuffer.el | 15 ++++++---
 lisp/simple.el     | 81 ++++++++++++++++++++++++++++++----------------
 2 files changed, 63 insertions(+), 33 deletions(-)

diff --git a/lisp/minibuffer.el b/lisp/minibuffer.el
index 28bd1df59a..112c609a0a 100644
--- a/lisp/minibuffer.el
+++ b/lisp/minibuffer.el
@@ -1379,14 +1379,18 @@ completion--in-region-1
    ;; and this command is repeated, scroll that window.
    ((and (window-live-p minibuffer-scroll-window)
          (eq t (frame-visible-p (window-frame minibuffer-scroll-window))))
-    (let ((window minibuffer-scroll-window))
+    (let ((window minibuffer-scroll-window)
+          (reverse (equal (this-command-keys) [backtab])))
       (with-current-buffer (window-buffer window)
-        (if (pos-visible-in-window-p (point-max) window)
-            ;; If end is in view, scroll up to the beginning.
-            (set-window-start window (point-min) nil)
+        (if (pos-visible-in-window-p (if reverse (point-min) (point-max)) window)
+            ;; If end or beginning is in view, scroll up to the
+            ;; beginning or end respectively.
+            (if reverse
+                (set-window-point window (point-max))
+              (set-window-start window (point-min) nil))
           ;; Else scroll down one screen.
           (with-selected-window window
-	    (scroll-up)))
+            (if reverse (scroll-down) (scroll-up))))
         nil)))
    ;; If we're cycling, keep on cycling.
    ((and completion-cycling completion-all-sorted-completions)
@@ -2651,6 +2655,7 @@ minibuffer-local-completion-map
   (let ((map (make-sparse-keymap)))
     (set-keymap-parent map minibuffer-local-map)
     (define-key map "\t" 'minibuffer-complete)
+    (define-key map [backtab] 'minibuffer-complete)
     ;; M-TAB is already abused for many other purposes, so we should find
     ;; another binding for it.
     ;; (define-key map "\e\t" 'minibuffer-force-complete)
diff --git a/lisp/simple.el b/lisp/simple.el
index d0e58575e1..626c24e10d 100644
--- a/lisp/simple.el
+++ b/lisp/simple.el
@@ -9027,38 +9027,57 @@ delete-completion-window
       (if (get-buffer-window buf)
 	  (select-window (get-buffer-window buf))))))
 
+(defcustom completion-wrap-movement t
+  "Non-nil means to wrap around when selecting completion options.
+This affects the commands `next-completion' and
+`previous-completion'."
+  :type 'boolean
+  :version "29.1"
+  :group 'completion)
+
 (defun previous-completion (n)
-  "Move to the previous item in the completion list."
+  "Move to the previous item in the completion list.
+With prefix argument N, move back N items (negative N means move
+forward)."
   (interactive "p")
   (next-completion (- n)))
 
 (defun next-completion (n)
   "Move to the next item in the completion list.
-With prefix argument N, move N items (negative N means move backward)."
+With prefix argument N, move N items (negative N means move
+backward)."
   (interactive "p")
   (let ((beg (point-min)) (end (point-max)))
-    (while (and (> n 0) (not (eobp)))
-      ;; If in a completion, move to the end of it.
-      (when (get-text-property (point) 'mouse-face)
-	(goto-char (next-single-property-change (point) 'mouse-face nil end)))
-      ;; Move to start of next one.
-      (unless (get-text-property (point) 'mouse-face)
-	(goto-char (next-single-property-change (point) 'mouse-face nil end)))
-      (setq n (1- n)))
-    (while (and (< n 0) (not (bobp)))
-      (let ((prop (get-text-property (1- (point)) 'mouse-face)))
-	;; If in a completion, move to the start of it.
-	(when (and prop (eq prop (get-text-property (point) 'mouse-face)))
-	  (goto-char (previous-single-property-change
-		      (point) 'mouse-face nil beg)))
-	;; Move to end of the previous completion.
-	(unless (or (bobp) (get-text-property (1- (point)) 'mouse-face))
-	  (goto-char (previous-single-property-change
-		      (point) 'mouse-face nil beg)))
-	;; Move to the start of that one.
-	(goto-char (previous-single-property-change
-		    (point) 'mouse-face nil beg))
-	(setq n (1+ n))))))
+    (catch 'bound
+      (while (> n 0)
+        ;; If in a completion, move to the end of it.
+        (when (get-text-property (point) 'mouse-face)
+          (goto-char (next-single-property-change (point) 'mouse-face nil end)))
+        (when (and completion-wrap-movement (eobp))
+          (throw 'bound nil))
+        ;; Move to start of next one.
+        (unless (get-text-property (point) 'mouse-face)
+          (goto-char (next-single-property-change (point) 'mouse-face nil end)))
+        (setq n (1- n)))
+      (while (< n 0)
+        (let ((prop (get-text-property (1- (point)) 'mouse-face)))
+          ;; If in a completion, move to the start of it.
+          (when (and prop (eq prop (get-text-property (point) 'mouse-face)))
+            (goto-char (previous-single-property-change
+                        (point) 'mouse-face nil beg)))
+          ;; Move to end of the previous completion.
+          (unless (or (bobp) (get-text-property (1- (point)) 'mouse-face))
+            (goto-char (previous-single-property-change
+                        (point) 'mouse-face nil beg)))
+          (when (and completion-wrap-movement (bobp))
+            (goto-char (next-single-property-change (point) 'mouse-face nil end))
+            (throw 'bound nil))
+          ;; Move to the start of that one.
+          (goto-char (previous-single-property-change
+                      (point) 'mouse-face nil beg))
+          (setq n (1+ n)))))
+    (when (/= 0 n)
+      (switch-to-minibuffer))))
 
 (defun choose-completion (&optional event)
   "Choose the completion at point.
@@ -9283,10 +9302,16 @@ switch-to-completions
                            (get-buffer-window "*Completions*" 0)))))
     (when window
       (select-window window)
-      ;; In the new buffer, go to the first completion.
-      ;; FIXME: Perhaps this should be done in `minibuffer-completion-help'.
-      (when (bobp)
-	(next-completion 1)))))
+      (cond
+       ((and (memq this-command '(completion-at-point minibuffer-complete))
+             (equal (this-command-keys) [backtab])
+             (bobp))
+        (goto-char (point-max))
+        (previous-completion 1))
+       ;; In the new buffer, go to the first completion.
+       ;; FIXME: Perhaps this should be done in `minibuffer-completion-help'.
+       ((bobp)
+        (next-completion 1))))))
 
 (defun read-expression-switch-to-completions ()
   "Select the completion list window while reading an expression."
-- 
2.30.2


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


-- 
	Philip Kaludercic

^ permalink raw reply related	[flat|nested] 32+ messages in thread

* Re: Suggestions for improvements to the *Completions* buffer
  2021-12-18 13:39           ` Philip Kaludercic
@ 2021-12-20  1:13             ` Po Lu
  0 siblings, 0 replies; 32+ messages in thread
From: Po Lu @ 2021-12-20  1:13 UTC (permalink / raw)
  To: Philip Kaludercic; +Cc: emacs-devel, Juri Linkov

Philip Kaludercic <philipk@posteo.net> writes:

> Sure, that was a mistake on end.  I don't even think it needs an option,
> so I just removed the code entirely:

Thanks, I'm happy now.



^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: Suggestions for improvements to the *Completions* buffer
  2021-12-19 23:58               ` Philip Kaludercic
@ 2021-12-20  9:03                 ` Philip Kaludercic
  2021-12-21 19:02                 ` Juri Linkov
  1 sibling, 0 replies; 32+ messages in thread
From: Philip Kaludercic @ 2021-12-20  9:03 UTC (permalink / raw)
  To: Juri Linkov; +Cc: emacs-devel

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

Philip Kaludercic <philipk@posteo.net> writes:

> Juri Linkov <juri@linkov.net> writes:
>
>>> +(defcustom completion-wrap-movement t
>>> +  "Non-nil means to wrap around when selecting completion options.
>>> +This affects the commands `next-completion' and
>>> +`previous-completion'."
>>> +  :type 'boolean
>>> +  :version "29.1"
>>> +  :group 'completion)
>>
>> It seems now completion-wrap-movement has no effect:
>> typing n, p, <right> or <left> eventually switches to the minibuffer,
>> where continuing typing these keys uses other commands.
>
> True, the only way I see right now to avoid this would be to check if
> tab/backtab was used before switching to the minibuffer, and otherwise
> wrap within the completions buffer.

I have tried this behaviour out, and it seems reasonable.


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0002-Allow-for-next-completion-to-wrap-around-the-complet.patch --]
[-- Type: text/x-diff, Size: 7738 bytes --]

From b5e1548e571c093e682996d0a5b32eb8fb4d7919 Mon Sep 17 00:00:00 2001
From: Philip Kaludercic <philipk@posteo.net>
Date: Thu, 9 Dec 2021 17:26:14 +0100
Subject: [PATCH 2/3] Allow for next-completion to wrap around the completion
 buffer

* lisp/simple.el (completion-wrap-movement): Add new option.
(previous-completion): Update docstring.
(next-completion): Respect completion-wrap-movement.
(switch-to-completions): Handle backwards completion by jumping to the
end of the buffer.
* lisp/minibuffer.el: (minibuffer-local-completion-map): Bind
minibuffer-complete to backtab
(completion--in-region-1): Handle backtab to scroll backwards
---
 lisp/minibuffer.el | 15 +++++---
 lisp/simple.el     | 92 ++++++++++++++++++++++++++++++++--------------
 2 files changed, 74 insertions(+), 33 deletions(-)

diff --git a/lisp/minibuffer.el b/lisp/minibuffer.el
index 28bd1df59a..112c609a0a 100644
--- a/lisp/minibuffer.el
+++ b/lisp/minibuffer.el
@@ -1379,14 +1379,18 @@ completion--in-region-1
    ;; and this command is repeated, scroll that window.
    ((and (window-live-p minibuffer-scroll-window)
          (eq t (frame-visible-p (window-frame minibuffer-scroll-window))))
-    (let ((window minibuffer-scroll-window))
+    (let ((window minibuffer-scroll-window)
+          (reverse (equal (this-command-keys) [backtab])))
       (with-current-buffer (window-buffer window)
-        (if (pos-visible-in-window-p (point-max) window)
-            ;; If end is in view, scroll up to the beginning.
-            (set-window-start window (point-min) nil)
+        (if (pos-visible-in-window-p (if reverse (point-min) (point-max)) window)
+            ;; If end or beginning is in view, scroll up to the
+            ;; beginning or end respectively.
+            (if reverse
+                (set-window-point window (point-max))
+              (set-window-start window (point-min) nil))
           ;; Else scroll down one screen.
           (with-selected-window window
-	    (scroll-up)))
+            (if reverse (scroll-down) (scroll-up))))
         nil)))
    ;; If we're cycling, keep on cycling.
    ((and completion-cycling completion-all-sorted-completions)
@@ -2651,6 +2655,7 @@ minibuffer-local-completion-map
   (let ((map (make-sparse-keymap)))
     (set-keymap-parent map minibuffer-local-map)
     (define-key map "\t" 'minibuffer-complete)
+    (define-key map [backtab] 'minibuffer-complete)
     ;; M-TAB is already abused for many other purposes, so we should find
     ;; another binding for it.
     ;; (define-key map "\e\t" 'minibuffer-force-complete)
diff --git a/lisp/simple.el b/lisp/simple.el
index d0e58575e1..2d81dc62f4 100644
--- a/lisp/simple.el
+++ b/lisp/simple.el
@@ -9027,38 +9027,68 @@ delete-completion-window
       (if (get-buffer-window buf)
 	  (select-window (get-buffer-window buf))))))
 
+(defcustom completion-wrap-movement t
+  "Non-nil means to wrap around when selecting completion options.
+This affects the commands `next-completion' and
+`previous-completion'."
+  :type 'boolean
+  :version "29.1"
+  :group 'completion)
+
 (defun previous-completion (n)
-  "Move to the previous item in the completion list."
+  "Move to the previous item in the completion list.
+With prefix argument N, move back N items (negative N means move
+forward)."
   (interactive "p")
   (next-completion (- n)))
 
 (defun next-completion (n)
   "Move to the next item in the completion list.
-With prefix argument N, move N items (negative N means move backward)."
+With prefix argument N, move N items (negative N means move
+backward)."
   (interactive "p")
   (let ((beg (point-min)) (end (point-max)))
-    (while (and (> n 0) (not (eobp)))
-      ;; If in a completion, move to the end of it.
-      (when (get-text-property (point) 'mouse-face)
-	(goto-char (next-single-property-change (point) 'mouse-face nil end)))
-      ;; Move to start of next one.
-      (unless (get-text-property (point) 'mouse-face)
-	(goto-char (next-single-property-change (point) 'mouse-face nil end)))
-      (setq n (1- n)))
-    (while (and (< n 0) (not (bobp)))
-      (let ((prop (get-text-property (1- (point)) 'mouse-face)))
-	;; If in a completion, move to the start of it.
-	(when (and prop (eq prop (get-text-property (point) 'mouse-face)))
-	  (goto-char (previous-single-property-change
-		      (point) 'mouse-face nil beg)))
-	;; Move to end of the previous completion.
-	(unless (or (bobp) (get-text-property (1- (point)) 'mouse-face))
-	  (goto-char (previous-single-property-change
-		      (point) 'mouse-face nil beg)))
-	;; Move to the start of that one.
-	(goto-char (previous-single-property-change
-		    (point) 'mouse-face nil beg))
-	(setq n (1+ n))))))
+    (catch 'bound
+      (while (> n 0)
+        ;; If in a completion, move to the end of it.
+        (when (get-text-property (point) 'mouse-face)
+          (goto-char (next-single-property-change (point) 'mouse-face nil end)))
+        ;; If at the last completion option, wrap or skip to the
+        ;; minibuffer, if requested.
+        (when (and completion-wrap-movement (eobp))
+          (if (and (member (this-command-keys) '("\t" [backtab]))
+                   completion-auto-select)
+              (throw 'bound nil)
+            (goto-char (point-min))))
+        ;; Move to start of next one.
+        (unless (get-text-property (point) 'mouse-face)
+          (goto-char (next-single-property-change (point) 'mouse-face nil end)))
+        (setq n (1- n)))
+      (while (< n 0)
+        (let ((prop (get-text-property (1- (point)) 'mouse-face)))
+          ;; If in a completion, move to the start of it.
+          (when (and prop (eq prop (get-text-property (point) 'mouse-face)))
+            (goto-char (previous-single-property-change
+                        (point) 'mouse-face nil beg)))
+          ;; Move to end of the previous completion.
+          (unless (or (bobp) (get-text-property (1- (point)) 'mouse-face))
+            (goto-char (previous-single-property-change
+                        (point) 'mouse-face nil beg)))
+          ;; If at the first completion option, wrap or skip to the
+          ;; minibuffer, if requested.
+          (when (and completion-wrap-movement (bobp))
+            (if (and (member (this-command-keys) '("\t" [backtab]))
+                     completion-auto-select)
+                (progn
+                  (goto-char (next-single-property-change (point) 'mouse-face nil end))
+                  (throw 'bound nil))
+              (goto-char (point-max))))
+          ;; Move to the start of that one.
+          (goto-char (previous-single-property-change
+                      (point) 'mouse-face nil beg))
+          (setq n (1+ n)))))
+    (when (/= 0 n)
+      (switch-to-minibuffer))))
 
 (defun choose-completion (&optional event)
   "Choose the completion at point.
@@ -9283,10 +9313,16 @@ switch-to-completions
                            (get-buffer-window "*Completions*" 0)))))
     (when window
       (select-window window)
-      ;; In the new buffer, go to the first completion.
-      ;; FIXME: Perhaps this should be done in `minibuffer-completion-help'.
-      (when (bobp)
-	(next-completion 1)))))
+      (cond
+       ((and (memq this-command '(completion-at-point minibuffer-complete))
+             (equal (this-command-keys) [backtab])
+             (bobp))
+        (goto-char (point-max))
+        (previous-completion 1))
+       ;; In the new buffer, go to the first completion.
+       ;; FIXME: Perhaps this should be done in `minibuffer-completion-help'.
+       ((bobp)
+        (next-completion 1))))))
 
 (defun read-expression-switch-to-completions ()
   "Select the completion list window while reading an expression."
-- 
2.30.2


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


-- 
	Philip Kaludercic

^ permalink raw reply related	[flat|nested] 32+ messages in thread

* Re: Suggestions for improvements to the *Completions* buffer
  2021-12-19 23:58               ` Philip Kaludercic
  2021-12-20  9:03                 ` Philip Kaludercic
@ 2021-12-21 19:02                 ` Juri Linkov
  2021-12-21 21:32                   ` Philip Kaludercic
  1 sibling, 1 reply; 32+ messages in thread
From: Juri Linkov @ 2021-12-21 19:02 UTC (permalink / raw)
  To: Philip Kaludercic; +Cc: emacs-devel

>> Thanks, this has now such a nice property that after typing TAB
>> that switches to the completions buffer, it's easy to switch back
>> to the minibuffer by typing S-TAB.  But this works only when
>> completion-wrap-movement is non-nil.
>
> True, even that was not the primary intention.

I've tested all your patches, and everything works smoothly, thanks.

> I guess this also raises the question of whether or not
> completion-wrap-movement and completion-auto-select should be set to
> non-nil by default or not?  If applied, maybe they could be enabled
> for a month or so, to gather experiences and then decide how to
> continue on that basis.

I agree it's a good idea to enable them both now, and hear any feedback
for a month.



^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: Suggestions for improvements to the *Completions* buffer
  2021-12-21 19:02                 ` Juri Linkov
@ 2021-12-21 21:32                   ` Philip Kaludercic
  2021-12-22  7:54                     ` Daniel Semyonov
  2021-12-22 12:27                     ` Eli Zaretskii
  0 siblings, 2 replies; 32+ messages in thread
From: Philip Kaludercic @ 2021-12-21 21:32 UTC (permalink / raw)
  To: Juri Linkov; +Cc: emacs-devel

Juri Linkov <juri@linkov.net> writes:

>> I guess this also raises the question of whether or not
>> completion-wrap-movement and completion-auto-select should be set to
>> non-nil by default or not?  If applied, maybe they could be enabled
>> for a month or so, to gather experiences and then decide how to
>> continue on that basis.
>
> I agree it's a good idea to enable them both now, and hear any feedback
> for a month.

Done.

I'll be awaiting the angry mob.

-- 
	Philip Kaludercic



^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: Suggestions for improvements to the *Completions* buffer
  2021-12-21 21:32                   ` Philip Kaludercic
@ 2021-12-22  7:54                     ` Daniel Semyonov
  2021-12-22  9:04                       ` Juri Linkov
  2021-12-22 12:27                     ` Eli Zaretskii
  1 sibling, 1 reply; 32+ messages in thread
From: Daniel Semyonov @ 2021-12-22  7:54 UTC (permalink / raw)
  To: Philip Kaludercic; +Cc: Juri Linkov, emacs-devel

>>>>> Philip Kaludercic writes:

    > Juri Linkov <juri@linkov.net> writes:
    >> I agree it's a good idea to enable them both now, and hear any
    >> feedback for a month.

    > Done.

    > I'll be awaiting the angry mob.

Hi Philip, Juri,

I like these improvements overall, but I think 'completion-auto-select'
should be split into two options (or allow more specific assignment) to
differentiate between automatically selecting the *Completions* buffer
when it appears and selecting it as part of "wrapping" (when
'completion-wrap-movement' is enabled).
The former behavior is very jarring when using a package which
automatically updates the *Completions* buffer (for example, ELPA
package aggressive-completion), while the latter behavior could still be
desired in such cases.

I would post a patch but I don't have copyright assignment and have
already contributed two small patches in the past, so I don't think it'd
count as small enough.

Thanks,
Daniel



^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: Suggestions for improvements to the *Completions* buffer
  2021-12-22  7:54                     ` Daniel Semyonov
@ 2021-12-22  9:04                       ` Juri Linkov
  2021-12-22  9:56                         ` Daniel Semyonov
  0 siblings, 1 reply; 32+ messages in thread
From: Juri Linkov @ 2021-12-22  9:04 UTC (permalink / raw)
  To: Daniel Semyonov; +Cc: Philip Kaludercic, emacs-devel

> I like these improvements overall, but I think 'completion-auto-select'
> should be split into two options (or allow more specific assignment) to
> differentiate between automatically selecting the *Completions* buffer
> when it appears and selecting it as part of "wrapping" (when
> 'completion-wrap-movement' is enabled).
> The former behavior is very jarring when using a package which
> automatically updates the *Completions* buffer (for example, ELPA
> package aggressive-completion), while the latter behavior could still be
> desired in such cases.

Sorry, I don't understand what is the latter behavior
that is selecting the *Completions* buffer as part of "wrapping".
What wrapping could select it?  What keys should be typed
to initiate such wrapping?



^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: Suggestions for improvements to the *Completions* buffer
  2021-12-22  9:04                       ` Juri Linkov
@ 2021-12-22  9:56                         ` Daniel Semyonov
  2021-12-22 17:42                           ` Juri Linkov
  0 siblings, 1 reply; 32+ messages in thread
From: Daniel Semyonov @ 2021-12-22  9:56 UTC (permalink / raw)
  To: Juri Linkov; +Cc: Philip Kaludercic, emacs-devel

>>>>> Juri Linkov writes:

    >> I like these improvements overall, but I think
    >> 'completion-auto-select' should be split into two options (or
    >> allow more specific assignment) to differentiate between
    >> automatically selecting the *Completions* buffer when it appears
    >> and selecting it as part of "wrapping" (when
    >> 'completion-wrap-movement' is enabled).  The former behavior is
    >> very jarring when using a package which automatically updates the
    >> *Completions* buffer (for example, ELPA package
    >> aggressive-completion), while the latter behavior could still be
    >> desired in such cases.

    > Sorry, I don't understand what is the latter behavior that is
    > selecting the *Completions* buffer as part of "wrapping".  What
    > wrapping could select it?

When just 'completion-wrap-movement' is enabled and the last completion
has been reached (in the *Completions* buffer), pressing TAB will jump
to the first completion.

When both 'completion-wrap-movement' and 'completion-auto-select' are
enabled, instead of jumping to the first completion, pressing TAB will
select the minibuffer.  Pressing TAB again will then select the
*Completions* buffer and jump to the first completion.

This the 'latter' behavior, which I would like to have independently of
enabling 'completion-auto-select'.

    > What keys should be typed to initiate such wrapping?

TAB and <backtab>, same as currently.

Thanks,
Daniel



^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: Suggestions for improvements to the *Completions* buffer
  2021-12-21 21:32                   ` Philip Kaludercic
  2021-12-22  7:54                     ` Daniel Semyonov
@ 2021-12-22 12:27                     ` Eli Zaretskii
  1 sibling, 0 replies; 32+ messages in thread
From: Eli Zaretskii @ 2021-12-22 12:27 UTC (permalink / raw)
  To: Philip Kaludercic; +Cc: emacs-devel, juri

> From: Philip Kaludercic <philipk@posteo.net>
> Date: Tue, 21 Dec 2021 21:32:37 +0000
> Cc: emacs-devel@gnu.org
> 
> Juri Linkov <juri@linkov.net> writes:
> 
> >> I guess this also raises the question of whether or not
> >> completion-wrap-movement and completion-auto-select should be set to
> >> non-nil by default or not?  If applied, maybe they could be enabled
> >> for a month or so, to gather experiences and then decide how to
> >> continue on that basis.
> >
> > I agree it's a good idea to enable them both now, and hear any feedback
> > for a month.
> 
> Done.
> 
> I'll be awaiting the angry mob.

Here it comes...



^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: Suggestions for improvements to the *Completions* buffer
  2021-12-22  9:56                         ` Daniel Semyonov
@ 2021-12-22 17:42                           ` Juri Linkov
  0 siblings, 0 replies; 32+ messages in thread
From: Juri Linkov @ 2021-12-22 17:42 UTC (permalink / raw)
  To: Daniel Semyonov; +Cc: Philip Kaludercic, emacs-devel

> When just 'completion-wrap-movement' is enabled and the last completion
> has been reached (in the *Completions* buffer), pressing TAB will jump
> to the first completion.
>
> When both 'completion-wrap-movement' and 'completion-auto-select' are
> enabled, instead of jumping to the first completion, pressing TAB will
> select the minibuffer.  Pressing TAB again will then select the
> *Completions* buffer and jump to the first completion.
>
> This the 'latter' behavior, which I would like to have independently of
> enabling 'completion-auto-select'.

Thanks for the explanation.  I agree 'completion-wrap-movement'
could provide an option to keep its behavior even when
'completion-auto-select' gets enabled or disabled.



^ permalink raw reply	[flat|nested] 32+ messages in thread

end of thread, other threads:[~2021-12-22 17:42 UTC | newest]

Thread overview: 32+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-12-09 17:22 Suggestions for improvements to the *Completions* buffer Philip Kaludercic
2021-12-09 17:49 ` [External] : " Drew Adams
2021-12-09 18:05   ` Philip Kaludercic
2021-12-09 19:21     ` Stefan Monnier
2021-12-09 18:27 ` Manuel Uberti
2021-12-09 19:49 ` Juri Linkov
2021-12-09 20:07   ` Philip Kaludercic
2021-12-09 20:21     ` Juri Linkov
2021-12-13 19:16       ` Philip Kaludercic
2021-12-09 21:16     ` Stefan Kangas
2021-12-13 19:13       ` Philip Kaludercic
2021-12-13 21:36 ` Philip Kaludercic
2021-12-14 21:13   ` Juri Linkov
2021-12-17 11:27     ` Philip Kaludercic
2021-12-17 15:00       ` Philip Kaludercic
2021-12-18 12:22       ` Philip Kaludercic
2021-12-18 12:31         ` Po Lu
2021-12-18 13:39           ` Philip Kaludercic
2021-12-20  1:13             ` Po Lu
2021-12-18 17:41         ` Juri Linkov
2021-12-19 14:55           ` Philip Kaludercic
2021-12-19 17:18             ` Juri Linkov
2021-12-19 23:58               ` Philip Kaludercic
2021-12-20  9:03                 ` Philip Kaludercic
2021-12-21 19:02                 ` Juri Linkov
2021-12-21 21:32                   ` Philip Kaludercic
2021-12-22  7:54                     ` Daniel Semyonov
2021-12-22  9:04                       ` Juri Linkov
2021-12-22  9:56                         ` Daniel Semyonov
2021-12-22 17:42                           ` Juri Linkov
2021-12-22 12:27                     ` Eli Zaretskii
2021-12-18 17:40       ` Juri Linkov

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).