2

How does one use ansi-wl-pprint with haskeline, without losing Windows support?

ansi-wl-pprint has two ways to output a SimpleDoc:

(\doc -> displayS doc "") :: SimpleDoc -> String
displayIO stdout :: SimpleDoc -> IO ()

However, the documentation warns that displayS does not work on Windows (cmd.exe doesn't implement ANSI escape sequences?).

displayIO doesn't use haskeline's print functions, however:

outputStr :: MonadIO m => String -> InputT m ()
outputStrLn :: MonadIO m => String -> InputT m ()
getExternalPrint :: MonadException m => InputT m (String -> IO ())

The closest thing to a solution I can see right now is:

outputPretty :: (MonadException m, MonadIO m, Pretty p) => p -> InputT m ()
outputPretty p = getExternalPrint >>= doPrint 
  where doc = renderPretty 0.4 80 $ pretty p
        doPrint print = liftIO . print $ displayS doc ""

However, if displayS doesn't work on Windows, I'd prefer not to use it.

Nathan Ringo
  • 973
  • 2
  • 10
  • 30
  • `displayS` will work on Windows only if the terminal supports it and `ansi-terminal` is able to detect that fact. This is also true of `displayIO`, the difference being that `displayIO` lives in `IO` and so can more aggressively attempt to cajole whatever `Handle` you've given it into a form where the ANSI code will work. Whether either one works in practice is a matter of exactly how you end up using your program. – user2407038 Aug 27 '17 at 02:40
  • Anyways, if you want the best chance of things working, you should probably write your own display function - it will be like [`displayIO`](https://hackage.haskell.org/package/ansi-wl-pprint-0.6.8.1/docs/src/Text-PrettyPrint-ANSI-Leijen-Internal.html#displayIO), but replacing calls with `hPutStr` with the print function given to you by haskeline. – user2407038 Aug 27 '17 at 02:42
  • I thought the issue was that if the user enters input when an SGR is set, there'll be garbling; I don't think that'll be fixed by reimplementing `displayIO`, right? – Nathan Ringo Aug 27 '17 at 02:46
  • `hSetSGR` is already checking if it will actually work; if that check happens to be a false positive, there is nothing you can really do to prevent garbling (this problem isn't related to haskeline at all). I suppose you could have a flag to explicitly disable `hSetSGR`, to be very sure you can avoid garbling if you happen to be using a terminal which won't support ANSI codes, but for which the checks done by `ansi-terminal` are likely to be false positives. – user2407038 Aug 27 '17 at 03:03
  • I can try to reproduce the issue I can foresee happening on Monday, but I'm still pretty sure that the user's input could still get mis-styled as a result of mixing the two. – Nathan Ringo Aug 27 '17 at 03:08
  • Indeed, a minimal verifiable example complete with the environment in which you run it is a much more concrete question than this current one. The behaviour of the functions in question is extremely sensitive to the environment they run in, so there simply isn't a solution which will work in every possible situation. – user2407038 Aug 27 '17 at 03:13

0 Answers0