From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!.POSTED!not-for-mail From: =?UTF-8?Q?Jo=C3=A3o_?= =?UTF-8?Q?T=C3=A1vora?= Newsgroups: gmane.emacs.bugs Subject: bug#34077: Status: 27.0.50; icomplete, substring completion and C-x C-f misbehaving Date: Thu, 17 Jan 2019 14:02:39 +0000 Message-ID: References: NNTP-Posting-Host: blaine.gmane.org Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" X-Trace: blaine.gmane.org 1547733672 25653 195.159.176.226 (17 Jan 2019 14:01:12 GMT) X-Complaints-To: usenet@blaine.gmane.org NNTP-Posting-Date: Thu, 17 Jan 2019 14:01:12 +0000 (UTC) User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/27.0.50 (windows-nt) To: bug#34077 <34077@debbugs.gnu.org> Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Thu Jan 17 15:01:08 2019 Return-path: Envelope-to: geb-bug-gnu-emacs@m.gmane.org Original-Received: from lists.gnu.org ([209.51.188.17]) by blaine.gmane.org with esmtp (Exim 4.84_2) (envelope-from ) id 1gk8EG-0006Vj-19 for geb-bug-gnu-emacs@m.gmane.org; Thu, 17 Jan 2019 15:01:08 +0100 Original-Received: from localhost ([127.0.0.1]:45379 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gk8GN-0000WZ-6E for geb-bug-gnu-emacs@m.gmane.org; Thu, 17 Jan 2019 09:03:19 -0500 Original-Received: from eggs.gnu.org ([209.51.188.92]:43156) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gk8G9-0000UM-Ls for bug-gnu-emacs@gnu.org; Thu, 17 Jan 2019 09:03:07 -0500 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gk8G7-0007yG-1y for bug-gnu-emacs@gnu.org; Thu, 17 Jan 2019 09:03:05 -0500 Original-Received: from debbugs.gnu.org ([209.51.188.43]:35013) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gk8G6-0007wh-La for bug-gnu-emacs@gnu.org; Thu, 17 Jan 2019 09:03:02 -0500 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1gk8G6-0000se-91 for bug-gnu-emacs@gnu.org; Thu, 17 Jan 2019 09:03:02 -0500 X-Loop: help-debbugs@gnu.org Resent-From: =?UTF-8?Q?Jo=C3=A3o_?= =?UTF-8?Q?T=C3=A1vora?= Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Thu, 17 Jan 2019 14:03:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 34077 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: Original-Received: via spool by 34077-submit@debbugs.gnu.org id=B34077.15477337713326 (code B ref 34077); Thu, 17 Jan 2019 14:03:02 +0000 Original-Received: (at 34077) by debbugs.gnu.org; 17 Jan 2019 14:02:51 +0000 Original-Received: from localhost ([127.0.0.1]:34294 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1gk8Fu-0000rY-TB for submit@debbugs.gnu.org; Thu, 17 Jan 2019 09:02:51 -0500 Original-Received: from mail-wm1-f43.google.com ([209.85.128.43]:53049) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1gk8Fs-0000rF-FO for 34077@debbugs.gnu.org; Thu, 17 Jan 2019 09:02:49 -0500 Original-Received: by mail-wm1-f43.google.com with SMTP id m1so1182600wml.2 for <34077@debbugs.gnu.org>; Thu, 17 Jan 2019 06:02:48 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:subject:date:in-reply-to:message-id:user-agent:mime-version; bh=QMQ5JhBwred0qg75G2PAyN1g7TKatIKVEO2klli6Tvc=; b=JfBu+u57vDhetoWhVB35F61sQ3p2wNottBBLdmVOYZFzDrPG3lxqOv0C4eg1CSZCt/ Jo+kuQuvc7+rbXqGcEmSbu3/+qlyBXDtBvWz9g/KHRWPJA4EwY4y7MZyzrBtc4ouQQ+5 taV6Z/mmA5HXfsHpRODjls+ii/fZhX4+gAX9X5z2f+uDSpKgvzO/cLV089VqAQHx90QS 9qyL1uernF3xHKtxkzloYslGgs9pjk19x3tggqXnJYn/GFSpUb5b+wr++4KOMo2T795H CQGyLTZ/W2SCGF5fp0lGzRP+vL8GTkVMUWJwtFGIRRtx9j6r/6F7R7VmhM3UQtn0VWWj yr2w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:in-reply-to:message-id :user-agent:mime-version; bh=QMQ5JhBwred0qg75G2PAyN1g7TKatIKVEO2klli6Tvc=; b=HV/5lXNOb7f/daPo51sfV9MQT6eIQC8eCdyLqbpnCBGkNfiAZGO7P0DiJqPn9NF+T8 61nhZXp3uaB7fciZpf+dAUvD433uTIwj23Ox2NPtaaH11PD5TOnnauJp7GYfUkDGQt5w Khd7wW+yBhgcoGf6xheVSjI4bky7u95mgcnYdXQ89oVvkAzwgFXG93qz12T8uq+y0HdF 925XhFDmHB9PC4lXFDGd1bIsDnqL3UbYemsJtS5KWDdiaL8DdMTsgQgg1zTzM3Y5P39q N+rw3vW71QMDWe6QQ9O8GKQLP9yMW1pg4tSRrU4GGzAIxkIT3HiYZKGHRnvsvF2eAatH 1sdg== X-Gm-Message-State: AJcUuke/Aifo4N/Tj0jfrSecTYT38hHnXnObFRVAPmvhqchJlWaAjTre +fIVGd0UQ3RzlzCTD4RHZvF5vaqg X-Google-Smtp-Source: ALg8bN70CyvzTllkp/yzHm2N/KS2EglXYi/BvJF3S2hGz9iRTFonzMJOtuvTX3gcyo8GUhlDPnHWlQ== X-Received: by 2002:a1c:16c5:: with SMTP id 188mr12204059wmw.69.1547733762293; Thu, 17 Jan 2019 06:02:42 -0800 (PST) Original-Received: from GONDOMAR.yourcompany.com (mail1.siscog.pt. [89.115.233.242]) by smtp.gmail.com with ESMTPSA id 207sm26484745wmb.12.2019.01.17.06.02.41 for <34077@debbugs.gnu.org> (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Thu, 17 Jan 2019 06:02:41 -0800 (PST) In-Reply-To: bug's message of "Thu\, 17 Jan 2019 14\:00\:15 +0000" X-Antivirus: AVG (VPS 190117-0, 17-01-2019), Outbound message X-Antivirus-Status: Clean X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.51.188.43 X-BeenThere: bug-gnu-emacs@gnu.org List-Id: "Bug reports for GNU Emacs, the Swiss army knife of text editors" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Original-Sender: "bug-gnu-emacs" Xref: news.gmane.org gmane.emacs.bugs:154510 Archived-At: --=-=-= Content-Type: text/plain tag 34077 patch Here's a simpler patch set to fix this: --=-=-= Content-Type: text/x-patch Content-Disposition: inline; filename=0001-Fix-nasty-cycling-on-minibuffer-force-complete-and-e.patch >From cc389a92a51dfab1707246d77d03c387b02f312d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20T=C3=A1vora?= Date: Wed, 16 Jan 2019 23:29:34 +0000 Subject: [PATCH 1/5] Fix nasty cycling on minibuffer-force-complete-and-exit (bug#34116) 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/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 --=-=-= Content-Type: text/x-patch Content-Disposition: inline; filename=0005-Avoid-broken-C-M-i-cycling-in-icomplete-mode-bug-340.patch >From f5538c8febc5f28ef08e30fe98b8b91c8fe1e525 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20T=C3=A1vora?= Date: Tue, 15 Jan 2019 16:50:40 +0000 Subject: [PATCH 5/5] Avoid broken C-M-i cycling in icomplete-mode (bug#34077) If there is only one propective candidate and it happens to be a directory then (1) C-M-i causes the prospects to be updated to the subfiles of the completed directory, otherwise (2) the prospects are merely rotated. It is very hard to tell if (1) or (2) happened because the rotated prospects may look identical to the updated prospects. Therefore, in icomplete-mode, it is preferable to do (1) always, to avoid iconsistencies with the presentation of prospects in this mode. There are already facilities in place to rotate the prospects list. * lisp/icomplete.el (icomplete-minibuffer-map): Bind C-M-i to icomplete-force-complete. (icomplete-force-complete): New command. --- lisp/icomplete.el | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/lisp/icomplete.el b/lisp/icomplete.el index 6d77c0649a..80357af4ad 100644 --- a/lisp/icomplete.el +++ b/lisp/icomplete.el @@ -145,13 +145,25 @@ icomplete-post-command-hook (defvar icomplete-minibuffer-map (let ((map (make-sparse-keymap))) - (define-key map [?\M-\t] 'minibuffer-force-complete) + (define-key map [?\M-\t] 'icomplete-force-complete) (define-key map [?\C-j] 'icomplete-force-complete-and-exit) (define-key map [?\C-.] 'icomplete-forward-completions) (define-key map [?\C-,] 'icomplete-backward-completions) map) "Keymap used by `icomplete-mode' in the minibuffer.") +(defun icomplete-force-complete () + "Complete the minibuffer. +Like `minibuffer-force-complete', but don't cycle." + (interactive) + ;; FIXME: it _could_ make sense to cycle in certain situations, by + ;; analyzing the current thing and the thing to cycle to for + ;; instance. Unfortunately that can't be done until a _very nasty + ;; hack_ in `minibuffer-force-complete' is removed. That hack uses + ;; transient maps and prevents two consecutive calls to + ;; `icomplete-force-complete'. + (minibuffer-force-complete nil nil t)) + (defun icomplete-force-complete-and-exit () "Complete the minibuffer and exit. Use the first of the matches if there are any displayed, and use -- 2.19.2 --=-=-=--