1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
|
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
|