Search code examples
haskellread-eval-print-loophaskeline

How do I get the command history using Haskelline?


I can't seem to figure out how to get Haskeline to allow the user to use the arrow keys to go through command history.

I read Hackage and tried using Settings { complete = completeFilename, historyFile = Nothing, autoAddHistory = True } like the default they gave and that didn't work, I tried giving historyFile a value and then it would only save the first command I typed in and only after the program was quit, and none of the small tweaks I tried have helped. I can provide the rest of my code if it's relevant.


Solution

  • Not a full answer, but can you test the following minimal example:

    import System.Console.Haskeline
    
    main :: IO ()
    main = runInputT settings loop
      where
    
        loop = do
          getInputLine "> "
          loop
    
        settings = Settings
          { complete = completeFilename
          , historyFile = Just ".foo_history"
          , autoAddHistory = True }
    

    You should be able to enter multiple input lines at the prompt and scroll through the history with the arrow keys:

    $ runghc Line.hs
    > foo
    > bar
    > baz
    > [use arrow keys here]
    

    If you Ctrl-C out after entering some lines, they should all appear in the ".foo_history" file:

    > [Ctrl-C]
    
    $ cat .foo_history 
    baz
    bar
    foo
    

    If the arrow keys don't work, try the Emacs-compatible keystrokes (Ctrl-P and Ctrl-N for previous and next).

    Based on this:

    • If this minimal example also fails to work correctly, then the problem is most likely that Haskeline is failing to work correctly with whatever your "terminal" is. (If neither arrow keys nor Ctrl-P/Ctrl-N work, then it probably doesn't think you're using a terminal at all; if the arrow keys don't work but Ctrl-P/Ctrl-N do, then it thinks you're using a terminal, but it's misidentifying the type of terminal). If this is the case, can you provide additional detail about what architecture you're running under (Linux, Windows, etc.) and how you're invoking the program (in a regular terminal, via an IDE console, or some other way).
    • If this minimal example works correctly but your program doesn't, then there's probably something wrong with your program. In this case, it would be helpful to have a minimal, standalone, and runnable example that illustrates the problem. Some possible things to check would be: Are you using any history-related functions (e.g., putHistory or modifyHistory) that might be interfering with Haskeline's automatic history handling? If not, is it possible your program is trying to read from the standard input through functions other than Haskeline's getInputLine, and maybe "stealing" some of the input that should be processed by Haskeline (e.g., if you meant to read something from a file but accidentally ran getLine instead of hGetLine)?