Ticket #112 (new enhancement)

Opened 4 years ago

Last modified 3 months ago

Multi-line prompt

Reported by: judah Owned by:
Priority: minor Milestone:
Version: Keywords:
Cc: acfoltzer@…, keshav.kini@…

Description

For ghci, it would be useful to have a mode which lets the user edit multiple lines at once. See:

http://hackage.haskell.org/trac/ghc/ticket/3984

http://hackage.haskell.org/trac/ghc/ticket/4316

Attachments

getMultiLine.patch (8.0 kB) - added by vivian 4 years ago.
getMultiLine method

Change History

Changed 4 years ago by judah

My initial thoughts: we could add a new action

getMultiLine :: [String] -> InputT m [String]

where the input to the function is the initial text to be edited.

However, what the ghci tickets are trying to achieve is that the user enters a single line of text, ghci notices via layout rules that the line is incomplete, and continues it in a multi-line input. If you used getInputLine followed by getMultiLine, the first row would be repeated, which is probably not the best UI. So getInputLine and getMultiLine would have to interact, and I'm not sure how that could work without making things much more complicated.

Changed 4 years ago by vivian

You could pass a function that tells you whether it needs another line:

getMultiLine :: Monad m => (String -> m Bool) -> InputT m [String]
getMultiLine test = do
  input <- getInputLine
  another <- lift $ test input
  if another
    then do
      rest <- getMultiLine test
      return $ input : rest
    else return input

This would help with an issue with GHC #4316 in that we might want to merge the strings into one history entry. That also introduces the issue of haskeline presenting multiline commands (those containing "\n") from the history.

Changed 4 years ago by vivian

This patch makes no attempt to provide a method to navigate/edit a multiline history entry. (I couldn't even find where pushing the up arrow displays history items).

Changed 4 years ago by vivian

getMultiLine :: MonadException m =>
             -> ([String] -> m (Bool,String))  -- ^ True to continue requesting lines
                                               --   initially called with `[]' for first prompt
             -> (String -> InputT m (Maybe String)) -- ^ prompt -> action to get another line 
             -> InputT m [String]
getMultiLine test getLine = do
  hs <- go []
  maybeAddHistory (Just $ concat $ intersperse ['\n'] hs)
  return hs
  where 
  go previous = do
    (another,prompt) <- lift $ test previous
    if another
      then do
        mb_input <- getLine prompt
        case mb_input of
          Nothing -> return previous
          Just input -> go $ previous ++ [input]
    else return previous

Changed 4 years ago by vivian

getMultiLine method

Changed 2 years ago by acfoltzer

  • cc acfoltzer@… added

Changed 3 months ago by kini

  • cc keshav.kini@… added
Note: See TracTickets for help on using tickets.