{-# LANGUAGE OverloadedStrings #-} {-# OPTIONS_HADDOCK show-extensions #-} -- | -- Module : Yi.Keymap.Vim.Ex.Commands.Buffer -- License : GPL-2 -- Maintainer : yi-devel@googlegroups.com -- Stability : experimental -- Portability : portable -- -- :buffer ex command to switch to named or numbered buffer. module Yi.Keymap.Vim.Ex.Commands.Buffer (parse) where import Control.Applicative (Alternative ((<|>)), Applicative ((*>)), (<$>)) import Control.Monad (void) import Control.Monad.State (gets) import qualified Data.Text as T (pack) import qualified Text.ParserCombinators.Parsec as P (GenParser, anyChar, digit, eof, many, many1, parse, space, string, try) import Yi.Buffer.Basic (BufferRef (..)) import Yi.Buffer.Misc (bkey, isUnchangedBuffer) import Yi.Editor import Yi.Keymap (Action (EditorA)) import Yi.Keymap.Vim.Common (EventString) import qualified Yi.Keymap.Vim.Ex.Commands.Common as Common (errorNoWrite, parseWithBangAndCount, pureExCommand) import Yi.Keymap.Vim.Ex.Types (ExCommand (cmdAction, cmdShow)) parse :: EventString -> Maybe ExCommand parse = Common.parseWithBangAndCount nameParser $ \ _ bang mcount -> do bufIdent <- P.try ( P.many1 P.digit <|> bufferSymbol) <|> P.many1 P.space *> P.many P.anyChar <|> P.eof *> return "" return $ Common.pureExCommand { cmdShow = "buffer" , cmdAction = EditorA $ do unchanged <- withCurrentBuffer $ gets isUnchangedBuffer if bang || unchanged then case mcount of Nothing -> switchToBuffer bufIdent Just i -> switchByRef $ BufferRef i else Common.errorNoWrite } where bufferSymbol = P.string "%" <|> P.string "#" nameParser :: P.GenParser Char () () nameParser = void $ P.try ( P.string "buffer") <|> P.try ( P.string "buf") <|> P.try ( P.string "bu") <|> P.try ( P.string "b") switchToBuffer :: String -> EditorM () switchToBuffer s = case P.parse bufferRef "" s of Right ref -> switchByRef ref Left _e -> switchByName s where bufferRef = BufferRef . read <$> P.many1 P.digit switchByName :: String -> EditorM () switchByName "" = return () switchByName "%" = return () switchByName "#" = switchToBufferWithNameE "" switchByName bufName = switchToBufferWithNameE (T.pack bufName) switchByRef :: BufferRef -> EditorM () switchByRef ref = do mBuf <- findBuffer ref maybe (return ()) (switchToBufferE . bkey) mBuf