{-# LANGUAGE OverloadedStrings #-} {-# OPTIONS_HADDOCK show-extensions #-} -- | -- Module : Yi.Keymap.Vim.Ex.Commands.Global -- License : GPL-2 -- Maintainer : yi-devel@googlegroups.com -- Stability : experimental -- Portability : portable 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]