Why is ghci not honouring my .haskeline?

I have, from many years ago, a ~/.haskeline file that let me do command-line editing in GHCi using vi keybindings:

completionType: ListCompletion
editMode: Vi

I’m getting back into this again, and the command-line editing in GHCi seems to be quite…well, odd. I thought it might be something to do with using stack ghci, but even when I run the binary given to me by stack exec -- which ghci (which gives me .stack/programs/x86_64-linux/ghc-tinfo6-9.8.2/bin/ghci) I still have the same issues.

Scrolling through the command history with up and down arrows works, and moving the cursor within a command line with the right and left arrow keys also works. But:

  • Typing Esc followed by k does bring up the previous command line, but apparently leaves me in insert mode: typing k again inserts a k at the start of the line. I need to type Esc, k again to switch to the command before that.
  • Neither l nor Esc,l move the cursor right in the current command line; the former inserts an l character and the latter gives me a visual bell, presumably indicating an error.

The file does seem to be read, since the Emacs-mode commands C-f and C-b to move forward and back in a line do work if I remove editMode: Vi and stop working when I put that line back again.

Am I missing some drastic change about how .haskeline works? The documentation seems to be the same as it was years ago; the UserPreferences page on the Wiki seems to be consistent with what I’m doing.

If it’s not obvious what’s gone wrong here, I’d appreciate hints on how to debug this.

2 Likes

Ok, I thought I might try some older versions of GHC and see if they work differently.

Using Stack resolver lts-18.28/ghc-8.10.7, the behaviour is slightly different: it now does not require me to use Esc,k to recall every previous command, but only the first, and after that j and k alone move up and down in the command history. Things are still otherwise broken, however.

Using Stack resolver lts-6.35/ghc-7.10.3 seems to work the same as 8.10.7.

I’m sure I must be missing something foolish here; this editMode: Vi behaviour really doesn’t make sense.

I found the problem: when I type Esc,j quickly, Haskeline seems to interpret this as a a terminal function key sequence; if I type Esc and then wait for a substantial fraction of a second, it goes into command mode and properly executes the Vi commands I type.

Looking through the wiki, I don’t see any obvious setting equivalent to readline’s set-keymap-timeout, and one would think that Esc followed by something that’s not a known terminal function key sequence would be interpreted as separate chars typed by the user anyway.

Any thoughts on fixing this? I could live without being able to use terminal function keys (e.g., arrow keys) at all, being the hard-core Vim user that I am, but that would still be somewhat inconvenient for people I’m pairing with.

Do you customize your prompt? I found this thread that smells similar: https://superuser.com/questions/1106545/why-would-esc-p-or-ctrl-p-not-work-in-one-terminal-but-work-in-all-the-others

I wonder if escape sequences are detected by reading the whole prompt and it needs to first rule out an escape sequence before deciding to go to command mode.

EDIT: also, this from the Haskeline wiki, just in case: ControlSequencesInPrompt · haskell/haskeline Wiki · GitHub