unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
From: Gregory Heytings <gregory@heytings.org>
To: Juri Linkov <juri@linkov.net>
Cc: emacs-devel@gnu.org
Subject: icomplete-vertical above prompt
Date: Sun, 11 Apr 2021 14:58:39 +0000	[thread overview]
Message-ID: <3755fe92dc7c2998a05d@heytings.org> (raw)

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


>
> I wonder how easy would be to improve Icomplete to display completions 
> in the standard buffer *Completions* instead of the minibuffer? Then 
> both use cases will be covered:
>
> 1. icomplete-vertical-mode for users who prefer vertical completions in 
> the minibuffer;
>
> 2. vertical completions in *Completions* for users who don't like when 
> the mode-line jumps up and down when completing.
>

Note that this doesn't happen with the default resize-mini-windows value, 
which is grow-only.  It jumps up once, and will not jump down until the 
end of the completion.

>
> In this case the same icomplete keys could be used to navigate 
> completions in the *Completions* buffer from the minibuffer with 
> icomplete-forward-completions and icomplete-backward-completions, and 
> icomplete-force-complete-and-exit to accept the selected completion.
>

By popular demand (Stefan M asked for something similar some time ago 
IIRC), here is a patch that does what you want, but not exactly how you 
described it.  It displays completion candidates above the prompt instead 
of below the prompt, and you can navigate them from the minibuffer.

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: Type: text/x-diff; name=Add-option-to-display-candidates-above-prompt-with-i.patch, Size: 6217 bytes --]

From c5bb62903c4985171f9ef3f654de8946fafa97e8 Mon Sep 17 00:00:00 2001
From: Gregory Heytings <gregory@heytings.org>
Date: Sun, 11 Apr 2021 14:22:17 +0000
Subject: [PATCH] Add option to display candidates above prompt with
 icomplete-vertical-mode

* lisp/icomplete.el (icomplete-vertical-mode-above-prompt,
icomplete-vertical-mode-above-prompt-height): New user variables.
(icomplete-exhibit): Consider the new user variables.

* doc/emacs/buffers.texi (Icomplete): Mention the new variables.

* etc/NEWS: Mention the new variables.
---
 doc/emacs/buffers.texi | 11 +++++++---
 etc/NEWS               |  4 ++++
 lisp/icomplete.el      | 46 ++++++++++++++++++++++++++++++++++++------
 3 files changed, 52 insertions(+), 9 deletions(-)

diff --git a/doc/emacs/buffers.texi b/doc/emacs/buffers.texi
index bec7f37547..b3e4316dd6 100644
--- a/doc/emacs/buffers.texi
+++ b/doc/emacs/buffers.texi
@@ -766,13 +766,18 @@ the variable @code{fido-mode} to @code{t} (@pxref{Easy
 Customization}).
 
 @findex icomplete-vertical-mode
+@vindex icomplete-vertical-mode-above-prompt
+@vindex icomplete-vertical-mode-above-prompt-height
 @cindex Icomplete vertical mode
 
   Icomplete mode and Fido mode display the possible completions on the
 same line as the prompt by default.  To display the completion candidates
-vertically under the prompt, type @kbd{M-x icomplete-vertical-mode}, or
-customize the variable @code{icomplete-vertical-mode} to @code{t}
-(@pxref{Easy Customization}).
+vertically, type @kbd{M-x icomplete-vertical-mode}, or customize the
+variable @code{icomplete-vertical-mode} to @code{t} (@pxref{Easy
+Customization}).  By default, this displays completion candidates under
+the prompt.  To display them above the prompt, customize the variables
+@code{icomplete-vertical-mode-above-prompt} to @code{t}, and the
+variable @code{icomplete-vertical-mode-above-prompt-height} to .
 
 @node Buffer Menus
 @subsection Customizing Buffer Menus
diff --git a/etc/NEWS b/etc/NEWS
index aaf38022c5..3d22f95d7d 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -500,6 +500,10 @@ indentation is done using SMIE or with the old ad-hoc code.
 *** New minor mode Icomplete-Vertical mode.
 This mode is intended to be used with Icomplete or Fido, to display the
 list of completions candidates vertically instead of horizontally.
+Additionally, the user options 'icomplete-vertical-mode-above-prompt'
+and 'icomplete-vertical-mode-above-prompt-height' control whether and
+how the completion candidates are displayed above the prompt instead of,
+by default, under the prompt.
 
 ---
 ** Specific warnings can now be disabled from the warning buffer.
diff --git a/lisp/icomplete.el b/lisp/icomplete.el
index d5b6f76d7b..794c6d776d 100644
--- a/lisp/icomplete.el
+++ b/lisp/icomplete.el
@@ -569,6 +569,22 @@ Usually run by inclusion in `minibuffer-setup-hook'."
     map)
   "Keymap used by `icomplete-vertical-mode' in the minibuffer.")
 
+(defcustom icomplete-vertical-mode-above-prompt nil
+  "Whether to display candidates above prompt with `icomplete-vertical-mode'.
+When nil, display the candidates under the prompt.
+When non-nil, display the candidates above the prompt."
+  :type '(choice (const :tag "Off" nil)
+                 (const :tag "On" t))
+  :version "28.1")
+
+(defcustom icomplete-vertical-mode-above-prompt-height 10
+  "How many candidates to display above prompt with `icomplete-vertical-mode'.
+In small frames, less candidates may be displayed."
+  :type 'integer
+  :version "28.1")
+
+(defvar icomplete--above-minibuffer-window nil)
+
 (defun icomplete--vertical-minibuffer-setup ()
   "Setup the minibuffer for vertical display of completion candidates."
   (use-local-map (make-composed-keymap icomplete-vertical-mode-minibuffer-map
@@ -659,12 +675,30 @@ See `icomplete-mode' and `minibuffer-setup-hook'."
                  deactivate-mark)
             ;; Do nothing if while-no-input was aborted.
             (when (stringp text)
-              (move-overlay icomplete-overlay (point) (point) (current-buffer))
-              ;; The current C cursor code doesn't know to use the overlay's
-              ;; marker's stickiness to figure out whether to place the cursor
-              ;; before or after the string, so let's spoon-feed it the pos.
-              (put-text-property 0 1 'cursor t text)
-              (overlay-put icomplete-overlay 'after-string text))))))))
+              (when (and icomplete-vertical-mode icomplete-vertical-mode-above-prompt)
+                (let ((buffer (get-buffer-create " *Icomplete Completions*"))
+                      (limit (string-search "\n" text)))
+                  (when limit
+                    (let ((candidates (substring text (1+ limit))))
+                      (setq text (substring text 0 limit))
+                      (unless (window-live-p icomplete--above-minibuffer-window)
+                        (setq icomplete--above-minibuffer-window
+                              (display-buffer
+                               buffer
+                               `(display-buffer-in-side-window
+                                 (side . bottom)
+                                 (window-height
+                                  . ,icomplete-vertical-mode-above-prompt-height)))))
+                      (with-current-buffer buffer
+                        (setq-local mode-line-format nil cursor-type nil)
+                        (erase-buffer)
+                        (insert candidates))))))
+                (move-overlay icomplete-overlay (point) (point) (current-buffer))
+                ;; The current C cursor code doesn't know to use the overlay's
+                ;; marker's stickiness to figure out whether to place the cursor
+                ;; before or after the string, so let's spoon-feed it the pos.
+                (put-text-property 0 1 'cursor t text)
+                (overlay-put icomplete-overlay 'after-string text))))))))
 
 ;;;_ > icomplete-completions (name candidates predicate require-match)
 (defun icomplete-completions (name candidates predicate require-match)
-- 
2.30.2


             reply	other threads:[~2021-04-11 14:58 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-04-11 14:58 Gregory Heytings [this message]
2021-04-11 15:11 ` icomplete-vertical above prompt Gregory Heytings
2021-04-11 21:59 ` Juri Linkov
2021-04-11 23:02   ` Gregory Heytings
2021-04-11 23:19     ` Juri Linkov
2021-04-11 23:25       ` Gregory Heytings
2021-04-11 23:34         ` Juri Linkov
2021-04-11 23:41           ` Ergus
2021-04-12  9:37     ` Jean Louis

Reply instructions:

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

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

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

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

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

  git send-email \
    --in-reply-to=3755fe92dc7c2998a05d@heytings.org \
    --to=gregory@heytings.org \
    --cc=emacs-devel@gnu.org \
    --cc=juri@linkov.net \
    /path/to/YOUR_REPLY

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

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).