haskell / haskeline

A Haskell library for line input in command-line programs.
https://hackage.haskell.org/package/haskeline
BSD 3-Clause "New" or "Revised" License
221 stars 75 forks source link

Quick fix for operator completions GHC Trac issue #23

Closed geraldus closed 9 years ago

geraldus commented 9 years ago

For more details see issue #10576 https://ghc.haskell.org/trac/ghc/ticket/10576

I've tested this with GHC head build, here is some results:

GHCi, version 7.11.20150630: http://www.haskell.org/ghc/  :? for help
Prelude> :complete repl "ma"
8 8 ""
"map"
"mapM"
"mapM_"
"mappend"
"max"
"maxBound"
"maximum"
"maybe"
Prelude> :complete repl "map con"
3 3 "map "
"concat"
"concatMap"
"const"
Prelude> :complete repl ">>"
2 2 ""
">>"
">>="
Prelude> :complete repl "(>>"
2 2 "("
">>"
">>="
Prelude> :complete repl "m>>"
0 0 ""
Prelude> :complete repl ">>m"
14 14 ">>"
"map"
"mapM"
"mapM_"
"mappend"
"max"
"maxBound"
"maximum"
"maybe"
"mconcat"
"mempty"
"min"
"minBound"
"minimum"
"mod"
Prelude> :complete repl "map con >>"
2 2 "map con "
">>"
">>="

Note, that in case of empty input or only whitespace input it still will return all imported names, but I suppose this is different issue.

Also, operator symbols also could be any [non-ascii] Unicode symbol or punctuation, but this stuff is unsupported.

geraldus commented 9 years ago

@judah well, this sounds reasonable for me, I'm just too new to GHC codebase. I can take care about this stuff, but need some clarification.

Let me briefly repeat what's happening. The entry point is ghciCompleteWord function. It takes a line, and searching completions for its last word. The point of interest is last case, where completeExpression function called for whole line. The latter uses completeQuotedWord function. It tries to get file path completions first if expression is quoted with " (I didn't understood this well), and in other case it uses completeIdentifier function. Finally, completeIdentifier uses wrapIdentCompleter function which is the crux of the matter.

Now I'm confused a bit, completeIdentifier function is used a lot in other places, for example in ghciCommands function, I didn't find Command definition yet, but I suspect that the third element of tuple is a completion function to be used with that command (and that's why there is listFiles used internally, because some commands expect path as input also). So it is possible to write a new function for a specific use case, but I believe that completeIndentifier should be fixed itself, for example when I type :info >> in REPL and hit Tab it shows me all imported names too, likely this is not expected bahaviour.

What do you think, what can you suggest?

Pinging @hvr , can you please review this discussion also?

judah commented 9 years ago

Command is defined in ghc/GhciMonad.hs; as you guessed, the third element is a CompletionFunc.

You're right that we need to change this for more than just expressions (e.g. :info, :type), and the right fix might be to change completeIdentifier itself as you've suggested. You just need to be careful that this doesn't affect the word-breaking behavior of other completers like, for example, completeSetModule, which tab-completes ":module +" or ":module -" to a list of module names. But since that's handled by a separate function (wrapIdentCompleterWithModifier) it might be fine regardless.

Let me know if you'd like any other pointers in the code or run into any other problems getting this working.

geraldus commented 9 years ago

Ok, after some delay I've finally figured out most important things for me, let's close this, because I have to continue with Phab again.