Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

company-mode is eating keystrokes when showing preview for a single candidate (using company-ghc) #226

Closed
unthingable opened this issue Nov 8, 2014 · 20 comments

Comments

@unthingable
Copy link

When typing moderately fast, around the time preview is shown, a character often doesn't make it.

Example: slowly typing readf triggers a preview ile. When typing fast enough, I usually end up with readfle.

Using company-ghc backend, if that makes any difference.

@unthingable unthingable changed the title company-mode is eating keystrokes when showing preview company-mode is eating keystrokes when showing preview for a single candidate Nov 8, 2014
@dgutov
Copy link
Member

dgutov commented Nov 8, 2014

What's your OS, Emacs and Company versions?

I've never seen the behavior you're describing. Can you reproduce it with, say, company-dabbrev (try a text-mode buffer)?

@unthingable
Copy link
Author

OSX 10.9.5, Emacs 24.4 (9.0), company-20141107.552, company-ghc-20141030.704

In text-mode it seems fine, but in haskell-mode it's reproducible fairly reliably. Curiously, it's happening to a completion inside a function, but not outside:

readConfig prefix dir = do
  files <- getDirectoryContents dir
  readfle
  readile

readfile
readfile
readfile

I would guess there is extra work happening, trying to guess types and what not, and somehow it's affecting the echoing behavior.

UPD: this stops when company-ghc is not in the list of backends, so that guess is at least dubious.

@unthingable unthingable changed the title company-mode is eating keystrokes when showing preview for a single candidate company-mode is eating keystrokes when showing preview for a single candidate (using company-ghc) Nov 8, 2014
@unthingable
Copy link
Author

A trace, the "i" is being lost:

1 -> (company-ghc-candidates #("read" 0 4 (fontified t)))
1 <- company-ghc-candidates: (#("readable" 0 1 (:module "System.Directory")) #("readfile" 0 1 (:module #1="Data.ConfigFile")) #("readhandle" 0 1 (:module #1#)) #("readstring" 0 1 (:module #1#)))
======================================================================
1 -> (company-ghc-prefix)
1 <- company-ghc-prefix: #("readf" 0 5 (fontified nil))
======================================================================
1 -> (company-ghc-prefix)
1 <- company-ghc-prefix: #("readfl" 0 6 (fontified nil))
======================================================================
1 -> (company-ghc-prefix)
1 <- company-ghc-prefix: #("readfle" 0 7 (fontified t))
======================================================================
1 -> (company-ghc-candidates #("readfle" 0 7 (fontified t)))
1 <- company-ghc-candidates: nil

Same with trace enabled on company-ghc:

======================================================================
1 -> (company-ghc prefix)
| 2 -> (company-ghc-prefix)
| 2 <- company-ghc-prefix: #("re" 0 2 (fontified t))
1 <- company-ghc: #("re" 0 2 (fontified t))
======================================================================
1 -> (company-ghc prefix)
| 2 -> (company-ghc-prefix)
| 2 <- company-ghc-prefix: #("read" 0 4 (fontified t))
1 <- company-ghc: #("read" 0 4 (fontified t))
======================================================================
1 -> (company-ghc ignore-case)
1 <- company-ghc: nil
======================================================================
1 -> (company-ghc candidates #("read" 0 4 (fontified t)))
| 2 -> (company-ghc-candidates #("read" 0 4 (fontified t)))
| 2 <- company-ghc-candidates: (#("readable" 0 1 (:module "System.Directory")) #("readfile" 0 1 (:module #1="Data.ConfigFile")) #("readhandle" 0 1 (:module #1#)) #("readstring" 0 1 (:module #1#)))
1 <- company-ghc: (#("readable" 0 1 (:module "System.Directory")) #("readfile" 0 1 (:module #1="Data.ConfigFile")) #("readhandle" 0 1 (:module #1#)) #("readstring" 0 1 (:module #1#)))
======================================================================
1 -> (company-ghc sorted)
1 <- company-ghc: t
======================================================================
1 -> (company-ghc duplicates)
1 <- company-ghc: nil
======================================================================
1 -> (company-ghc ignore-case)
1 <- company-ghc: nil
======================================================================
1 -> (company-ghc annotation #("readable" 0 1 (:module "System.Directory")))
1 <- company-ghc: " System.Directory"
======================================================================
1 -> (company-ghc annotation #("readfile" 0 1 (:module "Data.ConfigFile")))
1 <- company-ghc: " Data.ConfigFile"
======================================================================
1 -> (company-ghc annotation #("readhandle" 0 1 (:module "Data.ConfigFile")))
1 <- company-ghc: " Data.ConfigFile"
======================================================================
1 -> (company-ghc annotation #("readstring" 0 1 (:module "Data.ConfigFile")))
1 <- company-ghc: " Data.ConfigFile"
======================================================================
1 -> (company-ghc ignore-case)
1 <- company-ghc: nil
======================================================================
1 -> (company-ghc match #("readable" 0 1 (:module "System.Directory")))
1 <- company-ghc: nil
======================================================================
1 -> (company-ghc ignore-case)
1 <- company-ghc: nil
======================================================================
1 -> (company-ghc match #("readfile" 0 1 (:module "Data.ConfigFile")))
1 <- company-ghc: nil
======================================================================
1 -> (company-ghc ignore-case)
1 <- company-ghc: nil
======================================================================
1 -> (company-ghc match #("readhandle" 0 1 (:module "Data.ConfigFile")))
1 <- company-ghc: nil
======================================================================
1 -> (company-ghc ignore-case)
1 <- company-ghc: nil
======================================================================
1 -> (company-ghc match #("readstring" 0 1 (:module "Data.ConfigFile")))
1 <- company-ghc: nil
======================================================================
1 -> (company-ghc meta #("readable" 0 1 (:module "System.Directory")))
1 <- company-ghc: nil
======================================================================
1 -> (company-ghc no-cache #("read" 0 4 (fontified t)))
1 <- company-ghc: nil
======================================================================
1 -> (company-ghc prefix)
| 2 -> (company-ghc-prefix)
| 2 <- company-ghc-prefix: #("readf" 0 5 (fontified nil))
1 <- company-ghc: #("readf" 0 5 (fontified nil))
======================================================================
1 -> (company-ghc ignore-case)
1 <- company-ghc: nil
======================================================================
1 -> (company-ghc ignore-case)
1 <- company-ghc: nil
======================================================================
1 -> (company-ghc annotation #("readfile" 0 1 (:module "Data.ConfigFile")))
1 <- company-ghc: " Data.ConfigFile"
======================================================================
1 -> (company-ghc ignore-case)
1 <- company-ghc: nil
======================================================================
1 -> (company-ghc match #("readfile" 0 1 (:module "Data.ConfigFile")))
1 <- company-ghc: nil
======================================================================
1 -> (company-ghc ignore-case)
1 <- company-ghc: nil
======================================================================
1 -> (company-ghc meta #("readfile" 0 1 (:module "Data.ConfigFile")))
1 <- company-ghc: nil
======================================================================
1 -> (company-ghc ignore-case)
1 <- company-ghc: nil
======================================================================
1 -> (company-ghc no-cache #("readf" 0 5 (fontified nil)))
1 <- company-ghc: nil
======================================================================
1 -> (company-ghc prefix)
| 2 -> (company-ghc-prefix)
| 2 <- company-ghc-prefix: #("readfl" 0 6 (fontified nil))
1 <- company-ghc: #("readfl" 0 6 (fontified nil))
======================================================================
1 -> (company-ghc ignore-case)
1 <- company-ghc: nil
======================================================================
1 -> (company-ghc require-match)
1 <- company-ghc: nil
======================================================================
1 -> (company-ghc require-match)
1 <- company-ghc: nil
======================================================================
1 -> (company-ghc prefix)
| 2 -> (company-ghc-prefix)
| 2 <- company-ghc-prefix: #("readfle" 0 7 (fontified t))
1 <- company-ghc: #("readfle" 0 7 (fontified t))
======================================================================
1 -> (company-ghc ignore-case)
1 <- company-ghc: nil
======================================================================
1 -> (company-ghc candidates #("readfle" 0 7 (fontified t)))
| 2 -> (company-ghc-candidates #("readfle" 0 7 (fontified t)))
| 2 <- company-ghc-candidates: nil
1 <- company-ghc: nil
======================================================================
1 -> (company-ghc sorted)
1 <- company-ghc: t
======================================================================
1 -> (company-ghc duplicates)
1 <- company-ghc: nil

@dgutov
Copy link
Member

dgutov commented Nov 8, 2014

This "9.0" bit looks suspicious. Is it "Emacs for MacOS X", or some such?

I haven't tried company-ghc personally, and the closest bug to this description I've seen mentioned is this: http://debbugs.gnu.org/cgi/bugreport.cgi?bug=18684

Can you reproduce this with a "bare" configuration, starting with emacs -Q and then maybe only adding company-ghc. Without the latter without be even better, of course.

Same with trace enabled on company-ghc:

The trace tells me that indeed it seems some keystrokes go missing, but not why, sorry.

@unthingable
Copy link
Author

Ah, that's how OSX reported the version. Emacs itself says it's 24.4.1. Same behavior in 24.3.50.1.

Same behavior in "bare" configuration.

It seems to happen only with both haskell-mode is active and using company-ghc backend (that is, company-ghc backend works fine in text-mode).

@dgutov
Copy link
Member

dgutov commented Nov 8, 2014

What about company-dabbrev in haskell-mode?

@unthingable
Copy link
Author

company-dabbrev in haskell-mode: no problems.

@unthingable
Copy link
Author

Also, scrolling through candidates with arrow keys, those seem to be getting dropped too.

@dgutov
Copy link
Member

dgutov commented Nov 8, 2014

Well then, let's see what @iquiw says.

@unthingable
Copy link
Author

OK, thanks for jumping on this so quickly.

I have found a fix of sorts, and perhaps narrowed it down: the problem seems to go away after removing company-echo-metadata-frontend from the list of frontends.

@dgutov
Copy link
Member

dgutov commented Nov 9, 2014

Hmm, if so, you should be able to reproduce this with another backend that defines meta, such as company-clang or company-gtags.

And here a self-contained attempt to reproduce this without company-mode:

(defun cool-post-command ()
  (when (sit-for .01)
    (message "cool cool cool")))

(add-hook 'post-command-hook 'cool-post-command)

(Try it in a separate Emacs session).

@iquiw
Copy link
Contributor

iquiw commented Nov 9, 2014

company-ghc's meta command communicates with external process ghc-modi, which can be slow.
I am not yet sure this is the cause of the problem though.
If so, I have a plan to avoid the communication with ghc-modi at meta command by iquiw/company-ghc#6

@dgutov
Copy link
Member

dgutov commented Nov 9, 2014

@iquiw So, can you reproduce this?

I looked at the wrong function (company-ghc-complete-by-hoogle instead of company-ghc), so the situation is more complex than the example above, with the process communication and all, but it seems like a genuine Emacs bug anyway, which should be dissected and reported.

@iquiw
Copy link
Contributor

iquiw commented Nov 9, 2014

I have not noticed the originally reported one.
But sometimes seen the scroll problem #226 (comment) (on Windows especially).

company-ghc's meta command calls ghc-sync-process through ghc-get-info.
https://github.com/kazu-yamamoto/ghc-mod/blob/master/elisp/ghc-process.el#L108-L123

@iquiw
Copy link
Contributor

iquiw commented Nov 11, 2014

I found the cause is discard-input in ghc-sync-process.
https://github.com/kazu-yamamoto/ghc-mod/blob/master/elisp/ghc-process.el#L120

So it is neither company-mode's nor Emacs's issue.

@dgutov, I am not sure how it can be solved, so would very much appreciate it if you could give me any advice.
Anyway, I will open an issue in ghc-mod later.

@dgutov
Copy link
Member

dgutov commented Nov 11, 2014

Obtaining process output synchronously is usually performed with accept-process-output, not sit-for. Here's an example: https://github.com/nonsequitur/inf-ruby/blob/master/inf-ruby.el#L500-L501

@iquiw
Copy link
Contributor

iquiw commented Nov 11, 2014

I reported the issue in ghc-mod.

@dgutov @unthingable Thank you!

@unthingable
Copy link
Author

@dgutov, sorry, I haven't had the time to try different backends as per your suggestion. If that's still needed, let me know.

@dgutov
Copy link
Member

dgutov commented Nov 11, 2014

@unthingable Nope, thank you.

@dgutov
Copy link
Member

dgutov commented Nov 24, 2014

This is more or less resolved.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants