hob-0.0.1.0: src/lib/Hob/Command/ReplaceText.hs
module Hob.Command.ReplaceText (
createMatcherForReplace,
replaceCommandHandler,
replaceNextCommandHandler,
) where
import Data.Monoid (mconcat)
import Graphics.UI.Gtk
import Hob.Command.FindText
import Hob.Context
import Hob.Ui.Editor
import Hob.Ui.Editor.Search
createMatcherForReplace :: Char -> (String -> String -> CommandHandler) -> CommandMatcher
createMatcherForReplace prefix handler = CommandMatcher (const Nothing) match
where match [] = Nothing
match (p:ps)
| p == prefix = matchSearchAndReplaceFromStart ps
| otherwise = Nothing
matchSearchAndReplaceFromStart [] = Nothing
matchSearchAndReplaceFromStart (separator:xs) = matchSearchAndReplaceFromSearch separator xs ""
matchSearchAndReplaceFromSearch _ [] _ = Nothing
matchSearchAndReplaceFromSearch separator (x:xs) accumSearch
| '\\' == x = case xs of
[] -> Nothing
(s:xss) -> if s == separator then matchSearchAndReplaceFromSearch separator xss (accumSearch++[separator])
else matchSearchAndReplaceFromSearch separator xs (accumSearch++[x])
| separator == x = matchSearchAndReplaceFromReplace separator xs accumSearch ""
| otherwise = matchSearchAndReplaceFromSearch separator xs (accumSearch++[x])
matchSearchAndReplaceFromReplace _ [] search accumReplace = Just $ handler search accumReplace
matchSearchAndReplaceFromReplace separator (x:xs) search accumReplace
| '\\' == x = case xs of
[] -> Just $ handler search (accumReplace++[x])
(s:xss) -> if s == separator then matchSearchAndReplaceFromReplace separator xss search (accumReplace++[separator])
else matchSearchAndReplaceFromReplace separator xs search (accumReplace++[x])
| separator == x = Just $ handler search accumReplace
| otherwise = matchSearchAndReplaceFromReplace separator xs search (accumReplace++[x])
replaceCommandHandler :: String -> String -> CommandHandler
replaceCommandHandler searchText replaceText = CommandHandler (Just $ PreviewCommandHandler (searchPreview searchText) searchResetPreview) (replaceStart searchText replaceText)
replaceNextCommandHandler :: CommandHandler
replaceNextCommandHandler = CommandHandler Nothing invokeReplaceNext
replaceStart :: String -> String -> App()
replaceStart searchText replaceText = do
enterMode replaceMode
invokeOnActiveEditor $ \editor -> do
startReplace editor searchText replaceText
widgetGrabFocus editor
invokeReplaceNext :: App()
invokeReplaceNext = invokeOnActiveEditor replaceNext
replaceReset :: App()
replaceReset = invokeOnActiveEditor resetReplace
replaceMode :: Mode
replaceMode = Mode "replace" matcher replaceReset
where matcher = mconcat [ commandMatcher searchMode
, createMatcherForKeyBinding ([Shift, Control], "Down") replaceNextCommandHandler
]