{-# LANGUAGE OverloadedStrings, UnboxedTuples #-}
{-# OPTIONS_HADDOCK show-extensions #-}
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
Text
bufIdent <- Parser Text
bufferIdentifier
ExCommand -> Parser ExCommand
forall a. a -> Parser Text a
forall (m :: * -> *) a. Monad m => a -> m a
return (ExCommand -> Parser ExCommand) -> ExCommand -> Parser ExCommand
forall a b. (a -> b) -> a -> b
$ ExCommand
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
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"]