all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
From: Jorgen Schaefer <forcer@forcix.cx>
To: Stefan Monnier <monnier@iro.umontreal.ca>
Cc: 12619@debbugs.gnu.org
Subject: bug#12619: completion-at-point and changing buffer
Date: Thu, 11 Oct 2012 20:19:25 +0200	[thread overview]
Message-ID: <20121011201925.76b56a54@forcix.kollektiv-hamburg.de> (raw)
In-Reply-To: <jwv8vbdonmt.fsf-monnier+emacs@gnu.org>

On Wed, 10 Oct 2012 20:37:42 -0400
Stefan Monnier <monnier@iro.umontreal.ca> wrote:

> > First, in `completion-at-point',
> > `completion-in-region-mode-predicate' is set to a function that
> > compares the old start value with the new using `eq'. This prevents
> > markers to work in this case.  Simply replacing `eq' with `=' means
> > markers work, so the positions used by completion just move
> > together with text changes.
> 
> Sounds OK, tho we should make sure that those values can't be nil
> or some other non-numeric thingy.

True, I think some of those values can be nil in some cases (didn't
happen during my testing, though). Pity that neither `eql' nor `equal'
work on markers.

> > Second, `completion--cache-all-sorted-completions' adds a function
> > to `after-change-functions' that cleans up the cache of sorted
> > completions. I'm not entirely sure why it does so, but my patch adds
> > that function only if not both of the returned positions are
> > markers.
> 
> Hmm...but if the buffer modification happens right in the middle of
> the completion text what should we do?  Should we really ignore
> this modification?

Actually, I have no idea what would happen then and couldn't make a
test case to reproduce it easily. :-)

The patch below flushes the cache if the changed text intersects with
the completion text.


--- lisp/minibuffer.el	2012-10-06 17:29:15 +0000
+++ lisp/minibuffer.el	2012-10-11 17:56:42 +0000
@@ -1048,12 +1048,29 @@
 
 (defun completion--cache-all-sorted-completions (comps)
   (add-hook 'after-change-functions
-               'completion--flush-all-sorted-completions nil t)
+            'completion--flush-all-sorted-completions-after-change nil t)
   (setq completion-all-sorted-completions comps))
 
-(defun completion--flush-all-sorted-completions (&rest _ignore)
+(defun completion--flush-all-sorted-completions-after-change (change-start change-end pre-change-length)
+  (let ((start (nth 1 completion-in-region--data))
+        (end (nth 2 completion-in-region--data)))
+    (when (or
+           ;; We don't even have completion data
+           (not start)
+           (not end)
+           ;; Change completely before our completion, but our
+           ;; completion didn't use markers.
+           (and (<= change-end start)
+                (not (and (markerp start)
+                          (markerp end))))
+           ;; Change overlaps our completion, regardless of markers.
+           (not (or (< change-end start)
+                    (< end change-start))))
+      (completion--flush-all-sorted-completions))))
+
+(defun completion--flush-all-sorted-completions ()
   (remove-hook 'after-change-functions
-               'completion--flush-all-sorted-completions t)
+               'completion--flush-all-sorted-completions-after-change t)
   (setq completion-cycling nil)
   (setq completion-all-sorted-completions nil))
 
@@ -1882,8 +1899,12 @@
       (let* ((completion-extra-properties plist)
              (completion-in-region-mode-predicate
               (lambda ()
-                ;; We're still in the same completion field.
-                (eq (car-safe (funcall hookfun)) start))))
+                (let ((old-start (car-safe (funcall hookfun))))
+                  ;; We're still in the same completion field.
+                  (condition-case error
+                      (= old-start start)
+                    (error
+                     (eq old-start start)))))))
         (completion-in-region start end collection
                               (plist-get plist :predicate))))
      ;; Maybe completion already happened and the function returned t.



(I have no idea at what point patches are considered non-trivial for
copyright reasons, but there should be an assignment "for all future
contributions to Emacs" with the FSF.)

Regards,
	-- Jorgen





  reply	other threads:[~2012-10-11 18:19 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-10-10 19:39 bug#12619: completion-at-point and changing buffer Jorgen Schaefer
2012-10-11  0:37 ` Stefan Monnier
2012-10-11 18:19   ` Jorgen Schaefer [this message]
2012-10-24  3:19     ` Stefan Monnier
2012-10-24 16:35       ` Jorgen Schaefer
2012-10-24 17:48         ` Stefan Monnier
2012-10-24 18:58           ` Jorgen Schaefer
2012-10-24 19:40             ` Stefan Monnier

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

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

  git send-email \
    --in-reply-to=20121011201925.76b56a54@forcix.kollektiv-hamburg.de \
    --to=forcer@forcix.cx \
    --cc=12619@debbugs.gnu.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 external index

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

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.