bug#38024: 27.0.50; icomplete sometimes fails to show completions after backward-killing words

classic Classic list List threaded Threaded
8 messages Options
Reply | Threaded
Open this post in threaded view
|

bug#38024: 27.0.50; icomplete sometimes fails to show completions after backward-killing words

Kévin Le Gouguec
Hello,

tl;dr unless I'm mistaken, sometimes `while-no-input' returns t despite
no input having arrived; this prevents `icomplete-exhibit' from
displaying completion candidates.

In more details:

This is a bit of a heisenbug; hopefully someone out there will know what
knobs to tweak to find more information about this.

From emacs -Q:

    M-x icomplete-mode RET
    ;; Find a way to set `default-directory' to some long-ish path,
    ;; e.g. with:
    M-x find-library RET icomplete RET
    C-x C-f
    ;; icomplete should show a bunch of completions.
    M-DEL
    M-DEL
    …

After each `backward-kill-word', icomplete usually displays new
completion candidates with no further user input; sometimes however, no
candidates show up until the user does something (e.g. press TAB or
start typing).

Commit 5860fd3 (Make icomplete-exhibit actually work when navigating up
directories) tried to fix this, but AFAICT it merely reduces the odds of
the bug happening: I can still reproduce it, although less often.  Also,
this new call to `redisplay' causes some noticeable flickering when
typing characters: the completions blink in and out as I fill in the
prompt.

I've tinkered with icomplete.el (commenting out the call to `redisplay'
since it makes the bug harder to trigger); the closest I got to
pin-pointing the cause for this issue was while goofing around in
`icomplete-exhibit', specifically with the `while-no-input' part:

          (let* (…
                 (text (while-no-input
                         (icomplete-completions
                          …)))
                 …)
            ;; Do nothing if while-no-input was aborted.
            (when (stringp text)
              update overlay…))

I replaced (when (stringp text) …) with (if (stringp text) (progn …)
(message "text is %s" text)): it seems that text is t when icomplete
fails to show updated candidates, which according to `while-no-input'
means that some input arrived…

However, when I tried to debug `while-no-input', I got stumped: I tried
to do some more printf-debugging[1], but all I observe is that
sometimes, the code seems to be interrupted between

         (let ((throw-on-input ',catch-sym)
               val)
and
           (setq val (or (input-pending-p)
                         (progn ,@body)))

I tried to find where exactly the code gets interrupted, but I could not
get a consistent answer; sometimes it seems to be before executing body,
sometimes it seems to be somewhere inside `icomplete-completions'…

What would be the best way to investigate this further?

Thank you for your time.


[1] With this patch:



When the bug happens, I get the following messages:

    after with-local-quit
    after catch and let
    text is t


PS: It just occured to me that I should search debbugs for
    "while-no-input" in addition to "icomplete".  I just did that;
    bug#15042 looks like it could maybe be related?


In GNU Emacs 27.0.50 (build 6, i686-pc-linux-gnu, GTK+ Version 3.24.5, cairo version 1.16.0)
 of 2019-10-21 built on little-buster
Repository revision: 61fb5214816ef3d57e676d900e499ffcd079a1f9
Repository branch: master
Windowing system distributor 'The X.Org Foundation', version 11.0.12004000
System Description: Debian GNU/Linux 10 (buster)

Configured using:
 'configure --with-xwidgets --with-cairo'

Configured features:
XPM JPEG TIFF GIF PNG RSVG CAIRO SOUND GPM DBUS GSETTINGS GLIB NOTIFY
INOTIFY ACL LIBSELINUX GNUTLS LIBXML2 FREETYPE HARFBUZZ M17N_FLT LIBOTF
ZLIB TOOLKIT_SCROLL_BARS GTK3 X11 XDBE XIM MODULES THREADS XWIDGETS
LIBSYSTEMD JSON PDUMPER LCMS2 GMP

Important settings:
  value of $LANG: en_US.UTF-8
  locale-coding-system: utf-8-unix

icomplete-debug.patch (3K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

bug#38024: 27.0.50; icomplete sometimes fails to show completions after backward-killing words

João Távora
Kevin, you're on the right track. The redisplay thing is not the right fix, indeed. Stefan has a fix for this, which he sent me, but I can't find it now.

Anyway, it has to do with avoiding the 'select' event in while-no-input. 

In case you want to try that before Stefan drops by.

João

On Fri, Nov 1, 2019, 21:40 Kévin Le Gouguec <[hidden email]> wrote:
Hello,

tl;dr unless I'm mistaken, sometimes `while-no-input' returns t despite
no input having arrived; this prevents `icomplete-exhibit' from
displaying completion candidates.

In more details:

This is a bit of a heisenbug; hopefully someone out there will know what
knobs to tweak to find more information about this.

From emacs -Q:

    M-x icomplete-mode RET
    ;; Find a way to set `default-directory' to some long-ish path,
    ;; e.g. with:
    M-x find-library RET icomplete RET
    C-x C-f
    ;; icomplete should show a bunch of completions.
    M-DEL
    M-DEL
    …

After each `backward-kill-word', icomplete usually displays new
completion candidates with no further user input; sometimes however, no
candidates show up until the user does something (e.g. press TAB or
start typing).

Commit 5860fd3 (Make icomplete-exhibit actually work when navigating up
directories) tried to fix this, but AFAICT it merely reduces the odds of
the bug happening: I can still reproduce it, although less often.  Also,
this new call to `redisplay' causes some noticeable flickering when
typing characters: the completions blink in and out as I fill in the
prompt.

I've tinkered with icomplete.el (commenting out the call to `redisplay'
since it makes the bug harder to trigger); the closest I got to
pin-pointing the cause for this issue was while goofing around in
`icomplete-exhibit', specifically with the `while-no-input' part:

          (let* (…
                 (text (while-no-input
                         (icomplete-completions
                          …)))
                 …)
            ;; Do nothing if while-no-input was aborted.
            (when (stringp text)
              update overlay…))

I replaced (when (stringp text) …) with (if (stringp text) (progn …)
(message "text is %s" text)): it seems that text is t when icomplete
fails to show updated candidates, which according to `while-no-input'
means that some input arrived…

However, when I tried to debug `while-no-input', I got stumped: I tried
to do some more printf-debugging[1], but all I observe is that
sometimes, the code seems to be interrupted between

         (let ((throw-on-input ',catch-sym)
               val)
and
           (setq val (or (input-pending-p)
                         (progn ,@body)))

I tried to find where exactly the code gets interrupted, but I could not
get a consistent answer; sometimes it seems to be before executing body,
sometimes it seems to be somewhere inside `icomplete-completions'…

What would be the best way to investigate this further?

Thank you for your time.


[1] With this patch:


When the bug happens, I get the following messages:

    after with-local-quit
    after catch and let
    text is t


PS: It just occured to me that I should search debbugs for
    "while-no-input" in addition to "icomplete".  I just did that;
    bug#15042 looks like it could maybe be related?


In GNU Emacs 27.0.50 (build 6, i686-pc-linux-gnu, GTK+ Version 3.24.5, cairo version 1.16.0)
 of 2019-10-21 built on little-buster
Repository revision: 61fb5214816ef3d57e676d900e499ffcd079a1f9
Repository branch: master
Windowing system distributor 'The X.Org Foundation', version 11.0.12004000
System Description: Debian GNU/Linux 10 (buster)

Configured using:
 'configure --with-xwidgets --with-cairo'

Configured features:
XPM JPEG TIFF GIF PNG RSVG CAIRO SOUND GPM DBUS GSETTINGS GLIB NOTIFY
INOTIFY ACL LIBSELINUX GNUTLS LIBXML2 FREETYPE HARFBUZZ M17N_FLT LIBOTF
ZLIB TOOLKIT_SCROLL_BARS GTK3 X11 XDBE XIM MODULES THREADS XWIDGETS
LIBSYSTEMD JSON PDUMPER LCMS2 GMP

Important settings:
  value of $LANG: en_US.UTF-8
  locale-coding-system: utf-8-unix
Reply | Threaded
Open this post in threaded view
|

bug#38024: 27.0.50; icomplete sometimes fails to show completions after backward-killing words

João Távora
João Távora <[hidden email]> writes:

> Kevin, you're on the right track. The redisplay thing is not the right
> fix, indeed. Stefan has a fix for this, which he sent me, but I can't
> find it now.
>
> Anyway, it has to do with avoiding the 'select' event in
> while-no-input.

Hi Kévin,

In the meantime, I found the patch and pushed it right away.  It worked
better than the redisplay hack I had pushed before.

The commit you want to test with is
730e7da7ba6a4b545176ea246653928edb10cff4

Let me know how it works for you,
João



Reply | Threaded
Open this post in threaded view
|

bug#38024: 27.0.50; icomplete sometimes fails to show completions after backward-killing words

Eli Zaretskii
> From: João Távora <[hidden email]>
> Date: Sat, 02 Nov 2019 03:05:17 +0000
> Cc: [hidden email], Stefan Monnier <[hidden email]>
>
> João Távora <[hidden email]> writes:
>
> > Kevin, you're on the right track. The redisplay thing is not the right
> > fix, indeed. Stefan has a fix for this, which he sent me, but I can't
> > find it now.
> >
> > Anyway, it has to do with avoiding the 'select' event in
> > while-no-input.
>
> Hi Kévin,
>
> In the meantime, I found the patch and pushed it right away.  It worked
> better than the redisplay hack I had pushed before.
>
> The commit you want to test with is
> 730e7da7ba6a4b545176ea246653928edb10cff4

The current master displays this warning when byte-compiling
icomplete.el:

    ELC      icomplete.elc

  In end of data:
  icomplete.el:669:1:Warning: the function `while-no-input-ignore-events' is not
      known to be defined.

while-no-input-ignore-events is not a function, it's a variable.



Reply | Threaded
Open this post in threaded view
|

bug#38024: 27.0.50; icomplete sometimes fails to show completions after backward-killing words

João Távora
Eli Zaretskii <[hidden email]> writes:

>   In end of data:
>   icomplete.el:669:1:Warning: the function `while-no-input-ignore-events' is not
>       known to be defined.
>
> while-no-input-ignore-events is not a function, it's a variable.

Sorry,

This was a merge blunder when reordering commits. The reference appears
again in the corrct variable form below.  I've now fixed the problem in
6911ef3da69333cb7adc1a7fb0a0fc001220a0c4.

João



Reply | Threaded
Open this post in threaded view
|

bug#38024: 27.0.50; icomplete sometimes fails to show completions after backward-killing words

Eli Zaretskii
> From: João Távora <[hidden email]>
> Cc: [hidden email],  [hidden email],
>   [hidden email]
> Date: Sat, 02 Nov 2019 11:12:07 +0000
>
> > while-no-input-ignore-events is not a function, it's a variable.
>
> Sorry,
>
> This was a merge blunder when reordering commits. The reference appears
> again in the corrct variable form below.  I've now fixed the problem in
> 6911ef3da69333cb7adc1a7fb0a0fc001220a0c4.

Thanks, compiles cleanly now.



Reply | Threaded
Open this post in threaded view
|

bug#38024: 27.0.50; icomplete sometimes fails to show completions after backward-killing words

Kévin Le Gouguec
Eli Zaretskii <[hidden email]> writes:

> Thanks, compiles cleanly now.

And AFAICT, everything's fine now!  (Completions show up no matter how
many M-DELs I hit; no more flickering when typing.)

Thank you all for working on this; closing (if I'm reading
admin/notes/bugtracker correctly).




Reply | Threaded
Open this post in threaded view
|

bug#38024: 27.0.50; icomplete sometimes fails to show completions after backward-killing words

Stefan Monnier
In reply to this post by João Távora
[ Resending, as usual, since the bug was archived.  Sorry.  ]

João Távora [2019-11-02 11:12:07] wrote:
> Eli Zaretskii <[hidden email]> writes:
>>   In end of data:
>>   icomplete.el:669:1:Warning: the function `while-no-input-ignore-events' is not
>>       known to be defined.
>> while-no-input-ignore-events is not a function, it's a variable.
> Sorry,
> This was a merge blunder when reordering commits. The reference appears
> again in the corrct variable form below.  I've now fixed the problem in
> 6911ef3da69333cb7adc1a7fb0a0fc001220a0c4.

Hmm... so the patch installed was basically:

    commit 88f193ed05649b8c622867b8b2623b8cb08fdc96
    Author: João Távora <[hidden email]>
    Date:   Sat Nov 2 02:29:56 2019 +0000
   
        Improve fix for icomplete's backward-kill-word bug#38024
       
        * lisp/icomplete.el (icomplete-exhibit): Use
        while-no-input-ignore-events, not redisplay.
       
        Co-authored-by: Stefan Monnier <[hidden email]>
   
    diff --git a/lisp/icomplete.el b/lisp/icomplete.el
    index 02eae55a19..89318ca4c7 100644
    --- a/lisp/icomplete.el
    +++ b/lisp/icomplete.el
    @@ -399,8 +399,6 @@ icomplete-exhibit
     See `icomplete-mode' and `minibuffer-setup-hook'."
       (when (and icomplete-mode
                  (icomplete-simple-completing-p)) ;Shouldn't be necessary.
    -    (redisplay)     ; FIXME: why is this sometimes needed when moving
    -                    ; up dirs in a file-finding table?
         (save-excursion
           (goto-char (point-max))
                                             ; Insert the match-status information:
    @@ -420,6 +418,11 @@ icomplete-exhibit
                    ;; embarking on computing completions:
                    (sit-for icomplete-compute-delay)))
              (let* ((field-string (icomplete--field-string))
    +                 ;; Not sure why, but such requests seem to come
    +                 ;; every once in a while.  It's not fully
    +                 ;; deterministic but `C-x C-f M-DEL M-DEL ...'
    +                 ;; seems to trigger it fairly often!
    +                 (while-no-input-ignore-events '(selection-request))
                      (text (while-no-input
                              (icomplete-completions
                               field-string

but I don't understand why that would help and/or be needed:
`selection-request` is (and has been for many years) in the default
value of `while-no-input-ignore-events` (as set in `subr.el`), so what
this patch ends up doing is forcing `while-no-input` to exit with value
t in more cases (i.e. whenever one of the events in (focus-in focus-out
help-echo iconify-frame make-frame-visible) comes in) rather than
the opposite.

What am I missing?


        Stefan