{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE OverloadedStrings #-}
{-# OPTIONS_HADDOCK show-extensions #-}
module Yi.Keymap.Vim.SearchMotionMap (defSearchMotionMap) where
import Control.Monad (replicateM_)
import Data.Maybe (fromMaybe)
import qualified Data.Text as T (pack, unpack)
import Yi.Buffer (Direction (Backward, Forward), elemsB)
import Yi.Editor (getEditorDyn, withCurrentBuffer)
import Yi.History (historyFinish, historyPrefixSet)
import Yi.Keymap.Vim.Common
import Yi.Keymap.Vim.Search (continueVimSearch)
import Yi.Keymap.Vim.StateUtils (getCountE, switchModeE)
import Yi.Keymap.Vim.Utils (matchFromBool)
import qualified Yi.Rope as R (toText)
import Yi.Search
defSearchMotionMap :: [VimBinding]
defSearchMotionMap :: [VimBinding]
defSearchMotionMap = [VimBinding
enterBinding, VimBinding
editBinding, VimBinding
exitBinding]
enterBinding :: VimBinding
enterBinding :: VimBinding
enterBinding = (EventString -> VimState -> MatchResult (EditorM RepeatToken))
-> VimBinding
VimBindingE EventString -> VimState -> MatchResult (EditorM RepeatToken)
forall a.
(Eq a, IsString a) =>
a -> VimState -> MatchResult (EditorM RepeatToken)
f
where f :: a -> VimState -> MatchResult (EditorM RepeatToken)
f a
"<CR>" (VimState { vsMode :: VimState -> VimMode
vsMode = Search {}} ) = EditorM RepeatToken -> MatchResult (EditorM RepeatToken)
forall a. a -> MatchResult a
WholeMatch (EditorM RepeatToken -> MatchResult (EditorM RepeatToken))
-> EditorM RepeatToken -> MatchResult (EditorM RepeatToken)
forall a b. (a -> b) -> a -> b
$ do
Search VimMode
prevMode Direction
dir <- (VimState -> VimMode) -> EditorM VimState -> EditorM VimMode
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap VimState -> VimMode
vsMode EditorM VimState
forall (m :: * -> *) a.
(MonadEditor m, YiVariable a, Default a, Functor m) =>
m a
getEditorDyn
EditorM ()
isearchFinishE
EditorM ()
historyFinish
VimMode -> EditorM ()
switchModeE VimMode
prevMode
Int
count <- EditorM Int
getCountE
EditorM (Maybe SearchExp)
getRegexE EditorM (Maybe SearchExp)
-> (Maybe SearchExp -> EditorM ()) -> EditorM ()
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
Maybe SearchExp
Nothing -> () -> EditorM ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
Just SearchExp
regex -> BufferM () -> EditorM ()
forall (m :: * -> *) a. MonadEditor m => BufferM a -> m a
withCurrentBuffer (BufferM () -> EditorM ()) -> BufferM () -> EditorM ()
forall a b. (a -> b) -> a -> b
$
if Int
count Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
1 Bool -> Bool -> Bool
&& Direction
dir Direction -> Direction -> Bool
forall a. Eq a => a -> a -> Bool
== Direction
Forward
then do
(SearchExp, Direction) -> BufferM ()
continueVimSearch (SearchExp
regex, Direction
Backward)
(SearchExp, Direction) -> BufferM ()
continueVimSearch (SearchExp
regex, Direction
Forward)
else Int -> BufferM () -> BufferM ()
forall (m :: * -> *) a. Applicative m => Int -> m a -> m ()
replicateM_ (Int
count Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1) (BufferM () -> BufferM ()) -> BufferM () -> BufferM ()
forall a b. (a -> b) -> a -> b
$ (SearchExp, Direction) -> BufferM ()
continueVimSearch (SearchExp
regex, Direction
dir)
case VimMode
prevMode of
Visual RegionStyle
_ -> RepeatToken -> EditorM RepeatToken
forall (m :: * -> *) a. Monad m => a -> m a
return RepeatToken
Continue
VimMode
_ -> RepeatToken -> EditorM RepeatToken
forall (m :: * -> *) a. Monad m => a -> m a
return RepeatToken
Finish
f a
_ VimState
_ = MatchResult (EditorM RepeatToken)
forall a. MatchResult a
NoMatch
editBinding :: VimBinding
editBinding :: VimBinding
editBinding = (EventString -> VimState -> MatchResult (EditorM RepeatToken))
-> VimBinding
VimBindingE ([Char] -> VimState -> MatchResult (EditorM RepeatToken)
f ([Char] -> VimState -> MatchResult (EditorM RepeatToken))
-> (EventString -> [Char])
-> EventString
-> VimState
-> MatchResult (EditorM RepeatToken)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> [Char]
T.unpack (Text -> [Char]) -> (EventString -> Text) -> EventString -> [Char]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. EventString -> Text
_unEv)
where
f :: [Char] -> VimState -> MatchResult (EditorM RepeatToken)
f [Char]
evs (VimState { vsMode :: VimState -> VimMode
vsMode = Search {}} )
= [Char] -> EditorM RepeatToken
action [Char]
evs EditorM RepeatToken
-> MatchResult () -> MatchResult (EditorM RepeatToken)
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$
Bool -> MatchResult ()
matchFromBool ([Char]
evs [Char] -> [[Char]] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` ((Text, EditorM ()) -> [Char]) -> [(Text, EditorM ())] -> [[Char]]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Text -> [Char]
T.unpack (Text -> [Char])
-> ((Text, EditorM ()) -> Text) -> (Text, EditorM ()) -> [Char]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Text, EditorM ()) -> Text
forall a b. (a, b) -> a
fst) [(Text, EditorM ())]
binds
Bool -> Bool -> Bool
|| [Char] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null (Int -> [Char] -> [Char]
forall a. Int -> [a] -> [a]
drop Int
1 [Char]
evs))
f [Char]
_ VimState
_ = MatchResult (EditorM RepeatToken)
forall a. MatchResult a
NoMatch
action :: [Char] -> EditorM RepeatToken
action [Char]
evs = do
let evs' :: Text
evs' = [Char] -> Text
T.pack [Char]
evs
EditorM () -> Maybe (EditorM ()) -> EditorM ()
forall a. a -> Maybe a -> a
fromMaybe (Text -> EditorM ()
isearchAddE Text
evs') (Text -> [(Text, EditorM ())] -> Maybe (EditorM ())
forall a b. Eq a => a -> [(a, b)] -> Maybe b
lookup Text
evs' [(Text, EditorM ())]
binds)
BufferM YiString -> EditorM YiString
forall (m :: * -> *) a. MonadEditor m => BufferM a -> m a
withCurrentBuffer BufferM YiString
elemsB EditorM YiString -> (YiString -> EditorM ()) -> EditorM ()
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Text -> EditorM ()
historyPrefixSet (Text -> EditorM ())
-> (YiString -> Text) -> YiString -> EditorM ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. YiString -> Text
R.toText
RepeatToken -> EditorM RepeatToken
forall (m :: * -> *) a. Monad m => a -> m a
return RepeatToken
Continue
binds :: [(Text, EditorM ())]
binds = [ (Text
"<BS>", EditorM ()
isearchDelE)
, (Text
"<C-h>", EditorM ()
isearchDelE)
, (Text
"<C-p>", Int -> EditorM ()
isearchHistory Int
1)
, (Text
"<Up>", Int -> EditorM ()
isearchHistory Int
1)
, (Text
"<C-n>", Int -> EditorM ()
isearchHistory (-Int
1))
, (Text
"<Down>", Int -> EditorM ()
isearchHistory (-Int
1))
, (Text
"<lt>", Text -> EditorM ()
isearchAddE Text
"<")
]
exitBinding :: VimBinding
exitBinding :: VimBinding
exitBinding = (EventString -> VimState -> MatchResult (EditorM RepeatToken))
-> VimBinding
VimBindingE EventString -> VimState -> MatchResult (EditorM RepeatToken)
forall p. p -> VimState -> MatchResult (EditorM RepeatToken)
f
where f :: p -> VimState -> MatchResult (EditorM RepeatToken)
f p
_ (VimState { vsMode :: VimState -> VimMode
vsMode = Search {}} ) = EditorM RepeatToken -> MatchResult (EditorM RepeatToken)
forall a. a -> MatchResult a
WholeMatch (EditorM RepeatToken -> MatchResult (EditorM RepeatToken))
-> EditorM RepeatToken -> MatchResult (EditorM RepeatToken)
forall a b. (a -> b) -> a -> b
$ do
Search VimMode
prevMode Direction
_dir <- (VimState -> VimMode) -> EditorM VimState -> EditorM VimMode
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap VimState -> VimMode
vsMode EditorM VimState
forall (m :: * -> *) a.
(MonadEditor m, YiVariable a, Default a, Functor m) =>
m a
getEditorDyn
EditorM ()
isearchCancelE
VimMode -> EditorM ()
switchModeE VimMode
prevMode
RepeatToken -> EditorM RepeatToken
forall (m :: * -> *) a. Monad m => a -> m a
return RepeatToken
Drop
f p
_ VimState
_ = MatchResult (EditorM RepeatToken)
forall a. MatchResult a
NoMatch