{-# Language TemplateHaskell, BangPatterns #-}
module Client.State.EditBox.Content
(
Content
, above
, below
, singleLine
, noContent
, shift
, toStrings
, fromStrings
, Line(..)
, HasLine(..)
, endLine
, left
, right
, leftWord
, rightWord
, jumpLeft
, jumpRight
, delete
, backspace
, insertPastedString
, insertString
, insertChar
, toggle
, digraph
) where
import Control.Applicative ((<|>))
import Control.Lens (view, views, (+~), (-~), over, set, makeClassy, makeLenses)
import Control.Monad (guard)
import Data.Char (isAlphaNum)
import Data.List (find)
import Data.List.NonEmpty (NonEmpty(..), (<|))
import Data.Map (Map)
import Data.Map qualified as Map
import Data.Text (Text)
import Data.Text qualified as Text
import Digraphs (Digraph(..), lookupDigraph)
data Line = Line
{ Line -> Int
_pos :: !Int
, Line -> String
_text :: !String
}
deriving (ReadPrec [Line]
ReadPrec Line
Int -> ReadS Line
ReadS [Line]
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [Line]
$creadListPrec :: ReadPrec [Line]
readPrec :: ReadPrec Line
$creadPrec :: ReadPrec Line
readList :: ReadS [Line]
$creadList :: ReadS [Line]
readsPrec :: Int -> ReadS Line
$creadsPrec :: Int -> ReadS Line
Read, Int -> Line -> ShowS
[Line] -> ShowS
Line -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Line] -> ShowS
$cshowList :: [Line] -> ShowS
show :: Line -> String
$cshow :: Line -> String
showsPrec :: Int -> Line -> ShowS
$cshowsPrec :: Int -> Line -> ShowS
Show)
makeClassy ''Line
emptyLine :: Line
emptyLine :: Line
emptyLine = Int -> String -> Line
Line Int
0 String
""
beginLine :: String -> Line
beginLine :: String -> Line
beginLine = Int -> String -> Line
Line Int
0
endLine :: String -> Line
endLine :: String -> Line
endLine String
s = Int -> String -> Line
Line (forall (t :: * -> *) a. Foldable t => t a -> Int
length String
s) String
s
data Content = Content
{ Content -> [String]
_above :: ![String]
, Content -> Line
_currentLine :: !Line
, Content -> [String]
_below :: ![String]
}
deriving (ReadPrec [Content]
ReadPrec Content
Int -> ReadS Content
ReadS [Content]
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [Content]
$creadListPrec :: ReadPrec [Content]
readPrec :: ReadPrec Content
$creadPrec :: ReadPrec Content
readList :: ReadS [Content]
$creadList :: ReadS [Content]
readsPrec :: Int -> ReadS Content
$creadsPrec :: Int -> ReadS Content
Read, Int -> Content -> ShowS
[Content] -> ShowS
Content -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Content] -> ShowS
$cshowList :: [Content] -> ShowS
show :: Content -> String
$cshow :: Content -> String
showsPrec :: Int -> Content -> ShowS
$cshowsPrec :: Int -> Content -> ShowS
Show)
makeLenses ''Content
instance HasLine Content where
line :: Lens' Content Line
line = Lens' Content Line
currentLine
noContent :: Content
noContent :: Content
noContent = [String] -> Line -> [String] -> Content
Content [] Line
emptyLine []
singleLine :: Line -> Content
singleLine :: Line -> Content
singleLine Line
l = [String] -> Line -> [String] -> Content
Content [] Line
l []
shift :: Content -> (String, Content)
shift :: Content -> (String, Content)
shift (Content [] Line
l []) = (forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view forall c. HasLine c => Lens' c String
text Line
l, Content
noContent)
shift (Content a :: [String]
a@(String
_:[String]
_) Line
l [String]
b) = (forall a. [a] -> a
last [String]
a, [String] -> Line -> [String] -> Content
Content (forall a. [a] -> [a]
init [String]
a) Line
l [String]
b)
shift (Content [] Line
l (String
b:[String]
bs)) = (forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view forall c. HasLine c => Lens' c String
text Line
l, [String] -> Line -> [String] -> Content
Content [] (String -> Line
beginLine String
b) [String]
bs)
jumpLeft :: Content -> Content
jumpLeft :: Content -> Content
jumpLeft Content
c
| forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view forall c. HasLine c => Lens' c Int
pos Content
c forall a. Eq a => a -> a -> Bool
== Int
0 = forall b a. b -> (a -> b) -> Maybe a -> b
maybe Content
c Content -> Content
begin1 (Content -> Maybe Content
backwardLine Content
c)
| Bool
otherwise = Content -> Content
begin1 Content
c
where
begin1 :: Content -> Content
begin1 = forall s t a b. ASetter s t a b -> b -> s -> t
set forall c. HasLine c => Lens' c Int
pos Int
0
jumpRight :: Content -> Content
jumpRight :: Content -> Content
jumpRight Content
c
| forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view forall c. HasLine c => Lens' c Int
pos Content
c forall a. Eq a => a -> a -> Bool
== Int
len = forall b a. b -> (a -> b) -> Maybe a -> b
maybe Content
c forall {s}. HasLine s => s -> s
end1 (Content -> Maybe Content
forwardLine Content
c)
| Bool
otherwise = forall s t a b. ASetter s t a b -> b -> s -> t
set forall c. HasLine c => Lens' c Int
pos Int
len Content
c
where
len :: Int
len = forall s (m :: * -> *) r a.
MonadReader s m =>
LensLike' (Const r) s a -> (a -> r) -> m r
views forall c. HasLine c => Lens' c String
text forall (t :: * -> *) a. Foldable t => t a -> Int
length Content
c
end1 :: s -> s
end1 s
l = forall s t a b. ASetter s t a b -> b -> s -> t
set forall c. HasLine c => Lens' c Int
pos (forall s (m :: * -> *) r a.
MonadReader s m =>
LensLike' (Const r) s a -> (a -> r) -> m r
views forall c. HasLine c => Lens' c String
text forall (t :: * -> *) a. Foldable t => t a -> Int
length s
l) s
l
left :: Content -> Content
left :: Content -> Content
left Content
c =
case forall a. Ord a => a -> a -> Ordering
compare (forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view forall c. HasLine c => Lens' c Int
pos Content
c) Int
0 of
Ordering
GT -> (forall c. HasLine c => Lens' c Int
pos forall a s t. Num a => ASetter s t a a -> a -> s -> t
-~ Int
1) Content
c
Ordering
EQ | Just Content
c' <- Content -> Maybe Content
backwardLine Content
c -> Content
c'
Ordering
_ -> Content
c
right :: Content -> Content
right :: Content -> Content
right Content
c =
let Line Int
n String
s = forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view forall c. HasLine c => Lens' c Line
line Content
c in
case forall a. Ord a => a -> a -> Ordering
compare Int
n (forall (t :: * -> *) a. Foldable t => t a -> Int
length String
s) of
Ordering
LT -> (forall c. HasLine c => Lens' c Int
pos forall a s t. Num a => ASetter s t a a -> a -> s -> t
+~ Int
1) Content
c
Ordering
EQ | Just Content
c' <- Content -> Maybe Content
forwardLine Content
c -> Content
c'
Ordering
_ -> Content
c
leftWord :: Content -> Content
leftWord :: Content -> Content
leftWord Content
c
| Int
n forall a. Eq a => a -> a -> Bool
== Int
0 = forall b a. b -> (a -> b) -> Maybe a -> b
maybe Content
c Content -> Content
leftWord (Content -> Maybe Content
backwardLine Content
c)
| Bool
otherwise = forall s t a b. ASetter s t a b -> b -> s -> t
set forall c. HasLine c => Lens' c Int
pos Int
search Content
c
where
Line Int
n String
txt = forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view forall c. HasLine c => Lens' c Line
line Content
c
search :: Int
search = forall b a. b -> (a -> b) -> Maybe a -> b
maybe Int
0 forall a b. (a, b) -> a
fst
forall a b. (a -> b) -> a -> b
$ forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Maybe a
find (Bool -> Bool
not forall b c a. (b -> c) -> (a -> b) -> a -> c
. Char -> Bool
isAlphaNum forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a, b) -> b
snd)
forall a b. (a -> b) -> a -> b
$ forall a. (a -> Bool) -> [a] -> [a]
dropWhile (Bool -> Bool
not forall b c a. (b -> c) -> (a -> b) -> a -> c
. Char -> Bool
isAlphaNum forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a, b) -> b
snd)
forall a b. (a -> b) -> a -> b
$ forall a. [a] -> [a]
reverse
forall a b. (a -> b) -> a -> b
$ forall a. Int -> [a] -> [a]
take Int
n
forall a b. (a -> b) -> a -> b
$ forall a b. [a] -> [b] -> [(a, b)]
zip [Int
1..] String
txt
rightWord :: Content -> Content
rightWord :: Content -> Content
rightWord Content
c
| Int
n forall a. Eq a => a -> a -> Bool
== Int
txtLen = forall b a. b -> (a -> b) -> Maybe a -> b
maybe Content
c Content -> Content
rightWord (Content -> Maybe Content
forwardLine Content
c)
| Bool
otherwise = forall s t a b. ASetter s t a b -> b -> s -> t
set forall c. HasLine c => Lens' c Int
pos Int
search Content
c
where
Line Int
n String
txt = forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view forall c. HasLine c => Lens' c Line
line Content
c
txtLen :: Int
txtLen = forall (t :: * -> *) a. Foldable t => t a -> Int
length String
txt
search :: Int
search = forall b a. b -> (a -> b) -> Maybe a -> b
maybe Int
txtLen forall a b. (a, b) -> a
fst
forall a b. (a -> b) -> a -> b
$ forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Maybe a
find (Bool -> Bool
not forall b c a. (b -> c) -> (a -> b) -> a -> c
. Char -> Bool
isAlphaNum forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a, b) -> b
snd)
forall a b. (a -> b) -> a -> b
$ forall a. (a -> Bool) -> [a] -> [a]
dropWhile (Bool -> Bool
not forall b c a. (b -> c) -> (a -> b) -> a -> c
. Char -> Bool
isAlphaNum forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a, b) -> b
snd)
forall a b. (a -> b) -> a -> b
$ forall a. Int -> [a] -> [a]
drop Int
n
forall a b. (a -> b) -> a -> b
$ forall a b. [a] -> [b] -> [(a, b)]
zip [Int
0..] String
txt
backspace :: Content -> Content
backspace :: Content -> Content
backspace Content
c
| Int
n forall a. Eq a => a -> a -> Bool
== Int
0
= case forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Lens' Content [String]
above Content
c of
[] -> Content
c
String
a:[String]
as -> forall s t a b. ASetter s t a b -> b -> s -> t
set Lens' Content [String]
above [String]
as
forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall s t a b. ASetter s t a b -> b -> s -> t
set forall c. HasLine c => Lens' c Line
line (Int -> String -> Line
Line (forall (t :: * -> *) a. Foldable t => t a -> Int
length String
a) (String
a forall a. [a] -> [a] -> [a]
++ String
s))
forall a b. (a -> b) -> a -> b
$ Content
c
| (String
preS, String
postS) <- forall a. Int -> [a] -> ([a], [a])
splitAt (Int
nforall a. Num a => a -> a -> a
-Int
1) String
s
= forall s t a b. ASetter s t a b -> b -> s -> t
set forall c. HasLine c => Lens' c Line
line (Int -> String -> Line
Line (Int
nforall a. Num a => a -> a -> a
-Int
1) (String
preS forall a. [a] -> [a] -> [a]
++ forall a. Int -> [a] -> [a]
drop Int
1 String
postS)) Content
c
where
Line Int
n String
s = forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view forall c. HasLine c => Lens' c Line
line Content
c
delete :: Content -> Content
delete :: Content -> Content
delete Content
c =
let Line Int
n String
s = forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view forall c. HasLine c => Lens' c Line
line Content
c in
case forall a. Int -> [a] -> ([a], [a])
splitAt Int
n String
s of
(String
preS, Char
_:String
postS) -> forall s t a b. ASetter s t a b -> b -> s -> t
set forall c. HasLine c => Lens' c String
text (String
preS forall a. [a] -> [a] -> [a]
++ String
postS) Content
c
(String, String)
_ -> case forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Lens' Content [String]
below Content
c of
[] -> Content
c
String
b:[String]
bs -> forall s t a b. ASetter s t a b -> b -> s -> t
set Lens' Content [String]
below [String]
bs
forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall s t a b. ASetter s t a b -> b -> s -> t
set forall c. HasLine c => Lens' c String
text (String
s forall a. [a] -> [a] -> [a]
++ String
b)
forall a b. (a -> b) -> a -> b
$ Content
c
insertChar :: Char -> Content -> Content
insertChar :: Char -> Content -> Content
insertChar Char
'\n' Content
c =
let Line Int
n String
txt = forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view forall c. HasLine c => Lens' c Line
line Content
c in
case forall a. Int -> [a] -> ([a], [a])
splitAt Int
n String
txt of
(String
preS, String
postS) -> forall s t a b. ASetter s t a b -> (a -> b) -> s -> t
over Lens' Content [String]
above (String
preS forall a. a -> [a] -> [a]
:)
forall a b. (a -> b) -> a -> b
$ forall s t a b. ASetter s t a b -> b -> s -> t
set forall c. HasLine c => Lens' c Line
line (String -> Line
beginLine String
postS) Content
c
insertChar Char
ins Content
c = forall s t a b. ASetter s t a b -> (a -> b) -> s -> t
over forall c. HasLine c => Lens' c Line
line Line -> Line
aux Content
c
where
aux :: Line -> Line
aux (Line Int
n String
txt) =
case forall a. Int -> [a] -> ([a], [a])
splitAt Int
n String
txt of
(String
preS, String
postS) -> Int -> String -> Line
Line (Int
nforall a. Num a => a -> a -> a
+Int
1) (String
preS forall a. [a] -> [a] -> [a]
++ Char
ins forall a. a -> [a] -> [a]
: String
postS)
insertPastedString :: String -> Content -> Content
insertPastedString :: String -> Content -> Content
insertPastedString String
paste Content
c = String -> Content -> Content
insertString (forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr Char -> ShowS
scrub String
"" String
paste) Content
c
where
cursorAtEnd :: Bool
cursorAtEnd = forall (t :: * -> *) a. Foldable t => t a -> Bool
null (forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Lens' Content [String]
below Content
c)
Bool -> Bool -> Bool
&& forall (t :: * -> *) a. Foldable t => t a -> Int
length (forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view forall c. HasLine c => Lens' c String
text Content
c) forall a. Eq a => a -> a -> Bool
== forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view forall c. HasLine c => Lens' c Int
pos Content
c
scrub :: Char -> ShowS
scrub Char
'\r' String
xs = String
xs
scrub Char
'\n' xs :: String
xs@(Char
'\n':String
_) = String
xs
scrub Char
'\n' String
"" | Bool
cursorAtEnd = String
""
scrub Char
x String
xs = Char
x forall a. a -> [a] -> [a]
: String
xs
insertString :: String -> Content -> Content
insertString :: String -> Content -> Content
insertString String
ins Content
c =
case [String] -> String -> [String] -> ([String], Line)
push (forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Lens' Content [String]
above Content
c) (String
preS forall a. [a] -> [a] -> [a]
++ String
l) [String]
ls of
([String]
newAbove, Line
newLine) -> forall s t a b. ASetter s t a b -> b -> s -> t
set Lens' Content [String]
above [String]
newAbove
forall a b. (a -> b) -> a -> b
$ forall s t a b. ASetter s t a b -> b -> s -> t
set forall c. HasLine c => Lens' c Line
line Line
newLine Content
c
where
String
l:[String]
ls = String -> [String]
lines (String
ins forall a. [a] -> [a] -> [a]
++ String
"\n")
Line Int
n String
txt = forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view forall c. HasLine c => Lens' c Line
line Content
c
(String
preS, String
postS) = forall a. Int -> [a] -> ([a], [a])
splitAt Int
n String
txt
push :: [String] -> String -> [String] -> ([String], Line)
push [String]
stk String
x [] = ([String]
stk, Int -> String -> Line
Line (forall (t :: * -> *) a. Foldable t => t a -> Int
length String
x) (String
x forall a. [a] -> [a] -> [a]
++ String
postS))
push [String]
stk String
x (String
y:[String]
ys) = [String] -> String -> [String] -> ([String], Line)
push (String
xforall a. a -> [a] -> [a]
:[String]
stk) String
y [String]
ys
forwardLine :: Content -> Maybe Content
forwardLine :: Content -> Maybe Content
forwardLine Content
c =
case forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Lens' Content [String]
below Content
c of
[] -> forall a. Maybe a
Nothing
String
b:[String]
bs -> forall a. a -> Maybe a
Just
forall a b. (a -> b) -> a -> b
$! forall s t a b. ASetter s t a b -> (a -> b) -> s -> t
over Lens' Content [String]
above (forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view forall c. HasLine c => Lens' c String
text Content
c forall a. a -> [a] -> [a]
:)
forall a b. (a -> b) -> a -> b
$ forall s t a b. ASetter s t a b -> b -> s -> t
set Lens' Content [String]
below [String]
bs
forall a b. (a -> b) -> a -> b
$ forall s t a b. ASetter s t a b -> b -> s -> t
set forall c. HasLine c => Lens' c Line
line (String -> Line
beginLine String
b) Content
c
backwardLine :: Content -> Maybe Content
backwardLine :: Content -> Maybe Content
backwardLine Content
c =
case forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Lens' Content [String]
above Content
c of
[] -> forall a. Maybe a
Nothing
String
a:[String]
as -> forall a. a -> Maybe a
Just
forall a b. (a -> b) -> a -> b
$! forall s t a b. ASetter s t a b -> (a -> b) -> s -> t
over Lens' Content [String]
below (forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view forall c. HasLine c => Lens' c String
text Content
c forall a. a -> [a] -> [a]
:)
forall a b. (a -> b) -> a -> b
$ forall s t a b. ASetter s t a b -> b -> s -> t
set Lens' Content [String]
above [String]
as
forall a b. (a -> b) -> a -> b
$ forall s t a b. ASetter s t a b -> b -> s -> t
set forall c. HasLine c => Lens' c Line
line (String -> Line
endLine String
a) Content
c
toggle :: Content -> Content
toggle :: Content -> Content
toggle !Content
c
| Int
p forall a. Ord a => a -> a -> Bool
< Int
1 = Content
c
| Int
n forall a. Ord a => a -> a -> Bool
< Int
2 = Content
c
| Int
n forall a. Eq a => a -> a -> Bool
== Int
p = forall s t a b. ASetter s t a b -> (a -> b) -> s -> t
over forall c. HasLine c => Lens' c String
text (forall {t} {a}. (Eq t, Num t) => t -> [a] -> [a]
swapAt (Int
pforall a. Num a => a -> a -> a
-Int
2)) Content
c
| Bool
otherwise = forall s t a b. ASetter s t a b -> b -> s -> t
set forall c. HasLine c => Lens' c Int
pos (Int
pforall a. Num a => a -> a -> a
+Int
1)
forall a b. (a -> b) -> a -> b
$ forall s t a b. ASetter s t a b -> (a -> b) -> s -> t
over forall c. HasLine c => Lens' c String
text (forall {t} {a}. (Eq t, Num t) => t -> [a] -> [a]
swapAt (Int
pforall a. Num a => a -> a -> a
-Int
1)) Content
c
where
p :: Int
p = forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view forall c. HasLine c => Lens' c Int
pos Content
c
n :: Int
n = forall s (m :: * -> *) r a.
MonadReader s m =>
LensLike' (Const r) s a -> (a -> r) -> m r
views forall c. HasLine c => Lens' c String
text forall (t :: * -> *) a. Foldable t => t a -> Int
length Content
c
swapAt :: t -> [a] -> [a]
swapAt t
0 (a
x:a
y:[a]
z) = a
yforall a. a -> [a] -> [a]
:a
xforall a. a -> [a] -> [a]
:[a]
z
swapAt t
i (a
x:[a]
xs) = a
xforall a. a -> [a] -> [a]
:t -> [a] -> [a]
swapAt (t
iforall a. Num a => a -> a -> a
-t
1) [a]
xs
swapAt t
_ [a]
_ = forall a. HasCallStack => String -> a
error String
"toggle: PANIC! Invalid argument"
digraph :: Map Digraph Text -> Content -> Maybe Content
digraph :: Map Digraph Text -> Content -> Maybe Content
digraph Map Digraph Text
extras !Content
c =
do let Line Int
n String
txt = forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view forall c. HasLine c => Lens' c Line
line Content
c
forall (f :: * -> *). Alternative f => Bool -> f ()
guard (Int
2 forall a. Ord a => a -> a -> Bool
<= Int
n)
let (String
pfx,Char
x:Char
y:String
sfx) = forall a. Int -> [a] -> ([a], [a])
splitAt (Int
n forall a. Num a => a -> a -> a
- Int
2) String
txt
let key :: Digraph
key = Char -> Char -> Digraph
Digraph Char
x Char
y
String
d <- Text -> String
Text.unpack forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup Digraph
key Map Digraph Text
extras
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> forall (f :: * -> *) a. Applicative f => a -> f a
pure forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Digraph -> Maybe Char
lookupDigraph Digraph
key
let line' :: Line
line' = Int -> String -> Line
Line (Int
nforall a. Num a => a -> a -> a
-Int
1) (String
pfxforall a. [a] -> [a] -> [a]
++String
dforall a. [a] -> [a] -> [a]
++String
sfx)
forall a. a -> Maybe a
Just forall a b. (a -> b) -> a -> b
$! forall s t a b. ASetter s t a b -> b -> s -> t
set forall c. HasLine c => Lens' c Line
line Line
line' Content
c
fromStrings :: NonEmpty String -> Content
fromStrings :: NonEmpty String -> Content
fromStrings (String
x :| [String]
xs) = [String] -> Line -> [String] -> Content
Content [String]
xs (String -> Line
endLine String
x) []
toStrings :: Content -> NonEmpty String
toStrings :: Content -> NonEmpty String
toStrings Content
c = 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. a -> NonEmpty a -> NonEmpty a
(<|)) (forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view forall c. HasLine c => Lens' c String
text Content
c forall a. a -> [a] -> NonEmpty a
:| forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Lens' Content [String]
above Content
c) (forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Lens' Content [String]
below Content
c)