    {-# LANGUAGE DeriveDataTypeable         #-}
    {-# LANGUAGE EmptyDataDecls             #-}
    {-# LANGUAGE FlexibleInstances          #-}
    {-# LANGUAGE GeneralizedNewtypeDeriving #-}
    {-# LANGUAGE LambdaCase                 #-}
    {-# LANGUAGE MultiParamTypeClasses      #-}
    {-# LANGUAGE OverloadedStrings          #-}
    {-# LANGUAGE ScopedTypeVariables        #-}
    {-# LANGUAGE TypeOperators              #-}
    {-# LANGUAGE TypeSynonymInstances       #-}
    {-# LANGUAGE UndecidableInstances       #-}
    {-# OPTIONS_HADDOCK show-extensions #-}
    {-# OPTIONS_GHC -fno-warn-orphans #-}

    -- |
    -- Module      :  Yi.Minibuffer
    -- License     :  GPL-2
    -- Maintainer  :  yi-devel@googlegroups.com
    -- Stability   :  experimental
    -- Portability :  portable
    --
    -- Functions working with the minibuffer.

    module Yi.MiniBuffer ( spawnMinibufferE, withMinibufferFree, withMinibuffer
                         , withMinibufferGen, withMinibufferFin, noHint
                         , noPossibilities, mkCompleteFn, simpleComplete
                         , infixComplete, infixComplete', anyModeByName
                         , getAllModeNames, matchingBufferNames, anyModeByNameM
                         , anyModeName, (:::)(..), LineNumber, RegexTag
                         , FilePatternTag, ToKill, CommandArguments(..)
                         , commentRegion, promptingForBuffer
                         ) where

    import           Lens.Micro.Platform            (use, (%=))
    import           Control.Monad                  (forM, void, (<=<), (>=>))
    import           Data.Foldable                  (find, toList)
    import qualified Data.List.PointedList.Circular as PL (find, insertRight)
    import           Data.Maybe                     (catMaybes, fromJust, fromMaybe)
    import           Data.Proxy                     (Proxy)
    import           Data.String                    (IsString)
    import qualified Data.Text                      as T (Text, append, head,
                                                          isInfixOf, null, pack,
                                                          snoc, unpack, words)
    import           Data.Typeable                  (Typeable)
    import           System.CanonicalizePath        (replaceShorthands)
    import           Yi.Buffer
    import           Yi.Completion
    import           Yi.Config                      (modeTable)
    import           Yi.Core                        (runAction)
    import           Yi.Editor
    import           Yi.History                     (historyFinishGen, historyMove, historyStartGen)
    import           Yi.Keymap
    import           Yi.Keymap.Keys
    import           Yi.Monad                       (gets)
    import qualified Yi.Rope                        as R (YiString, fromText, toText)
    import           Yi.String                      (commonTPrefix)
    import           Yi.Style                       (defaultStyle)
    import           Yi.Window                      (bufkey)

    -- | Prompts for a buffer name, turns it into a 'BufferRef' and passes
    -- it on to the handler function. Uses all known buffers for hinting.
    promptingForBuffer :: T.Text -- ^ Prompt
                       -> (BufferRef -> YiM ()) -- ^ Handler
                       -> ([BufferRef] -> [BufferRef] -> [BufferRef])
                       -- ^ Hint pre-processor. It takes the list of open
                       -- buffers and a list of all buffers, and should
                       -- spit out all the buffers to possibly hint, in
                       -- the wanted order. Note the hinter uses name
                       -- prefix for filtering regardless of what you do
                       -- here.
                       -> YiM ()
    promptingForBuffer :: Text
    -> (BufferRef -> YiM ())
    -> ([BufferRef] -> [BufferRef] -> [BufferRef])
    -> YiM ()
    promptingForBuffer Text
    prompt BufferRef -> YiM ()
    act [BufferRef] -> [BufferRef] -> [BufferRef]
    hh = do
        openBufs <- (Window -> BufferRef) -> [Window] -> [BufferRef]
    forall a b. (a -> b) -> [a] -> [b]
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap Window -> BufferRef
    bufkey ([Window] -> [BufferRef])
    -> (PointedList Window -> [Window])
    -> PointedList Window
    -> [BufferRef]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . PointedList Window -> [Window]
    forall a. PointedList a -> [a]
    forall (t :: * -> *) a. Foldable t => t a -> [a]
    toList (PointedList Window -> [BufferRef])
    -> YiM (PointedList Window) -> YiM [BufferRef]
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Getting (PointedList Window) Editor (PointedList Window)
    -> YiM (PointedList Window)
    forall s (m :: * -> *) a. MonadState s m => Getting a s a -> m a
    use Getting (PointedList Window) Editor (PointedList Window)
    Lens' Editor (PointedList Window)
    windowsA
        names <- withEditor $ do
          bs <- toList . fmap bkey <$> getBufferStack
          let choices = [BufferRef] -> [BufferRef] -> [BufferRef]
    hh [BufferRef]
    openBufs [BufferRef]
    bs
          prefix <- gets commonNamePrefix
          forM choices $ \BufferRef
    k ->
            (Editor -> Text) -> EditorM Text
    forall s (m :: * -> *) a. MonadState s m => (s -> a) -> m a
    gets (Int -> FBuffer -> Text
    shortIdentString ([[Char]] -> Int
    forall a. [a] -> Int
    forall (t :: * -> *) a. Foldable t => t a -> Int
    length [[Char]]
    prefix) (FBuffer -> Text) -> (Editor -> FBuffer) -> Editor -> Text
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . BufferRef -> Editor -> FBuffer
    findBufferWith BufferRef
    k)
        withMinibufferFin prompt names (withEditor . getBufferWithName >=> act)

    -- | Prompts the user for comment syntax to use for the current mode.
    commentRegion :: YiM ()
    commentRegion :: YiM ()
    commentRegion =
      BufferM (Maybe (BufferM ())) -> YiM (Maybe (BufferM ()))
    forall (m :: * -> *) a. MonadEditor m => BufferM a -> m a
    withCurrentBuffer ((FBuffer -> Maybe (BufferM ())) -> BufferM (Maybe (BufferM ()))
    forall s (m :: * -> *) a. MonadState s m => (s -> a) -> m a
    gets ((FBuffer -> Maybe (BufferM ())) -> BufferM (Maybe (BufferM ())))
    -> (FBuffer -> Maybe (BufferM ())) -> BufferM (Maybe (BufferM ()))
    forall a b. (a -> b) -> a -> b
    $ (forall syntax. Mode syntax -> Maybe (BufferM ()))
    -> FBuffer -> Maybe (BufferM ())
    forall a. (forall syntax. Mode syntax -> a) -> FBuffer -> a
    withMode0 Mode syntax -> Maybe (BufferM ())
    forall syntax. Mode syntax -> Maybe (BufferM ())
    modeToggleCommentSelection) YiM (Maybe (BufferM ()))
    -> (Maybe (BufferM ()) -> YiM ()) -> YiM ()
    forall a b. YiM a -> (a -> YiM b) -> YiM b
    forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= \case
        Maybe (BufferM ())
    Nothing ->
          Text -> (Text -> YiM ()) -> YiM ()
    withMinibufferFree Text
    "No comment syntax is defined. Use: " ((Text -> YiM ()) -> YiM ()) -> (Text -> YiM ()) -> YiM ()
    forall a b. (a -> b) -> a -> b
    $ \Text
    cString ->
            BufferM () -> YiM ()
    forall (m :: * -> *) a. MonadEditor m => BufferM a -> m a
    withCurrentBuffer (BufferM () -> YiM ()) -> BufferM () -> YiM ()
    forall a b. (a -> b) -> a -> b
    $ do
              let toggle :: BufferM ()
    toggle = YiString -> BufferM ()
    toggleCommentB (Text -> YiString
    R.fromText Text
    cString)
              BufferM () -> BufferM ()
    forall (f :: * -> *) a. Functor f => f a -> f ()
    void BufferM ()
    toggle
              (forall syntax. Mode syntax -> Mode syntax) -> BufferM ()
    modifyMode ((forall syntax. Mode syntax -> Mode syntax) -> BufferM ())
    -> (forall syntax. Mode syntax -> Mode syntax) -> BufferM ()
    forall a b. (a -> b) -> a -> b
    $ \Mode syntax
    x -> Mode syntax
    x { modeToggleCommentSelection = Just toggle }
        Just BufferM ()
    b -> BufferM () -> YiM ()
    forall (m :: * -> *) a. MonadEditor m => BufferM a -> m a
    withCurrentBuffer BufferM ()
    b

    -- | Open a minibuffer window with the given prompt and keymap
    -- The third argument is an action to perform after the minibuffer
    -- is opened such as move to the first occurrence of a searched for
    -- string. If you don't need this just supply @return ()@
    spawnMinibufferE :: T.Text -> KeymapEndo -> EditorM BufferRef
    spawnMinibufferE :: Text -> KeymapEndo -> EditorM BufferRef
    spawnMinibufferE Text
    prompt KeymapEndo
    kmMod = do
      b <- BufferId -> YiString -> EditorM BufferRef
    forall (m :: * -> *).
    MonadEditor m =>
    BufferId -> YiString -> m BufferRef
    stringToNewBuffer (Text -> BufferId
    MemBuffer Text
    prompt) YiString
    forall a. Monoid a => a
    mempty
      -- Now create the minibuffer keymap and switch to the minibuffer window
      withGivenBuffer b $
        modifyMode $ \Mode syntax
    m -> Mode syntax
    m { modeKeymap = \KeymapSet
    kms -> KeymapSet
    kms { topKeymap = kmMod (insertKeymap kms)
                                                        } }
      -- The minibuffer window must not be moved from the position newWindowE places it!
      -- First: This way the minibuffer is just below the window that was in focus when
      -- the minibuffer was spawned. This clearly indicates what window is the target of
      -- some actions. Such as searching or the :w (save) command in the Vim keymap.
      -- Second: The users of the minibuffer expect the window and buffer that was in
      -- focus when the minibuffer was spawned to be in focus when the minibuffer is closed
      -- Given that window focus works as follows:
      --    - The new window is brought into focus.
      --    - The previous window in focus is to the left of the new window in the window
      --    set list.
      --    - When a window is deleted and is in focus then the window to the left is brought
      --    into focus.
      --
      -- If the minibuffer is moved then when the minibuffer is deleted the window brought
      -- into focus may not be the window that spawned the minibuffer.
      w <- newWindowE True b
      windowsA %= PL.insertRight w
      return b

    -- | @withMinibuffer prompt completer act@: open a minibuffer with @prompt@. Once
    -- a string @s@ is obtained, run @act s@. @completer@ can be used to complete
    -- functions: it returns a list of possible matches.
    withMinibuffer :: T.Text -> (T.Text -> YiM [T.Text]) -> (T.Text -> YiM ()) -> YiM ()
    withMinibuffer :: Text -> (Text -> YiM [Text]) -> (Text -> YiM ()) -> YiM ()
    withMinibuffer Text
    prompt Text -> YiM [Text]
    getPossibilities =
      Text
    -> (Text -> YiM [Text])
    -> Text
    -> (Text -> YiM Text)
    -> (Text -> YiM ())
    -> (Text -> YiM ())
    -> YiM ()
    withMinibufferGen Text
    "" Text -> YiM [Text]
    giveHint Text
    prompt Text -> YiM Text
    completer (YiM () -> Text -> YiM ()
    forall a b. a -> b -> a
    const (YiM () -> Text -> YiM ()) -> YiM () -> Text -> YiM ()
    forall a b. (a -> b) -> a -> b
    $ () -> YiM ()
    forall a. a -> YiM a
    forall (m :: * -> *) a. Monad m => a -> m a
    return ())
        where giveHint :: Text -> YiM [Text]
    giveHint Text
    s = [Maybe Text] -> [Text]
    forall a. [Maybe a] -> [a]
    catMaybes ([Maybe Text] -> [Text])
    -> ([Text] -> [Maybe Text]) -> [Text] -> [Text]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (Text -> Maybe Text) -> [Text] -> [Maybe Text]
    forall a b. (a -> b) -> [a] -> [b]
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap (Text -> Text -> Maybe Text
    prefixMatch Text
    s) ([Text] -> [Text]) -> YiM [Text] -> YiM [Text]
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Text -> YiM [Text]
    getPossibilities Text
    s
              completer :: Text -> YiM Text
    completer = (Text -> YiM [Text]) -> Text -> YiM Text
    simpleComplete Text -> YiM [Text]
    getPossibilities

    -- | Makes a completion function.
    mkCompleteFn :: (T.Text -> (T.Text -> Maybe T.Text)
                     -> [T.Text] -> EditorM T.Text)
                    -- ^ List completion, such as 'completeInList'.
                    -> (T.Text -> T.Text -> Maybe T.Text)
                    -- ^ Matcher such as 'prefixMatch'
                    -> (T.Text -> YiM [T.Text])
                    -- ^ Function to fetch possibilites for completion.
                    -> T.Text
                    -- ^ Input to try and complete against
                    -> YiM T.Text
    mkCompleteFn :: (Text -> (Text -> Maybe Text) -> [Text] -> EditorM Text)
    -> (Text -> Text -> Maybe Text)
    -> (Text -> YiM [Text])
    -> Text
    -> YiM Text
    mkCompleteFn Text -> (Text -> Maybe Text) -> [Text] -> EditorM Text
    completeInListFn Text -> Text -> Maybe Text
    match Text -> YiM [Text]
    getPossibilities Text
    s = do
                  possibles <- Text -> YiM [Text]
    getPossibilities Text
    s
                  withEditor $ completeInListFn s (match s) possibles

    simpleComplete :: (T.Text -> YiM [T.Text]) -> T.Text -> YiM T.Text
    simpleComplete :: (Text -> YiM [Text]) -> Text -> YiM Text
    simpleComplete = (Text -> (Text -> Maybe Text) -> [Text] -> EditorM Text)
    -> (Text -> Text -> Maybe Text)
    -> (Text -> YiM [Text])
    -> Text
    -> YiM Text
    mkCompleteFn Text -> (Text -> Maybe Text) -> [Text] -> EditorM Text
    completeInList Text -> Text -> Maybe Text
    prefixMatch

    infixComplete' :: Bool -> (T.Text -> YiM [T.Text]) -> T.Text -> YiM T.Text
    infixComplete' :: Bool -> (Text -> YiM [Text]) -> Text -> YiM Text
    infixComplete' Bool
    caseSensitive = (Text -> (Text -> Maybe Text) -> [Text] -> EditorM Text)
    -> (Text -> Text -> Maybe Text)
    -> (Text -> YiM [Text])
    -> Text
    -> YiM Text
    mkCompleteFn Text -> (Text -> Maybe Text) -> [Text] -> EditorM Text
    completeInList' ((Text -> Text -> Maybe Text)
     -> (Text -> YiM [Text]) -> Text -> YiM Text)
    -> (Text -> Text -> Maybe Text)
    -> (Text -> YiM [Text])
    -> Text
    -> YiM Text
    forall a b. (a -> b) -> a -> b
    $ Bool -> Text -> Text -> Maybe Text
    containsMatch' Bool
    caseSensitive

    infixComplete :: (T.Text -> YiM [T.Text]) -> T.Text -> YiM T.Text
    infixComplete :: (Text -> YiM [Text]) -> Text -> YiM Text
    infixComplete = Bool -> (Text -> YiM [Text]) -> Text -> YiM Text
    infixComplete' Bool
    True

    -- | Hint function that does nothing, for use with @'withMinibufferGen'@
    noHint :: a -> YiM [a]
    noHint :: forall a. a -> YiM [a]
    noHint = YiM [a] -> a -> YiM [a]
    forall a b. a -> b -> a
    const (YiM [a] -> a -> YiM [a]) -> YiM [a] -> a -> YiM [a]
    forall a b. (a -> b) -> a -> b
    $ [a] -> YiM [a]
    forall a. a -> YiM a
    forall (m :: * -> *) a. Monad m => a -> m a
    return []

    noPossibilities :: String -> YiM [ String ]
    noPossibilities :: [Char] -> YiM [[Char]]
    noPossibilities [Char]
    _s = [[Char]] -> YiM [[Char]]
    forall a. a -> YiM a
    forall (m :: * -> *) a. Monad m => a -> m a
    return []

    -- | @withMinibufferFree prompt act@:
    -- Simple version of @'withMinibufferGen'@
    withMinibufferFree :: T.Text -> (T.Text -> YiM ()) -> YiM ()
    withMinibufferFree :: Text -> (Text -> YiM ()) -> YiM ()
    withMinibufferFree Text
    prompt = Text
    -> (Text -> YiM [Text])
    -> Text
    -> (Text -> YiM Text)
    -> (Text -> YiM ())
    -> (Text -> YiM ())
    -> YiM ()
    withMinibufferGen Text
    "" Text -> YiM [Text]
    forall a. a -> YiM [a]
    noHint Text
    prompt
                                Text -> YiM Text
    forall a. a -> YiM a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (YiM () -> Text -> YiM ()
    forall a b. a -> b -> a
    const (YiM () -> Text -> YiM ()) -> YiM () -> Text -> YiM ()
    forall a b. (a -> b) -> a -> b
    $ () -> YiM ()
    forall a. a -> YiM a
    forall (m :: * -> *) a. Monad m => a -> m a
    return ())

    -- | @withMinibufferGen proposal getHint prompt completer onTyping act@:
    -- open a minibuffer with @prompt@, and initial content @proposal@. Once
    -- a string @s@ is obtained, run @act s@. @completer@ can be used to
    -- complete inputs by returning an incrementally better match, and
    -- getHint can give an immediate feedback to the user on the current
    -- input.
    --
    -- @on Typing@ is an extra action which will fire with every user
    -- key-press and receives minibuffer contents. Use something like
    -- @const $ return ()@ if you don't need this.
    withMinibufferGen :: T.Text -> (T.Text -> YiM [T.Text]) -> T.Text
                      -> (T.Text -> YiM T.Text) -> (T.Text -> YiM ())
                      -> (T.Text -> YiM ()) -> YiM ()
    withMinibufferGen :: Text
    -> (Text -> YiM [Text])
    -> Text
    -> (Text -> YiM Text)
    -> (Text -> YiM ())
    -> (Text -> YiM ())
    -> YiM ()
    withMinibufferGen Text
    proposal Text -> YiM [Text]
    getHint Text
    prompt Text -> YiM Text
    completer Text -> YiM ()
    onTyping Text -> YiM ()
    act = do
      initialBuffer <- (Editor -> BufferRef) -> YiM BufferRef
    forall s (m :: * -> *) a. MonadState s m => (s -> a) -> m a
    gets Editor -> BufferRef
    currentBuffer
      initialWindow <- use currentWindowA
      let innerAction :: YiM ()
          -- ^ Read contents of current buffer (which should be the minibuffer), and
          -- apply it to the desired action
          closeMinibuffer = EditorM ()
    closeBufferAndWindowE EditorM () -> EditorM () -> EditorM ()
    forall a b. EditorM a -> EditorM b -> EditorM b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >>
                            (PointedList Window -> Identity (PointedList Window))
    -> Editor -> Identity Editor
    Lens' Editor (PointedList Window)
    windowsA ((PointedList Window -> Identity (PointedList Window))
     -> Editor -> Identity Editor)
    -> (PointedList Window -> PointedList Window) -> EditorM ()
    forall s (m :: * -> *) a b.
    MonadState s m =>
    ASetter s s a b -> (a -> b) -> m ()
    %= Maybe (PointedList Window) -> PointedList Window
    forall a. HasCallStack => Maybe a -> a
    fromJust (Maybe (PointedList Window) -> PointedList Window)
    -> (PointedList Window -> Maybe (PointedList Window))
    -> PointedList Window
    -> PointedList Window
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Window -> PointedList Window -> Maybe (PointedList Window)
    forall a. Eq a => a -> PointedList a -> Maybe (PointedList a)
    PL.find Window
    initialWindow
          showMatchings = Text -> YiM ()
    showMatchingsOf (Text -> YiM ()) -> (YiString -> Text) -> YiString -> YiM ()
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . YiString -> Text
    R.toText (YiString -> YiM ()) -> YiM YiString -> YiM ()
    forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
    =<< BufferM YiString -> YiM YiString
    forall (m :: * -> *) a. MonadEditor m => BufferM a -> m a
    withCurrentBuffer BufferM YiString
    elemsB
          showMatchingsOf Text
    userInput =
            Status -> YiM ()
    forall (m :: * -> *). MonadEditor m => Status -> m ()
    printStatus (Status -> YiM ()) -> YiM Status -> YiM ()
    forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
    =<< [Text] -> Status
    forall {a}. a -> (a, StyleName)
    withDefaultStyle ([Text] -> Status) -> YiM [Text] -> YiM Status
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Text -> YiM [Text]
    getHint Text
    userInput
          withDefaultStyle a
    msg = (a
    msg, StyleName
    defaultStyle)
          typing = Text -> YiM ()
    onTyping (Text -> YiM ()) -> (YiString -> Text) -> YiString -> YiM ()
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . YiString -> Text
    R.toText (YiString -> YiM ()) -> YiM YiString -> YiM ()
    forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
    =<< BufferM YiString -> YiM YiString
    forall (m :: * -> *) a. MonadEditor m => BufferM a -> m a
    withCurrentBuffer BufferM YiString
    elemsB

          innerAction = do
            lineString <- EditorM Text -> YiM Text
    forall a. EditorM a -> YiM a
    forall (m :: * -> *) a. MonadEditor m => EditorM a -> m a
    withEditor (EditorM Text -> YiM Text) -> EditorM Text -> YiM Text
    forall a b. (a -> b) -> a -> b
    $ do
              let bufToText :: EditorM Text
    bufToText = YiString -> Text
    R.toText (YiString -> Text) -> EditorM YiString -> EditorM Text
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> BufferM YiString -> EditorM YiString
    forall (m :: * -> *) a. MonadEditor m => BufferM a -> m a
    withCurrentBuffer BufferM YiString
    elemsB
              Text -> EditorM Text -> EditorM ()
    historyFinishGen Text
    prompt EditorM Text
    bufToText
              lineString <- EditorM Text
    bufToText
              closeMinibuffer
              switchToBufferE initialBuffer
              -- The above ensures that the action is performed on the buffer
              -- that originated the minibuffer.
              return lineString
            act lineString

          up   = Text -> Int -> EditorM ()
    historyMove Text
    prompt Int
    1
          down = Text -> Int -> EditorM ()
    historyMove Text
    prompt (-Int
    1)

          rebindings =
            [Keymap] -> Keymap
    forall (m :: * -> *) w e a.
    (MonadInteract m w e, MonadFail m) =>
    [m a] -> m a
    choice [[Event] -> I Event Action Event
    forall event (m :: * -> *) w.
    (Ord event, MonadInteract m w event, MonadFail m) =>
    [event] -> m event
    oneOf [Key -> Event
    spec Key
    KEnter, Event -> Event
    ctrl (Event -> Event) -> Event -> Event
    forall a b. (a -> b) -> a -> b
    $ Char -> Event
    char Char
    'm'] I Event Action Event -> YiM () -> Keymap
    forall (m :: * -> *) a x b.
    (MonadInteract m Action Event, YiAction a x, Show x) =>
    m b -> a -> m ()
    >>! YiM ()
    innerAction,
                    [Event] -> I Event Action Event
    forall event (m :: * -> *) w.
    (Ord event, MonadInteract m w event, MonadFail m) =>
    [event] -> m event
    oneOf [Key -> Event
    spec Key
    KUp,    Event -> Event
    meta (Event -> Event) -> Event -> Event
    forall a b. (a -> b) -> a -> b
    $ Char -> Event
    char Char
    'p'] I Event Action Event -> EditorM () -> Keymap
    forall (m :: * -> *) a x b.
    (MonadInteract m Action Event, YiAction a x, Show x) =>
    m b -> a -> m ()
    >>! EditorM ()
    up,
                    [Event] -> I Event Action Event
    forall event (m :: * -> *) w.
    (Ord event, MonadInteract m w event, MonadFail m) =>
    [event] -> m event
    oneOf [Key -> Event
    spec Key
    KDown,  Event -> Event
    meta (Event -> Event) -> Event -> Event
    forall a b. (a -> b) -> a -> b
    $ Char -> Event
    char Char
    'n'] I Event Action Event -> EditorM () -> Keymap
    forall (m :: * -> *) a x b.
    (MonadInteract m Action Event, YiAction a x, Show x) =>
    m b -> a -> m ()
    >>! EditorM ()
    down,
                    [Event] -> I Event Action Event
    forall event (m :: * -> *) w.
    (Ord event, MonadInteract m w event, MonadFail m) =>
    [event] -> m event
    oneOf [Key -> Event
    spec Key
    KTab,   Event -> Event
    ctrl (Event -> Event) -> Event -> Event
    forall a b. (a -> b) -> a -> b
    $ Char -> Event
    char Char
    'i']
                      I Event Action Event -> YiM () -> Keymap
    forall (m :: * -> *) a x b.
    (MonadInteract m Action Event, YiAction a x, Show x) =>
    m b -> a -> m ()
    >>! (Text -> YiM Text) -> YiM ()
    completionFunction Text -> YiM Text
    completer Keymap -> YiM () -> Keymap
    forall (m :: * -> *) a x b.
    (MonadInteract m Action Event, YiAction a x, Show x) =>
    m b -> a -> m ()
    >>! YiM ()
    showMatchings,
                    Event -> Event
    ctrl (Char -> Event
    char Char
    'g')                     Event -> EditorM () -> Keymap
    forall (m :: * -> *) a x.
    (MonadInteract m Action Event, YiAction a x, Show x) =>
    Event -> a -> m ()
    ?>>! EditorM ()
    closeMinibuffer]

      showMatchingsOf ""
      withEditor $ do
          historyStartGen prompt
          void $ spawnMinibufferE (prompt `T.snoc` ' ')
            (\Keymap
    bindings -> Keymap
    rebindings Keymap -> KeymapEndo
    forall (f :: * -> *) w e a.
    MonadInteract f w e =>
    f a -> f a -> f a
    <|| (Keymap
    bindings Keymap -> KeymapEndo
    forall a b.
    I Event Action a -> I Event Action b -> I Event Action b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> YiM () -> Keymap
    forall (m :: * -> *) ev a x.
    (MonadInteract m Action ev, YiAction a x, Show x) =>
    a -> m ()
    write YiM ()
    showMatchings
                                          Keymap -> KeymapEndo
    forall a b.
    I Event Action a -> I Event Action b -> I Event Action b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> YiM () -> Keymap
    forall (m :: * -> *) ev a x.
    (MonadInteract m Action ev, YiAction a x, Show x) =>
    a -> m ()
    write YiM ()
    typing))
          withCurrentBuffer . replaceBufferContent . R.fromText
            $ replaceShorthands proposal

    -- | Open a minibuffer, given a finite number of suggestions.
    withMinibufferFin :: T.Text -> [T.Text] -> (T.Text -> YiM ()) -> YiM ()
    withMinibufferFin :: Text -> [Text] -> (Text -> YiM ()) -> YiM ()
    withMinibufferFin Text
    prompt [Text]
    possibilities Text -> YiM ()
    act
        = Text
    -> (Text -> YiM [Text])
    -> Text
    -> (Text -> YiM Text)
    -> (Text -> YiM ())
    -> (Text -> YiM ())
    -> YiM ()
    withMinibufferGen Text
    "" Text -> YiM [Text]
    forall {m :: * -> *}. Monad m => Text -> m [Text]
    hinter Text
    prompt Text -> YiM Text
    forall {m :: * -> *}. Monad m => Text -> m Text
    completer
          (YiM () -> Text -> YiM ()
    forall a b. a -> b -> a
    const (YiM () -> Text -> YiM ()) -> YiM () -> Text -> YiM ()
    forall a b. (a -> b) -> a -> b
    $ () -> YiM ()
    forall a. a -> YiM a
    forall (m :: * -> *) a. Monad m => a -> m a
    return ()) (Text -> YiM ()
    act (Text -> YiM ()) -> (Text -> Text) -> Text -> YiM ()
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Text -> Text
    best)
      where
        -- The function for returning the hints provided to the user underneath
        -- the input, basically all those that currently match.
        hinter :: Text -> m [Text]
    hinter Text
    s = [Text] -> m [Text]
    forall a. a -> m a
    forall (m :: * -> *) a. Monad m => a -> m a
    return ([Text] -> m [Text]) -> [Text] -> m [Text]
    forall a b. (a -> b) -> a -> b
    $ Text -> [Text]
    match Text
    s
        -- All those which currently match.
        match :: Text -> [Text]
    match Text
    s = (Text -> Bool) -> [Text] -> [Text]
    forall a. (a -> Bool) -> [a] -> [a]
    filter (Text
    s Text -> Text -> Bool
    `T.isInfixOf`) [Text]
    possibilities

        -- The best match from the list of matches
        -- If the string matches completely then we take that
        -- otherwise we just take the first match.
        best :: Text -> Text
    best Text
    s
          | Text
    s Text -> [Text] -> Bool
    forall a. Eq a => a -> [a] -> Bool
    forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
    `elem` [Text]
    matches = Text
    s
          | [Text] -> Bool
    forall a. [a] -> Bool
    forall (t :: * -> *) a. Foldable t => t a -> Bool
    null [Text]
    matches       = Text
    s
          | Bool
    otherwise          = [Text] -> Text
    forall a. HasCallStack => [a] -> a
    head [Text]
    matches
          where matches :: [Text]
    matches = Text -> [Text]
    match Text
    s

        -- We still want "TAB" to complete even though the user could just
        -- press return with an incomplete possibility. The reason is we
        -- may have for example two possibilities which share a long
        -- prefix and hence we wish to press tab to complete up to the
        -- point at which they differ.
        completer :: Text -> m Text
    completer Text
    s = Text -> m Text
    forall a. a -> m a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Text -> m Text) -> Text -> m Text
    forall a b. (a -> b) -> a -> b
    $ Text -> Maybe Text -> Text
    forall a. a -> Maybe a -> a
    fromMaybe Text
    s (Maybe Text -> Text) -> Maybe Text -> Text
    forall a b. (a -> b) -> a -> b
    $ [Text] -> Maybe Text
    commonTPrefix ([Text] -> Maybe Text) -> [Text] -> Maybe Text
    forall a b. (a -> b) -> a -> b
    $ [Maybe Text] -> [Text]
    forall a. [Maybe a] -> [a]
    catMaybes (Text -> Text -> Maybe Text
    infixUptoEndMatch Text
    s (Text -> Maybe Text) -> [Text] -> [Maybe Text]
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> [Text]
    possibilities)

    -- | TODO: decide whether we should be keeping 'T.Text' here or moving
    -- to 'YiString'.
    completionFunction :: (T.Text -> YiM T.Text) -> YiM ()
    completionFunction :: (Text -> YiM Text) -> YiM ()
    completionFunction Text -> YiM Text
    f = do
      p <- BufferM Point -> YiM Point
    forall (m :: * -> *) a. MonadEditor m => BufferM a -> m a
    withCurrentBuffer BufferM Point
    pointB
      let r = Point -> Point -> Region
    mkRegion Point
    0 Point
    p
      text <- withCurrentBuffer $ readRegionB r
      compl <- R.fromText <$> f (R.toText text)

      -- it's important to do this before removing the text, so if the
      -- completion function raises an exception, we don't delete the
      -- buffer contents.
      withCurrentBuffer $ replaceRegionB r compl

    class Promptable a where
        getPromptedValue :: T.Text -> YiM a
        getPrompt :: Proxy a -> T.Text
        getMinibuffer :: Proxy a -> T.Text -> (T.Text -> YiM ()) -> YiM ()
        getMinibuffer Proxy a
    _ = Text -> (Text -> YiM ()) -> YiM ()
    withMinibufferFree

    doPrompt :: forall a. Promptable a => (a -> YiM ()) -> YiM ()
    doPrompt :: forall a. Promptable a => (a -> YiM ()) -> YiM ()
    doPrompt a -> YiM ()
    act = Proxy a -> Text -> (Text -> YiM ()) -> YiM ()
    forall a.
    Promptable a =>
    Proxy a -> Text -> (Text -> YiM ()) -> YiM ()
    getMinibuffer Proxy a
    witness (Proxy a -> Text
    forall a. Promptable a => Proxy a -> Text
    getPrompt Proxy a
    witness Text -> Text -> Text
    `T.append` Text
    ":") (a -> YiM ()
    act (a -> YiM ()) -> (Text -> YiM a) -> Text -> YiM ()
    forall (m :: * -> *) b c a.
    Monad m =>
    (b -> m c) -> (a -> m b) -> a -> m c
    <=< Text -> YiM a
    forall a. Promptable a => Text -> YiM a
    getPromptedValue)
      where
        witness :: Proxy a
    witness = Proxy a
    forall a. HasCallStack => a
    undefined
        witness :: Proxy a

    instance Promptable String where
        getPromptedValue :: Text -> YiM [Char]
    getPromptedValue = [Char] -> YiM [Char]
    forall a. a -> YiM a
    forall (m :: * -> *) a. Monad m => a -> m a
    return ([Char] -> YiM [Char]) -> (Text -> [Char]) -> Text -> YiM [Char]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Text -> [Char]
    T.unpack
        getPrompt :: Proxy [Char] -> Text
    getPrompt Proxy [Char]
    _ = Text
    "String"

    instance Promptable Char where
        getPromptedValue :: Text -> YiM Char
    getPromptedValue Text
    x = if Text -> Bool
    T.null Text
    x
                             then [Char] -> YiM Char
    forall a. HasCallStack => [Char] -> a
    error [Char]
    "Please supply a character."
                             else Char -> YiM Char
    forall a. a -> YiM a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Char -> YiM Char) -> Char -> YiM Char
    forall a b. (a -> b) -> a -> b
    $ HasCallStack => Text -> Char
    Text -> Char
    T.head Text
    x
        getPrompt :: Proxy Char -> Text
    getPrompt Proxy Char
    _ = Text
    "Char"

    instance Promptable Int where
        getPromptedValue :: Text -> YiM Int
    getPromptedValue = Int -> YiM Int
    forall a. a -> YiM a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Int -> YiM Int) -> (Text -> Int) -> Text -> YiM Int
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . [Char] -> Int
    forall a. Read a => [Char] -> a
    read ([Char] -> Int) -> (Text -> [Char]) -> Text -> Int
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Text -> [Char]
    T.unpack
        getPrompt :: Proxy Int -> Text
    getPrompt Proxy Int
    _ = Text
    "Integer"

    instance Promptable T.Text where
      getPromptedValue :: Text -> YiM Text
    getPromptedValue = Text -> YiM Text
    forall a. a -> YiM a
    forall (m :: * -> *) a. Monad m => a -> m a
    return
      getPrompt :: Proxy Text -> Text
    getPrompt Proxy Text
    _ = Text
    "Text"

    instance Promptable R.YiString where
      getPromptedValue :: Text -> YiM YiString
    getPromptedValue = YiString -> YiM YiString
    forall a. a -> YiM a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (YiString -> YiM YiString)
    -> (Text -> YiString) -> Text -> YiM YiString
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Text -> YiString
    R.fromText
      getPrompt :: Proxy YiString -> Text
    getPrompt Proxy YiString
    _ = Text
    "YiString"

    -- helper functions:
    getPromptedValueList :: [(T.Text, a)] -> T.Text -> YiM a
    getPromptedValueList :: forall a. [(Text, a)] -> Text -> YiM a
    getPromptedValueList [(Text, a)]
    vs Text
    s = YiM a -> (a -> YiM a) -> Maybe a -> YiM a
    forall b a. b -> (a -> b) -> Maybe a -> b
    maybe ([Char] -> YiM a
    forall a. HasCallStack => [Char] -> a
    error [Char]
    "Invalid choice") a -> YiM a
    forall a. a -> YiM a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Text -> [(Text, a)] -> Maybe a
    forall a b. Eq a => a -> [(a, b)] -> Maybe b
    lookup Text
    s [(Text, a)]
    vs)

    getMinibufferList :: [(T.Text, a)] -> Proxy a -> T.Text
                      -> (T.Text -> YiM ()) -> YiM ()
    getMinibufferList :: forall a.
    [(Text, a)] -> Proxy a -> Text -> (Text -> YiM ()) -> YiM ()
    getMinibufferList [(Text, a)]
    vs Proxy a
    _ Text
    prompt = Text -> [Text] -> (Text -> YiM ()) -> YiM ()
    withMinibufferFin Text
    prompt (((Text, a) -> Text) -> [(Text, a)] -> [Text]
    forall a b. (a -> b) -> [a] -> [b]
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap (Text, a) -> Text
    forall a b. (a, b) -> a
    fst [(Text, a)]
    vs)

    enumAll :: (Enum a, Bounded a, Show a) => [(T.Text, a)]
    enumAll :: forall a. (Enum a, Bounded a, Show a) => [(Text, a)]
    enumAll = (a -> (Text, a)) -> [a] -> [(Text, a)]
    forall a b. (a -> b) -> [a] -> [b]
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap (\a
    v -> ([Char] -> Text
    T.pack ([Char] -> Text) -> [Char] -> Text
    forall a b. (a -> b) -> a -> b
    $ a -> [Char]
    forall a. Show a => a -> [Char]
    show a
    v, a
    v)) [a
    forall a. Bounded a => a
    minBound..]

    instance Promptable Direction where
        getPromptedValue :: Text -> YiM Direction
    getPromptedValue = [(Text, Direction)] -> Text -> YiM Direction
    forall a. [(Text, a)] -> Text -> YiM a
    getPromptedValueList [(Text, Direction)]
    forall a. (Enum a, Bounded a, Show a) => [(Text, a)]
    enumAll
        getPrompt :: Proxy Direction -> Text
    getPrompt Proxy Direction
    _ = Text
    "Direction"
        getMinibuffer :: Proxy Direction -> Text -> (Text -> YiM ()) -> YiM ()
    getMinibuffer = [(Text, Direction)]
    -> Proxy Direction -> Text -> (Text -> YiM ()) -> YiM ()
    forall a.
    [(Text, a)] -> Proxy a -> Text -> (Text -> YiM ()) -> YiM ()
    getMinibufferList [(Text, Direction)]
    forall a. (Enum a, Bounded a, Show a) => [(Text, a)]
    enumAll

    textUnits :: [(T.Text, TextUnit)]
    textUnits :: [(Text, TextUnit)]
    textUnits =
           [(Text
    "Character", TextUnit
    Character),
            (Text
    "Document", TextUnit
    Document),
            (Text
    "Line", TextUnit
    Line),
            (Text
    "Paragraph", TextUnit
    unitParagraph),
            (Text
    "Word", TextUnit
    unitWord),
            (Text
    "ViWord", TextUnit
    unitViWord)
           ]

    instance Promptable TextUnit where
        getPromptedValue :: Text -> YiM TextUnit
    getPromptedValue = [(Text, TextUnit)] -> Text -> YiM TextUnit
    forall a. [(Text, a)] -> Text -> YiM a
    getPromptedValueList [(Text, TextUnit)]
    textUnits
        getPrompt :: Proxy TextUnit -> Text
    getPrompt Proxy TextUnit
    _ = Text
    "Unit"
        getMinibuffer :: Proxy TextUnit -> Text -> (Text -> YiM ()) -> YiM ()
    getMinibuffer = [(Text, TextUnit)]
    -> Proxy TextUnit -> Text -> (Text -> YiM ()) -> YiM ()
    forall a.
    [(Text, a)] -> Proxy a -> Text -> (Text -> YiM ()) -> YiM ()
    getMinibufferList [(Text, TextUnit)]
    textUnits

    instance Promptable Point where
        getPromptedValue :: Text -> YiM Point
    getPromptedValue Text
    s = Int -> Point
    Point (Int -> Point) -> YiM Int -> YiM Point
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Text -> YiM Int
    forall a. Promptable a => Text -> YiM a
    getPromptedValue Text
    s
        getPrompt :: Proxy Point -> Text
    getPrompt Proxy Point
    _ = Text
    "Point"

    anyModeName :: AnyMode -> T.Text
    anyModeName :: AnyMode -> Text
    anyModeName (AnyMode Mode syntax
    m) = Mode syntax -> Text
    forall syntax. Mode syntax -> Text
    modeName Mode syntax
    m

    -- TODO: Better name
    anyModeByNameM :: T.Text -> YiM (Maybe AnyMode)
    anyModeByNameM :: Text -> YiM (Maybe AnyMode)
    anyModeByNameM Text
    n = (AnyMode -> Bool) -> [AnyMode] -> Maybe AnyMode
    forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Maybe a
    find ((Text
    nText -> Text -> Bool
    forall a. Eq a => a -> a -> Bool
    ==) (Text -> Bool) -> (AnyMode -> Text) -> AnyMode -> Bool
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . AnyMode -> Text
    anyModeName) ([AnyMode] -> Maybe AnyMode)
    -> (Config -> [AnyMode]) -> Config -> Maybe AnyMode
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Config -> [AnyMode]
    modeTable (Config -> Maybe AnyMode) -> YiM Config -> YiM (Maybe AnyMode)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> YiM Config
    forall (m :: * -> *). MonadEditor m => m Config
    askCfg

    anyModeByName :: T.Text -> YiM AnyMode
    anyModeByName :: Text -> YiM AnyMode
    anyModeByName Text
    n = Text -> YiM (Maybe AnyMode)
    anyModeByNameM Text
    n YiM (Maybe AnyMode)
    -> (Maybe AnyMode -> YiM AnyMode) -> YiM AnyMode
    forall a b. YiM a -> (a -> YiM b) -> YiM b
    forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= \case
      Maybe AnyMode
    Nothing -> [Char] -> YiM AnyMode
    forall a. [Char] -> YiM a
    forall (m :: * -> *) a. MonadFail m => [Char] -> m a
    fail ([Char] -> YiM AnyMode) -> [Char] -> YiM AnyMode
    forall a b. (a -> b) -> a -> b
    $ [Char]
    "anyModeByName: no such mode: " [Char] -> [Char] -> [Char]
    forall a. [a] -> [a] -> [a]
    ++ Text -> [Char]
    T.unpack Text
    n
      Just AnyMode
    m  -> AnyMode -> YiM AnyMode
    forall a. a -> YiM a
    forall (m :: * -> *) a. Monad m => a -> m a
    return AnyMode
    m

    getAllModeNames :: YiM [T.Text]
    getAllModeNames :: YiM [Text]
    getAllModeNames = (AnyMode -> Text) -> [AnyMode] -> [Text]
    forall a b. (a -> b) -> [a] -> [b]
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap AnyMode -> Text
    anyModeName ([AnyMode] -> [Text]) -> (Config -> [AnyMode]) -> Config -> [Text]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Config -> [AnyMode]
    modeTable (Config -> [Text]) -> YiM Config -> YiM [Text]
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> YiM Config
    forall (m :: * -> *). MonadEditor m => m Config
    askCfg

    instance Promptable AnyMode where
        getPrompt :: Proxy AnyMode -> Text
    getPrompt Proxy AnyMode
    _ = Text
    "Mode"
        getPromptedValue :: Text -> YiM AnyMode
    getPromptedValue = Text -> YiM AnyMode
    anyModeByName
        getMinibuffer :: Proxy AnyMode -> Text -> (Text -> YiM ()) -> YiM ()
    getMinibuffer Proxy AnyMode
    _ Text
    prompt Text -> YiM ()
    act = do
          names <- YiM [Text]
    getAllModeNames
          withMinibufferFin prompt names act

    instance Promptable BufferRef where
        getPrompt :: Proxy BufferRef -> Text
    getPrompt Proxy BufferRef
    _ = Text
    "Buffer"
        getPromptedValue :: Text -> YiM BufferRef
    getPromptedValue = Text -> YiM BufferRef
    forall (m :: * -> *). MonadEditor m => Text -> m BufferRef
    getBufferWithNameOrCurrent
        getMinibuffer :: Proxy BufferRef -> Text -> (Text -> YiM ()) -> YiM ()
    getMinibuffer Proxy BufferRef
    _ Text
    prompt Text -> YiM ()
    act = do
          bufs <- YiM [Text]
    matchingBufferNames
          withMinibufferFin prompt bufs act

    -- | Returns all the buffer names
    matchingBufferNames :: YiM [T.Text]
    matchingBufferNames :: YiM [Text]
    matchingBufferNames = EditorM [Text] -> YiM [Text]
    forall a. EditorM a -> YiM a
    forall (m :: * -> *) a. MonadEditor m => EditorM a -> m a
    withEditor (EditorM [Text] -> YiM [Text]) -> EditorM [Text] -> YiM [Text]
    forall a b. (a -> b) -> a -> b
    $ do
      p <- (Editor -> [[Char]]) -> EditorM [[Char]]
    forall s (m :: * -> *) a. MonadState s m => (s -> a) -> m a
    gets Editor -> [[Char]]
    commonNamePrefix
      bs <- gets bufferSet
      return $ fmap (shortIdentString $ length p) bs

    instance (YiAction a x, Promptable r) => YiAction (r -> a) x where
        makeAction :: Show x => (r -> a) -> Action
    makeAction r -> a
    f = YiM () -> Action
    forall a. Show a => YiM a -> Action
    YiA (YiM () -> Action) -> YiM () -> Action
    forall a b. (a -> b) -> a -> b
    $ (r -> YiM ()) -> YiM ()
    forall a. Promptable a => (a -> YiM ()) -> YiM ()
    doPrompt (Action -> YiM ()
    runAction (Action -> YiM ()) -> (r -> Action) -> r -> YiM ()
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . a -> Action
    forall a x. (YiAction a x, Show x) => a -> Action
    makeAction (a -> Action) -> (r -> a) -> r -> Action
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . r -> a
    f)

    -- | Tag a type with a documentation
    newtype (:::) t doc = Doc {forall t doc. (t ::: doc) -> t
    fromDoc :: t} deriving ((t ::: doc) -> (t ::: doc) -> Bool
    ((t ::: doc) -> (t ::: doc) -> Bool)
    -> ((t ::: doc) -> (t ::: doc) -> Bool) -> Eq (t ::: doc)
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    forall t doc. Eq t => (t ::: doc) -> (t ::: doc) -> Bool
    $c== :: forall t doc. Eq t => (t ::: doc) -> (t ::: doc) -> Bool
    == :: (t ::: doc) -> (t ::: doc) -> Bool
    $c/= :: forall t doc. Eq t => (t ::: doc) -> (t ::: doc) -> Bool
    /= :: (t ::: doc) -> (t ::: doc) -> Bool
    Eq, Typeable, Integer -> t ::: doc
    (t ::: doc) -> t ::: doc
    (t ::: doc) -> (t ::: doc) -> t ::: doc
    ((t ::: doc) -> (t ::: doc) -> t ::: doc)
    -> ((t ::: doc) -> (t ::: doc) -> t ::: doc)
    -> ((t ::: doc) -> (t ::: doc) -> t ::: doc)
    -> ((t ::: doc) -> t ::: doc)
    -> ((t ::: doc) -> t ::: doc)
    -> ((t ::: doc) -> t ::: doc)
    -> (Integer -> t ::: doc)
    -> Num (t ::: doc)
    forall a.
    (a -> a -> a)
    -> (a -> a -> a)
    -> (a -> a -> a)
    -> (a -> a)
    -> (a -> a)
    -> (a -> a)
    -> (Integer -> a)
    -> Num a
    forall t doc. Num t => Integer -> t ::: doc
    forall t doc. Num t => (t ::: doc) -> t ::: doc
    forall t doc. Num t => (t ::: doc) -> (t ::: doc) -> t ::: doc
    $c+ :: forall t doc. Num t => (t ::: doc) -> (t ::: doc) -> t ::: doc
    + :: (t ::: doc) -> (t ::: doc) -> t ::: doc
    $c- :: forall t doc. Num t => (t ::: doc) -> (t ::: doc) -> t ::: doc
    - :: (t ::: doc) -> (t ::: doc) -> t ::: doc
    $c* :: forall t doc. Num t => (t ::: doc) -> (t ::: doc) -> t ::: doc
    * :: (t ::: doc) -> (t ::: doc) -> t ::: doc
    $cnegate :: forall t doc. Num t => (t ::: doc) -> t ::: doc
    negate :: (t ::: doc) -> t ::: doc
    $cabs :: forall t doc. Num t => (t ::: doc) -> t ::: doc
    abs :: (t ::: doc) -> t ::: doc
    $csignum :: forall t doc. Num t => (t ::: doc) -> t ::: doc
    signum :: (t ::: doc) -> t ::: doc
    $cfromInteger :: forall t doc. Num t => Integer -> t ::: doc
    fromInteger :: Integer -> t ::: doc
    Num, [Char] -> t ::: doc
    ([Char] -> t ::: doc) -> IsString (t ::: doc)
    forall a. ([Char] -> a) -> IsString a
    forall t doc. IsString t => [Char] -> t ::: doc
    $cfromString :: forall t doc. IsString t => [Char] -> t ::: doc
    fromString :: [Char] -> t ::: doc
    IsString)

    instance Show x => Show (x ::: t) where
        show :: (x ::: t) -> [Char]
    show (Doc x
    d) = x -> [Char]
    forall a. Show a => a -> [Char]
    show x
    d

    instance (DocType doc, Promptable t) => Promptable (t ::: doc) where
        getPrompt :: Proxy (t ::: doc) -> Text
    getPrompt Proxy (t ::: doc)
    _ = doc -> Text
    forall t. DocType t => t -> Text
    typeGetPrompt ([Char] -> doc
    forall a. HasCallStack => [Char] -> a
    error [Char]
    "typeGetPrompt should not enter its argument" :: doc)
        getPromptedValue :: Text -> YiM (t ::: doc)
    getPromptedValue Text
    x = t -> t ::: doc
    forall t doc. t -> t ::: doc
    Doc (t -> t ::: doc) -> YiM t -> YiM (t ::: doc)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Text -> YiM t
    forall a. Promptable a => Text -> YiM a
    getPromptedValue Text
    x

    class DocType t where
        -- | What to prompt the user when asked this type?
        typeGetPrompt :: t -> T.Text

    data LineNumber
    instance DocType LineNumber where
        typeGetPrompt :: LineNumber -> Text
    typeGetPrompt LineNumber
    _ = Text
    "Line"

    data ToKill
    instance DocType ToKill where
        typeGetPrompt :: ToKill -> Text
    typeGetPrompt ToKill
    _ = Text
    "kill buffer"

    data RegexTag deriving Typeable
    instance DocType RegexTag where
        typeGetPrompt :: RegexTag -> Text
    typeGetPrompt RegexTag
    _ = Text
    "Regex"

    data FilePatternTag deriving Typeable
    instance DocType FilePatternTag where
        typeGetPrompt :: FilePatternTag -> Text
    typeGetPrompt FilePatternTag
    _ = Text
    "File pattern"

    newtype CommandArguments = CommandArguments [T.Text]
        deriving (Int -> CommandArguments -> [Char] -> [Char]
    [CommandArguments] -> [Char] -> [Char]
    CommandArguments -> [Char]
    (Int -> CommandArguments -> [Char] -> [Char])
    -> (CommandArguments -> [Char])
    -> ([CommandArguments] -> [Char] -> [Char])
    -> Show CommandArguments
    forall a.
    (Int -> a -> [Char] -> [Char])
    -> (a -> [Char]) -> ([a] -> [Char] -> [Char]) -> Show a
    $cshowsPrec :: Int -> CommandArguments -> [Char] -> [Char]
    showsPrec :: Int -> CommandArguments -> [Char] -> [Char]
    $cshow :: CommandArguments -> [Char]
    show :: CommandArguments -> [Char]
    $cshowList :: [CommandArguments] -> [Char] -> [Char]
    showList :: [CommandArguments] -> [Char] -> [Char]
    Show, CommandArguments -> CommandArguments -> Bool
    (CommandArguments -> CommandArguments -> Bool)
    -> (CommandArguments -> CommandArguments -> Bool)
    -> Eq CommandArguments
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: CommandArguments -> CommandArguments -> Bool
    == :: CommandArguments -> CommandArguments -> Bool
    $c/= :: CommandArguments -> CommandArguments -> Bool
    /= :: CommandArguments -> CommandArguments -> Bool
    Eq, Typeable)

    instance Promptable CommandArguments where
        getPromptedValue :: Text -> YiM CommandArguments
    getPromptedValue = CommandArguments -> YiM CommandArguments
    forall a. a -> YiM a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (CommandArguments -> YiM CommandArguments)
    -> (Text -> CommandArguments) -> Text -> YiM CommandArguments
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . [Text] -> CommandArguments
    CommandArguments ([Text] -> CommandArguments)
    -> (Text -> [Text]) -> Text -> CommandArguments
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Text -> [Text]
    T.words
        getPrompt :: Proxy CommandArguments -> Text
    getPrompt Proxy CommandArguments
    _ = Text
    "Command arguments"