Search code examples
haskellread-eval-print-loopghci

Is there a simple way to access the REPL history (e.g. as a list) from within GHCi?


Other REPLs, e.g. Octave, have dedicated commands for browsing the command history. I find that quite handy (though whenever I use such a feature I ask myself, why didn't I properly define that command in a file in the first place?).

GHCi seems to have no such feature, and I think it probably shouldn't – such interactivity would make endevours like control from Emacs more troublesome than they are already.

However, it sounds like a rather trivial task to simply fetch the entire history, and then use ordinary Haskell to browse it. Has anything like that been implemented anywhere yet?


Solution

  • There's probably a better way to do this that's more cross-platform way that could be developed into a nice little package to load in a .ghci file or something, but the quick and dirty way using haskeline is pretty simple. You can just read in the ghci_history file for your system, mine is located at C:/Users/bheklilr/AppData/Roaming/ghc/ghci_history, but I believe on a *nix system it should be at ~/.ghci_history. Pick whichever is appropriate for your system.

    > import System.Console.Haskeline.History
    > hist <- fmap $ readHistory "path/to/ghci_history"
    > putStrLn $ unlines hist
    

    Unfortunately, at least for me, it seems that the history file is not updated until GHCi exits, so for a particular session hist should be the same (provided you only have one instance of GHCi). This is a pretty limited API in my opinion, I think it wouldn't be too hard to dump the history on each command or at least every couple commands, but this is not done.

    Alternatively, you can use CTRL-R and a handful of other commands to search your history, it's a lot more useful. It's especially useful because it'll search for matching subtext.