    {-# LANGUAGE OverloadedStrings, UnboxedTuples #-}
    {-# OPTIONS_HADDOCK show-extensions #-}

    -- |
    -- Module      :  Yi.Keymap.Vim.Ex.Commands.BufferDelete
    -- License     :  GPL-2
    -- Maintainer  :  yi-devel@googlegroups.com
    -- Stability   :  experimental
    -- Portability :  portable

    module Yi.Keymap.Vim.Ex.Commands.BufferDelete (parse) where

    import           Control.Applicative              (Alternative (some))
    import           Control.Monad                    (void, when)
    import qualified Data.Text                        as T (null)
    import qualified Data.Attoparsec.Text             as P (Parser, choice, digit, parseOnly, string)
    import           Lens.Micro.Platform              (use)
    import           Yi.Buffer.Basic                  (BufferRef (..))
    import           Yi.Core                          (closeWindow, errorEditor)
    import           Yi.Editor                        (currentWindowA, deleteBuffer, getBufferWithName, withEditor)
    import           Yi.Keymap                        (Action (YiA))
    import           Yi.Keymap.Vim.Common             (EventString)
    import           Yi.Keymap.Vim.Ex.Commands.Buffer (bufferIdentifier)
    import qualified Yi.Keymap.Vim.Ex.Commands.Common as Common (needsSaving, parseWithBangAndCount, impureExCommand)
    import           Yi.Keymap.Vim.Ex.Types           (ExCommand (cmdAction, cmdShow))
    import           Yi.Window                        (bufkey)

    parse :: EventString -> Maybe ExCommand
    parse :: EventString -> Maybe ExCommand
    parse = Parser ()
    -> (() -> Bool -> Maybe Int -> Parser ExCommand)
    -> EventString
    -> Maybe ExCommand
    forall a.
    Parser a
    -> (a -> Bool -> Maybe Int -> Parser ExCommand)
    -> EventString
    -> Maybe ExCommand
    Common.parseWithBangAndCount Parser ()
    nameParser ((() -> Bool -> Maybe Int -> Parser ExCommand)
     -> EventString -> Maybe ExCommand)
    -> (() -> Bool -> Maybe Int -> Parser ExCommand)
    -> EventString
    -> Maybe ExCommand
    forall a b. (a -> b) -> a -> b
    $ \ ()
    _ Bool
    bang Maybe Int
    mcount -> do
        bufIdent <- Parser Text
    bufferIdentifier
        return $ Common.impureExCommand {
            cmdShow = "bdelete"
          , cmdAction = YiA $ do
                buffer <- case (# mcount, P.parseOnly bufferRef bufIdent #) of
                    (# Just Int
    i, Either String BufferRef
    _ #) -> BufferRef -> YiM BufferRef
    forall a. a -> YiM a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (BufferRef -> YiM BufferRef) -> BufferRef -> YiM BufferRef
    forall a b. (a -> b) -> a -> b
    $ Int -> BufferRef
    BufferRef Int
    i
                    (# Maybe Int, Either String BufferRef #)
    _ | Text -> Bool
    T.null Text
    bufIdent -> EditorM BufferRef -> YiM BufferRef
    forall a. EditorM a -> YiM a
    forall (m :: * -> *) a. MonadEditor m => EditorM a -> m a
    withEditor (EditorM BufferRef -> YiM BufferRef)
    -> EditorM BufferRef -> YiM BufferRef
    forall a b. (a -> b) -> a -> b
    $ Window -> BufferRef
    bufkey (Window -> BufferRef) -> EditorM Window -> EditorM BufferRef
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Getting Window Editor Window -> EditorM Window
    forall s (m :: * -> *) a. MonadState s m => Getting a s a -> m a
    use Getting Window Editor Window
    Lens' Editor Window
    currentWindowA
                    (# Maybe Int
    _, Right BufferRef
    ref #) -> BufferRef -> YiM BufferRef
    forall a. a -> YiM a
    forall (m :: * -> *) a. Monad m => a -> m a
    return BufferRef
    ref
                    (# Maybe Int
    _, Left String
    _ #) -> Text -> YiM BufferRef
    forall (m :: * -> *). MonadEditor m => Text -> m BufferRef
    getBufferWithName Text
    bufIdent
                q <- if bang then pure True else not <$> Common.needsSaving buffer
                if q
                    then do
                        deleteBuffer buffer
                        when (T.null bufIdent) $ closeWindow -- Because this function closed the window before I started altering it
                    else errorEditor "No write since last change (add ! to override)"
          }
      where
        bufferRef :: Parser BufferRef
    bufferRef = Int -> BufferRef
    BufferRef (Int -> BufferRef) -> (String -> Int) -> String -> BufferRef
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . String -> Int
    forall a. Read a => String -> a
    read (String -> BufferRef) -> Parser Text String -> Parser BufferRef
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Parser Text Char -> Parser Text String
    forall a. Parser Text a -> Parser Text [a]
    forall (f :: * -> *) a. Alternative f => f a -> f [a]
    some Parser Text Char
    P.digit

    nameParser :: P.Parser ()
    nameParser :: Parser ()
    nameParser = Parser Text -> Parser ()
    forall (f :: * -> *) a. Functor f => f a -> f ()
    void (Parser Text -> Parser ())
    -> ([Text] -> Parser Text) -> [Text] -> Parser ()
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . [Parser Text] -> Parser Text
    forall (f :: * -> *) a. Alternative f => [f a] -> f a
    P.choice ([Parser Text] -> Parser Text)
    -> ([Text] -> [Parser Text]) -> [Text] -> Parser Text
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (Text -> Parser Text) -> [Text] -> [Parser Text]
    forall a b. (a -> b) -> [a] -> [b]
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap Text -> Parser Text
    P.string ([Text] -> Parser ()) -> [Text] -> Parser ()
    forall a b. (a -> b) -> a -> b
    $ [Text
    "bdelete",Text
    "bdel",Text
    "bd"]