unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
From: Ergus <spacibba@aol.com>
To: Eli Zaretskii <eliz@gnu.org>
Cc: Gregory Heytings <ghe@sdf.org>,
	casouri@gmail.com, joaotavora@gmail.com, emacs-devel@gnu.org
Subject: Re: feature/icomplete-vertical
Date: Sun, 20 Sep 2020 17:04:54 +0200	[thread overview]
Message-ID: <20200920150454.62emnrrzu6uuquc3@Ergus> (raw)
In-Reply-To: <83lfh4zfml.fsf@gnu.org>

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

On Sun, Sep 20, 2020 at 05:28:50PM +0300, Eli Zaretskii wrote:
>
>Please note that I wasn't replying to your proposal, I was replying to
>Jimmy's.
>
>> trying to calculate the height of the completion candidate list,
>> which amount (as Stefan wrote) to redoing what redisplay does.
>
>I don't agree with Stefan, if this interpretation of what he said is
>correct.  We have window-text-pixel-size to measure the size of text
>on display without redoing what redisplay does.

Hi Eli that's what I have been doing so far, but the approach looks a
bit too complex. It is actually not, but I understand that a better
simpler one is desirable.

You can look at the attached patch.

Any way it seems to me a bit buggy that (only) the prompt disappears in
this situation and how it behaves when we use the arrows. In general
without this issue we should be allowed to set \n separator and it
basically should work out of the box without requiring my code at all.

Best,
Ergus

[-- Attachment #2: icomplete-vertical-Eli.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-20 15:04 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             ` Ergus [this message]
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                   ` feature/icomplete-vertical Ergus
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=20200920150454.62emnrrzu6uuquc3@Ergus \
    --to=spacibba@aol.com \
    --cc=casouri@gmail.com \
    --cc=eliz@gnu.org \
    --cc=emacs-devel@gnu.org \
    --cc=ghe@sdf.org \
    --cc=joaotavora@gmail.com \
    /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).