haskell-mode
haskell-mode copied to clipboard
Autocompletion in REPL in multiline mode hangs Emacs
I like to work in multiline mode with auto-complete, and have noticed the following bug: when I press TAB to complete a word, the entire Emacs session hangs. I have not found anything that mitigates the issue, short of restarting Emacs.
What is multiline mode?
Multiline mode is a GHCi mode in which one can insert statements over multiple lines. It is activated by using ":set +m" in the GHCi prompt.
Oh boy. I do not think anybody thought about mixing this one...
Note that interactive-haskell-mode interacts with GHCi as a subprocess when inferior-haskell-mode interacts wih GHCi as a subshell (with terminal capabilities). I guess this might be the reason multiline does not work as it should.
I did some research.
- start a new session for some haskell project
- now REPL completions is available when editing Haskell files
- go to REPL buffer
- enter multi-line editing mode: type
:{
hit RET - go back to Haskell file you edited before
- now completions is not available
Likely, all this is because when REPL in multi-line mode doesn't evaluate received commands and doesn't produce output, that is it's waiting :}
to leave multi-line mode. And this is a pitfall.
I see few ways for now:
- do not complete things when REPL is in multi-line edit mode
- implement timeout argument for async REPL calls
- split REPL somehow into several process threads, one for direct user interaction and another for internal purposes
- implement another way for multi-line editing.
Options 1-3 do not seem good to me. As for last option, first I want to mention few things about multi-line edit in GHCi itself:
- when you entered a single line it is not possible to change it, this is pain if you tend to write 10+ lines of code and made typo somewhere (in this case you have to re-type everything again)
- TAB-completions work in multi-line mode in GHCi
Here is my thoughts: when user hits RET examine input to determine that user is tended to enter multi-line editing mode. Open special temporal buffer where user can enter the code, allowing to easily navigate across lines and changing them; bind C-c C-c to finish editing, C-c C-k to cancel, and optionally something else to test input (e.g. send buffer contents to REPL and notify is it OK or not). Optionally enable syntax highlight and completions in this buffer.
Another less comfortable way would be: change prompt to indicate multi-line editing mode but do not send :{
to REPL, rather start collecting lines that user type in some session variable. When user enters newline do not send it to REPL immediately, rather collect it. When user finished (e.g. entered :}
) send everything that was collected to REPL.
Hmm, so basically haskell-mode would need to track if GHCi is currently in mulitline mode by checking when it enters multiline mode and when it exits multiline mode.
This is too much to ask for.
Solution for now is:
- do not use multiline mode with GHCi
- start using haskell-ide-engine when it is ready
I'm sorry but we have too much work in other places of haskell-mode to support multiline mode.
@gracjan let's keep this open as a reminder. I have many thoughts about interactive Haskell improvements (and going to spend some time on it).
Just add some labels such as milestone infinity or won't be fixed in near future.
We can reopen anytime anybody has something useful to add. Resolution for now is that we aren't going to implement this, sadly it is too much.
I'm no longer sure we should not take care of this. There are too many reports from people hitting this problem to ignore it outright.
it killed a few of my editing sessions tonight.
The problem is, the emacs workflow is so good, that it's not really necessary to keep a terminal open at all. So is is a bit annoying when things don't work.
In the meantime, is there a clean way to prevent the user entering multi-line mode? give a warning message and abort the command?
@shanemikel: Have you manually entered multiline mode?
You mean in the repl with :{
? Sure, is there another way?
Of course, at this point, I could keep myself from doing that, but discovering the bug was a bit unpleasant; I'm trying to help other users.
I see. I just thought for a moment that haskell-mode somehow triggers multiline mode by itself.
I also get occasional hanging in other circumstances. Sometimes, when moving to a previous line and trying to edit it (before hitting return, which copies the line to the last prompt), after entering a few characters, the repl hangs. Even in the case of the repl process failing to respond (or taking it's time), the interactive interface should echo, right?
Should. Now somebody needs to find out what made it hang.
There is this magic: https://github.com/haskell/haskell-mode/blob/be9044b2e633b9342a68f762d07e82fe9ababf5f/haskell-interactive-mode.el#L254
This means that by using C-j one can have multiline command like this:
λ> let x = 1
y = 3
it will be wrapped in :{
and }:
and send to GHCi like this:
:{
let x = 1
y = 3
:}
Note that this is not documented and does not really work due to misaligned indentation.
Just got hit by this issue. Is there anything new?
Just got hit by this issue. Is there anything new?
Hey, haven't used emacs
for several years. Sorry, can't help right now and quickly enough.