emacs-helm / helm

Emacs incremental completion and selection narrowing framework
https://emacs-helm.github.io/helm/
GNU General Public License v3.0
3.37k stars 390 forks source link

Wrong candidate when typing too fast #450

Closed michael-heerdegen closed 10 years ago

michael-heerdegen commented 10 years ago

Yes, this was discussed several times before:

(setq helm-input-idle-delay 1.0)

(completing-read "Input: " '(a b c))

Type b and hit enter immedaitely. You get "a" instead of "b". The situation with a smaller helm-input-idle-delay is not much different, the only difference is that the slip-up happens less frequently, but it stil happens when typing fast, and this is annoying, it can even be dangerous.

In addition, it is not good that you have to choose a small value for helm-input-idle-delay in your config, or as default value in helm, only for the sake of preventing this issue.

Is there any chance to fix this? Can't we just do add something to `helm-exit-minibuffer' that checks (for non-delayed sources) whether the current candidate is "outdated"? Or add a trivial timeout that waits until the timeout is over? Or is there any reason that prevents us from treating this case?

IMHO, the goal should be that for completion with non-delayed sources, the behavior should only depend on hit keys, not on the time delays between them.

thierryvolpiatto commented 10 years ago

michael-heerdegen notifications@github.com writes:

Yes, this was discussed several times before:

(setq helm-input-idle-delay 1.0)

(completing-read "Input: " '(a b c))

Type b and hit enter immedaitely. You get "a" instead of "b". The situation with a smaller helm-input-idle-delay is not much different,

Huh! with your example and helm-input-idle-delay set to 0.01 the difference is much different, I can't get "a" when typing "b", doing my best to be as fast as possible.

the only difference is that the slip-up happens less frequently, but it stil happens when typing fast, and this is annoying, it can even be dangerous.

In addition, it is not good that you have to choose a small value for helm-input-idle-delay in your config, or as default value in helm, only for the sake of preventing this issue.

Is there any chance to fix this?

No, I will not fix this, this is not an issue as I said many times.

When pressing RET after writing something in minibuffer and assume that what is in minibuffer is what you will get after update finish, you are wrong, except if you write the full name in minibuffer and end up with only one candidate in helm-buffer.

The problem is that people expect that what they have in minibuffer is what they will get after pressing RET; This is true in vanilla emacs but not in helm; You will get in helm what is under selection in the helm-buffer, but not what is in minibuffer in most cases.

When using helm, it is just like if you were always using TAB in vanilla emacs, that is expecting a completion on what you type, in this case you have to wait and see what emacs completion propose.

Thierry Get my Gnupg key: gpg --keyserver pgp.mit.edu --recv-keys 59F29997

michael-heerdegen commented 10 years ago

Thierry Volpiatto notifications@github.com writes:

(completing-read "Input: " '(a b c))

Huh! with your example and helm-input-idle-delay set to 0.01 the difference is much different, I can't get "a" when typing "b", doing my best to be as fast as possible.

This was just to demonstrate what I mean. But even with .01 ... see below.

No, I will not fix this, this is not an issue as I said many times.

Yes, I know that the behavior is intended, and that you said this many times. I don't question the design in general, but maybe there's room for improvement.

A general problem is that there is one constant setting of idle time. It may be appropriate for lots of sources, but still be inappropriate for some other sources.

Sources which generate lots of candidates "get quite slow" when idle time is too short, because completion takes long. This is the only reason why we need deltas and timers at all, right? So, to make things work, I must not set the idle delay to a too small number. 0.1 is really a lower border, setting it smaller will make you crazy with some sources.

OTOH, there are sources with few candidates where you type fast, and .1 is much too large as a delay. You must look and wait until the right cand is highlighted. Annoying and distracting.

Maybe helm could do better - maybe by accommodating the idle delay if it notices that the current delay isn't appropriate? Or maybe the constant could be (dynamically) multiplied by a factor depending on the number of all candidates? I think that could be worth a try.

Ok so now to my example:

I use this in a command of mine to read system commands:

(interactive
 (list (if (featurep 'helm)
       (let ((helm-input-idle-delay 0)
         (helm-idle-delay       0))
     (helm-comp-read
      "Run external application: "
      (helm-external-commands-list-1 'sort)
      :must-match nil
      :del-input nil
      :input-history 'helm-external-command-history
      :name "External Commands"))
     (read-shell-command  "Run external application: "))))

I have a command "mnt" that is a wrapper for "pmount". It can be typed quite fast. I want to say that I can't write fast, for an Emacs hacker, I'm typing really slow.

Every once in a while, the above gives me "m4" or such and calls this external command. I don't know what m4 is, and I don't want to.

You know that the delay can't be smaller than 0.01 in practice because of

(max helm-input-idle-delay 0.01)

in helm-read-pattern-maybe. Maybe the hardcoded 0.01 should be smaller

Summary: this isn't urgent, and there are ways to work around the issue. But given the fact that many people do have problems with the current situation, we IMHO should deliberate if we can improve what we have, without given up any design decisions.

thierryvolpiatto commented 10 years ago

michael-heerdegen notifications@github.com writes:

Thierry Volpiatto notifications@github.com writes:

(completing-read "Input: " '(a b c))

Huh! with your example and helm-input-idle-delay set to 0.01 the difference is much different, I can't get "a" when typing "b", doing my best to be as fast as possible.

This was just to demonstrate what I mean. But even with .01 ... see below.

No, I will not fix this, this is not an issue as I said many times.

Yes, I know that the behavior is intended, and that you said this many times. I don't question the design in general, but maybe there's room for improvement.

A general problem is that there is one constant setting of idle time. It may be appropriate for lots of sources, but still be inappropriate for some other sources.

Now all sources except helm-source-find-files and helm-read-file-name are no more delayed.

Sources which generate lots of candidates "get quite slow" when idle time is too short,

This is unrelated to speed, why sources would be slower when helm-input-idle-delay have a small value ?

I use personally 0.01 by default (global value) and I have no problems.

because completion takes long. This is the only reason why we need deltas and timers at all, right?

You are speaking of delayed source right ? They are no more needed now, except for the two mentioned above, but this is needed for other reasons.

So, to make things work, I must not set the idle delay to a too small number. 0.1 is really a lower border, setting it smaller will make you crazy with some sources.

Which sources ? I use 0.01 everywhere with no problems.

OTOH, there are sources with few candidates where you type fast, and .1 is much too large as a delay. You must look and wait until the right cand is highlighted. Annoying and distracting.

Probably nowaday 0.01 should be the default.

Maybe helm could do better - maybe by accommodating the idle delay if it notices that the current delay isn't appropriate? Or maybe the constant could be (dynamically) multiplied by a factor depending on the number of all candidates?

When you know this number that mean update is finish and changing the value of helm-input-idle-delay at this time would be unuseful isn't it ? Or maybe I miss something ?

I think that could be worth a try.

Ok so now to my example:

I use this in a command of mine to read system commands:

(interactive (list (if (featurep 'helm) (let ((helm-input-idle-delay 0) (helm-idle-delay 0)) (helm-comp-read "Run external application: " (helm-external-commands-list-1 'sort) :must-match nil :del-input nil :input-history 'helm-external-command-history :name "External Commands")) (read-shell-command "Run external application: "))))

Why not using `helm-run-external-command' here ?

I have a command "mnt" that is a wrapper for "pmount". It can be typed quite fast. I want to say that I can't write fast, for an Emacs hacker, I'm typing really slow.

Me too with my old rockclimber fingers.

Every once in a while, the above gives me "m4" or such and calls this external command. I don't know what m4 is, and I don't want to.

I can't reproduce this using `helm-run-external-command'.

You know that the delay can't be smaller than 0.01 in practice because of

(max helm-input-idle-delay 0.01)

in helm-read-pattern-maybe. Maybe the hardcoded 0.01 should be smaller

  • at least, using zero seems to help in this case.

Setting to zero may lead to emacs crashes on some platforms (at least windows).

Summary: this isn't urgent, and there are ways to work around the issue. But given the fact that many people do have problems with the current situation, we IMHO should deliberate if we can improve what we have, without given up any design decisions.

Why not? But I see no reliable solutions yet.

Thierry Get my Gnupg key: gpg --keyserver pgp.mit.edu --recv-keys 59F29997

michael-heerdegen commented 10 years ago

Thierry Volpiatto notifications@github.com writes:

Sources which generate lots of candidates "get quite slow" when idle time is too short,

This is unrelated to speed, why sources would be slower when helm-input-idle-delay have a small value ?

When they generate lots of candidates, completion takes longer, and with a small idle delaye, completion is performed more often when typing. But maybe you're right and most sources are efficient enough (through using candidates buffers etc.) so that this aspect is neglectable on today's computers. Forget it.

You are speaking of delayed source right ?

No, see above.

Which sources ? I use 0.01 everywhere with no problems.

Really? Ok, I'll try this!

Why not using `helm-run-external-command' here ?

I've written my own external commands infrastructure with features I would miss.

(max helm-input-idle-delay 0.01)

in helm-read-pattern-maybe. Maybe the hardcoded 0.01 should be smaller - at least, using zero seems to help in this case.

Setting to zero may lead to emacs crashes on some platforms (at least windows).

Can we reduce the hardcoded 0.01 in the max call, or make it configurable? At least in my case, it is sometimes not small enough. I had to try ~20 times for a wrong completion to happen, but it does happen. Maybe I've here some time holes flying around in my flat... but it happens.

thierryvolpiatto commented 10 years ago

michael-heerdegen notifications@github.com writes:

When they generate lots of candidates, completion takes longer, and with a small idle delaye, completion is performed more often when typing. But maybe you're right and most sources are efficient enough (through using candidates buffers etc.)

A noticable example is helm-find-files which is now much faster (try with old versions and current version on huge directories), here a directory with 2400 candidates popup nearly immediately.

Can we reduce the hardcoded 0.01 in the max call, or make it configurable?

Hmm, I can try, if we have bug report about crashes I will revert the changes. But I will reduce the hardcoded value, making a var for this will lead to issues immediately.

Thierry Get my Gnupg key: gpg --keyserver pgp.mit.edu --recv-keys 59F29997

michael-heerdegen commented 10 years ago

Thierry Volpiatto notifications@github.com writes:

A noticable example is helm-find-files which is now much faster (try with old versions and current version on huge directories), here a directory with 2400 candidates popup nearly immediately.

Yip, that's cool indeed!

Can we reduce the hardcoded 0.01 in the max call, or make it configurable?

Hmm, I can try, if we have bug report about crashes I will revert the changes. But I will reduce the hardcoded value, making a var for this will lead to issues immediately.

Ok, agreed, thanks.

thierryvolpiatto commented 10 years ago

michael-heerdegen notifications@github.com writes:

Thierry Volpiatto notifications@github.com writes:

A noticable example is helm-find-files which is now much faster (try with old versions and current version on huge directories), here a directory with 2400 candidates popup nearly immediately.

Yip, that's cool indeed!

Can we reduce the hardcoded 0.01 in the max call, or make it configurable?

Hmm, I can try, if we have bug report about crashes I will revert the changes. But I will reduce the hardcoded value, making a var for this will lead to issues immediately.

Ok, agreed, thanks.

  • I have modified the timer function and now the min value is 0.001.
  • You have a new var helm--update-idle-delay that you can set on the fly. I.e You can modify helm-input-idle-delay only before starting helm session while you can set this new var during the computation of the candidates function, it will have effect once the function finish or quit.
  • The computation of candidates is done outside of the timer
  • accept-process-output is now supported within computation of candidates.
  • The performances seem improved though i didn't make any measures.

See the improve-timer branch.

Thierry Get my Gnupg key: gpg --keyserver pgp.mit.edu --recv-keys 59F29997

michael-heerdegen commented 10 years ago

Ok, thanks. I've checked it out and will use it for working - and I'll have a look at your changes.

thierryvolpiatto commented 10 years ago

michael-heerdegen notifications@github.com writes:

Ok, thanks. I've checked it out and will use it for working - and I'll have a look at your changes.

Thanks, still not fully working on async sources (grep locate etc..)

Thierry Get my Gnupg key: gpg --keyserver pgp.mit.edu --recv-keys 59F29997

michael-heerdegen commented 10 years ago

I tried

(if (featurep 'helm)
    (let ;; ((helm-input-idle-delay 0)
    ;;  (helm-idle-delay       0))
    ((helm--update-idle-delay 0.0))
      (helm-comp-read
       "Run external application: "
       (helm-external-commands-list-1 'sort)
       :must-match nil
       :del-input nil
       :input-history 'helm-external-command-history
       :name "External Commands"))
  (read-shell-command  "Run external application: "))

but it's really slow. Completion takes ~ 2secs with helm.sh.

michael-heerdegen commented 10 years ago

Also, using helm-M-x in helm.sh, I get 100% CPU usage - although Emacs doesn't freeze.

thierryvolpiatto commented 10 years ago

michael-heerdegen notifications@github.com writes:

Also, using helm-M-x in helm.sh, I get 100% CPU usage - although Emacs doesn't freeze.

Hmm yes I see, thanks, I think I see what's happening.

Thierry Get my Gnupg key: gpg --keyserver pgp.mit.edu --recv-keys 59F29997

michael-heerdegen commented 10 years ago

FWIW, the setting of the min value to .001 doesn't completely fix my issue. Probably, the completion performed after I entered the first two chars "mn" takes much longer than these .01 or .001 secs, and when I hit "t" and RET before Emacs got idle again, the problem happens. If this is true (I think so, but I guess it would be possible to verfiy this), then fixing this will be probably not possible, unless we interrupt helm's completion when there is new input. I tried to bind helm-mp-highlight-threshold to a larger value, but that also didn't fix it.

thierryvolpiatto commented 10 years ago

michael-heerdegen notifications@github.com writes:

FWIW, the setting of the min value to .001 doesn't completely fix my issue.

I notice also that using 0.001 as default make M-n insertion fail (no error but the update is not starting, tried with grep and occur)

Probably, the completion performed after I entered the first two chars "mn" takes much longer than these .01 or .001 secs, and when I hit "t" and RET before Emacs got idle again, the problem happens. If this is true (I think so, but I guess it would be possible to verfiy this), then fixing this will be probably not possible,

I am afraid that's true.

unless we interrupt helm's completion when there is new input.

The only way actually is to bind helm-suspend-update-flag to t. But well if we stop update when a new input is coming we will have to restart it, and it maybe too long, we may endup with something unusable.

I tried to bind helm-mp-highlight-threshold to a larger value, but that also didn't fix it.

This is unrelated to this.

Thierry Get my Gnupg key: gpg --keyserver pgp.mit.edu --recv-keys 59F29997

michael-heerdegen commented 10 years ago

Thierry Volpiatto notifications@github.com writes:

I tried to bind helm-mp-highlight-threshold to a larger value, but that also didn't fix it.

This is unrelated to this.

Is there something I can do in my call to avoid the problematic behavior? Some time ago, I knew a var that caused completion not to start before input was N chars long, but I can't find it anymore.

For the rest of this issue: don't waste your time if it causes that much trouble, unless you find an elegant fix. I thought it would be easier.

thierryvolpiatto commented 10 years ago

michael-heerdegen notifications@github.com writes:

Thierry Volpiatto notifications@github.com writes:

I tried to bind helm-mp-highlight-threshold to a larger value, but that also didn't fix it.

This is unrelated to this.

Is there something I can do in my call to avoid the problematic behavior? Some time ago, I knew a var that caused completion not to start before input was N chars long, but I can't find it anymore.

Add requires-pattern attr to your source, if you use helm-comp-read, it is the keyword :requires-pattern.

For the rest of this issue: don't waste your time if it causes that much trouble, unless you find an elegant fix. I thought it would be easier.

No it is really complex, I will try to continue exploring the improve-timer branch when I have the time, but it is mostly unralated to your problem.

Thanks.

Thierry Get my Gnupg key: gpg --keyserver pgp.mit.edu --recv-keys 59F29997

michael-heerdegen commented 10 years ago

Thierry Volpiatto notifications@github.com writes:

Add requires-pattern attr to your source, if you use helm-comp-read, it is the keyword :requires-pattern.

Ah, thanks.

No it is really complex, I will try to continue exploring the improve-timer branch when I have the time, but it is mostly unralated to your problem.

Another approach that comes to my mind and which would obviously easily fix the issue would be

(defun my-helm-ret-around (F &rest args)
  (apply #'run-with-idle-timer (* 2 .01) nil F args))

(advice-add 'helm-exit-minibuffer
    :around #'my-helm-ret-around)

But I've the impression you won't like the idea.

thierryvolpiatto commented 10 years ago

michael-heerdegen notifications@github.com writes:

Thierry Volpiatto notifications@github.com writes:

Add requires-pattern attr to your source, if you use helm-comp-read, it is the keyword :requires-pattern.

Ah, thanks.

No it is really complex, I will try to continue exploring the improve-timer branch when I have the time, but it is mostly unralated to your problem.

Another approach that comes to my mind and which would obviously easily fix the issue would be

(defun my-helm-ret-around (F &rest args) (apply #'run-with-idle-timer (* 2 .01) nil F args))

(advice-add 'helm-exit-minibuffer :around #'my-helm-ret-around)

But I've the impression you won't like the idea.

Hmm, yes I don't like that too much, however this can be easily setup with the new helm-exit-minibuffer-hook' that run just before exit-minibuffer'.

Thierry Get my Gnupg key: gpg --keyserver pgp.mit.edu --recv-keys 59F29997

michael-heerdegen commented 10 years ago

Do you mean like

(add-hook 'helm-exit-minibuffer-hook (lambda () (sit-for .1)))

No, that won't work. The sit-for is executed immediatly, and while sitting, Emacs does nothing. After sit-for returns, Emacs isn't idle, because it continues evaluation. So this doesn't make any difference other than waisting some amount of time. Or did you mean smth different?

michael-heerdegen commented 10 years ago

Also note that sitting or sleeping doesn't make Emacs idle in the meantime.

kini commented 10 years ago

I opened #538 which @thierryvolpiatto marked as a duplicate of this issue. I am a complete newcomer to helm (just started using it yesterday) so please tell me if I'm missing something obvious, or if there's some contradiction in what I'm saying below.

It seems to me that if I type some letters and then hit enter, the final behavior should be deterministic, regardless of how long various completion sources may take to return, or how long I take to type those letters, or whatever. I should be able to pipe keystrokes into Emacs at light-speed if I want. Input should be synchronous -- not a conversational dialogue between me and Emacs, but a unidirectional stream of commands from me to Emacs, which can be as fast or slow as I want. Emacs only needs to wait for me, I shouldn't need to wait for Emacs. This is a big part of what makes Emacs so different from other editors and allows people to use it so fluidly.

On the other hand, the whole point of helm is to give you hints while you're typing! If I were able to type all my input to helm in literally zero time, there would be no need to even display a completion window. However, this must be secondary to the fact that I am inputting commands into Emacs which I expect to be followed in a predictable way that I can model in my head. Otherwise it just gets in the way.

I think my problem would be solved if helm were to force all asynchronous calls to return before actually doing anything when I hit RET. Is this feasible?

kini commented 10 years ago

I would like to add that my helm-input-idle-delay is set to 0.01 which is the current default as I understand it. Nevertheless I see this behavior all the time. In my experience so far, close to 30% of the times that I use helm, I will end up with this "no match" text when I hit RET (see #538 for a description of my particular problem).

I'm not saying that these delays should be increased or decreased or whatever. I'm sure you know far better than I how to make the completion window work smoothly and responsively using these timers. But IMO that's different from the question of what happens when I type keys and hit RET. Which is why I originally reported this as #538 rather than just commenting on this issue, FWIW.

thierryvolpiatto commented 10 years ago

Should be fixed now in exp branch.

here a test:

(let ((helm-input-idle-delay 0.6))
  (completing-read "test: " '("far" "fair" "fear" "foo" "bar" "baz")))

Eval and type "fa", when done you end up with: far fair

type now very fast "r" and <RET>

A message flash [Display not ready]

you have to type again <RET>

the result string is "far" and not "fa" as before fix.

thierryvolpiatto commented 10 years ago

merged.

kini commented 10 years ago

Thanks, but can you reopen #538? This fix doesn't change the behavior I described there at all. (Even the exact same message "[No match]" is still displayed.)

thierryvolpiatto commented 10 years ago

Keshav Kini notifications@github.com writes:

Thanks, but can you reopen #538?

No.

This fix doesn't change the behavior I described there at all.

What you want is pressing RET only once, then helm finish updating and execute its action on the first candidate.

With what you are asking for, user may have bad surprise when pressing RET while helm is updating, unless he know in advance what will be the result, so I do not want this.

I think the new behavior is a good compromise.

Thierry Get my Gnupg key: gpg --keyserver pgp.mit.edu --recv-keys 59F29997

kini commented 10 years ago

What you want is pressing RET only once, then helm finish updating and execute its action on the first candidate.

With what you are asking for, user may have bad surprise when pressing RET while helm is updating, unless he know in advance what will be the result, so I do not want this.

That's a good point, I agree. Though maybe it can be a configurable setting, off by default? (I understand if you don't want to take the time to implement it of course :) ).

I think the new behavior is a good compromise.

Fine, but there is no "new behavior" for #538, it is literally the same as before. It still says "[No match]" and aborts the helm window update. I cannot press RET again. There is no "[Display not ready]" message. If it helps, the function bound to RET in that context is helm-confirm-and-exit-minibuffer, which does not call your new helm-maybe-exit-minibuffer function.

thierryvolpiatto commented 10 years ago

Keshav Kini notifications@github.com writes:

That's a good point, I agree. Though maybe it can be a configurable setting, off by default? (I understand if you don't want to take the time to implement it of course :) ).

A lot of work with introduction of many bugs for a little benefit.

Fine, but there is no "new behavior" for #538, it is literally the same as before. It still says "[No match]" and aborts the helm window update. I cannot press RET again. There is no "[Display not ready]" message. If it helps, the function bound to RET in that context is helm-confirm-and-exit-minibuffer, which does not call your new helm-maybe-exit-minibuffer function.

Thanks fixed.

Thierry Get my Gnupg key: gpg --keyserver pgp.mit.edu --recv-keys 59F29997

kini commented 10 years ago

Thanks fixed.

Still not fixed. The cond branches to this line and doesn't reach the line you changed.

thierryvolpiatto commented 10 years ago

Keshav Kini notifications@github.com writes:

Thanks fixed.

Still not fixed. The cond branches to this line and doesn't reach the line you changed.

It is what is expected in such cases ([no match]).

Start with the simple recipe I sent to reproduce.

Thanks.

Thierry Volpiatto

thierryvolpiatto commented 10 years ago

Ok I think I understand what you mean, I have commited another fix, please try.

Thanks.

Thierry Volpiatto

kini commented 10 years ago

Still no effect. BTW, it seems that (helm--updating-p) is false in this situation. I tried changing (and (helm--updating-p) (null helm--reading-passwd-or-string)) to simply (helm--updating-p), and I still get the "[No match]" text and aborted completion search. Also, further playing around shows that empty-buffer-p is true in this situation (which makes sense since, as the screenshot shows, the helm buffer is empty).

thierryvolpiatto commented 10 years ago

Keshav Kini notifications@github.com writes:

Still no effect. BTW, it seems that (helm--updating-p) is false in this situation. I tried changing (and (helm--updating-p) (null helm--reading-passwd-or-string)) to simply (helm--updating-p), and I still get the "[No match]" text and aborted completion search. Also, further playing around shows that empty-buffer-p is true in this situation (which makes sense since, as the screenshot shows, the helm buffer is empty).

Sorry but I can't reproduce, perhaps send again a recipe of what you are doing exactly.

Note that with my computer and the default value of helm-input-idle-delay, after typing the "t" after "recover" and press RET as fast as I can, I am always able to run recover-this-file'. I must sethelm-input-idle-delay' to a highest value (e.g 0.6) to make [display not ready] popping up.

Thierry Get my Gnupg key: gpg --keyserver pgp.mit.edu --recv-keys 59F29997

kini commented 10 years ago

Well, I don't know how more complete of a recipe I can give than what I wrote on #538. I run helm-M-x, I type "recover ", then I press "t" and the helm buffer becomes empty for a moment. Quickly, before the buffer becomes filled with the next completion list, I press RET. Then "[No match]" appears in the minibuffer, and the helm buffer remains empty forever. If I press SPC, then the helm buffer becomes filled with a completion list again.

Here is a video of what I did, including a display of what keystrokes Emacs recorded, at the end.

By the way, this is not caused by the boundary between patterns. I can produce the same effect by typing "r", then quickly "e" followed by RET.

kini commented 10 years ago

In fact, here is another video. I started emacs with emacs-helm.sh provided in the helm repo, so you can be sure that none of my other customizations cause the bug. Also I reduced the problem instance further, making the bug appear simply by doing M-x x RET.

thierryvolpiatto commented 10 years ago

Keshav Kini notifications@github.com writes:

In fact, here is another video. I started emacs with emacs-helm.sh provided in the helm repo, so you can be sure that none of my other customizations cause the bug. Also I reduced the problem instance further, making the bug appear simply by doing M-x x RET.

Hmm! Are you sure you have installed the last changes and compile properly ? (using make file) Don't you have a old copy of helm.el somewhere in your load-path ?

Once this checked, can you eval this:

(let ((helm-input-idle-delay 1))
(completing-read "test: " '("far" "fair" "fall" "fax") nil t))

Then type "fa" and wait for update. Now type very fast "i" RET

What happen ?

Now instead type "za" RET very fast

what happen ?

Now instead type "za" wait for display and type RET

what happen ?

Thierry Get my Gnupg key: gpg --keyserver pgp.mit.edu --recv-keys 59F29997

kini commented 10 years ago

On 06/25/2014 09:24 PM, Thierry Volpiatto wrote:

Hmm! Are you sure you have installed the last changes and compile properly ? (using make file) Don't you have a old copy of helm.el somewhere in your load-path ?

I am using the latest version.

Once this checked, can you eval this:

(let ((helm-input-idle-delay 1)) (completing-read "test: " '("far" "fair" "fall" "fax") nil t))

Then type "fa" and wait for update. Now type very fast "i" RET

What happen ?

The text "[Display not ready]" appears in the minibuffer. After half a second, the text in the minibuffer now says "test: fai". After another half a second, the helm buffer updates to show only "fair". Now if I hit RET again, it returns "fair".

Now instead type "za" RET very fast

what happen ?

The text "[Display not ready]" appears in the minibuffer. After half a second, the text in the minibuffer now says "test: za". After another half a second, the helm buffer becomes empty. Now if I hit RET again, it says "[No match]" for half a second, and the helm buffer remains empty.

Now instead type "za" wait for display and type RET

what happen ?

The text "[No match]" appears in the minibuffer. After half a second it goes away and the minibuffer says "test: za". The helm buffer remains empty throughout.

By the way, I also tried to reproduce my problem by evaluating this:

(completing-read "test: " '("far" "fair" "fall" "fax") nil t)

i.e. without increasing helm-input-idle-delay, and typing x RET. In this situation I couldn't produce the "[No match]" text. Every time it would return "fax" (which is the correct behavior). But I can still produce "[No match]" from helm-M-x and x RET as shown in the video.

thierryvolpiatto commented 10 years ago

Keshav Kini notifications@github.com writes:

i.e. without increasing helm-input-idle-delay, and typing x RET. In this situation I couldn't produce the "[No match]" text. Every time it would return "fax" (which is the correct behavior). But I can still produce "[No match]" from helm-M-x and x RET as shown in the video.

That's strange I can't reproduce, but well when you stop typing and wait, recover-this-file appear in helm-buffer right ?

Thierry Get my Gnupg key: gpg --keyserver pgp.mit.edu --recv-keys 59F29997

michael-heerdegen commented 10 years ago

Keshav Kini notifications@github.com writes:

But I can still produce "[No match]" from helm-M-x and x RET as shown in the video.

I also see this. I hit M-x (bound here to helm-M-x), and then x RET in fast succession, and get [No match]. I have to be very fast to get this.

I replaced

(minibuffer-message " [No match]")

with (debug) in helm-confirm-and-exit-minibuffer, and reproduced. The debugger pops up using the recipe. I can verify that (helm--updating-p) returns nil, but the completions buffer is empty. Seems helm--updating-p does not return non-nil in every case where we expect.

thierryvolpiatto commented 10 years ago

michael-heerdegen notifications@github.com writes:

Keshav Kini notifications@github.com writes:

But I can still produce "[No match]" from helm-M-x and x RET as shown in the video.

I also see this. I hit M-x (bound here to helm-M-x), and then x RET in fast succession, and get [No match]. I have to be very fast to get this.

I replaced

(minibuffer-message " [No match]")

with (debug) in helm-confirm-and-exit-minibuffer, and reproduced. The debugger pops up using the recipe. I can verify that (helm--updating-p) returns nil, but the completions buffer is empty. Seems helm--updating-p does not return non-nil in every case where we expect.

I have commited another change in exp branch, can you try ? Thanks.

Thierry Get my Gnupg key: gpg --keyserver pgp.mit.edu --recv-keys 59F29997

thierryvolpiatto commented 10 years ago

Try to play with new var helm-exit-idle-delay until you have what is expected.

michael-heerdegen commented 10 years ago

Thierry Volpiatto notifications@github.com writes:

I have commited another change in exp branch, can you try ? Thanks.

It fixes the M-x x RET case for me. Maybe kini can also make some tests.

Thierry, why does helm-exit-idle-delay have to be > 0 at all?

thierryvolpiatto commented 10 years ago

michael-heerdegen notifications@github.com writes:

Thierry Volpiatto notifications@github.com writes:

I have commited another change in exp branch, can you try ? Thanks.

It fixes the M-x x RET case for me.

Great, thanks.

Maybe kini can also make some tests.

Thierry, why does helm-exit-idle-delay have to be > 0 at all?

This ensure the user can see what he is about to select, it also ensure display is really ready, but you can play with this value as you want, just remember this value is used in an idle timer.

Thierry Get my Gnupg key: gpg --keyserver pgp.mit.edu --recv-keys 59F29997

michael-heerdegen commented 10 years ago

I see. Then it looks like a good change to me.

michael-heerdegen commented 10 years ago

But .3 sometimes bites me - and I don't type fast - e.g. for M-x gnus RET. I guess lots of people will want a smaller value, and a lot may even prefer 0. If I'm not sure what I'll get, I can just wait with confirming.

thierryvolpiatto commented 10 years ago

michael-heerdegen notifications@github.com writes:

But .3 sometimes bites me - and I don't type fast - e.g. for M-x gnus RET. I guess lots of people will want a smaller value, and a lot may even prefer 0.

I don't type fast at all me too, so I test only with the last letter and RET, so this way I am able to go very fast, and under 0.2, I am unable to get "[display not ready]" when I type "x" after "fa", I exit immediately with "fax":

(let ((helm-exit-idle-delay 0.2)) (completing-read "test: " '("far" "fair" "fall" "fax") nil t))

(I never been able to see the behavior you and kini describe with M-x x RET with a value <= 0.2)

So it's why I used 0.3 as default value (a little more to be sure). But well, now it is implemented and working, we can wait and see what other people think of this value ? Probably 0.3 is too much so we can start at 0.2 ?

If I'm not sure what I'll get, I can just wait with confirming.

Not sure what you mean with confirming, note that what you saw with M-x under ./emacs-helm.sh (i.e [No match]) will happen only in source build with helm-mode and a completing-read using a "REQUIRE-MATCH", or like helm-M-x commands using helm-comp-read with ":must-match", otherwise you do not have such a second protection and exit immediately with the first candidate computed (or not yet) by helm.

Thierry Get my Gnupg key: gpg --keyserver pgp.mit.edu --recv-keys 59F29997

michael-heerdegen commented 10 years ago

I understand. Ok, let's see what others think.

kini commented 10 years ago

With the latest code from master, I am no longer able to get "[No match]" with M-x x RET. If I type fast enough, I get "[Display not ready]", and the completion buffer fills with things that have "x" in them. But if I type really fast, I get "[Display not ready]", and the completion buffer remains empty even if I continue to wait.

If it helps, I tried evaluating this:

(let ((helm-exit-idle-delay 0)) (helm-M-x))

Then I type x RET, and if I'm fast enough, I'm still able to reproduce the blank completion buffer which never fills. So it's unrelated to the value of helm-exit-idle-delay.

kini commented 10 years ago

(I should mention that it is much harder to get the blank completion buffer now. I have to try several times before I'm able to get it to happen.)

michael-heerdegen commented 10 years ago

You're right.

BTW when I set helm-exit-idle-delay to 0, and type M-x x RET extremely fast, I even sometimes still get [No match].

I think the culprit is the usage of throw-on-input in helm. It kicks us out the the calculation even for RET and when we do nothing. I guess that's why the candidates buffer remains empty.