{-# 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 (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 :: Text
cmdShow = Text
"bdelete"
, cmdAction :: Action
cmdAction = YiM () -> Action
forall a. Show a => YiM a -> Action
YiA (YiM () -> Action) -> YiM () -> Action
forall a b. (a -> b) -> a -> b
$ do
BufferRef
buffer <- case (# Maybe Int
mcount, Parser BufferRef -> Text -> Either String BufferRef
forall a. Parser a -> Text -> Either String a
P.parseOnly Parser BufferRef
bufferRef Text
bufIdent #) of
(# Just Int
i, Either String BufferRef
_ #) -> BufferRef -> YiM BufferRef
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 (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 (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
Bool
q <- if Bool
bang then Bool -> YiM Bool
forall (f :: * -> *) a. Applicative f => a -> f a
pure Bool
True else Bool -> Bool
not (Bool -> Bool) -> YiM Bool -> YiM Bool
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> BufferRef -> YiM Bool
Common.needsSaving BufferRef
buffer
if Bool
q
then do
BufferRef -> YiM ()
forall (m :: * -> *). MonadEditor m => BufferRef -> m ()
deleteBuffer BufferRef
buffer
Bool -> YiM () -> YiM ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Text -> Bool
T.null Text
bufIdent) (YiM () -> YiM ()) -> YiM () -> YiM ()
forall a b. (a -> b) -> a -> b
$ YiM ()
closeWindow
else Text -> YiM ()
errorEditor Text
"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 (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 (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"]