module Yi.Keymap.Vim2.Ex.Commands.Quit
( parse
) where
import Prelude ()
import Yi.Prelude
import Data.Either (either)
import qualified Text.ParserCombinators.Parsec as P
import Yi.Core (quitEditor, errorEditor, closeWindow)
import Yi.Buffer
import Yi.Editor
import Yi.File
import Yi.Keymap
import Yi.Keymap.Vim2.Ex.Types
import qualified Yi.Keymap.Vim2.Ex.Commands.Common as Common
parse :: String -> Maybe ExCommand
parse = Common.parse $ do
ws <- P.many (P.char 'w')
discard $ P.try ( P.string "quit") <|> P.string "q"
as <- P.many (P.try ( P.string "all") <|> P.string "a")
bangs <- P.many (P.char '!')
return $! quit (not $ null ws) (not $ null bangs) (not $ null as)
quit :: Bool -> Bool -> Bool -> ExCommand
quit w f a = Common.impureExCommand {
cmdShow = concat
[ (if w then "w" else "")
, "quit"
, (if a then "all" else "")
, (if f then "!" else "")
]
, cmdAction = YiA $ action w f a
}
action :: Bool -> Bool -> Bool -> YiM ()
action False False False = closeWindow
action False False True = quitAllE
action True False False = viWrite >> closeWindow
action True False True = saveAndQuitAllE
action False True False = quitEditor
action False True True = quitAllE
action True True False = viWrite >> closeWindow
action True True True = saveAndQuitAllE
quitAllE :: YiM ()
quitAllE = do
bs <- mapM (\b -> (,) b <$> withEditor (withGivenBuffer0 b needsAWindowB)) =<< readEditor bufferStack
case find snd bs of
Nothing -> quitEditor
Just (b, _) -> do
bufferName <- withEditor $ withGivenBuffer0 b $ gets file
errorEditor $ "No write since last change for buffer "
++ show bufferName
++ " (add ! to override)"
saveAndQuitAllE :: YiM ()
saveAndQuitAllE = Common.forAllBuffers fwriteBufferE >> quitEditor
needsAWindowB :: BufferM Bool
needsAWindowB = do
isWorthless <- gets (either (const True) (const False) . (^. identA))
canClose <- gets isUnchangedBuffer
return (not (isWorthless || canClose))