module Buffer.Motion where import Data.List (dropWhileEnd) import Buffer.Class --data Motion = Motion Int LeftRightMotion -- TODO factor Count -- TODO various Vim gX data LeftRightMotion = GotoLeft | GotoRight | GotoFirstChar -- | GotoFirstNonBlankChar | GotoEndOfLine -- XXX in Vi this can go downwards | GotoColumn -- | GotoFindLeft (Char -> Bool) -- TODO don't use functions here -- | GotoFindRight (Char -> Bool) -- TODO ^ dto. -- | GotillFindLeft Char -- | GotillFindRight Char -- | RepeatLastFind -- | RepeatLastFindReverse | WordsForward | WordsBackward deriving (Show) -- TODO fail if cannot splitAt properly OR if we didn't modify the buffer gotoLeft :: Int -> Buffer -> Buffer gotoLeft i (ls, rs) = let (lls, rls) = splitAt (length ls - i) ls in (lls, rls ++ rs) -- TODO fail if cannot splitAt properly OR if we didn't modify the buffer gotoRight :: Int -> Buffer -> Buffer gotoRight i (ls, rs) = let (lrs, rrs) = splitAt i rs in (ls ++ lrs, rrs) gotoFirstChar :: Buffer -> Buffer gotoFirstChar (ls, rs) = ("", ls ++ rs) gotoEndOfLine :: Buffer -> Buffer gotoEndOfLine (ls, rs) = (ls ++ rs, "") -- TODO fail if i <= 0 or i > length gotoColumn :: Int -> Buffer -> Buffer gotoColumn i (ls, rs) = splitAt (i - 1) $ ls ++ rs wordsForward :: Int -> Buffer -> Buffer wordsForward i (ls, rs) = let rs' = dropWhile (==' ') $ dropWhile (/=' ') rs ls' = ls ++ take (length rs - length rs') rs b' = (ls', rs') in if i > 1 then wordsForward (i - 1) b' else b' wordsBackward :: Int -> Buffer -> Buffer wordsBackward i (ls, rs) = let ls' = dropWhileEnd (/=' ') $ dropWhileEnd (==' ') ls rs' = drop (length ls') ls ++ rs b' = (ls', rs') in if i > 1 then wordsBackward (i - 1) b' else b' move :: LeftRightMotion -> Int -> Buffer -> Buffer move GotoLeft c = gotoLeft c move GotoRight c = gotoRight c move GotoFirstChar _ = gotoFirstChar -- TODO use count move GotoEndOfLine _ = gotoEndOfLine -- TODO use count move GotoColumn c = gotoColumn c move WordsForward c = wordsForward c move WordsBackward c = wordsBackward c