GNU bug report logs - #34116
27.0.50; minibuffer-force-complete-and-exit mostly broken

Please note: This is a static page, with minimal formatting, updated once a day.
Click here to see this page with the latest information and nicer formatting.

Package: emacs; Reported by: João Távora <joaotavora@HIDDEN>; Keywords: patch; dated Thu, 17 Jan 2019 13:57:02 UTC; Maintainer for emacs is bug-gnu-emacs@HIDDEN.
Added tag(s) patch. Request was from João Távora <joaotavora@HIDDEN> to control <at> debbugs.gnu.org. Full text available.

Message received at submit <at> debbugs.gnu.org:


Received: (at submit) by debbugs.gnu.org; 17 Jan 2019 13:57:01 +0000
From debbugs-submit-bounces <at> debbugs.gnu.org Thu Jan 17 08:57:01 2019
Received: from localhost ([127.0.0.1]:34276 helo=debbugs.gnu.org)
	by debbugs.gnu.org with esmtp (Exim 4.84_2)
	(envelope-from <debbugs-submit-bounces <at> debbugs.gnu.org>)
	id 1gk8AH-0000bw-6K
	for submit <at> debbugs.gnu.org; Thu, 17 Jan 2019 08:57:01 -0500
Received: from eggs.gnu.org ([209.51.188.92]:59048)
 by debbugs.gnu.org with esmtp (Exim 4.84_2)
 (envelope-from <joaotavora@HIDDEN>) id 1gk8AF-0000bg-2d
 for submit <at> debbugs.gnu.org; Thu, 17 Jan 2019 08:56:59 -0500
Received: from lists.gnu.org ([209.51.188.17]:38309)
 by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32)
 (Exim 4.71) (envelope-from <joaotavora@HIDDEN>)
 id 1gk8A9-0006fy-NT
 for submit <at> debbugs.gnu.org; Thu, 17 Jan 2019 08:56:53 -0500
Received: from eggs.gnu.org ([209.51.188.92]:40969)
 by lists.gnu.org with esmtp (Exim 4.71)
 (envelope-from <joaotavora@HIDDEN>) id 1gk8A6-0004IP-0g
 for bug-gnu-emacs@HIDDEN; Thu, 17 Jan 2019 08:56:53 -0500
X-Spam-Checker-Version: SpamAssassin 3.3.2 (2011-06-06) on eggs.gnu.org
X-Spam-Level: 
X-Spam-Status: No, score=0.8 required=5.0 tests=BAYES_50,FREEMAIL_FROM
 autolearn=disabled version=3.3.2
Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71)
 (envelope-from <joaotavora@HIDDEN>) id 1gk8A4-0006aT-Mz
 for bug-gnu-emacs@HIDDEN; Thu, 17 Jan 2019 08:56:49 -0500
Received: from mail-wr1-x435.google.com ([2a00:1450:4864:20::435]:38269)
 by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16)
 (Exim 4.71) (envelope-from <joaotavora@HIDDEN>)
 id 1gk8A4-0006XV-8Z
 for bug-gnu-emacs@HIDDEN; Thu, 17 Jan 2019 08:56:48 -0500
Received: by mail-wr1-x435.google.com with SMTP id v13so11123624wrw.5
 for <bug-gnu-emacs@HIDDEN>; Thu, 17 Jan 2019 05:56:47 -0800 (PST)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025;
 h=from:to:cc:subject:date:message-id:user-agent:mime-version;
 bh=Z5SqcoFp1cipHTW/Vk9o1SfKLtxNd8qP/1NsI/I1mGw=;
 b=XzZGIxFbwJSsQDagLzgk7pLry3R4r+uqd2ZeixSrHkNWYm76z25HnUQxiQjN+lAbZU
 O/MQgfutnE9l4ENKxb9xDlRfWydJKyRFrIvAwY0/KLExKHpKkM9U+/jUt606LVbo+tv4
 l8OGtrM2kGaCOOtLIgYNIYShvAaVHnMdzszQTICrb6s0WiMUM/lTZwghMU8df8vWeEZ/
 1AmH5wy0gg/Y+hP8pYp4iLuIC2yKPXhe7QxREBYGMrLaL+dJIAbNvVcW9jog5ibVWud0
 k74UUXA/8GJeQD4RxsvuMh14el/vPzXDaa/cOkXFeUgdrOlFjxSukEVXg/HcU3cvH9nz
 oAsg==
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
 d=1e100.net; s=20161025;
 h=x-gm-message-state:from:to:cc:subject:date:message-id:user-agent
 :mime-version;
 bh=Z5SqcoFp1cipHTW/Vk9o1SfKLtxNd8qP/1NsI/I1mGw=;
 b=Kyy3C547nN3PnE0yZfOfgr8+rZ/sLOgL969qfv3egAuBlV35XpFnjkQ1eqFM9H0ZTc
 IR7u/lBCCZkHj4hc94QzX3SoleZApUEq/ldp0pGElZPxb7Z9XgpEFMlfsdeM3nyuL3sx
 qXdR5vsG+VaadmOBffOxJJeR8Zwn842iGKfp7rZKV9IzVqauWafT7XM9zBRbf9zp4x7l
 fUX9GTkRem78StQl7Euaho0k/+qg5TjVXjLaKrMI9jWx3pE45hydjs1yg56HVHdVMBbQ
 8NGSPIQ9iZQAKeLLPRjFnW8GOdFrpM3VQ67yZUXCnzyNd3Ws1ePzaA6W2e8qtJIDdIO9
 7E/Q==
X-Gm-Message-State: AJcUukcxcGobmF0n2DZbxUWhOyV7GbZ5sv1Wmedcr4bIFl39Xchn5jbb
 0Qv19VkVV4tOsxt61Umgy60=
X-Google-Smtp-Source: ALg8bN6E2LNP/5u4gvni11Vw1XByLqT1NmBZ/MpaA4/NkwTexQvH7mdOG4ssfLTM/QfeIDjdX75O3w==
X-Received: by 2002:adf:b102:: with SMTP id l2mr11782300wra.296.1547733405979; 
 Thu, 17 Jan 2019 05:56:45 -0800 (PST)
Received: from GONDOMAR.yourcompany.com (mail3.siscog.pt. [195.23.29.18])
 by smtp.gmail.com with ESMTPSA id u204sm65510033wmu.30.2019.01.17.05.56.45
 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256);
 Thu, 17 Jan 2019 05:56:45 -0800 (PST)
From: =?iso-8859-1?Q?Jo=E3o_T=E1vora?= <joaotavora@HIDDEN>
To: bug-gnu-emacs@HIDDEN
Subject: 27.0.50; minibuffer-force-complete-and-exit mostly broken
Date: Thu, 17 Jan 2019 13:56:39 +0000
Message-ID: <jjb4la74cbs.fsf@HIDDEN>
User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/27.0.50 (windows-nt)
MIME-Version: 1.0
Content-Type: multipart/mixed; boundary="=-=-="
X-Antivirus: AVG (VPS 190117-0, 17-01-2019), Outbound message
X-Antivirus-Status: Clean
X-detected-operating-system: by eggs.gnu.org: Genre and OS details not
 recognized.
X-Received-From: 2a00:1450:4864:20::435
X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6.x
X-Spam-Score: 1.0 (+)
X-Debbugs-Envelope-To: submit
Cc: monnier@HIDDEN
X-BeenThere: debbugs-submit <at> debbugs.gnu.org
X-Mailman-Version: 2.1.18
Precedence: list
List-Id: <debbugs-submit.debbugs.gnu.org>
List-Unsubscribe: <https://debbugs.gnu.org/cgi-bin/mailman/options/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=unsubscribe>
List-Archive: <https://debbugs.gnu.org/cgi-bin/mailman/private/debbugs-submit/>
List-Post: <mailto:debbugs-submit <at> debbugs.gnu.org>
List-Help: <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=help>
List-Subscribe: <https://debbugs.gnu.org/cgi-bin/mailman/listinfo/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=subscribe>
Errors-To: debbugs-submit-bounces <at> debbugs.gnu.org
Sender: "Debbugs-submit" <debbugs-submit-bounces <at> debbugs.gnu.org>
X-Spam-Score: -0.0 (/)

--=-=-=
Content-Type: text/plain; charset=iso-8859-1
Content-Transfer-Encoding: quoted-printable

Hi maintainers,

Here's a cute one from my recent icomplete adventures,

  Emacs -Q
  M-x icomplete-mode
  M-: (completing-read "test: " '("foo" "bar"))
  C-M-i ;; minibuffer-force-complete, this completes to "foo"
  C-j   ;; icomplete-force-complete-and-exit

Expected "foo", right?  Nope: you get "bar".

Incidently, this also happens without icomplete, provided you have bound
the commands minibuffer-force-complete and
minibuffer-force-complete-and-exit in minibuffer-local-completion-map.

The problem happens because m-f-b cycles/rotates silently rotates the
candidate list _after_ forcing the completion.  The other second
"and-exit" command, which also calls m-f-b during its execution, catches
this extra rotation before returning the final value to the user.

The attached patch fixes this.  It add considerable hackery to an
already nasty collection of hacks, but is the safest way short of
redesigning this whole cycling business (which is heavily used in
completion-at-point).

This patch also simplifies the fix for bug#34077 which I had previously
submitted.

Jo=E3o


--=-=-=
Content-Type: text/x-patch
Content-Disposition: inline;
 filename=0001-Fix-nasty-cycling-on-minibuffer-force-complete-and-e.patch

From 97756513d4fe4521f3eff5376ad1ecfce5e1f266 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jo=C3=A3o=20T=C3=A1vora?= <joaotavora@HIDDEN>
Date: Wed, 16 Jan 2019 23:29:34 +0000
Subject: [PATCH] Fix nasty cycling on minibuffer-force-complete-and-exit

minibuffer-force-complete sets up cycling after forcing the
completion, which is mostly fine for successive interactive calls.
However minibuffer-force-complete-and-exit also calls it.  In
situations where the former and latter are called in succession this
causes an unwanted extra cycle, which ultimately yields the wrong
completion.

* lisp/minibuffer.el (minibuffer-force-complete): Take DONT-CYCLE
arg.
(minibuffer-force-complete-and-exit): Pass DONT-CYCLE to
minibuffer-force-complete.
---
 lisp/minibuffer.el | 79 +++++++++++++++++++++++++++-------------------
 1 file changed, 47 insertions(+), 32 deletions(-)

diff --git a/lisp/minibuffer.el b/lisp/minibuffer.el
index 5760a2e49d..74f85e7b90 100644
--- a/lisp/minibuffer.el
+++ b/lisp/minibuffer.el
@@ -1257,29 +1257,32 @@ completion-all-sorted-completions
 (defun minibuffer-force-complete-and-exit ()
   "Complete the minibuffer with first of the matches and exit."
   (interactive)
-  (minibuffer-force-complete)
+  (minibuffer-force-complete nil nil t)
   (completion--complete-and-exit
    (minibuffer-prompt-end) (point-max) #'exit-minibuffer
    ;; If the previous completion completed to an element which fails
    ;; test-completion, then we shouldn't exit, but that should be rare.
    (lambda () (minibuffer-message "Incomplete"))))
 
-(defun minibuffer-force-complete (&optional start end)
-  "Complete the minibuffer to an exact match.
-Repeated uses step through the possible completions."
+(defun minibuffer-force-complete (&optional start end dont-cycle)
+  "Complete the minibuffer string between START and END to an exact match.
+Repeated uses step through the possible completions, unless
+prevented to do so by DONT-CYCLE."
   (interactive)
   (setq minibuffer-scroll-window nil)
   ;; FIXME: Need to deal with the extra-size issue here as well.
   ;; FIXME: ~/src/emacs/t<M-TAB>/lisp/minibuffer.el completes to
   ;; ~/src/emacs/trunk/ and throws away lisp/minibuffer.el.
+  ;; FIXME: shouldn't we cycle _before_ instead of after forcing??
   (let* ((start (copy-marker (or start (minibuffer-prompt-end))))
          (end (or end (point-max)))
          ;; (md (completion--field-metadata start))
          (all (completion-all-sorted-completions start end))
-         (base (+ start (or (cdr (last all)) 0))))
+         (base (+ start (or (cdr (last all)) 0)))
+         last second-last)
     (cond
      ((not (consp all))
-        (completion--message
+      (completion--message
        (if all "No more completions" "No completions")))
      ((not (consp (cdr all)))
       (let ((done (equal (car all) (buffer-substring-no-properties base end))))
@@ -1287,36 +1290,48 @@ minibuffer-force-complete
         (completion--done (buffer-substring-no-properties start (point))
                           'finished (when done "Sole completion"))))
      (t
+      (setq second-last (last all 2)
+            last        (cdr second-last))
+      ;; If we happened to be already cycling, we must undo the
+      ;; effects of the last rotation (get out yer' pen and paper to
+      ;; get the cons cell math).
+      (when (and dont-cycle completion-cycling)
+        (let ((lastcdr (cddr second-last)))
+          (setcdr (cdr second-last) all)
+          (setq all (cdr second-last))
+          (setcdr second-last lastcdr)
+          (setq last second-last)))
       (completion--replace base end (car all))
       (setq end (+ base (length (car all))))
       (completion--done (buffer-substring-no-properties start (point)) 'sole)
-      ;; Set cycling after modifying the buffer since the flush hook resets it.
-      (setq completion-cycling t)
-      (setq this-command 'completion-at-point) ;For completion-in-region.
-      ;; If completing file names, (car all) may be a directory, so we'd now
-      ;; have a new set of possible completions and might want to reset
-      ;; completion-all-sorted-completions to nil, but we prefer not to,
-      ;; so that repeated calls minibuffer-force-complete still cycle
-      ;; through the previous possible completions.
-      (let ((last (last all)))
+      (unless dont-cycle
+        ;; Set cycling after modifying the buffer since the flush hook resets it.
+        (setq completion-cycling t)
+        (setq this-command 'completion-at-point) ;For completion-in-region.
+        ;; Rotate the completions collected earlier and cache them.  If
+        ;; completing file names, (car all) may be a directory, so we'd
+        ;; now have a new set of possible completions and might want to
+        ;; reset completion-all-sorted-completions to nil, but we prefer
+        ;; not to, so that repeated calls minibuffer-force-complete
+        ;; still cycle through the previous possible completions.
         (setcdr last (cons (car all) (cdr last)))
-        (completion--cache-all-sorted-completions start end (cdr all)))
-      ;; Make sure repeated uses cycle, even though completion--done might
-      ;; have added a space or something that moved us outside of the field.
-      ;; (bug#12221).
-      (let* ((table minibuffer-completion-table)
-             (pred minibuffer-completion-predicate)
-             (extra-prop completion-extra-properties)
-             (cmd
-              (lambda () "Cycle through the possible completions."
-                (interactive)
-                (let ((completion-extra-properties extra-prop))
-                  (completion-in-region start (point) table pred)))))
-        (set-transient-map
-         (let ((map (make-sparse-keymap)))
-           (define-key map [remap completion-at-point] cmd)
-           (define-key map (vector last-command-event) cmd)
-           map)))))))
+        (completion--cache-all-sorted-completions start end (cdr all))
+        ;; Make sure repeated uses cycle, even though completion--done
+        ;; might have added a space or something that moved us outside
+        ;; of the field.  (bug#12221).
+        (let* ((table minibuffer-completion-table)
+               (pred minibuffer-completion-predicate)
+               (extra-prop completion-extra-properties)
+               (cmd
+                (lambda () "Cycle through the possible completions."
+                  (interactive)
+                  (let ((completion-extra-properties extra-prop))
+                    (completion-in-region start (point) table pred)))))
+          (set-transient-map
+           (let ((map (make-sparse-keymap)))
+             (define-key map [remap completion-at-point] cmd)
+             (define-key map (vector last-command-event) cmd)
+             map))))))))
 
 (defvar minibuffer-confirm-exit-commands
   '(completion-at-point minibuffer-complete
-- 
2.19.2


--=-=-=--




Acknowledgement sent to João Távora <joaotavora@HIDDEN>:
New bug report received and forwarded. Copy sent to bug-gnu-emacs@HIDDEN. Full text available.
Report forwarded to bug-gnu-emacs@HIDDEN:
bug#34116; Package emacs. Full text available.
Please note: This is a static page, with minimal formatting, updated once a day.
Click here to see this page with the latest information and nicer formatting.
Last modified: Thu, 17 Jan 2019 14:15:01 UTC

GNU bug tracking system
Copyright (C) 1999 Darren O. Benham, 1997 nCipher Corporation Ltd, 1994-97 Ian Jackson.