module System.Console.Haskeline.Backend.DumbTerm where
import System.Console.Haskeline.Backend.Posix
import System.Console.Haskeline.Backend.WCWidth
import System.Console.Haskeline.Term
import System.Console.Haskeline.LineState
import System.Console.Haskeline.Monads as Monads
import System.IO
import Control.Applicative(Applicative)
import Control.Monad(liftM)
import Control.Monad.Catch
data Window = Window {Window -> Int
pos :: Int
}
initWindow :: Window
initWindow :: Window
initWindow = Window {pos :: Int
pos=Int
0}
newtype DumbTerm m a = DumbTerm {forall (m :: * -> *) a. DumbTerm m a -> StateT Window (PosixT m) a
unDumbTerm :: StateT Window (PosixT m) a}
deriving ((forall a b. (a -> b) -> DumbTerm m a -> DumbTerm m b)
-> (forall a b. a -> DumbTerm m b -> DumbTerm m a)
-> Functor (DumbTerm m)
forall a b. a -> DumbTerm m b -> DumbTerm m a
forall a b. (a -> b) -> DumbTerm m a -> DumbTerm m b
forall (m :: * -> *) a b.
Functor m =>
a -> DumbTerm m b -> DumbTerm m a
forall (m :: * -> *) a b.
Functor m =>
(a -> b) -> DumbTerm m a -> DumbTerm m b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
$cfmap :: forall (m :: * -> *) a b.
Functor m =>
(a -> b) -> DumbTerm m a -> DumbTerm m b
fmap :: forall a b. (a -> b) -> DumbTerm m a -> DumbTerm m b
$c<$ :: forall (m :: * -> *) a b.
Functor m =>
a -> DumbTerm m b -> DumbTerm m a
<$ :: forall a b. a -> DumbTerm m b -> DumbTerm m a
Functor, Functor (DumbTerm m)
Functor (DumbTerm m) =>
(forall a. a -> DumbTerm m a)
-> (forall a b.
DumbTerm m (a -> b) -> DumbTerm m a -> DumbTerm m b)
-> (forall a b c.
(a -> b -> c) -> DumbTerm m a -> DumbTerm m b -> DumbTerm m c)
-> (forall a b. DumbTerm m a -> DumbTerm m b -> DumbTerm m b)
-> (forall a b. DumbTerm m a -> DumbTerm m b -> DumbTerm m a)
-> Applicative (DumbTerm m)
forall a. a -> DumbTerm m a
forall a b. DumbTerm m a -> DumbTerm m b -> DumbTerm m a
forall a b. DumbTerm m a -> DumbTerm m b -> DumbTerm m b
forall a b. DumbTerm m (a -> b) -> DumbTerm m a -> DumbTerm m b
forall a b c.
(a -> b -> c) -> DumbTerm m a -> DumbTerm m b -> DumbTerm m c
forall (m :: * -> *). Monad m => Functor (DumbTerm m)
forall (m :: * -> *) a. Monad m => a -> DumbTerm m a
forall (m :: * -> *) a b.
Monad m =>
DumbTerm m a -> DumbTerm m b -> DumbTerm m a
forall (m :: * -> *) a b.
Monad m =>
DumbTerm m a -> DumbTerm m b -> DumbTerm m b
forall (m :: * -> *) a b.
Monad m =>
DumbTerm m (a -> b) -> DumbTerm m a -> DumbTerm m b
forall (m :: * -> *) a b c.
Monad m =>
(a -> b -> c) -> DumbTerm m a -> DumbTerm m b -> DumbTerm m c
forall (f :: * -> *).
Functor f =>
(forall a. a -> f a)
-> (forall a b. f (a -> b) -> f a -> f b)
-> (forall a b c. (a -> b -> c) -> f a -> f b -> f c)
-> (forall a b. f a -> f b -> f b)
-> (forall a b. f a -> f b -> f a)
-> Applicative f
$cpure :: forall (m :: * -> *) a. Monad m => a -> DumbTerm m a
pure :: forall a. a -> DumbTerm m a
$c<*> :: forall (m :: * -> *) a b.
Monad m =>
DumbTerm m (a -> b) -> DumbTerm m a -> DumbTerm m b
<*> :: forall a b. DumbTerm m (a -> b) -> DumbTerm m a -> DumbTerm m b
$cliftA2 :: forall (m :: * -> *) a b c.
Monad m =>
(a -> b -> c) -> DumbTerm m a -> DumbTerm m b -> DumbTerm m c
liftA2 :: forall a b c.
(a -> b -> c) -> DumbTerm m a -> DumbTerm m b -> DumbTerm m c
$c*> :: forall (m :: * -> *) a b.
Monad m =>
DumbTerm m a -> DumbTerm m b -> DumbTerm m b
*> :: forall a b. DumbTerm m a -> DumbTerm m b -> DumbTerm m b
$c<* :: forall (m :: * -> *) a b.
Monad m =>
DumbTerm m a -> DumbTerm m b -> DumbTerm m a
<* :: forall a b. DumbTerm m a -> DumbTerm m b -> DumbTerm m a
Applicative, Applicative (DumbTerm m)
Applicative (DumbTerm m) =>
(forall a b. DumbTerm m a -> (a -> DumbTerm m b) -> DumbTerm m b)
-> (forall a b. DumbTerm m a -> DumbTerm m b -> DumbTerm m b)
-> (forall a. a -> DumbTerm m a)
-> Monad (DumbTerm m)
forall a. a -> DumbTerm m a
forall a b. DumbTerm m a -> DumbTerm m b -> DumbTerm m b
forall a b. DumbTerm m a -> (a -> DumbTerm m b) -> DumbTerm m b
forall (m :: * -> *). Monad m => Applicative (DumbTerm m)
forall (m :: * -> *) a. Monad m => a -> DumbTerm m a
forall (m :: * -> *) a b.
Monad m =>
DumbTerm m a -> DumbTerm m b -> DumbTerm m b
forall (m :: * -> *) a b.
Monad m =>
DumbTerm m a -> (a -> DumbTerm m b) -> DumbTerm m b
forall (m :: * -> *).
Applicative m =>
(forall a b. m a -> (a -> m b) -> m b)
-> (forall a b. m a -> m b -> m b)
-> (forall a. a -> m a)
-> Monad m
$c>>= :: forall (m :: * -> *) a b.
Monad m =>
DumbTerm m a -> (a -> DumbTerm m b) -> DumbTerm m b
>>= :: forall a b. DumbTerm m a -> (a -> DumbTerm m b) -> DumbTerm m b
$c>> :: forall (m :: * -> *) a b.
Monad m =>
DumbTerm m a -> DumbTerm m b -> DumbTerm m b
>> :: forall a b. DumbTerm m a -> DumbTerm m b -> DumbTerm m b
$creturn :: forall (m :: * -> *) a. Monad m => a -> DumbTerm m a
return :: forall a. a -> DumbTerm m a
Monad, Monad (DumbTerm m)
Monad (DumbTerm m) =>
(forall a. IO a -> DumbTerm m a) -> MonadIO (DumbTerm m)
forall a. IO a -> DumbTerm m a
forall (m :: * -> *).
Monad m =>
(forall a. IO a -> m a) -> MonadIO m
forall (m :: * -> *). MonadIO m => Monad (DumbTerm m)
forall (m :: * -> *) a. MonadIO m => IO a -> DumbTerm m a
$cliftIO :: forall (m :: * -> *) a. MonadIO m => IO a -> DumbTerm m a
liftIO :: forall a. IO a -> DumbTerm m a
MonadIO,
Monad (DumbTerm m)
Monad (DumbTerm m) =>
(forall e a. (HasCallStack, Exception e) => e -> DumbTerm m a)
-> MonadThrow (DumbTerm m)
forall e a. (HasCallStack, Exception e) => e -> DumbTerm m a
forall (m :: * -> *).
Monad m =>
(forall e a. (HasCallStack, Exception e) => e -> m a)
-> MonadThrow m
forall (m :: * -> *). MonadThrow m => Monad (DumbTerm m)
forall (m :: * -> *) e a.
(MonadThrow m, HasCallStack, Exception e) =>
e -> DumbTerm m a
$cthrowM :: forall (m :: * -> *) e a.
(MonadThrow m, HasCallStack, Exception e) =>
e -> DumbTerm m a
throwM :: forall e a. (HasCallStack, Exception e) => e -> DumbTerm m a
MonadThrow, MonadThrow (DumbTerm m)
MonadThrow (DumbTerm m) =>
(forall e a.
(HasCallStack, Exception e) =>
DumbTerm m a -> (e -> DumbTerm m a) -> DumbTerm m a)
-> MonadCatch (DumbTerm m)
forall e a.
(HasCallStack, Exception e) =>
DumbTerm m a -> (e -> DumbTerm m a) -> DumbTerm m a
forall (m :: * -> *). MonadCatch m => MonadThrow (DumbTerm m)
forall (m :: * -> *) e a.
(MonadCatch m, HasCallStack, Exception e) =>
DumbTerm m a -> (e -> DumbTerm m a) -> DumbTerm m a
forall (m :: * -> *).
MonadThrow m =>
(forall e a.
(HasCallStack, Exception e) =>
m a -> (e -> m a) -> m a)
-> MonadCatch m
$ccatch :: forall (m :: * -> *) e a.
(MonadCatch m, HasCallStack, Exception e) =>
DumbTerm m a -> (e -> DumbTerm m a) -> DumbTerm m a
catch :: forall e a.
(HasCallStack, Exception e) =>
DumbTerm m a -> (e -> DumbTerm m a) -> DumbTerm m a
MonadCatch, MonadCatch (DumbTerm m)
MonadCatch (DumbTerm m) =>
(forall b.
HasCallStack =>
((forall a. DumbTerm m a -> DumbTerm m a) -> DumbTerm m b)
-> DumbTerm m b)
-> (forall b.
HasCallStack =>
((forall a. DumbTerm m a -> DumbTerm m a) -> DumbTerm m b)
-> DumbTerm m b)
-> (forall a b c.
HasCallStack =>
DumbTerm m a
-> (a -> ExitCase b -> DumbTerm m c)
-> (a -> DumbTerm m b)
-> DumbTerm m (b, c))
-> MonadMask (DumbTerm m)
forall b.
HasCallStack =>
((forall a. DumbTerm m a -> DumbTerm m a) -> DumbTerm m b)
-> DumbTerm m b
forall a b c.
HasCallStack =>
DumbTerm m a
-> (a -> ExitCase b -> DumbTerm m c)
-> (a -> DumbTerm m b)
-> DumbTerm m (b, c)
forall (m :: * -> *). MonadMask m => MonadCatch (DumbTerm m)
forall (m :: * -> *) b.
(MonadMask m, HasCallStack) =>
((forall a. DumbTerm m a -> DumbTerm m a) -> DumbTerm m b)
-> DumbTerm m b
forall (m :: * -> *) a b c.
(MonadMask m, HasCallStack) =>
DumbTerm m a
-> (a -> ExitCase b -> DumbTerm m c)
-> (a -> DumbTerm m b)
-> DumbTerm m (b, c)
forall (m :: * -> *).
MonadCatch m =>
(forall b. HasCallStack => ((forall a. m a -> m a) -> m b) -> m b)
-> (forall b.
HasCallStack =>
((forall a. m a -> m a) -> m b) -> m b)
-> (forall a b c.
HasCallStack =>
m a -> (a -> ExitCase b -> m c) -> (a -> m b) -> m (b, c))
-> MonadMask m
$cmask :: forall (m :: * -> *) b.
(MonadMask m, HasCallStack) =>
((forall a. DumbTerm m a -> DumbTerm m a) -> DumbTerm m b)
-> DumbTerm m b
mask :: forall b.
HasCallStack =>
((forall a. DumbTerm m a -> DumbTerm m a) -> DumbTerm m b)
-> DumbTerm m b
$cuninterruptibleMask :: forall (m :: * -> *) b.
(MonadMask m, HasCallStack) =>
((forall a. DumbTerm m a -> DumbTerm m a) -> DumbTerm m b)
-> DumbTerm m b
uninterruptibleMask :: forall b.
HasCallStack =>
((forall a. DumbTerm m a -> DumbTerm m a) -> DumbTerm m b)
-> DumbTerm m b
$cgeneralBracket :: forall (m :: * -> *) a b c.
(MonadMask m, HasCallStack) =>
DumbTerm m a
-> (a -> ExitCase b -> DumbTerm m c)
-> (a -> DumbTerm m b)
-> DumbTerm m (b, c)
generalBracket :: forall a b c.
HasCallStack =>
DumbTerm m a
-> (a -> ExitCase b -> DumbTerm m c)
-> (a -> DumbTerm m b)
-> DumbTerm m (b, c)
MonadMask,
MonadState Window, MonadReader Handles)
type DumbTermM a = forall m . (MonadIO m, MonadReader Layout m) => DumbTerm m a
instance MonadTrans DumbTerm where
lift :: forall (m :: * -> *) a. Monad m => m a -> DumbTerm m a
lift = StateT Window (PosixT m) a -> DumbTerm m a
forall (m :: * -> *) a. StateT Window (PosixT m) a -> DumbTerm m a
DumbTerm (StateT Window (PosixT m) a -> DumbTerm m a)
-> (m a -> StateT Window (PosixT m) a) -> m a -> DumbTerm m a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PosixT m a -> StateT Window (PosixT m) a
forall (m :: * -> *) a. Monad m => m a -> StateT Window m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (PosixT m a -> StateT Window (PosixT m) a)
-> (m a -> PosixT m a) -> m a -> StateT Window (PosixT m) a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. m a -> PosixT m a
forall (m :: * -> *) a. Monad m => m a -> ReaderT Handles m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift
evalDumb :: (MonadReader Layout m, CommandMonad m) => EvalTerm (PosixT m)
evalDumb :: forall (m :: * -> *).
(MonadReader Layout m, CommandMonad m) =>
EvalTerm (PosixT m)
evalDumb = (forall a. DumbTerm m a -> PosixT m a)
-> (forall a. PosixT m a -> DumbTerm m a) -> EvalTerm (PosixT m)
forall (m :: * -> *) (n :: * -> *).
(Term n, CommandMonad n) =>
(forall a. n a -> m a) -> (forall a. m a -> n a) -> EvalTerm m
EvalTerm (Window -> StateT Window (PosixT m) a -> ReaderT Handles m a
forall (m :: * -> *) s a. Monad m => s -> StateT s m a -> m a
evalStateT' Window
initWindow (StateT Window (PosixT m) a -> ReaderT Handles m a)
-> (DumbTerm m a -> StateT Window (PosixT m) a)
-> DumbTerm m a
-> ReaderT Handles m a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. DumbTerm m a -> StateT Window (PosixT m) a
forall (m :: * -> *) a. DumbTerm m a -> StateT Window (PosixT m) a
unDumbTerm) (StateT Window (PosixT m) a -> DumbTerm m a
forall (m :: * -> *) a. StateT Window (PosixT m) a -> DumbTerm m a
DumbTerm (StateT Window (PosixT m) a -> DumbTerm m a)
-> (PosixT m a -> StateT Window (PosixT m) a)
-> PosixT m a
-> DumbTerm m a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PosixT m a -> StateT Window (PosixT m) a
forall (m :: * -> *) a. Monad m => m a -> StateT Window m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift)
runDumbTerm :: Handles -> MaybeT IO RunTerm
runDumbTerm :: Handles -> MaybeT IO RunTerm
runDumbTerm Handles
h = IO RunTerm -> MaybeT IO RunTerm
forall a. IO a -> MaybeT IO a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO RunTerm -> MaybeT IO RunTerm)
-> IO RunTerm -> MaybeT IO RunTerm
forall a b. (a -> b) -> a -> b
$ Handles
-> [IO (Maybe Layout)]
-> [(String, Key)]
-> (forall (m :: * -> *) b. (MonadIO m, MonadMask m) => m b -> m b)
-> (forall (m :: * -> *).
(MonadMask m, CommandMonad m) =>
EvalTerm (PosixT m))
-> IO RunTerm
posixRunTerm Handles
h (Handles -> [IO (Maybe Layout)]
posixLayouts Handles
h) [] m b -> m b
forall a. a -> a
forall (m :: * -> *) b. (MonadIO m, MonadMask m) => m b -> m b
id EvalTerm (PosixT m)
forall (m :: * -> *).
(MonadMask m, CommandMonad m) =>
EvalTerm (PosixT m)
forall (m :: * -> *).
(MonadReader Layout m, CommandMonad m) =>
EvalTerm (PosixT m)
evalDumb
instance (MonadIO m, MonadMask m, MonadReader Layout m) => Term (DumbTerm m) where
reposition :: Layout -> LineChars -> DumbTerm m ()
reposition Layout
_ LineChars
s = LineChars -> DumbTermM ()
refitLine LineChars
s
drawLineDiff :: LineChars -> LineChars -> DumbTerm m ()
drawLineDiff LineChars
x LineChars
y = LineChars -> LineChars -> DumbTermM ()
drawLineDiff' LineChars
x LineChars
y
printLines :: [String] -> DumbTerm m ()
printLines = (String -> DumbTerm m ()) -> [String] -> DumbTerm m ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ (String -> DumbTerm m ()
forall (m :: * -> *). MonadIO m => String -> DumbTerm m ()
printText (String -> DumbTerm m ())
-> (String -> String) -> String -> DumbTerm m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
crlf))
moveToNextLine :: LineChars -> DumbTerm m ()
moveToNextLine LineChars
_ = String -> DumbTerm m ()
forall (m :: * -> *). MonadIO m => String -> DumbTerm m ()
printText String
crlf
clearLayout :: DumbTerm m ()
clearLayout = DumbTerm m ()
DumbTermM ()
clearLayoutD
ringBell :: Bool -> DumbTerm m ()
ringBell Bool
True = String -> DumbTerm m ()
forall (m :: * -> *). MonadIO m => String -> DumbTerm m ()
printText String
"\a"
ringBell Bool
False = () -> DumbTerm m ()
forall a. a -> DumbTerm m a
forall (m :: * -> *) a. Monad m => a -> m a
return ()
printText :: MonadIO m => String -> DumbTerm m ()
printText :: forall (m :: * -> *). MonadIO m => String -> DumbTerm m ()
printText String
str = do
h <- (Handles -> Handle) -> DumbTerm m Handles -> DumbTerm m Handle
forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
liftM Handles -> Handle
ehOut DumbTerm m Handles
forall r (m :: * -> *). MonadReader r m => m r
ask
liftIO $ hPutStr h str
liftIO $ hFlush h
cr,crlf :: String
crlf :: String
crlf = String
"\r\n"
cr :: String
cr = String
"\r"
backs,spaces :: Int -> String
backs :: Int -> String
backs Int
n = Int -> Char -> String
forall a. Int -> a -> [a]
replicate Int
n Char
'\b'
spaces :: Int -> String
spaces Int
n = Int -> Char -> String
forall a. Int -> a -> [a]
replicate Int
n Char
' '
clearLayoutD :: DumbTermM ()
clearLayoutD :: DumbTermM ()
clearLayoutD = do
w <- DumbTerm m Int
DumbTermM Int
maxWidth
printText (cr ++ spaces w ++ cr)
maxWidth :: DumbTermM Int
maxWidth :: DumbTermM Int
maxWidth = (Layout -> Int) -> DumbTerm m Int
forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
asks (\Layout
lay -> Layout -> Int
width Layout
lay Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1)
drawLineDiff' :: LineChars -> LineChars -> DumbTermM ()
drawLineDiff' :: LineChars -> LineChars -> DumbTermM ()
drawLineDiff' ([Grapheme]
xs1,[Grapheme]
ys1) ([Grapheme]
xs2,[Grapheme]
ys2) = do
Window {pos=p} <- DumbTerm m Window
forall s (m :: * -> *). MonadState s m => m s
get
w <- maxWidth
let (xs1',xs2') = matchInit xs1 xs2
let (xw1, xw2) = (gsWidth xs1', gsWidth xs2')
let newP = Int
p Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
xw2 Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
xw1
let (ys2', yw2) = takeWidth (w-newP) ys2
if xw1 > p || newP >= w
then refitLine (xs2,ys2)
else do
put Window {pos=newP}
case (xs1',xs2') of
([],[]) | [Grapheme]
ys1 [Grapheme] -> [Grapheme] -> Bool
forall a. Eq a => a -> a -> Bool
== [Grapheme]
ys2 -> () -> DumbTerm m ()
forall a. a -> DumbTerm m a
forall (m :: * -> *) a. Monad m => a -> m a
return ()
([Grapheme]
_,[]) | [Grapheme]
xs1' [Grapheme] -> [Grapheme] -> [Grapheme]
forall a. [a] -> [a] -> [a]
++ [Grapheme]
ys1 [Grapheme] -> [Grapheme] -> Bool
forall a. Eq a => a -> a -> Bool
== [Grapheme]
ys2 ->
String -> DumbTerm m ()
forall (m :: * -> *). MonadIO m => String -> DumbTerm m ()
printText (String -> DumbTerm m ()) -> String -> DumbTerm m ()
forall a b. (a -> b) -> a -> b
$ Int -> String
backs Int
xw1
([],[Grapheme]
_) | [Grapheme]
ys1 [Grapheme] -> [Grapheme] -> Bool
forall a. Eq a => a -> a -> Bool
== [Grapheme]
xs2' [Grapheme] -> [Grapheme] -> [Grapheme]
forall a. [a] -> [a] -> [a]
++ [Grapheme]
ys2 ->
String -> DumbTerm m ()
forall (m :: * -> *). MonadIO m => String -> DumbTerm m ()
printText ([Grapheme] -> String
graphemesToString [Grapheme]
xs2')
LineChars
_ -> let extraLength :: Int
extraLength = Int
xw1 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ ([Grapheme], Int) -> Int
forall a b. (a, b) -> b
snd (Int -> [Grapheme] -> ([Grapheme], Int)
takeWidth (Int
wInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
p) [Grapheme]
ys1)
Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
xw2 Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
yw2
in String -> DumbTerm m ()
forall (m :: * -> *). MonadIO m => String -> DumbTerm m ()
printText (String -> DumbTerm m ()) -> String -> DumbTerm m ()
forall a b. (a -> b) -> a -> b
$ Int -> String
backs Int
xw1
String -> String -> String
forall a. [a] -> [a] -> [a]
++ [Grapheme] -> String
graphemesToString ([Grapheme]
xs2' [Grapheme] -> [Grapheme] -> [Grapheme]
forall a. [a] -> [a] -> [a]
++ [Grapheme]
ys2') String -> String -> String
forall a. [a] -> [a] -> [a]
++ Int -> String
clearDeadText Int
extraLength
String -> String -> String
forall a. [a] -> [a] -> [a]
++ Int -> String
backs Int
yw2
refitLine :: ([Grapheme],[Grapheme]) -> DumbTermM ()
refitLine :: LineChars -> DumbTermM ()
refitLine ([Grapheme]
xs,[Grapheme]
ys) = do
w <- DumbTerm m Int
DumbTermM Int
maxWidth
let (xs',p) = dropFrames w xs
put Window {pos=p}
let (ys',k) = takeWidth (w - p) ys
printText $ cr ++ graphemesToString (xs' ++ ys')
++ spaces (w-k-p)
++ backs (w-p)
where
dropFrames :: Int -> [Grapheme] -> ([Grapheme], Int)
dropFrames Int
w [Grapheme]
zs = case Int -> [Grapheme] -> ([Grapheme], [Grapheme], Int)
splitAtWidth Int
w [Grapheme]
zs of
([Grapheme]
_,[],Int
l) -> ([Grapheme]
zs,Int
l)
([Grapheme]
_,[Grapheme]
zs',Int
_) -> Int -> [Grapheme] -> ([Grapheme], Int)
dropFrames Int
w [Grapheme]
zs'
clearDeadText :: Int -> String
clearDeadText :: Int -> String
clearDeadText Int
n | Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
0 = Int -> String
spaces Int
n String -> String -> String
forall a. [a] -> [a] -> [a]
++ Int -> String
backs Int
n
| Bool
otherwise = String
""