I want to be able to prompt the user for input (let's say a FilePath
), but also to offer a mutable/interactive string as a default, so instead of having the user type the full path, I can prompt with:
C:\Users\John\project\test
and have them be able to backspace 4 times and enter final
to yield C:\Users\John\project\final
, rather than type the entire path.
However printing a default string with putStr
or System.IO.hPutStr stdout
does print this default to the terminal, but does not allow me to alter any of it. E.g.
import System.IO
main = do
hSetBuffering stdout NoBuffering
putStr "C:\\Users\\John\\project\\test"
l <- getLine
doSomethingWith l
I suspect Data.Text.IO
's interact
may be able to do what I want but I could not get it to work.
Any suggestions would be greatly appreciated.
CodePudding user response:
getLine
doesn’t offer any facility for line editing. For this you can use a library like haskeline
instead, for example:
import System.Console.Haskeline
main :: IO ()
main = do
runInputT defaultSettings $ do
mInput <- getInputLineWithInitial "Enter path: "
("C:\\Users\\John\\project\\test", "")
case mInput of
Nothing -> do
outputStrLn "No entry."
Just input -> do
outputStrLn $ "Entry: " show input
An alternative is to invoke the program with a wrapper that provides line editing, such as rlwrap
. For building a more complex fullscreen text UI, there is also brick
, which provides a simple text editing component in Brick.Widgets.Edit
.