module Potato.Data.Text.Zipper2 where
import Prelude
import Control.Exception (assert)
import Control.Monad.State (evalState, forM, get, put)
import Data.Char (isSpace)
import Data.Map (Map)
import Data.Maybe (fromMaybe)
import Data.String
import Data.Text (Text)
import Data.Text.Internal (Text(..), text)
import Data.Text.Internal.Fusion (stream)
import Data.Text.Internal.Fusion.Types (Stream(..), Step(..))
import Data.Text.Unsafe
import qualified Data.List as L
import qualified Data.Map as Map
import qualified Data.Text as T
import Graphics.Text.Width (wcwidth)
import qualified Data.List.NonEmpty as NE
charWidth :: Char -> Int
charWidth :: Char -> Int
charWidth = Char -> Int
wcwidth
data TextZipper = TextZipper
{ TextZipper -> [Text]
_textZipper_linesBefore :: [Text]
, TextZipper -> Text
_textZipper_before :: Text
, TextZipper -> [Text]
_textZipper_selected :: [Text]
, TextZipper -> Text
_textZipper_after :: Text
, TextZipper -> [Text]
_textZipper_linesAfter :: [Text]
}
deriving (Int -> TextZipper -> ShowS
[TextZipper] -> ShowS
TextZipper -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [TextZipper] -> ShowS
$cshowList :: [TextZipper] -> ShowS
show :: TextZipper -> String
$cshow :: TextZipper -> String
showsPrec :: Int -> TextZipper -> ShowS
$cshowsPrec :: Int -> TextZipper -> ShowS
Show, TextZipper -> TextZipper -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: TextZipper -> TextZipper -> Bool
$c/= :: TextZipper -> TextZipper -> Bool
== :: TextZipper -> TextZipper -> Bool
$c== :: TextZipper -> TextZipper -> Bool
Eq)
instance IsString TextZipper where
fromString :: String -> TextZipper
fromString = Text -> TextZipper
fromText forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Text
T.pack
mapZipper :: (Char -> Char) -> TextZipper -> TextZipper
mapZipper :: (Char -> Char) -> TextZipper -> TextZipper
mapZipper Char -> Char
f (TextZipper [Text]
lb Text
b [Text]
s Text
a [Text]
la) = TextZipper
{ _textZipper_linesBefore :: [Text]
_textZipper_linesBefore = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((Char -> Char) -> Text -> Text
T.map Char -> Char
f) [Text]
lb
, _textZipper_before :: Text
_textZipper_before = (Char -> Char) -> Text -> Text
T.map Char -> Char
f Text
b
, _textZipper_selected :: [Text]
_textZipper_selected = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((Char -> Char) -> Text -> Text
T.map Char -> Char
f) [Text]
s
, _textZipper_after :: Text
_textZipper_after = (Char -> Char) -> Text -> Text
T.map Char -> Char
f Text
a
, _textZipper_linesAfter :: [Text]
_textZipper_linesAfter = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((Char -> Char) -> Text -> Text
T.map Char -> Char
f) [Text]
la
}
appendEnd :: [Text] -> Text -> [Text]
appendEnd :: [Text] -> Text -> [Text]
appendEnd [Text]
stuff Text
addme = case [Text]
stuff of
[] -> [Text
addme]
(Text
x:[]) -> [Text
x forall a. Semigroup a => a -> a -> a
<> Text
addme]
(Text
x:[Text]
xs) -> Text
x forall a. a -> [a] -> [a]
: [Text] -> Text -> [Text]
appendEnd [Text]
xs Text
addme
left :: TextZipper -> TextZipper
left :: TextZipper -> TextZipper
left = Int -> TextZipper -> TextZipper
leftN Int
1
leftN :: Int -> TextZipper -> TextZipper
leftN :: Int -> TextZipper -> TextZipper
leftN Int
n z :: TextZipper
z@(TextZipper [Text]
lb Text
b [] Text
a [Text]
la) =
if Text -> Int
T.length Text
b forall a. Ord a => a -> a -> Bool
>= Int
n
then
let n' :: Int
n' = Text -> Int
T.length Text
b forall a. Num a => a -> a -> a
- Int
n
in [Text] -> Text -> [Text] -> Text -> [Text] -> TextZipper
TextZipper [Text]
lb (Int -> Text -> Text
T.take Int
n' Text
b) [] (Int -> Text -> Text
T.drop Int
n' Text
b forall a. Semigroup a => a -> a -> a
<> Text
a) [Text]
la
else case [Text]
lb of
[] -> TextZipper -> TextZipper
home TextZipper
z
(Text
l:[Text]
ls) -> Int -> TextZipper -> TextZipper
leftN (Int
n forall a. Num a => a -> a -> a
- Text -> Int
T.length Text
b forall a. Num a => a -> a -> a
- Int
1) forall a b. (a -> b) -> a -> b
$ [Text] -> Text -> [Text] -> Text -> [Text] -> TextZipper
TextZipper [Text]
ls Text
l [] Text
"" ((Text
b forall a. Semigroup a => a -> a -> a
<> Text
a) forall a. a -> [a] -> [a]
: [Text]
la)
leftN Int
n (TextZipper [Text]
lb Text
b [Text]
s Text
a [Text]
la) = Int -> TextZipper -> TextZipper
leftN Int
n forall a b. (a -> b) -> a -> b
$ [Text] -> Text -> [Text] -> Text -> [Text] -> TextZipper
TextZipper [Text]
lb Text
b [] Text
newa [Text]
newla where
(Text
newa, [Text]
newla') = case [Text]
s of
[] -> (Text
a, [Text]
la)
(Text
x:[]) -> (Text
x forall a. Semigroup a => a -> a -> a
<> Text
a, [Text]
la)
(Text
x:[Text]
xs) -> (Text
x, [Text] -> Text -> [Text]
appendEnd [Text]
xs Text
a)
newla :: [Text]
newla = [Text]
newla' forall a. Semigroup a => a -> a -> a
<> [Text]
la
shiftLeftN :: TextZipper -> TextZipper
shiftLeftN :: TextZipper -> TextZipper
shiftLeftN = forall a. HasCallStack => a
undefined
leftWord :: TextZipper -> TextZipper
leftWord :: TextZipper -> TextZipper
leftWord = forall a. HasCallStack => a
undefined
shiftLeftWord :: TextZipper -> TextZipper
shiftLeftWord :: TextZipper -> TextZipper
shiftLeftWord = forall a. HasCallStack => a
undefined
right :: TextZipper -> TextZipper
right :: TextZipper -> TextZipper
right = Int -> TextZipper -> TextZipper
rightN Int
1
rightN :: Int -> TextZipper -> TextZipper
rightN :: Int -> TextZipper -> TextZipper
rightN Int
n z :: TextZipper
z@(TextZipper [Text]
lb Text
b [Text]
s Text
a [Text]
la) = forall a. HasCallStack => a
undefined
shiftRightN :: TextZipper -> TextZipper
shiftRightN :: TextZipper -> TextZipper
shiftRightN = forall a. HasCallStack => a
undefined
rightWord :: TextZipper -> TextZipper
rightWord :: TextZipper -> TextZipper
rightWord = forall a. HasCallStack => a
undefined
rightLeftWord :: TextZipper -> TextZipper
rightLeftWord :: TextZipper -> TextZipper
rightLeftWord = forall a. HasCallStack => a
undefined
deselect :: TextZipper -> TextZipper
deselect :: TextZipper -> TextZipper
deselect tz :: TextZipper
tz@(TextZipper [Text]
lb Text
b [] Text
a [Text]
la) = TextZipper
tz
deselect (TextZipper [Text]
lb Text
b [Text
x] Text
a [Text]
la) = [Text] -> Text -> [Text] -> Text -> [Text] -> TextZipper
TextZipper [Text]
lb (Text
b forall a. Semigroup a => a -> a -> a
<> Text
x) [] Text
a [Text]
la
deselect (TextZipper [Text]
lb Text
b (Text
x:(Text
xs:[Text]
xss)) Text
a [Text]
la) = [Text] -> Text -> [Text] -> Text -> [Text] -> TextZipper
TextZipper ((forall a. [a] -> [a]
reverse forall a b. (a -> b) -> a -> b
$ forall a. NonEmpty a -> [a]
NE.init NonEmpty Text
xs') forall a. Semigroup a => a -> a -> a
<> [Text
b forall a. Semigroup a => a -> a -> a
<> Text
x] forall a. Semigroup a => a -> a -> a
<> [Text]
lb) (forall a. NonEmpty a -> a
NE.last NonEmpty Text
xs') [] Text
a [Text]
la where
xs' :: NonEmpty Text
xs' = Text
xs forall a. a -> [a] -> NonEmpty a
NE.:| [Text]
xss
up :: TextZipper -> TextZipper
up :: TextZipper -> TextZipper
up (TextZipper [] Text
b [] Text
a [Text]
la) = [Text] -> Text -> [Text] -> Text -> [Text] -> TextZipper
TextZipper [] Text
"" [] (Text
b forall a. Semigroup a => a -> a -> a
<> Text
a) [Text]
la
up (TextZipper (Text
x:[Text]
xs) Text
b [] Text
a [Text]
la) = [Text] -> Text -> [Text] -> Text -> [Text] -> TextZipper
TextZipper [Text]
xs Text
b' [] Text
a' ([Text
b forall a. Semigroup a => a -> a -> a
<> Text
a] forall a. Semigroup a => a -> a -> a
<> [Text]
la) where
(Text
b', Text
a') = Int -> Text -> (Text, Text)
T.splitAt (Text -> Int
T.length Text
b) Text
x
up tz :: TextZipper
tz@(TextZipper [Text]
lb Text
b [Text]
s Text
a [Text]
la) = TextZipper -> TextZipper
up forall a b. (a -> b) -> a -> b
$ TextZipper -> TextZipper
deselect TextZipper
tz
down :: TextZipper -> TextZipper
down :: TextZipper -> TextZipper
down (TextZipper [Text]
lb Text
b [] Text
a []) = [Text] -> Text -> [Text] -> Text -> [Text] -> TextZipper
TextZipper [Text]
lb (Text
b forall a. Semigroup a => a -> a -> a
<> Text
a) [] Text
"" []
down (TextZipper [Text]
lb Text
b [] Text
a (Text
x:[Text]
xs)) = [Text] -> Text -> [Text] -> Text -> [Text] -> TextZipper
TextZipper ([Text
b forall a. Semigroup a => a -> a -> a
<> Text
a] forall a. Semigroup a => a -> a -> a
<> [Text]
lb) Text
b' [] Text
a' [Text]
xs where
(Text
b', Text
a') = Int -> Text -> (Text, Text)
T.splitAt (Text -> Int
T.length Text
b) Text
x
down tz :: TextZipper
tz@(TextZipper [Text]
lb Text
b [Text]
s Text
a [Text]
la) = TextZipper -> TextZipper
down forall a b. (a -> b) -> a -> b
$ TextZipper -> TextZipper
deselect TextZipper
tz
pageUp :: Int -> TextZipper -> TextZipper
pageUp :: Int -> TextZipper -> TextZipper
pageUp Int
pageSize TextZipper
z = forall a. HasCallStack => a
undefined
pageDown :: Int -> TextZipper -> TextZipper
pageDown :: Int -> TextZipper -> TextZipper
pageDown Int
pageSize TextZipper
z = forall a. HasCallStack => a
undefined
home :: TextZipper -> TextZipper
home :: TextZipper -> TextZipper
home (TextZipper [Text]
lb Text
b [] Text
a [Text]
la) = [Text] -> Text -> [Text] -> Text -> [Text] -> TextZipper
TextZipper [Text]
lb Text
"" [] (Text
b forall a. Semigroup a => a -> a -> a
<> Text
a) [Text]
la
home (TextZipper [Text]
lb Text
b (Text
x:[]) Text
a [Text]
la) = [Text] -> Text -> [Text] -> Text -> [Text] -> TextZipper
TextZipper [Text]
lb Text
"" [] (Text
b forall a. Semigroup a => a -> a -> a
<> Text
x forall a. Semigroup a => a -> a -> a
<> Text
a) [Text]
la
home (TextZipper [Text]
lb Text
b (Text
x:(Text
xs:[Text]
xss)) Text
a [Text]
la) = [Text] -> Text -> [Text] -> Text -> [Text] -> TextZipper
TextZipper [Text]
lb Text
"" [] (Text
b forall a. Semigroup a => a -> a -> a
<> Text
x) (forall a. NonEmpty a -> [a]
NE.init NonEmpty Text
xs' forall a. Semigroup a => a -> a -> a
<> [forall a. NonEmpty a -> a
NE.last NonEmpty Text
xs' forall a. Semigroup a => a -> a -> a
<> Text
a] forall a. Semigroup a => a -> a -> a
<> [Text]
la) where
xs' :: NonEmpty Text
xs' = Text
xs forall a. a -> [a] -> NonEmpty a
NE.:| [Text]
xss
end :: TextZipper -> TextZipper
end :: TextZipper -> TextZipper
end (TextZipper [Text]
lb Text
b [] Text
a [Text]
la) = [Text] -> Text -> [Text] -> Text -> [Text] -> TextZipper
TextZipper [Text]
lb (Text
b forall a. Semigroup a => a -> a -> a
<> Text
a) [] Text
"" [Text]
la
end (TextZipper [Text]
lb Text
b (Text
x:[]) Text
a [Text]
la) = [Text] -> Text -> [Text] -> Text -> [Text] -> TextZipper
TextZipper [Text]
lb (Text
b forall a. Semigroup a => a -> a -> a
<> Text
x forall a. Semigroup a => a -> a -> a
<> Text
a) [] Text
"" [Text]
la
end (TextZipper [Text]
lb Text
b (Text
x:(Text
xs:[Text]
xss)) Text
a [Text]
la) =[Text] -> Text -> [Text] -> Text -> [Text] -> TextZipper
TextZipper ([Text]
lb forall a. Semigroup a => a -> a -> a
<> ([Text
b forall a. Semigroup a => a -> a -> a
<> Text
x] forall a. Semigroup a => a -> a -> a
<> forall a. NonEmpty a -> [a]
NE.init NonEmpty Text
xs')) (forall a. NonEmpty a -> a
NE.last NonEmpty Text
xs' forall a. Semigroup a => a -> a -> a
<> Text
a) [] Text
"" [Text]
la where
xs' :: NonEmpty Text
xs' = Text
xs forall a. a -> [a] -> NonEmpty a
NE.:| [Text]
xss
top :: TextZipper -> TextZipper
top :: TextZipper -> TextZipper
top tz :: TextZipper
tz@(TextZipper [] Text
"" [] Text
_ [Text]
_) = TextZipper
tz
top (TextZipper [Text
x] Text
"" [] Text
a [Text]
la) = [Text] -> Text -> [Text] -> Text -> [Text] -> TextZipper
TextZipper [] Text
"" [] Text
x (Text
aforall a. a -> [a] -> [a]
:[Text]
la)
top (TextZipper (Text
x:[Text]
xs) Text
"" [] Text
a [Text]
la) = [Text] -> Text -> [Text] -> Text -> [Text] -> TextZipper
TextZipper [] Text
"" [] (forall a. NonEmpty a -> a
NE.last NonEmpty Text
xs') ((forall a. [a] -> [a]
reverse forall a b. (a -> b) -> a -> b
$ forall a. NonEmpty a -> [a]
NE.init NonEmpty Text
xs') forall a. Semigroup a => a -> a -> a
<> (Text
aforall a. a -> [a] -> [a]
:[Text]
la)) where
xs' :: NonEmpty Text
xs' = Text
x forall a. a -> [a] -> NonEmpty a
NE.:| [Text]
xs
top TextZipper
tz = TextZipper -> TextZipper
top forall a b. (a -> b) -> a -> b
$ TextZipper -> TextZipper
home TextZipper
tz
insertChar :: Char -> TextZipper -> TextZipper
insertChar :: Char -> TextZipper -> TextZipper
insertChar Char
i = Text -> TextZipper -> TextZipper
insert (Char -> Text
T.singleton Char
i)
insert :: Text -> TextZipper -> TextZipper
insert :: Text -> TextZipper -> TextZipper
insert Text
i z :: TextZipper
z@(TextZipper [Text]
lb Text
b [Text]
s Text
a [Text]
la) = case (Char -> Bool) -> Text -> [Text]
T.split (forall a. Eq a => a -> a -> Bool
==Char
'\n') Text
i of
[] -> TextZipper
z
(Text
x:[Text]
xs) -> forall a. HasCallStack => a
undefined
deleteSelection :: TextZipper -> TextZipper
deleteSelection :: TextZipper -> TextZipper
deleteSelection = forall a. HasCallStack => a
undefined
deleteLeft :: TextZipper-> TextZipper
deleteLeft :: TextZipper -> TextZipper
deleteLeft z :: TextZipper
z@(TextZipper [Text]
lb Text
b [Text]
s Text
a [Text]
la) = forall a. HasCallStack => a
undefined
deleteRight :: TextZipper -> TextZipper
deleteRight :: TextZipper -> TextZipper
deleteRight z :: TextZipper
z@(TextZipper [Text]
lb Text
b [Text]
s Text
a [Text]
la) = forall a. HasCallStack => a
undefined
deleteLeftWord :: TextZipper -> TextZipper
deleteLeftWord :: TextZipper -> TextZipper
deleteLeftWord (TextZipper [Text]
lb Text
b [Text]
s Text
a [Text]
la) = forall a. HasCallStack => a
undefined
tab :: Int -> TextZipper -> TextZipper
tab :: Int -> TextZipper -> TextZipper
tab Int
n (TextZipper [Text]
_ Text
b [Text]
s Text
_ [Text]
_) = forall a. HasCallStack => a
undefined
value :: TextZipper -> Text
value :: TextZipper -> Text
value (TextZipper [Text]
lb Text
b [Text]
s Text
a [Text]
la) = forall a. HasCallStack => a
undefined
empty :: TextZipper
empty :: TextZipper
empty = [Text] -> Text -> [Text] -> Text -> [Text] -> TextZipper
TextZipper [] Text
"" [] Text
"" []
fromText :: Text -> TextZipper
fromText :: Text -> TextZipper
fromText = forall a b c. (a -> b -> c) -> b -> a -> c
flip Text -> TextZipper -> TextZipper
insert TextZipper
empty
data TextAlignment =
TextAlignment_Left
| TextAlignment_Right
| TextAlignment_Center
deriving (TextAlignment -> TextAlignment -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: TextAlignment -> TextAlignment -> Bool
$c/= :: TextAlignment -> TextAlignment -> Bool
== :: TextAlignment -> TextAlignment -> Bool
$c== :: TextAlignment -> TextAlignment -> Bool
Eq, Int -> TextAlignment -> ShowS
[TextAlignment] -> ShowS
TextAlignment -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [TextAlignment] -> ShowS
$cshowList :: [TextAlignment] -> ShowS
show :: TextAlignment -> String
$cshow :: TextAlignment -> String
showsPrec :: Int -> TextAlignment -> ShowS
$cshowsPrec :: Int -> TextAlignment -> ShowS
Show)
type OffsetMapWithAlignment = Map Int (Int, Int)
data DisplayLines = DisplayLines
{ DisplayLines -> [[Text]]
_displayLines_text :: [[Text]]
, DisplayLines -> OffsetMapWithAlignment
_displayLines_offsetMap :: OffsetMapWithAlignment
, DisplayLines -> (Int, Int)
_displayLines_cursorPos :: (Int, Int)
, DisplayLines -> Int
_displayLines_selectionCount :: Int
}
deriving (DisplayLines -> DisplayLines -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: DisplayLines -> DisplayLines -> Bool
$c/= :: DisplayLines -> DisplayLines -> Bool
== :: DisplayLines -> DisplayLines -> Bool
$c== :: DisplayLines -> DisplayLines -> Bool
Eq, Int -> DisplayLines -> ShowS
[DisplayLines] -> ShowS
DisplayLines -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [DisplayLines] -> ShowS
$cshowList :: [DisplayLines] -> ShowS
show :: DisplayLines -> String
$cshow :: DisplayLines -> String
showsPrec :: Int -> DisplayLines -> ShowS
$cshowsPrec :: Int -> DisplayLines -> ShowS
Show)
goToDisplayLinePosition :: Bool -> Int -> Int -> DisplayLines -> TextZipper -> TextZipper
goToDisplayLinePosition :: Bool -> Int -> Int -> DisplayLines -> TextZipper -> TextZipper
goToDisplayLinePosition Bool
add Int
x Int
y DisplayLines
dl TextZipper
tz = forall a. HasCallStack => a
undefined
displayLinesWithAlignment
:: TextAlignment
-> Int
-> TextZipper
-> DisplayLines
displayLinesWithAlignment :: TextAlignment -> Int -> TextZipper -> DisplayLines
displayLinesWithAlignment = forall a. HasCallStack => a
undefined