yi-0.7.0: src/library/Yi/Keymap/Vim2/Ex/Commands/Global.hs
module Yi.Keymap.Vim2.Ex.Commands.Global
( parse
) where
import Prelude ()
import Yi.Prelude
import Data.List (reverse, isInfixOf)
import qualified Text.ParserCombinators.Parsec as P
import Yi.Buffer
import Yi.Editor
import Yi.Keymap
import Yi.Keymap.Vim2.Ex.Types
import qualified Yi.Keymap.Vim2.Ex.Commands.Common as Common
import qualified Yi.Keymap.Vim2.Ex.Commands.Delete as Delete
import qualified Yi.Keymap.Vim2.Ex.Commands.Substitute as Substitute
parse :: String -> Maybe ExCommand
parse = Common.parse $ do
discard $ P.try (P.string "global/") <|> P.string "g/"
predicate <- P.many (P.noneOf "/")
discard $ P.char '/'
cmdString <- P.many P.anyChar
cmd <- case stringToExCommand allowedCmds cmdString of
Just c -> return c
_ -> fail "Unexpected command argument for global command."
return $! global predicate cmd
global :: String -> ExCommand -> ExCommand
global p c = Common.pureExCommand {
cmdShow = concat ["g/", p, "/", show c]
, cmdAction = EditorA $ do
mark <- withBuffer0 setMarkHereB
lineCount <- withBuffer0 lineCountB
forM_ (reverse [1..lineCount]) $ \l -> do
ln <- withBuffer0 $ gotoLn l >> readLnB
when (p `isInfixOf` ln) $
case cmdAction c of
BufferA action -> withBuffer0 $ discard action
EditorA action -> discard action
_ -> error "Impure command as an argument to global."
withBuffer0 $ do
getMarkPointB mark >>= moveTo
deleteMarkB mark
}
allowedCmds :: [String -> Maybe ExCommand]
allowedCmds = [Delete.parse, Substitute.parse]