unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
From: Ergus <spacibba@aol.com>
To: Gregory Heytings <ghe@sdf.org>
Cc: Stefan Monnier <monnier@iro.umontreal.ca>,
	Eli Zaretskii <eliz@gnu.org>,
	casouri@gmail.com, emacs-devel@gnu.org
Subject: Re: feature/icomplete-vertical
Date: Sat, 19 Sep 2020 16:43:16 +0200	[thread overview]
Message-ID: <20200919144316.bl6vwq33o6tzfecc@Ergus> (raw)
In-Reply-To: <alpine.NEB.2.22.394.2009191547180453.19525@sdf.lonestar.org>

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

On Sat, Sep 19, 2020 at 01:59:18PM +0000, Gregory Heytings wrote:

Hi Stefan and Gregory:

Here it is so far my last patch about vertical only feature. Please feel
free to correct it.

I removed the format variable and now to get vertical we only need to
add at least a \n to the separator. With the simple cases I tested it
works.

Stefan:

As you requested for a single feature I will remove the remote branch
again and push one only with this commit.

Gregory:

I took the freedom to add one condition from your code and added it to
mine. (The one for empty candidates)

I didn't do this before because I was keeping the first candidate in the
same line so it made sense to keep the empty one. So after all I will
condition this condition in a future too; when I add options to
remove/change the [] and ().

The other one

(prospects-max (- icomplete--prospects-available-height (/ (point) (window-width))))

I think is good for continuation lines, but I am not sure if that's
better than truncate line and horizontally scroll because in that case
the proposed candidates will be very long as well and continuing them
will reduce their number to the half too. (I took ivy as a pattern for
this)

So I will wait for other users' suggestions about what they prefer OR
take this condition conditionally in case the user explicitly disables
the lines truncation.

Best,
Ergus


[-- Attachment #2: icomplete-vertical.patch --]
[-- Type: text/plain, Size: 10469 bytes --]

diff --git a/lisp/icomplete.el b/lisp/icomplete.el
index 4e546807b7..c071691b07 100644
--- a/lisp/icomplete.el
+++ b/lisp/icomplete.el
@@ -50,6 +50,7 @@
 ;;; Code:
 
 (require 'rfn-eshadow) ; rfn-eshadow-overlay
+(require 'cl-lib)
 
 (defgroup icomplete nil
   "Show completions dynamically in minibuffer."
@@ -139,6 +140,19 @@ icomplete-minibuffer-setup-hook
   :group 'icomplete)
 
 
+(defvar-local icomplete--ellipsis nil
+  "Ellipsis symbol to indicate continuation.")
+
+(defvar-local icomplete--list-indicators-format nil
+  "Indicator for when multiple prospects are available.
+means that further input is required to distinguish a single one")
+
+(defvar-local icomplete--prospects nil)
+(defvar-local icomplete--match-braket nil)
+(defvar-local icomplete--prospects-max-height nil)
+(defvar-local icomplete--lines-per-candidate 0)
+
+
 ;;;_* Initialization
 
 ;;;_ + Internal Variables
@@ -437,6 +451,62 @@ icomplete-simple-completing-p
                (member table icomplete-with-completion-tables))))))
 
 ;;;_ > icomplete-minibuffer-setup ()
+
+(defun icomplete--vertical-prospects (prefix-len _determ comps)
+  "List of vertical completions limited."
+  ;; Max total rows to use, including the minibuffer content.
+  (let* (;; Needed for prospects-max-height-pixel
+         (single-line-height (line-pixel-height))
+         ;; in general this should be done for every line
+         (line-height (* icomplete--lines-per-candidate single-line-height))
+         (prospects-rows (* (1+ (cl-count ?\n icomplete--list-indicators-format))
+                            single-line-height))
+         limit prospects comp comp-len)
+
+    (while (and comps (not limit))
+      (setq comp (substring (pop comps) prefix-len)
+            comp-len (> (length comp) 0))
+
+      (if comp-len
+           (setq prospects-rows (+ prospects-rows line-height)))
+
+      (if (< prospects-rows icomplete--prospects-max-height)
+          (if comp-len
+              (push comp prospects))
+        (push icomplete--ellipsis prospects)
+        (setq limit t)))
+    (nreverse prospects)))
+
+
+(defun icomplete--horizontal-prospects (prefix-len determ comps)
+  "List of horizontal completions limited."
+
+  (let* (;; Max total length to use, including the minibuffer content.
+         (separator-width (string-width icomplete-separator))
+         (prospects-len (+ (string-width (or determ (format icomplete--match-braket "")))
+                           (string-width icomplete-separator)
+                           (+ 2 (string-width icomplete--ellipsis)) ;; take {…} into account
+                           (string-width (buffer-string))))
+         (prospects-max-len (* (+ icomplete-prospects-height
+                                  ;; If the minibuffer content already uses up more than
+                                  ;; one line, increase the allowable space accordingly.
+                                  (/ prospects-len (window-width)))
+                               (window-width)))
+         limit prospects comp)
+
+    (while (and comps (not limit))
+      (setq comp (substring (pop comps) prefix-len))
+
+      (when (> (length comp) 0)
+          (setq prospects-len (+ prospects-len (string-width comp) separator-width)))
+
+      (if (< prospects-len prospects-max-len)
+          (push comp prospects)
+        (push icomplete--ellipsis prospects)
+        (setq limit t)))
+    (nreverse prospects)))
+
+
 (defun icomplete-minibuffer-setup ()
   "Run in minibuffer on activation to establish incremental completion.
 Usually run by inclusion in `minibuffer-setup-hook'."
@@ -446,7 +516,29 @@ icomplete-minibuffer-setup
     					 (current-local-map)))
     (add-hook 'pre-command-hook  #'icomplete-pre-command-hook  nil t)
     (add-hook 'post-command-hook #'icomplete-post-command-hook nil t)
-    (run-hooks 'icomplete-minibuffer-setup-hook)))
+    (run-hooks 'icomplete-minibuffer-setup-hook)
+
+    (setq icomplete--ellipsis (if (char-displayable-p ?…) "…" "...")
+          icomplete--lines-per-candidate (cl-count ?\n icomplete-separator))
+
+    (if (> icomplete--lines-per-candidate 0)
+        (setq-local icomplete--list-indicators-format " \n%s"
+                    icomplete--prospects 'icomplete--vertical-prospects
+                    icomplete--prospects-max-height
+                    (let ((minibuffer-parameter (frame-parameter nil 'minibuffer)))
+                      (min (cond
+                            ((eq minibuffer-parameter t)
+                             (if (floatp max-mini-window-height)
+                                 (* max-mini-window-height (frame-pixel-height))
+                               (* max-mini-window-height (frame-char-height))))
+                            ;; TODO : minibuffer-parameter can have other values.
+                            ((eq minibuffer-parameter 'only)
+                             (frame-pixel-height)))
+                           (* (+ 2 icomplete-prospects-height) (line-pixel-height)))))
+
+      (setq-local icomplete--list-indicators-format "{%s}"
+                  icomplete--prospects 'icomplete--horizontal-prospects))))
+
 
 (defvar icomplete--in-region-buffer nil)
 
@@ -639,8 +731,6 @@ icomplete-completions
 
   (...) - a single prospect is identified and matching is enforced,
   [...] - a single prospect is identified but matching is optional, or
-  {...} - multiple prospects, separated by commas, are indicated, and
-          further input is required to distinguish a single one.
 
 If there are multiple possibilities, `icomplete-separator' separates them.
 
@@ -665,13 +755,13 @@ icomplete-completions
 	 (md (completion--field-metadata (icomplete--field-beg)))
 	 (comps (icomplete--sorted-completions))
          (last (if (consp comps) (last comps)))
-         (base-size (cdr last))
-         (open-bracket (if require-match "(" "["))
-         (close-bracket (if require-match ")" "]")))
+         (base-size (cdr last)))
+
+    (setq-local icomplete--match-braket (if require-match "(%s)" "[%s]"))
     ;; `concat'/`mapconcat' is the slow part.
     (if (not (consp comps))
 	(progn ;;(debug (format "Candidates=%S field=%S" candidates name))
-	  (format " %sNo matches%s" open-bracket close-bracket))
+	  (format icomplete--match-braket "No matches"))
       (if last (setcdr last nil))
       (let* ((most-try
               (if (and base-size (> base-size 0))
@@ -687,33 +777,18 @@ icomplete-completions
              ;; a prefix of most, or something else.
 	     (compare (compare-strings name nil nil
 				       most nil nil completion-ignore-case))
-	     (ellipsis (if (char-displayable-p ?…) "…" "..."))
 	     (determ (unless (or (eq t compare) (eq t most-try)
 				 (= (setq compare (1- (abs compare)))
 				    (length most)))
-		       (concat open-bracket
+		       (format icomplete--match-braket
 			       (cond
 				((= compare (length name))
                                  ;; Typical case: name is a prefix.
 				 (substring most compare))
                                 ;; Don't bother truncating if it doesn't gain
                                 ;; us at least 2 columns.
-				((< compare (+ 2 (string-width ellipsis))) most)
-				(t (concat ellipsis (substring most compare))))
-			       close-bracket)))
-	     ;;"-prospects" - more than one candidate
-	     (prospects-len (+ (string-width
-				(or determ (concat open-bracket close-bracket)))
-			       (string-width icomplete-separator)
-			       (+ 2 (string-width ellipsis)) ;; take {…} into account
-			       (string-width (buffer-string))))
-             (prospects-max
-              ;; Max total length to use, including the minibuffer content.
-              (* (+ icomplete-prospects-height
-                    ;; If the minibuffer content already uses up more than
-                    ;; one line, increase the allowable space accordingly.
-                    (/ prospects-len (window-width)))
-                 (window-width)))
+				((< compare (+ 2 (string-width icomplete--ellipsis))) most)
+				(t (concat icomplete--ellipsis (substring most compare)))))))
              ;; Find the common prefix among `comps'.
              ;; We can't use the optimization below because its assumptions
              ;; aren't always true, e.g. when completion-cycling (bug#10850):
@@ -725,12 +800,13 @@ icomplete-completions
 	     (prefix (when icomplete-hide-common-prefix
 		       (try-completion "" comps)))
              (prefix-len
-	      (and (stringp prefix)
+              (and icomplete-hide-common-prefix
+                   (stringp prefix)
                    ;; Only hide the prefix if the corresponding info
                    ;; is already displayed via `most'.
                    (string-prefix-p prefix most t)
-                   (length prefix))) ;;)
-	     prospects comp limit)
+                   (length prefix)))
+	     prospects)
 	(if (or (eq most-try t) (not (consp (cdr comps))))
 	    (setq prospects nil)
 	  (when (member name comps)
@@ -751,20 +827,11 @@ icomplete-completions
 	    ;; To circumvent all the above problems, provide a visual
 	    ;; cue to the user via an "empty string" in the try
 	    ;; completion field.
-	    (setq determ (concat open-bracket "" close-bracket)))
+	    (setq determ (format icomplete--match-braket "")))
 	  ;; Compute prospects for display.
-	  (while (and comps (not limit))
-	    (setq comp
-		  (if prefix-len (substring (car comps) prefix-len) (car comps))
-		  comps (cdr comps))
-	    (setq prospects-len
-                  (+ (string-width comp)
-		     (string-width icomplete-separator)
-		     prospects-len))
-	    (if (< prospects-len prospects-max)
-		(push comp prospects)
-	      (setq limit t))))
-	(setq prospects (nreverse prospects))
+          (setq prospects
+                (funcall icomplete--prospects prefix-len determ comps)))
+
 	;; Decorate first of the prospects.
 	(when prospects
 	  (let ((first (copy-sequence (pop prospects))))
@@ -776,10 +843,8 @@ icomplete-completions
         (if last (setcdr last base-size))
 	(if prospects
 	    (concat determ
-		    "{"
-		    (mapconcat 'identity prospects icomplete-separator)
-		    (and limit (concat icomplete-separator ellipsis))
-		    "}")
+                    (format icomplete--list-indicators-format
+                            (mapconcat 'identity prospects icomplete-separator)))
 	  (concat determ " [Matched]"))))))
 
 ;;; Iswitchb compatibility

  reply	other threads:[~2020-09-19 14:43 UTC|newest]

Thread overview: 118+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-09-12 13:10 feature/icomplete-vertical Gregory Heytings via Emacs development discussions.
2020-09-12 13:33 ` feature/icomplete-vertical Ergus
2020-09-12 14:30   ` feature/icomplete-vertical Gregory Heytings via Emacs development discussions.
2020-09-14  6:44   ` feature/icomplete-vertical jixiuf
2020-09-14  7:08     ` feature/icomplete-vertical Ergus
2020-09-14 15:02     ` feature/icomplete-vertical Ergus
2020-09-14 17:13       ` feature/icomplete-vertical Gregory Heytings via Emacs development discussions.
2020-09-14 17:31         ` feature/icomplete-vertical Ergus
2020-09-16 15:22       ` feature/icomplete-vertical jixiuf
     [not found]         ` <20200918005354.muskx2b7tssyqzzk@Ergus>
2020-09-18  3:08           ` feature/icomplete-vertical jixiuf
2020-09-18 11:58             ` feature/icomplete-vertical Ergus
2020-09-18 17:05             ` feature/icomplete-vertical Ergus
2020-09-18 19:52               ` feature/icomplete-vertical Eli Zaretskii
2020-09-20 10:55   ` feature/icomplete-vertical João Távora
2020-09-20 13:04     ` feature/icomplete-vertical Ergus
2020-09-20 13:15       ` feature/icomplete-vertical Eli Zaretskii
2020-09-20 13:37         ` feature/icomplete-vertical Ergus
2020-09-20 14:07         ` feature/icomplete-vertical Gregory Heytings via Emacs development discussions.
2020-09-20 14:28           ` feature/icomplete-vertical Eli Zaretskii
2020-09-20 15:04             ` feature/icomplete-vertical Ergus
2020-09-20 15:54               ` feature/icomplete-vertical Eli Zaretskii
2020-09-20 16:13                 ` feature/icomplete-vertical Ergus
2020-09-20 17:09             ` feature/icomplete-vertical Gregory Heytings via Emacs development discussions.
2020-09-20 17:43               ` feature/icomplete-vertical Eli Zaretskii
2020-10-01 16:48                 ` feature/icomplete-vertical Ergus
2020-10-02  4:45                   ` feature/icomplete-vertical jixiuf
2020-10-03  2:13                     ` feature/icomplete-vertical Ergus
2020-10-04 23:47                   ` feature/icomplete-vertical João Távora
2020-10-05  4:48                     ` feature/icomplete-vertical Ergus
2020-10-05  9:06                       ` feature/icomplete-vertical João Távora
2020-10-05 12:23                         ` feature/icomplete-vertical Ergus
2020-10-05 12:28                           ` feature/icomplete-vertical João Távora
2020-10-05 12:52                             ` feature/icomplete-vertical Ergus
2020-10-05  5:45                     ` feature/icomplete-vertical Eli Zaretskii
2020-10-05  9:13                       ` feature/icomplete-vertical João Távora
2020-10-05  9:46                         ` feature/icomplete-vertical Eli Zaretskii
2020-10-05  9:57                           ` feature/icomplete-vertical João Távora
2020-10-05 10:11                             ` feature/icomplete-vertical Eli Zaretskii
2020-10-05 10:52                               ` feature/icomplete-vertical João Távora
2020-10-05 11:00                                 ` feature/icomplete-vertical Eli Zaretskii
2020-10-05 11:11                                   ` feature/icomplete-vertical Gregory Heytings via Emacs development discussions.
2020-10-05 11:33                                     ` feature/icomplete-vertical Eli Zaretskii
2020-10-05 11:48                                       ` feature/icomplete-vertical João Távora
2020-10-05 17:59                                     ` feature/icomplete-vertical martin rudalics
2020-10-05 18:24                                       ` feature/icomplete-vertical Gregory Heytings via Emacs development discussions.
2020-10-05 11:24                                   ` feature/icomplete-vertical João Távora
2020-10-05 11:45                                     ` feature/icomplete-vertical Eli Zaretskii
2020-10-05 11:54                                       ` feature/icomplete-vertical João Távora
2020-10-05 12:05                                         ` feature/icomplete-vertical Eli Zaretskii
2020-10-05 13:07                                           ` feature/icomplete-vertical João Távora
2020-10-05 13:25                                             ` feature/icomplete-vertical Eli Zaretskii
2020-10-05 19:03                                               ` feature/icomplete-vertical João Távora
2020-10-05 19:12                                                 ` feature/icomplete-vertical Eli Zaretskii
2020-10-05 19:19                                                   ` feature/icomplete-vertical João Távora
2020-10-05 19:30                                                     ` feature/icomplete-vertical Eli Zaretskii
2020-10-05 19:36                                                       ` feature/icomplete-vertical João Távora
2020-10-05 11:02                                 ` feature/icomplete-vertical Gregory Heytings via Emacs development discussions.
2020-10-05 11:32                                   ` feature/icomplete-vertical João Távora
2020-10-05 11:54                                     ` feature/icomplete-vertical Gregory Heytings via Emacs development discussions.
2020-10-05 11:58                                       ` feature/icomplete-vertical João Távora
2020-10-05 12:02                                         ` feature/icomplete-vertical Gregory Heytings via Emacs development discussions.
2020-10-05 12:07                                           ` feature/icomplete-vertical Eli Zaretskii
2020-10-05 12:25                                             ` feature/icomplete-vertical Gregory Heytings via Emacs development discussions.
2020-10-05 12:33                                               ` feature/icomplete-vertical Eli Zaretskii
2020-10-05 13:19                                                 ` feature/icomplete-vertical Gregory Heytings via Emacs development discussions.
2020-10-05 13:44                                                   ` feature/icomplete-vertical Eli Zaretskii
2020-10-05 19:14                                                     ` feature/icomplete-vertical João Távora
2020-10-05 19:24                                                       ` feature/icomplete-vertical Eli Zaretskii
2020-10-05 19:32                                                         ` feature/icomplete-vertical João Távora
2020-10-06  6:16                                                           ` feature/icomplete-vertical Eli Zaretskii
2020-10-05 19:44                                                         ` feature/icomplete-vertical Gregory Heytings via Emacs development discussions.
2020-10-05 19:49                                                           ` feature/icomplete-vertical João Távora
2020-10-06  6:20                                                           ` feature/icomplete-vertical Eli Zaretskii
2020-10-05 13:13                               ` feature/icomplete-vertical Stefan Monnier
2020-10-05  7:52                     ` feature/icomplete-vertical Gregory Heytings via Emacs development discussions.
2020-10-05  8:22                       ` feature/icomplete-vertical Manuel Uberti
2020-10-05  9:40                       ` feature/icomplete-vertical João Távora
2020-10-05 10:53                         ` feature/icomplete-vertical Gregory Heytings via Emacs development discussions.
2020-09-20 14:49           ` feature/icomplete-vertical Ergus
2020-09-20 15:46             ` feature/icomplete-vertical Eli Zaretskii
2020-09-18 21:39 ` feature/icomplete-vertical Gregory Heytings via Emacs development discussions.
2020-09-18 23:27   ` feature/icomplete-vertical Stefan Monnier
2020-09-19  1:59   ` feature/icomplete-vertical Ergus
2020-09-19  4:03     ` feature/icomplete-vertical Gregory Heytings via Emacs development discussions.
2020-09-19  6:15       ` feature/icomplete-vertical Ergus
2020-09-19  8:35         ` feature/icomplete-vertical Gregory Heytings via Emacs development discussions.
2020-09-19 10:30           ` feature/icomplete-vertical Gregory Heytings via Emacs development discussions.
2020-09-19 11:19             ` feature/icomplete-vertical Ergus
2020-09-19 11:56               ` feature/icomplete-vertical Gregory Heytings via Emacs development discussions.
2020-09-19 12:57                 ` feature/icomplete-vertical Ergus
2020-09-19 11:43             ` feature/icomplete-vertical Ergus
2020-09-19 13:00               ` feature/icomplete-vertical Stefan Monnier
2020-09-19 13:42                 ` feature/icomplete-vertical Ergus
2020-09-19 15:35                   ` feature/icomplete-vertical Stefan Monnier
2020-09-19 13:59                 ` feature/icomplete-vertical Gregory Heytings via Emacs development discussions.
2020-09-19 14:43                   ` Ergus [this message]
2020-09-19 15:37                   ` feature/icomplete-vertical Stefan Monnier
2020-09-19 15:49                     ` feature/icomplete-vertical Ergus
2020-09-19 16:01                       ` feature/icomplete-vertical Stefan Monnier
2020-09-19 16:05                         ` feature/icomplete-vertical Gregory Heytings via Emacs development discussions.
2020-09-19 16:15                           ` feature/icomplete-vertical Stefan Monnier
2020-09-19 16:19                             ` feature/icomplete-vertical Gregory Heytings via Emacs development discussions.
2020-09-19 16:58                               ` feature/icomplete-vertical Eli Zaretskii
2020-09-19 17:06                                 ` feature/icomplete-vertical Ergus
2020-09-19 17:21                                   ` feature/icomplete-vertical Eli Zaretskii
2020-09-19 20:47                                     ` feature/icomplete-vertical Ergus
2020-09-19 22:07                                       ` feature/icomplete-vertical Stefan Monnier
2020-09-20  5:31                                       ` feature/icomplete-vertical Eli Zaretskii
2020-09-20 10:47                                       ` feature/icomplete-vertical Gregory Heytings via Emacs development discussions.
2020-09-20 13:04                                         ` feature/icomplete-vertical Ergus
2020-09-19 21:40                                     ` feature/icomplete-vertical Dmitry Gutov
2020-09-20  5:45                                       ` feature/icomplete-vertical Eli Zaretskii
2020-09-19 15:55                     ` feature/icomplete-vertical Gregory Heytings via Emacs development discussions.
2020-09-19 10:47           ` feature/icomplete-vertical Ergus
2020-09-19 17:08           ` feature/icomplete-vertical Drew Adams
2020-09-20  0:28             ` feature/icomplete-vertical Gregory Heytings via Emacs development discussions.
2020-09-20  1:18               ` feature/icomplete-vertical Drew Adams
  -- strict thread matches above, loose matches on Subject: below --
2020-10-02  6:37 feature/icomplete-vertical Manuel Uberti

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=20200919144316.bl6vwq33o6tzfecc@Ergus \
    --to=spacibba@aol.com \
    --cc=casouri@gmail.com \
    --cc=eliz@gnu.org \
    --cc=emacs-devel@gnu.org \
    --cc=ghe@sdf.org \
    --cc=monnier@iro.umontreal.ca \
    /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).