module Data.Text.Zipper
( TextZipper
, mkZipper
, textZipper
, stringZipper
, clearZipper
, vectorZipper
, getText
, currentLine
, cursorPosition
, lineLengths
, getLineLimit
, moveCursor
, moveCursorClosest
, moveRight
, moveLeft
, moveUp
, moveDown
, gotoEOL
, gotoBOL
, gotoEOF
, gotoBOF
, currentChar
, nextChar
, previousChar
, insertChar
, insertMany
, deletePrevChar
, deleteChar
, breakLine
, killToEOL
, killToBOL
, killToEOF
, killToBOF
, transposeChars
)
where
import Control.Applicative ((<$>))
import Control.DeepSeq
import Data.Char (isPrint)
import Data.List (foldl')
import Data.Monoid
import qualified Data.Text as T
import qualified Data.Vector as V
import qualified Data.Text.Zipper.Vector as V
data TextZipper a =
TZ { forall a. TextZipper a -> a
toLeft :: a
, forall a. TextZipper a -> a
toRight :: a
, forall a. TextZipper a -> [a]
above :: [a]
, forall a. TextZipper a -> [a]
below :: [a]
, forall a. TextZipper a -> Char -> a
fromChar :: Char -> a
, forall a. TextZipper a -> Int -> a -> a
drop_ :: Int -> a -> a
, forall a. TextZipper a -> Int -> a -> a
take_ :: Int -> a -> a
, forall a. TextZipper a -> a -> Int
length_ :: a -> Int
, forall a. TextZipper a -> a -> Char
last_ :: a -> Char
, forall a. TextZipper a -> a -> a
init_ :: a -> a
, forall a. TextZipper a -> a -> Bool
null_ :: a -> Bool
, forall a. TextZipper a -> a -> [a]
lines_ :: a -> [a]
, forall a. TextZipper a -> a -> String
toList_ :: a -> [Char]
, forall a. TextZipper a -> Maybe Int
lineLimit :: Maybe Int
}
instance (NFData a) => NFData (TextZipper a) where
rnf :: TextZipper a -> ()
rnf TextZipper a
z = (forall a. TextZipper a -> a
toLeft TextZipper a
z) forall a b. NFData a => a -> b -> b
`deepseq`
(forall a. TextZipper a -> a
toRight TextZipper a
z) forall a b. NFData a => a -> b -> b
`deepseq`
(forall a. TextZipper a -> [a]
above TextZipper a
z) forall a b. NFData a => a -> b -> b
`deepseq`
(forall a. TextZipper a -> [a]
below TextZipper a
z) forall a b. NFData a => a -> b -> b
`deepseq`
()
getLineLimit :: TextZipper a -> Maybe Int
getLineLimit :: forall a. TextZipper a -> Maybe Int
getLineLimit = forall a. TextZipper a -> Maybe Int
lineLimit
instance (Eq a) => Eq (TextZipper a) where
TextZipper a
a == :: TextZipper a -> TextZipper a -> Bool
== TextZipper a
b = forall (t :: * -> *). Foldable t => t Bool -> Bool
and [ forall a. TextZipper a -> a
toLeft TextZipper a
a forall a. Eq a => a -> a -> Bool
== forall a. TextZipper a -> a
toLeft TextZipper a
b
, forall a. TextZipper a -> a
toRight TextZipper a
a forall a. Eq a => a -> a -> Bool
== forall a. TextZipper a -> a
toRight TextZipper a
b
, forall a. TextZipper a -> [a]
above TextZipper a
a forall a. Eq a => a -> a -> Bool
== forall a. TextZipper a -> [a]
above TextZipper a
b
, forall a. TextZipper a -> [a]
below TextZipper a
a forall a. Eq a => a -> a -> Bool
== forall a. TextZipper a -> [a]
below TextZipper a
b
]
instance (Show a) => Show (TextZipper a) where
show :: TextZipper a -> String
show TextZipper a
tz = forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat [ String
"TextZipper { "
, String
"above = "
, forall a. Show a => a -> String
show forall a b. (a -> b) -> a -> b
$ forall a. TextZipper a -> [a]
above TextZipper a
tz
, String
", below = "
, forall a. Show a => a -> String
show forall a b. (a -> b) -> a -> b
$ forall a. TextZipper a -> [a]
below TextZipper a
tz
, String
", toLeft = "
, forall a. Show a => a -> String
show forall a b. (a -> b) -> a -> b
$ forall a. TextZipper a -> a
toLeft TextZipper a
tz
, String
", toRight = "
, forall a. Show a => a -> String
show forall a b. (a -> b) -> a -> b
$ forall a. TextZipper a -> a
toRight TextZipper a
tz
, String
" }"
]
mkZipper :: (Monoid a) =>
(Char -> a)
-> (Int -> a -> a)
-> (Int -> a -> a)
-> (a -> Int)
-> (a -> Char)
-> (a -> a)
-> (a -> Bool)
-> (a -> [a])
-> (a -> [Char])
-> [a]
-> Maybe Int
-> TextZipper a
mkZipper :: forall a.
Monoid a =>
(Char -> a)
-> (Int -> a -> a)
-> (Int -> a -> a)
-> (a -> Int)
-> (a -> Char)
-> (a -> a)
-> (a -> Bool)
-> (a -> [a])
-> (a -> String)
-> [a]
-> Maybe Int
-> TextZipper a
mkZipper Char -> a
fromCh Int -> a -> a
drp Int -> a -> a
tk a -> Int
lngth a -> Char
lst a -> a
int a -> Bool
nl a -> [a]
linesFunc a -> String
toListF [a]
ls Maybe Int
lmt =
let limitedLs :: [a]
limitedLs = case Maybe Int
lmt of
Maybe Int
Nothing -> [a]
ls
Just Int
n -> forall a. Int -> [a] -> [a]
take Int
n [a]
ls
(a
first, [a]
rest) = if forall (t :: * -> *) a. Foldable t => t a -> Bool
null [a]
limitedLs
then (forall a. Monoid a => a
mempty, forall a. Monoid a => a
mempty)
else (forall a. [a] -> a
head [a]
limitedLs, forall a. [a] -> [a]
tail [a]
limitedLs)
numLines :: Int
numLines = forall (t :: * -> *) a. Foldable t => t a -> Int
length [a]
ls
insertLine :: TextZipper a -> (Int, a) -> TextZipper a
insertLine TextZipper a
z (Int
i, a
l) = (if Int
i forall a. Ord a => a -> a -> Bool
< Int
numLines forall a. Num a => a -> a -> a
- Int
1 then forall a. Monoid a => TextZipper a -> TextZipper a
breakLine else forall a. a -> a
id) forall a b. (a -> b) -> a -> b
$ forall a. Monoid a => a -> TextZipper a -> TextZipper a
insertMany a
l TextZipper a
z
loadInitial :: TextZipper a -> TextZipper a
loadInitial TextZipper a
z = forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' forall {a}. Monoid a => TextZipper a -> (Int, a) -> TextZipper a
insertLine TextZipper a
z forall a b. (a -> b) -> a -> b
$ forall a b. [a] -> [b] -> [(a, b)]
zip [Int
0..] (a
firstforall a. a -> [a] -> [a]
:[a]
rest)
in TextZipper a -> TextZipper a
loadInitial forall a b. (a -> b) -> a -> b
$ forall a.
a
-> a
-> [a]
-> [a]
-> (Char -> a)
-> (Int -> a -> a)
-> (Int -> a -> a)
-> (a -> Int)
-> (a -> Char)
-> (a -> a)
-> (a -> Bool)
-> (a -> [a])
-> (a -> String)
-> Maybe Int
-> TextZipper a
TZ forall a. Monoid a => a
mempty forall a. Monoid a => a
mempty forall a. Monoid a => a
mempty forall a. Monoid a => a
mempty Char -> a
fromCh Int -> a -> a
drp Int -> a -> a
tk a -> Int
lngth a -> Char
lst a -> a
int a -> Bool
nl a -> [a]
linesFunc a -> String
toListF Maybe Int
lmt
getText :: (Monoid a) => TextZipper a -> [a]
getText :: forall a. Monoid a => TextZipper a -> [a]
getText TextZipper a
tz = forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat [ forall a. TextZipper a -> [a]
above TextZipper a
tz
, [forall a. Monoid a => TextZipper a -> a
currentLine TextZipper a
tz]
, forall a. TextZipper a -> [a]
below TextZipper a
tz
]
lineLengths :: (Monoid a) => TextZipper a -> [Int]
lineLengths :: forall a. Monoid a => TextZipper a -> [Int]
lineLengths TextZipper a
tz = (forall a. TextZipper a -> a -> Int
length_ TextZipper a
tz) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat [ forall a. TextZipper a -> [a]
above TextZipper a
tz
, [forall a. Monoid a => TextZipper a -> a
currentLine TextZipper a
tz]
, forall a. TextZipper a -> [a]
below TextZipper a
tz
]
cursorPosition :: TextZipper a -> (Int, Int)
cursorPosition :: forall a. TextZipper a -> (Int, Int)
cursorPosition TextZipper a
tz = (forall (t :: * -> *) a. Foldable t => t a -> Int
length forall a b. (a -> b) -> a -> b
$ forall a. TextZipper a -> [a]
above TextZipper a
tz, forall a. TextZipper a -> a -> Int
length_ TextZipper a
tz forall a b. (a -> b) -> a -> b
$ forall a. TextZipper a -> a
toLeft TextZipper a
tz)
moveCursor :: (Monoid a) => (Int, Int) -> TextZipper a -> TextZipper a
moveCursor :: forall a. Monoid a => (Int, Int) -> TextZipper a -> TextZipper a
moveCursor (Int
row, Int
col) TextZipper a
tz =
let t :: [a]
t = forall a. Monoid a => TextZipper a -> [a]
getText TextZipper a
tz
in if Int
row forall a. Ord a => a -> a -> Bool
< Int
0
Bool -> Bool -> Bool
|| Int
row forall a. Ord a => a -> a -> Bool
>= forall (t :: * -> *) a. Foldable t => t a -> Int
length [a]
t
Bool -> Bool -> Bool
|| Int
col forall a. Ord a => a -> a -> Bool
< Int
0
Bool -> Bool -> Bool
|| Int
col forall a. Ord a => a -> a -> Bool
> forall a. TextZipper a -> a -> Int
length_ TextZipper a
tz ([a]
t forall a. [a] -> Int -> a
!! Int
row)
then TextZipper a
tz
else TextZipper a
tz { above :: [a]
above = forall a. Int -> [a] -> [a]
take Int
row [a]
t
, below :: [a]
below = forall a. Int -> [a] -> [a]
drop (Int
row forall a. Num a => a -> a -> a
+ Int
1) [a]
t
, toLeft :: a
toLeft = forall a. TextZipper a -> Int -> a -> a
take_ TextZipper a
tz Int
col ([a]
t forall a. [a] -> Int -> a
!! Int
row)
, toRight :: a
toRight = forall a. TextZipper a -> Int -> a -> a
drop_ TextZipper a
tz Int
col ([a]
t forall a. [a] -> Int -> a
!! Int
row)
}
moveCursorClosest :: (Monoid a) => (Int, Int) -> TextZipper a -> TextZipper a
moveCursorClosest :: forall a. Monoid a => (Int, Int) -> TextZipper a -> TextZipper a
moveCursorClosest (Int
row, Int
col) TextZipper a
tz =
let t :: [a]
t = forall a. Monoid a => TextZipper a -> [a]
getText TextZipper a
tz
bestRow :: Int
bestRow = forall a. Ord a => a -> a -> a
min (forall a. Ord a => a -> a -> a
max Int
0 forall a b. (a -> b) -> a -> b
$ forall (t :: * -> *) a. Foldable t => t a -> Int
length [a]
t forall a. Num a => a -> a -> a
- Int
1) forall a b. (a -> b) -> a -> b
$ forall a. Ord a => a -> a -> a
max Int
0 Int
row
bestCol :: Int
bestCol = if Int
bestRow forall a. Ord a => a -> a -> Bool
< forall (t :: * -> *) a. Foldable t => t a -> Int
length [a]
t
then forall a. Ord a => a -> a -> a
min (forall a. TextZipper a -> a -> Int
length_ TextZipper a
tz ([a]
t forall a. [a] -> Int -> a
!! Int
bestRow)) forall a b. (a -> b) -> a -> b
$ forall a. Ord a => a -> a -> a
max Int
0 Int
col
else Int
0
in TextZipper a
tz { above :: [a]
above = forall a. Int -> [a] -> [a]
take Int
bestRow [a]
t
, below :: [a]
below = forall a. Int -> [a] -> [a]
drop (Int
bestRow forall a. Num a => a -> a -> a
+ Int
1) [a]
t
, toLeft :: a
toLeft = forall a. TextZipper a -> Int -> a -> a
take_ TextZipper a
tz Int
bestCol ([a]
t forall a. [a] -> Int -> a
!! Int
bestRow)
, toRight :: a
toRight = forall a. TextZipper a -> Int -> a -> a
drop_ TextZipper a
tz Int
bestCol ([a]
t forall a. [a] -> Int -> a
!! Int
bestRow)
}
isFirstLine :: TextZipper a -> Bool
isFirstLine :: forall a. TextZipper a -> Bool
isFirstLine = forall (t :: * -> *) a. Foldable t => t a -> Bool
null forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. TextZipper a -> [a]
above
isLastLine :: TextZipper a -> Bool
isLastLine :: forall a. TextZipper a -> Bool
isLastLine = (forall a. Eq a => a -> a -> Bool
== Int
0) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (t :: * -> *) a. Foldable t => t a -> Int
length forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. TextZipper a -> [a]
below
nextLine :: TextZipper a -> a
nextLine :: forall a. TextZipper a -> a
nextLine = forall a. [a] -> a
head forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. TextZipper a -> [a]
below
currentLine :: (Monoid a) => TextZipper a -> a
currentLine :: forall a. Monoid a => TextZipper a -> a
currentLine TextZipper a
tz = (forall a. TextZipper a -> a
toLeft TextZipper a
tz) forall a. Monoid a => a -> a -> a
`mappend` (forall a. TextZipper a -> a
toRight TextZipper a
tz)
insertChar :: (Monoid a) => Char -> TextZipper a -> TextZipper a
insertChar :: forall a. Monoid a => Char -> TextZipper a -> TextZipper a
insertChar Char
ch TextZipper a
tz
| Char
ch forall a. Eq a => a -> a -> Bool
== Char
'\n' = forall a. Monoid a => TextZipper a -> TextZipper a
breakLine TextZipper a
tz
| Char -> Bool
isPrint Char
ch = TextZipper a
tz { toLeft :: a
toLeft = forall a. TextZipper a -> a
toLeft TextZipper a
tz forall a. Monoid a => a -> a -> a
`mappend` (forall a. TextZipper a -> Char -> a
fromChar TextZipper a
tz Char
ch) }
| Bool
otherwise = TextZipper a
tz
insertMany :: (Monoid a) => a -> TextZipper a -> TextZipper a
insertMany :: forall a. Monoid a => a -> TextZipper a -> TextZipper a
insertMany a
str TextZipper a
tz = forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' (forall a b c. (a -> b -> c) -> b -> a -> c
flip forall a. Monoid a => Char -> TextZipper a -> TextZipper a
insertChar) TextZipper a
tz forall a b. (a -> b) -> a -> b
$ forall a. TextZipper a -> a -> String
toList_ TextZipper a
tz a
str
breakLine :: (Monoid a) => TextZipper a -> TextZipper a
breakLine :: forall a. Monoid a => TextZipper a -> TextZipper a
breakLine TextZipper a
tz =
let modified :: TextZipper a
modified = TextZipper a
tz { above :: [a]
above = forall a. TextZipper a -> [a]
above TextZipper a
tz forall a. [a] -> [a] -> [a]
++ [forall a. TextZipper a -> a
toLeft TextZipper a
tz]
, toLeft :: a
toLeft = forall a. Monoid a => a
mempty
}
in case forall a. TextZipper a -> Maybe Int
lineLimit TextZipper a
tz of
Just Int
lim -> if forall (t :: * -> *) a. Foldable t => t a -> Int
length (forall a. TextZipper a -> [a]
above TextZipper a
tz) forall a. Num a => a -> a -> a
+ forall (t :: * -> *) a. Foldable t => t a -> Int
length (forall a. TextZipper a -> [a]
below TextZipper a
tz) forall a. Num a => a -> a -> a
+ Int
2 forall a. Ord a => a -> a -> Bool
> Int
lim
then TextZipper a
tz
else TextZipper a
modified
Maybe Int
Nothing -> TextZipper a
modified
gotoEOL :: (Monoid a) => TextZipper a -> TextZipper a
gotoEOL :: forall a. Monoid a => TextZipper a -> TextZipper a
gotoEOL TextZipper a
tz = TextZipper a
tz { toLeft :: a
toLeft = forall a. Monoid a => TextZipper a -> a
currentLine TextZipper a
tz
, toRight :: a
toRight = forall a. Monoid a => a
mempty
}
gotoEOF :: (Monoid a) => TextZipper a -> TextZipper a
gotoEOF :: forall a. Monoid a => TextZipper a -> TextZipper a
gotoEOF TextZipper a
tz =
TextZipper a
tz { toLeft :: a
toLeft = a
end
, toRight :: a
toRight = forall a. Monoid a => a
mempty
, above :: [a]
above = [a]
top
, below :: [a]
below = forall a. Monoid a => a
mempty
}
where
tx :: [a]
tx = forall a. Monoid a => TextZipper a -> [a]
getText TextZipper a
tz
([a]
top, a
end) = if forall (t :: * -> *) a. Foldable t => t a -> Bool
null [a]
tx
then (forall a. Monoid a => a
mempty, forall a. Monoid a => a
mempty)
else (forall a. [a] -> [a]
init [a]
tx, forall a. [a] -> a
last [a]
tx)
killToEOL :: (Monoid a) => TextZipper a -> TextZipper a
killToEOL :: forall a. Monoid a => TextZipper a -> TextZipper a
killToEOL TextZipper a
tz
| (forall a. TextZipper a -> a -> Bool
null_ TextZipper a
tz forall a b. (a -> b) -> a -> b
$ forall a. TextZipper a -> a
toLeft TextZipper a
tz) Bool -> Bool -> Bool
&& (forall a. TextZipper a -> a -> Bool
null_ TextZipper a
tz forall a b. (a -> b) -> a -> b
$ forall a. TextZipper a -> a
toRight TextZipper a
tz) Bool -> Bool -> Bool
&&
(Bool -> Bool
not forall a b. (a -> b) -> a -> b
$ forall (t :: * -> *) a. Foldable t => t a -> Bool
null forall a b. (a -> b) -> a -> b
$ forall a. TextZipper a -> [a]
below TextZipper a
tz) =
TextZipper a
tz { toRight :: a
toRight = forall a. [a] -> a
head forall a b. (a -> b) -> a -> b
$ forall a. TextZipper a -> [a]
below TextZipper a
tz
, below :: [a]
below = forall a. [a] -> [a]
tail forall a b. (a -> b) -> a -> b
$ forall a. TextZipper a -> [a]
below TextZipper a
tz
}
| Bool
otherwise = TextZipper a
tz { toRight :: a
toRight = forall a. Monoid a => a
mempty
}
killToBOL :: Monoid a => TextZipper a -> TextZipper a
killToBOL :: forall a. Monoid a => TextZipper a -> TextZipper a
killToBOL TextZipper a
tz = TextZipper a
tz { toLeft :: a
toLeft = forall a. Monoid a => a
mempty
}
killToEOF :: (Monoid a) => TextZipper a -> TextZipper a
killToEOF :: forall a. Monoid a => TextZipper a -> TextZipper a
killToEOF TextZipper a
tz =
TextZipper a
tz { toRight :: a
toRight = forall a. Monoid a => a
mempty
, below :: [a]
below = forall a. Monoid a => a
mempty
}
killToBOF :: Monoid a => TextZipper a -> TextZipper a
killToBOF :: forall a. Monoid a => TextZipper a -> TextZipper a
killToBOF TextZipper a
tz =
TextZipper a
tz { toLeft :: a
toLeft = forall a. Monoid a => a
mempty
, above :: [a]
above = forall a. Monoid a => a
mempty
}
deletePrevChar :: (Eq a, Monoid a) => TextZipper a -> TextZipper a
deletePrevChar :: forall a. (Eq a, Monoid a) => TextZipper a -> TextZipper a
deletePrevChar TextZipper a
tz
| forall a. Monoid a => TextZipper a -> TextZipper a
moveLeft TextZipper a
tz forall a. Eq a => a -> a -> Bool
== TextZipper a
tz = TextZipper a
tz
| Bool
otherwise = forall a. Monoid a => TextZipper a -> TextZipper a
deleteChar forall a b. (a -> b) -> a -> b
$ forall a. Monoid a => TextZipper a -> TextZipper a
moveLeft TextZipper a
tz
deleteChar :: (Monoid a) => TextZipper a -> TextZipper a
deleteChar :: forall a. Monoid a => TextZipper a -> TextZipper a
deleteChar TextZipper a
tz
| (Bool -> Bool
not forall a b. (a -> b) -> a -> b
$ forall a. TextZipper a -> a -> Bool
null_ TextZipper a
tz (forall a. TextZipper a -> a
toRight TextZipper a
tz)) =
TextZipper a
tz { toRight :: a
toRight = forall a. TextZipper a -> Int -> a -> a
drop_ TextZipper a
tz Int
1 forall a b. (a -> b) -> a -> b
$ forall a. TextZipper a -> a
toRight TextZipper a
tz
}
| forall a. TextZipper a -> a -> Bool
null_ TextZipper a
tz (forall a. TextZipper a -> a
toRight TextZipper a
tz) Bool -> Bool -> Bool
&& (Bool -> Bool
not forall a b. (a -> b) -> a -> b
$ forall (t :: * -> *) a. Foldable t => t a -> Bool
null forall a b. (a -> b) -> a -> b
$ forall a. TextZipper a -> [a]
below TextZipper a
tz) =
TextZipper a
tz { toRight :: a
toRight = forall a. [a] -> a
head forall a b. (a -> b) -> a -> b
$ forall a. TextZipper a -> [a]
below TextZipper a
tz
, below :: [a]
below = forall a. [a] -> [a]
tail forall a b. (a -> b) -> a -> b
$ forall a. TextZipper a -> [a]
below TextZipper a
tz
}
| Bool
otherwise = TextZipper a
tz
currentChar :: TextZipper a -> Maybe Char
currentChar :: forall a. TextZipper a -> Maybe Char
currentChar TextZipper a
tz
| Bool -> Bool
not (forall a. TextZipper a -> a -> Bool
null_ TextZipper a
tz (forall a. TextZipper a -> a
toRight TextZipper a
tz)) =
forall a. a -> Maybe a
Just (forall a. TextZipper a -> a -> Char
last_ TextZipper a
tz (forall a. TextZipper a -> Int -> a -> a
take_ TextZipper a
tz Int
1 (forall a. TextZipper a -> a
toRight TextZipper a
tz)))
| Bool
otherwise = forall a. Maybe a
Nothing
nextChar :: (Monoid a) => TextZipper a -> Maybe Char
nextChar :: forall a. Monoid a => TextZipper a -> Maybe Char
nextChar TextZipper a
tz = forall a. TextZipper a -> Maybe Char
currentChar (forall a. Monoid a => TextZipper a -> TextZipper a
moveRight TextZipper a
tz)
previousChar :: (Monoid a) => TextZipper a -> Maybe Char
previousChar :: forall a. Monoid a => TextZipper a -> Maybe Char
previousChar TextZipper a
tz
| forall a b. (a, b) -> b
snd (forall a. TextZipper a -> (Int, Int)
cursorPosition TextZipper a
tz) forall a. Eq a => a -> a -> Bool
== Int
0 Bool -> Bool -> Bool
&& forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all (forall a. TextZipper a -> a -> Bool
null_ TextZipper a
tz) (forall a. TextZipper a -> [a]
above TextZipper a
tz) =
forall a. Maybe a
Nothing
| Bool
otherwise =
forall a. TextZipper a -> Maybe Char
currentChar (forall a. Monoid a => TextZipper a -> TextZipper a
moveLeft TextZipper a
tz)
gotoBOL :: (Monoid a) => TextZipper a -> TextZipper a
gotoBOL :: forall a. Monoid a => TextZipper a -> TextZipper a
gotoBOL TextZipper a
tz = TextZipper a
tz { toLeft :: a
toLeft = forall a. Monoid a => a
mempty
, toRight :: a
toRight = forall a. Monoid a => TextZipper a -> a
currentLine TextZipper a
tz
}
gotoBOF :: (Monoid a) => TextZipper a -> TextZipper a
gotoBOF :: forall a. Monoid a => TextZipper a -> TextZipper a
gotoBOF TextZipper a
tz =
TextZipper a
tz { toLeft :: a
toLeft = forall a. Monoid a => a
mempty
, toRight :: a
toRight = a
first
, above :: [a]
above = forall a. Monoid a => a
mempty
, below :: [a]
below = [a]
rest
}
where
tx :: [a]
tx = forall a. Monoid a => TextZipper a -> [a]
getText TextZipper a
tz
(a
first, [a]
rest) = if forall (t :: * -> *) a. Foldable t => t a -> Bool
null [a]
tx
then (forall a. Monoid a => a
mempty, forall a. Monoid a => a
mempty)
else (forall a. [a] -> a
head [a]
tx, forall a. [a] -> [a]
tail [a]
tx)
moveRight :: (Monoid a) => TextZipper a -> TextZipper a
moveRight :: forall a. Monoid a => TextZipper a -> TextZipper a
moveRight TextZipper a
tz
| Bool -> Bool
not (forall a. TextZipper a -> a -> Bool
null_ TextZipper a
tz (forall a. TextZipper a -> a
toRight TextZipper a
tz)) =
TextZipper a
tz { toLeft :: a
toLeft = forall a. TextZipper a -> a
toLeft TextZipper a
tz
forall a. Monoid a => a -> a -> a
`mappend` (forall a. TextZipper a -> Int -> a -> a
take_ TextZipper a
tz Int
1 forall a b. (a -> b) -> a -> b
$ forall a. TextZipper a -> a
toRight TextZipper a
tz)
, toRight :: a
toRight = forall a. TextZipper a -> Int -> a -> a
drop_ TextZipper a
tz Int
1 (forall a. TextZipper a -> a
toRight TextZipper a
tz)
}
| Bool -> Bool
not forall a b. (a -> b) -> a -> b
$ forall (t :: * -> *) a. Foldable t => t a -> Bool
null (forall a. TextZipper a -> [a]
below TextZipper a
tz) =
TextZipper a
tz { above :: [a]
above = forall a. TextZipper a -> [a]
above TextZipper a
tz forall a. [a] -> [a] -> [a]
++ [forall a. TextZipper a -> a
toLeft TextZipper a
tz]
, below :: [a]
below = forall a. [a] -> [a]
tail forall a b. (a -> b) -> a -> b
$ forall a. TextZipper a -> [a]
below TextZipper a
tz
, toLeft :: a
toLeft = forall a. Monoid a => a
mempty
, toRight :: a
toRight = forall a. TextZipper a -> a
nextLine TextZipper a
tz
}
| Bool
otherwise = TextZipper a
tz
moveLeft :: (Monoid a) => TextZipper a -> TextZipper a
moveLeft :: forall a. Monoid a => TextZipper a -> TextZipper a
moveLeft TextZipper a
tz
| Bool -> Bool
not forall a b. (a -> b) -> a -> b
$ forall a. TextZipper a -> a -> Bool
null_ TextZipper a
tz (forall a. TextZipper a -> a
toLeft TextZipper a
tz) =
TextZipper a
tz { toLeft :: a
toLeft = forall a. TextZipper a -> a -> a
init_ TextZipper a
tz forall a b. (a -> b) -> a -> b
$ forall a. TextZipper a -> a
toLeft TextZipper a
tz
, toRight :: a
toRight = forall a. TextZipper a -> Char -> a
fromChar TextZipper a
tz (forall a. TextZipper a -> a -> Char
last_ TextZipper a
tz (forall a. TextZipper a -> a
toLeft TextZipper a
tz))
forall a. Monoid a => a -> a -> a
`mappend` forall a. TextZipper a -> a
toRight TextZipper a
tz
}
| Bool -> Bool
not forall a b. (a -> b) -> a -> b
$ forall (t :: * -> *) a. Foldable t => t a -> Bool
null (forall a. TextZipper a -> [a]
above TextZipper a
tz) =
TextZipper a
tz { above :: [a]
above = forall a. [a] -> [a]
init forall a b. (a -> b) -> a -> b
$ forall a. TextZipper a -> [a]
above TextZipper a
tz
, below :: [a]
below = forall a. Monoid a => TextZipper a -> a
currentLine TextZipper a
tz forall a. a -> [a] -> [a]
: forall a. TextZipper a -> [a]
below TextZipper a
tz
, toLeft :: a
toLeft = forall a. [a] -> a
last forall a b. (a -> b) -> a -> b
$ forall a. TextZipper a -> [a]
above TextZipper a
tz
, toRight :: a
toRight = forall a. Monoid a => a
mempty
}
| Bool
otherwise = TextZipper a
tz
moveUp :: (Monoid a) => TextZipper a -> TextZipper a
moveUp :: forall a. Monoid a => TextZipper a -> TextZipper a
moveUp TextZipper a
tz
| (Bool -> Bool
not forall a b. (a -> b) -> a -> b
$ forall a. TextZipper a -> Bool
isFirstLine TextZipper a
tz) Bool -> Bool -> Bool
&&
(forall a. TextZipper a -> a -> Int
length_ TextZipper a
tz forall a b. (a -> b) -> a -> b
$ forall a. [a] -> a
last forall a b. (a -> b) -> a -> b
$ forall a. TextZipper a -> [a]
above TextZipper a
tz) forall a. Ord a => a -> a -> Bool
>= forall a. TextZipper a -> a -> Int
length_ TextZipper a
tz (forall a. TextZipper a -> a
toLeft TextZipper a
tz) =
TextZipper a
tz { below :: [a]
below = forall a. Monoid a => TextZipper a -> a
currentLine TextZipper a
tz forall a. a -> [a] -> [a]
: forall a. TextZipper a -> [a]
below TextZipper a
tz
, above :: [a]
above = forall a. [a] -> [a]
init forall a b. (a -> b) -> a -> b
$ forall a. TextZipper a -> [a]
above TextZipper a
tz
, toLeft :: a
toLeft = forall a. TextZipper a -> Int -> a -> a
take_ TextZipper a
tz (forall a. TextZipper a -> a -> Int
length_ TextZipper a
tz forall a b. (a -> b) -> a -> b
$ forall a. TextZipper a -> a
toLeft TextZipper a
tz) (forall a. [a] -> a
last forall a b. (a -> b) -> a -> b
$ forall a. TextZipper a -> [a]
above TextZipper a
tz)
, toRight :: a
toRight = forall a. TextZipper a -> Int -> a -> a
drop_ TextZipper a
tz (forall a. TextZipper a -> a -> Int
length_ TextZipper a
tz forall a b. (a -> b) -> a -> b
$ forall a. TextZipper a -> a
toLeft TextZipper a
tz) (forall a. [a] -> a
last forall a b. (a -> b) -> a -> b
$ forall a. TextZipper a -> [a]
above TextZipper a
tz)
}
| (Bool -> Bool
not forall a b. (a -> b) -> a -> b
$ forall a. TextZipper a -> Bool
isFirstLine TextZipper a
tz) =
TextZipper a
tz { above :: [a]
above = forall a. [a] -> [a]
init forall a b. (a -> b) -> a -> b
$ forall a. TextZipper a -> [a]
above TextZipper a
tz
, below :: [a]
below = forall a. Monoid a => TextZipper a -> a
currentLine TextZipper a
tz forall a. a -> [a] -> [a]
: forall a. TextZipper a -> [a]
below TextZipper a
tz
, toLeft :: a
toLeft = forall a. [a] -> a
last forall a b. (a -> b) -> a -> b
$ forall a. TextZipper a -> [a]
above TextZipper a
tz
, toRight :: a
toRight = forall a. Monoid a => a
mempty
}
| Bool
otherwise = forall a. Monoid a => TextZipper a -> TextZipper a
gotoBOL TextZipper a
tz
moveDown :: (Monoid a) => TextZipper a -> TextZipper a
moveDown :: forall a. Monoid a => TextZipper a -> TextZipper a
moveDown TextZipper a
tz
| (Bool -> Bool
not forall a b. (a -> b) -> a -> b
$ forall a. TextZipper a -> Bool
isLastLine TextZipper a
tz) Bool -> Bool -> Bool
&&
(forall a. TextZipper a -> a -> Int
length_ TextZipper a
tz forall a b. (a -> b) -> a -> b
$ forall a. TextZipper a -> a
nextLine TextZipper a
tz) forall a. Ord a => a -> a -> Bool
>= forall a. TextZipper a -> a -> Int
length_ TextZipper a
tz (forall a. TextZipper a -> a
toLeft TextZipper a
tz) =
TextZipper a
tz { below :: [a]
below = forall a. [a] -> [a]
tail forall a b. (a -> b) -> a -> b
$ forall a. TextZipper a -> [a]
below TextZipper a
tz
, above :: [a]
above = forall a. TextZipper a -> [a]
above TextZipper a
tz forall a. [a] -> [a] -> [a]
++ [forall a. Monoid a => TextZipper a -> a
currentLine TextZipper a
tz]
, toLeft :: a
toLeft = forall a. TextZipper a -> Int -> a -> a
take_ TextZipper a
tz (forall a. TextZipper a -> a -> Int
length_ TextZipper a
tz forall a b. (a -> b) -> a -> b
$ forall a. TextZipper a -> a
toLeft TextZipper a
tz) (forall a. TextZipper a -> a
nextLine TextZipper a
tz)
, toRight :: a
toRight = forall a. TextZipper a -> Int -> a -> a
drop_ TextZipper a
tz (forall a. TextZipper a -> a -> Int
length_ TextZipper a
tz forall a b. (a -> b) -> a -> b
$ forall a. TextZipper a -> a
toLeft TextZipper a
tz) (forall a. TextZipper a -> a
nextLine TextZipper a
tz)
}
| (Bool -> Bool
not forall a b. (a -> b) -> a -> b
$ forall a. TextZipper a -> Bool
isLastLine TextZipper a
tz) =
TextZipper a
tz { above :: [a]
above = forall a. TextZipper a -> [a]
above TextZipper a
tz forall a. [a] -> [a] -> [a]
++ [forall a. Monoid a => TextZipper a -> a
currentLine TextZipper a
tz]
, below :: [a]
below = forall a. [a] -> [a]
tail forall a b. (a -> b) -> a -> b
$ forall a. TextZipper a -> [a]
below TextZipper a
tz
, toLeft :: a
toLeft = forall a. TextZipper a -> a
nextLine TextZipper a
tz
, toRight :: a
toRight = forall a. Monoid a => a
mempty
}
| Bool
otherwise = forall a. Monoid a => TextZipper a -> TextZipper a
gotoEOL TextZipper a
tz
transposeChars :: (Monoid a) => TextZipper a -> TextZipper a
transposeChars :: forall a. Monoid a => TextZipper a -> TextZipper a
transposeChars TextZipper a
tz
| forall a. TextZipper a -> a -> Bool
null_ TextZipper a
tz (forall a. TextZipper a -> a
toLeft TextZipper a
tz) = TextZipper a
tz
| forall a. TextZipper a -> a -> Bool
null_ TextZipper a
tz (forall a. TextZipper a -> a
toRight TextZipper a
tz) =
if forall a. TextZipper a -> a -> Int
length_ TextZipper a
tz (forall a. TextZipper a -> a
toLeft TextZipper a
tz) forall a. Ord a => a -> a -> Bool
< Int
2
then TextZipper a
tz
else let prefixLen :: Int
prefixLen = forall a. TextZipper a -> a -> Int
length_ TextZipper a
tz (forall a. TextZipper a -> a
toLeft TextZipper a
tz) forall a. Num a => a -> a -> a
- Int
2
prefix :: a
prefix = forall a. TextZipper a -> Int -> a -> a
take_ TextZipper a
tz Int
prefixLen (forall a. TextZipper a -> a
toLeft TextZipper a
tz)
lastTwo :: a
lastTwo = forall a. TextZipper a -> Int -> a -> a
drop_ TextZipper a
tz Int
prefixLen (forall a. TextZipper a -> a
toLeft TextZipper a
tz)
a :: a
a = forall a. TextZipper a -> Int -> a -> a
take_ TextZipper a
tz Int
1 a
lastTwo
b :: a
b = forall a. TextZipper a -> Int -> a -> a
drop_ TextZipper a
tz Int
1 a
lastTwo
in TextZipper a
tz { toLeft :: a
toLeft = a
prefix forall a. Semigroup a => a -> a -> a
<> a
b forall a. Semigroup a => a -> a -> a
<> a
a
}
| Bool
otherwise = TextZipper a
tz { toLeft :: a
toLeft = (forall a. TextZipper a -> a -> a
init_ TextZipper a
tz forall a b. (a -> b) -> a -> b
$ forall a. TextZipper a -> a
toLeft TextZipper a
tz) forall a. Semigroup a => a -> a -> a
<>
(forall a. TextZipper a -> Int -> a -> a
take_ TextZipper a
tz Int
1 forall a b. (a -> b) -> a -> b
$ forall a. TextZipper a -> a
toRight TextZipper a
tz) forall a. Semigroup a => a -> a -> a
<>
(forall a. TextZipper a -> Char -> a
fromChar TextZipper a
tz forall a b. (a -> b) -> a -> b
$ forall a. TextZipper a -> a -> Char
last_ TextZipper a
tz forall a b. (a -> b) -> a -> b
$ forall a. TextZipper a -> a
toLeft TextZipper a
tz)
, toRight :: a
toRight = (forall a. TextZipper a -> Int -> a -> a
drop_ TextZipper a
tz Int
1 forall a b. (a -> b) -> a -> b
$ forall a. TextZipper a -> a
toRight TextZipper a
tz)
}
stringZipper :: [String] -> Maybe Int -> TextZipper String
stringZipper :: [String] -> Maybe Int -> TextZipper String
stringZipper =
forall a.
Monoid a =>
(Char -> a)
-> (Int -> a -> a)
-> (Int -> a -> a)
-> (a -> Int)
-> (a -> Char)
-> (a -> a)
-> (a -> Bool)
-> (a -> [a])
-> (a -> String)
-> [a]
-> Maybe Int
-> TextZipper a
mkZipper (forall a. a -> [a] -> [a]
:[]) forall a. Int -> [a] -> [a]
drop forall a. Int -> [a] -> [a]
take forall (t :: * -> *) a. Foldable t => t a -> Int
length forall a. [a] -> a
last forall a. [a] -> [a]
init forall (t :: * -> *) a. Foldable t => t a -> Bool
null String -> [String]
lines forall a. a -> a
id
vectorZipper :: [V.Vector Char] -> Maybe Int -> TextZipper (V.Vector Char)
vectorZipper :: [Vector Char] -> Maybe Int -> TextZipper (Vector Char)
vectorZipper =
forall a.
Monoid a =>
(Char -> a)
-> (Int -> a -> a)
-> (Int -> a -> a)
-> (a -> Int)
-> (a -> Char)
-> (a -> a)
-> (a -> Bool)
-> (a -> [a])
-> (a -> String)
-> [a]
-> Maybe Int
-> TextZipper a
mkZipper forall a. a -> Vector a
V.singleton forall a. Int -> Vector a -> Vector a
V.drop forall a. Int -> Vector a -> Vector a
V.take forall a. Vector a -> Int
V.length forall a. Vector a -> a
V.last forall a. Vector a -> Vector a
V.init forall a. Vector a -> Bool
V.null Vector Char -> [Vector Char]
V.vecLines forall a. Vector a -> [a]
V.toList
clearZipper :: (Monoid a) => TextZipper a -> TextZipper a
clearZipper :: forall a. Monoid a => TextZipper a -> TextZipper a
clearZipper TextZipper a
tz =
TextZipper a
tz { toLeft :: a
toLeft = forall a. Monoid a => a
mempty
, toRight :: a
toRight = forall a. Monoid a => a
mempty
, above :: [a]
above = []
, below :: [a]
below = []
}
textZipper :: [T.Text] -> Maybe Int -> TextZipper T.Text
textZipper :: [Text] -> Maybe Int -> TextZipper Text
textZipper =
forall a.
Monoid a =>
(Char -> a)
-> (Int -> a -> a)
-> (Int -> a -> a)
-> (a -> Int)
-> (a -> Char)
-> (a -> a)
-> (a -> Bool)
-> (a -> [a])
-> (a -> String)
-> [a]
-> Maybe Int
-> TextZipper a
mkZipper Char -> Text
T.singleton Int -> Text -> Text
T.drop Int -> Text -> Text
T.take Text -> Int
T.length Text -> Char
T.last Text -> Text
T.init Text -> Bool
T.null Text -> [Text]
T.lines Text -> String
T.unpack