预先填写的用户输入

时间:2017-11-07 10:30:58

标签: haskell io

我打算为逐行文件编辑编写一个简单的程序。除了删除和替换行之外,该程序的基本形式(我知道我可以做)将允许用户在文件中添加,插入和追加行。

行替换操作将要求用户在stdin中写入行的所有期望内容,但如果新行与旧行充分相似,则这是繁琐的。理想情况下,他们会有添加选项来编辑该行。用户输入将预先填充行的旧内容,允许他们修改此行而不是输入整个行。

我理解常规getLine函数无法解释除退格之外的箭头按键或其他元键,因此这可能是一个比表面看起来更复杂的问题;但如果有这种操作的预先存在的功能或库,我将非常感激。

如果有帮助,所需的类型如下:

editLine :: String -> IO String

2 个答案:

答案 0 :(得分:4)

编辑输入行和类似功能通常在POSIX世界中由readline library提供,并搜索" haskell readline"如果您想了解更多信息,那将是一个很好的起点。

在Haskell中,haskeline包提供了类似的功能。

您的用例的功能是getInputLineWithInitial

getInputLineWithInitial
    :: MonadException m  
    => String                  -- ^ The input prompt
    -> (String, String)        -- ^ The initial value left and right of the cursor
    -> InputT m (Maybe String)

您可以使用runInputTInputT IO值转换为IO

runInputT defaultSettings :: InputT IO a -> IO a

答案 1 :(得分:2)

建立@Koterpillar的答案,这里是问题中指定的editLine的实现,以及稍微更通用(但同样强大)的功能:

import System.Console.Haskeline (InputT, runInputT, getInputLineWithInitial, defaultSettings)

editLine :: String -> IO String
editLine = getLinePrefill ""

-- getLinePrefill prompt = (putStr prompt >>) . editLine
getLinePrefill :: String -> String -> IO String
getLinePrefill prompt fill = line
    where
        -- no line == empty line
        line :: IO String
        line = concat <$> maybeLine

        -- run the InputT monad
        maybeLine :: IO (Maybe String)
        maybeLine = runInputT defaultSettings $ inputLine

        -- Get input line, prompt as supplied, default-string to the left of mouse
        inputLine :: InputT IO (Maybe String)
        inputLine = getInputLineWithInitial prompt (fill, "")