diff options
Diffstat (limited to 'src/Hack')
| -rw-r--r-- | src/Hack/Buffer.hs | 7 | ||||
| -rw-r--r-- | src/Hack/Buffer/Class.hs | 13 | ||||
| -rw-r--r-- | src/Hack/Buffer/Motion.hs | 108 | 
3 files changed, 128 insertions, 0 deletions
| diff --git a/src/Hack/Buffer.hs b/src/Hack/Buffer.hs new file mode 100644 index 0000000..8e03eb7 --- /dev/null +++ b/src/Hack/Buffer.hs @@ -0,0 +1,7 @@ +module Hack.Buffer +    ( module Hack.Buffer.Class +    , module Hack.Buffer.Motion +    ) where + +import Hack.Buffer.Class +import Hack.Buffer.Motion diff --git a/src/Hack/Buffer/Class.hs b/src/Hack/Buffer/Class.hs new file mode 100644 index 0000000..3644717 --- /dev/null +++ b/src/Hack/Buffer/Class.hs @@ -0,0 +1,13 @@ +-- TODO Class is a lie +module Hack.Buffer.Class where + + +type Buffer = (String, String) + +emptyBuffer :: Buffer +emptyBuffer = ("", "") + + +-- TODO instance Show Buffer (w/newtype Buffer) (?) +showBuffer :: Buffer -> String +showBuffer (lhs, rhs) = lhs ++ rhs diff --git a/src/Hack/Buffer/Motion.hs b/src/Hack/Buffer/Motion.hs new file mode 100644 index 0000000..5ddddc9 --- /dev/null +++ b/src/Hack/Buffer/Motion.hs @@ -0,0 +1,108 @@ +module Hack.Buffer.Motion where + +import Data.List (dropWhileEnd) +import Hack.Buffer.Class + +-- TODO factor Count +-- TODO various Vim gX +data Motion +  = CharsBackward +  | CharsForward +  | ToStartOfLine +  -- | GotoFirstNonBlankChar +  | ToEndOfLine             -- XXX in Vi this can go downwards +  | ToColumn +  -- | 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 :: Motion -> Int -> Buffer -> Buffer +move CharsBackward c = gotoLeft c +move CharsForward c = gotoRight c +move ToStartOfLine _ = gotoFirstChar -- TODO use count +move ToEndOfLine _ = gotoEndOfLine -- TODO use count +move ToColumn c = gotoColumn c +move WordsForward c = wordsForward c +move WordsBackward c = wordsBackward c + + +select :: Motion -> Int -> Buffer -> String +select x i b = +    if nls' < nls then take (nls - nls') rs' else +    if nrs' < nrs then take (nrs - nrs') rs else +    "" +  where +    (ls, rs) = b +    (ls', rs') = move x i b +    nls = length ls +    nls' = length ls' +    nrs = length rs +    nrs' = length rs' + + +delete :: Motion -> Int -> Buffer -> Buffer +delete x i b = +    ( if nls' < nls then ls' else ls +    , if nrs' < nrs then rs' else rs +    ) +  where +    (ls, rs) = b +    (ls', rs')= move x i b +    nls = length ls +    nls' = length ls' +    nrs = length rs +    nrs' = length rs' | 
