module Yi.Keymap.Vim.Ex.Commands.Global (parse) where
import Control.Applicative
import Control.Lens
import Control.Monad
import Data.Monoid
import qualified Data.Text as T
import qualified Text.ParserCombinators.Parsec as P
import Yi.Buffer.Adjusted
import Yi.Editor
import Yi.Keymap
import Yi.Keymap.Vim.Common
import qualified Yi.Keymap.Vim.Ex.Commands.Common as Common
import qualified Yi.Keymap.Vim.Ex.Commands.Delete as Delete
import qualified Yi.Keymap.Vim.Ex.Commands.Substitute as Substitute
import Yi.Keymap.Vim.Ex.Types
import qualified Yi.Rope as R
import Yi.String (showT)
parse :: EventString -> Maybe ExCommand
parse = Common.parse $ do
void $ P.try (P.string "global/") <|> P.string "g/"
predicate <- T.pack <$> P.many (P.noneOf "/")
void $ P.char '/'
cmdString <- Ev . T.pack <$> P.many P.anyChar
cmd <- case evStringToExCommand allowedCmds cmdString of
Just c -> return c
_ -> fail "Unexpected command argument for global command."
return $! global predicate cmd
global :: T.Text -> ExCommand -> ExCommand
global p c = Common.pureExCommand {
cmdShow = "g/" <> p `T.snoc` '/' <> showT c
, cmdAction = EditorA $ do
mark <- withCurrentBuffer setMarkHereB
lineCount <- withCurrentBuffer lineCountB
forM_ (reverse [1..lineCount]) $ \l -> do
ln <- withCurrentBuffer $ gotoLn l >> R.toText <$> readLnB
when (p `T.isInfixOf` ln) $
case cmdAction c of
BufferA action -> withCurrentBuffer $ void action
EditorA action -> void action
_ -> error "Impure command as an argument to global."
withCurrentBuffer $ do
use (markPointA mark) >>= moveTo
deleteMarkB mark
}
allowedCmds :: [EventString -> Maybe ExCommand]
allowedCmds = [Delete.parse, Substitute.parse]