module System.Console.Haskeline.LineState(
Grapheme(),
baseChar,
stringToGraphemes,
graphemesToString,
modifyBaseChar,
mapBaseChars,
LineState(..),
Prefix,
LineChars,
lineChars,
lengthToEnd,
Result(..),
Save(..),
listSave,
listRestore,
Move(..),
InsertMode(..),
emptyIM,
insertChar,
insertString,
replaceCharIM,
insertGraphemes,
deleteNext,
deletePrev,
skipLeft,
skipRight,
transposeChars,
goRightUntil,
goLeftUntil,
atStart,
atEnd,
beforeChar,
afterChar,
overChar,
CommandMode(..),
deleteChar,
replaceChar,
pasteGraphemesBefore,
pasteGraphemesAfter,
enterCommandMode,
enterCommandModeRight,
insertFromCommandMode,
appendFromCommandMode,
withCommandMode,
ArgMode(..),
startArg,
addNum,
applyArg,
applyCmdArg,
Message(..),
Password(..),
addPasswordChar,
deletePasswordChar,
) where
import Data.Char
data Grapheme = Grapheme {Grapheme -> Char
gBaseChar :: Char,
Grapheme -> [Char]
combiningChars :: [Char]}
deriving Grapheme -> Grapheme -> Bool
(Grapheme -> Grapheme -> Bool)
-> (Grapheme -> Grapheme -> Bool) -> Eq Grapheme
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Grapheme -> Grapheme -> Bool
$c/= :: Grapheme -> Grapheme -> Bool
== :: Grapheme -> Grapheme -> Bool
$c== :: Grapheme -> Grapheme -> Bool
Eq
instance Show Grapheme where
show :: Grapheme -> [Char]
show g :: Grapheme
g = ShowS
forall a. Show a => a -> [Char]
show (Grapheme -> Char
gBaseChar Grapheme
g Char -> ShowS
forall a. a -> [a] -> [a]
: Grapheme -> [Char]
combiningChars Grapheme
g)
baseChar :: Grapheme -> Char
baseChar :: Grapheme -> Char
baseChar = Grapheme -> Char
gBaseChar
modifyBaseChar :: (Char -> Char) -> Grapheme -> Grapheme
modifyBaseChar :: (Char -> Char) -> Grapheme -> Grapheme
modifyBaseChar f :: Char -> Char
f g :: Grapheme
g = Grapheme
g {gBaseChar :: Char
gBaseChar = Char -> Char
f (Grapheme -> Char
gBaseChar Grapheme
g)}
mapBaseChars :: (Char -> Char) -> [Grapheme] -> [Grapheme]
mapBaseChars :: (Char -> Char) -> [Grapheme] -> [Grapheme]
mapBaseChars f :: Char -> Char
f = (Grapheme -> Grapheme) -> [Grapheme] -> [Grapheme]
forall a b. (a -> b) -> [a] -> [b]
map ((Char -> Char) -> Grapheme -> Grapheme
modifyBaseChar Char -> Char
f)
baseGrapheme :: Char -> Grapheme
baseGrapheme :: Char -> Grapheme
baseGrapheme c :: Char
c = Grapheme :: Char -> [Char] -> Grapheme
Grapheme {gBaseChar :: Char
gBaseChar = Char
c, combiningChars :: [Char]
combiningChars = []}
addCombiner :: Grapheme -> Char -> Grapheme
addCombiner :: Grapheme -> Char -> Grapheme
addCombiner g :: Grapheme
g c :: Char
c = Grapheme
g {combiningChars :: [Char]
combiningChars = Grapheme -> [Char]
combiningChars Grapheme
g [Char] -> ShowS
forall a. [a] -> [a] -> [a]
++ [Char
c]}
isCombiningChar :: Char -> Bool
isCombiningChar :: Char -> Bool
isCombiningChar c :: Char
c = Char -> GeneralCategory
generalCategory Char
c GeneralCategory -> GeneralCategory -> Bool
forall a. Eq a => a -> a -> Bool
== GeneralCategory
NonSpacingMark
stringToGraphemes :: String -> [Grapheme]
stringToGraphemes :: [Char] -> [Grapheme]
stringToGraphemes = [Char] -> [Grapheme]
mkString ([Char] -> [Grapheme]) -> ShowS -> [Char] -> [Grapheme]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Char -> Bool) -> ShowS
forall a. (a -> Bool) -> [a] -> [a]
dropWhile Char -> Bool
isCombiningChar
where
mkString :: [Char] -> [Grapheme]
mkString [] = []
mkString ('\SOH':cs :: [Char]
cs) = [Char] -> [Grapheme]
stringToGraphemes [Char]
cs
mkString ('\ESC':cs :: [Char]
cs) | (ctrl :: [Char]
ctrl,'\STX':rest :: [Char]
rest) <- (Char -> Bool) -> [Char] -> ([Char], [Char])
forall a. (a -> Bool) -> [a] -> ([a], [a])
break (Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
=='\STX') [Char]
cs
= Char -> [Char] -> Grapheme
Grapheme '\ESC' [Char]
ctrl Grapheme -> [Grapheme] -> [Grapheme]
forall a. a -> [a] -> [a]
: [Char] -> [Grapheme]
stringToGraphemes [Char]
rest
mkString (c :: Char
c:cs :: [Char]
cs) = Char -> [Char] -> Grapheme
Grapheme Char
c ((Char -> Bool) -> ShowS
forall a. (a -> Bool) -> [a] -> [a]
takeWhile Char -> Bool
isCombiningChar [Char]
cs)
Grapheme -> [Grapheme] -> [Grapheme]
forall a. a -> [a] -> [a]
: [Char] -> [Grapheme]
mkString ((Char -> Bool) -> ShowS
forall a. (a -> Bool) -> [a] -> [a]
dropWhile Char -> Bool
isCombiningChar [Char]
cs)
graphemesToString :: [Grapheme] -> String
graphemesToString :: [Grapheme] -> [Char]
graphemesToString = (Grapheme -> [Char]) -> [Grapheme] -> [Char]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (\g :: Grapheme
g -> (Grapheme -> Char
baseChar Grapheme
g Char -> ShowS
forall a. a -> [a] -> [a]
: Grapheme -> [Char]
combiningChars Grapheme
g))
class LineState s where
beforeCursor :: Prefix
-> s
-> [Grapheme]
afterCursor :: s -> [Grapheme]
type Prefix = [Grapheme]
type LineChars = ([Grapheme],[Grapheme])
lineChars :: LineState s => Prefix -> s -> LineChars
lineChars :: [Grapheme] -> s -> LineChars
lineChars prefix :: [Grapheme]
prefix s :: s
s = ([Grapheme] -> s -> [Grapheme]
forall s. LineState s => [Grapheme] -> s -> [Grapheme]
beforeCursor [Grapheme]
prefix s
s, s -> [Grapheme]
forall s. LineState s => s -> [Grapheme]
afterCursor s
s)
lengthToEnd :: LineChars -> Int
lengthToEnd :: LineChars -> Int
lengthToEnd = [Grapheme] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length ([Grapheme] -> Int)
-> (LineChars -> [Grapheme]) -> LineChars -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. LineChars -> [Grapheme]
forall a b. (a, b) -> b
snd
class LineState s => Result s where
toResult :: s -> String
class LineState s => Save s where
save :: s -> InsertMode
restore :: InsertMode -> s
listSave :: Save s => s -> [Grapheme]
listSave :: s -> [Grapheme]
listSave s :: s
s = case s -> InsertMode
forall s. Save s => s -> InsertMode
save s
s of IMode xs :: [Grapheme]
xs ys :: [Grapheme]
ys -> [Grapheme] -> [Grapheme]
forall a. [a] -> [a]
reverse [Grapheme]
xs [Grapheme] -> [Grapheme] -> [Grapheme]
forall a. [a] -> [a] -> [a]
++ [Grapheme]
ys
listRestore :: Save s => [Grapheme] -> s
listRestore :: [Grapheme] -> s
listRestore xs :: [Grapheme]
xs = InsertMode -> s
forall s. Save s => InsertMode -> s
restore (InsertMode -> s) -> InsertMode -> s
forall a b. (a -> b) -> a -> b
$ [Grapheme] -> [Grapheme] -> InsertMode
IMode ([Grapheme] -> [Grapheme]
forall a. [a] -> [a]
reverse [Grapheme]
xs) []
class Move s where
goLeft, goRight, moveToStart, moveToEnd :: s -> s
data InsertMode = IMode [Grapheme] [Grapheme]
deriving (Int -> InsertMode -> ShowS
[InsertMode] -> ShowS
InsertMode -> [Char]
(Int -> InsertMode -> ShowS)
-> (InsertMode -> [Char])
-> ([InsertMode] -> ShowS)
-> Show InsertMode
forall a.
(Int -> a -> ShowS) -> (a -> [Char]) -> ([a] -> ShowS) -> Show a
showList :: [InsertMode] -> ShowS
$cshowList :: [InsertMode] -> ShowS
show :: InsertMode -> [Char]
$cshow :: InsertMode -> [Char]
showsPrec :: Int -> InsertMode -> ShowS
$cshowsPrec :: Int -> InsertMode -> ShowS
Show, InsertMode -> InsertMode -> Bool
(InsertMode -> InsertMode -> Bool)
-> (InsertMode -> InsertMode -> Bool) -> Eq InsertMode
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: InsertMode -> InsertMode -> Bool
$c/= :: InsertMode -> InsertMode -> Bool
== :: InsertMode -> InsertMode -> Bool
$c== :: InsertMode -> InsertMode -> Bool
Eq)
instance LineState InsertMode where
beforeCursor :: [Grapheme] -> InsertMode -> [Grapheme]
beforeCursor prefix :: [Grapheme]
prefix (IMode xs :: [Grapheme]
xs _) = [Grapheme]
prefix [Grapheme] -> [Grapheme] -> [Grapheme]
forall a. [a] -> [a] -> [a]
++ [Grapheme] -> [Grapheme]
forall a. [a] -> [a]
reverse [Grapheme]
xs
afterCursor :: InsertMode -> [Grapheme]
afterCursor (IMode _ ys :: [Grapheme]
ys) = [Grapheme]
ys
instance Result InsertMode where
toResult :: InsertMode -> [Char]
toResult (IMode xs :: [Grapheme]
xs ys :: [Grapheme]
ys) = [Grapheme] -> [Char]
graphemesToString ([Grapheme] -> [Char]) -> [Grapheme] -> [Char]
forall a b. (a -> b) -> a -> b
$ [Grapheme] -> [Grapheme]
forall a. [a] -> [a]
reverse [Grapheme]
xs [Grapheme] -> [Grapheme] -> [Grapheme]
forall a. [a] -> [a] -> [a]
++ [Grapheme]
ys
instance Save InsertMode where
save :: InsertMode -> InsertMode
save = InsertMode -> InsertMode
forall a. a -> a
id
restore :: InsertMode -> InsertMode
restore = InsertMode -> InsertMode
forall a. a -> a
id
instance Move InsertMode where
goLeft :: InsertMode -> InsertMode
goLeft im :: InsertMode
im@(IMode [] _) = InsertMode
im
goLeft (IMode (x :: Grapheme
x:xs :: [Grapheme]
xs) ys :: [Grapheme]
ys) = [Grapheme] -> [Grapheme] -> InsertMode
IMode [Grapheme]
xs (Grapheme
xGrapheme -> [Grapheme] -> [Grapheme]
forall a. a -> [a] -> [a]
:[Grapheme]
ys)
goRight :: InsertMode -> InsertMode
goRight im :: InsertMode
im@(IMode _ []) = InsertMode
im
goRight (IMode ys :: [Grapheme]
ys (x :: Grapheme
x:xs :: [Grapheme]
xs)) = [Grapheme] -> [Grapheme] -> InsertMode
IMode (Grapheme
xGrapheme -> [Grapheme] -> [Grapheme]
forall a. a -> [a] -> [a]
:[Grapheme]
ys) [Grapheme]
xs
moveToStart :: InsertMode -> InsertMode
moveToStart (IMode xs :: [Grapheme]
xs ys :: [Grapheme]
ys) = [Grapheme] -> [Grapheme] -> InsertMode
IMode [] ([Grapheme] -> [Grapheme]
forall a. [a] -> [a]
reverse [Grapheme]
xs [Grapheme] -> [Grapheme] -> [Grapheme]
forall a. [a] -> [a] -> [a]
++ [Grapheme]
ys)
moveToEnd :: InsertMode -> InsertMode
moveToEnd (IMode xs :: [Grapheme]
xs ys :: [Grapheme]
ys) = [Grapheme] -> [Grapheme] -> InsertMode
IMode ([Grapheme] -> [Grapheme]
forall a. [a] -> [a]
reverse [Grapheme]
ys [Grapheme] -> [Grapheme] -> [Grapheme]
forall a. [a] -> [a] -> [a]
++ [Grapheme]
xs) []
emptyIM :: InsertMode
emptyIM :: InsertMode
emptyIM = [Grapheme] -> [Grapheme] -> InsertMode
IMode [] []
insertChar :: Char -> InsertMode -> InsertMode
insertChar :: Char -> InsertMode -> InsertMode
insertChar c :: Char
c im :: InsertMode
im@(IMode xs :: [Grapheme]
xs ys :: [Grapheme]
ys)
| Char -> Bool
isCombiningChar Char
c = case [Grapheme]
xs of
[] -> InsertMode
im
z :: Grapheme
z:zs :: [Grapheme]
zs -> [Grapheme] -> [Grapheme] -> InsertMode
IMode (Grapheme -> Char -> Grapheme
addCombiner Grapheme
z Char
c Grapheme -> [Grapheme] -> [Grapheme]
forall a. a -> [a] -> [a]
: [Grapheme]
zs) [Grapheme]
ys
| Bool
otherwise = [Grapheme] -> [Grapheme] -> InsertMode
IMode (Char -> Grapheme
baseGrapheme Char
c Grapheme -> [Grapheme] -> [Grapheme]
forall a. a -> [a] -> [a]
: [Grapheme]
xs) [Grapheme]
ys
insertString :: String -> InsertMode -> InsertMode
insertString :: [Char] -> InsertMode -> InsertMode
insertString s :: [Char]
s (IMode xs :: [Grapheme]
xs ys :: [Grapheme]
ys) = [Grapheme] -> [Grapheme] -> InsertMode
IMode ([Grapheme] -> [Grapheme]
forall a. [a] -> [a]
reverse ([Char] -> [Grapheme]
stringToGraphemes [Char]
s) [Grapheme] -> [Grapheme] -> [Grapheme]
forall a. [a] -> [a] -> [a]
++ [Grapheme]
xs) [Grapheme]
ys
deleteNext, deletePrev :: InsertMode -> InsertMode
deleteNext :: InsertMode -> InsertMode
deleteNext im :: InsertMode
im@(IMode _ []) = InsertMode
im
deleteNext (IMode xs :: [Grapheme]
xs (_:ys :: [Grapheme]
ys)) = [Grapheme] -> [Grapheme] -> InsertMode
IMode [Grapheme]
xs [Grapheme]
ys
deletePrev :: InsertMode -> InsertMode
deletePrev im :: InsertMode
im@(IMode [] _) = InsertMode
im
deletePrev (IMode (_:xs :: [Grapheme]
xs) ys :: [Grapheme]
ys) = [Grapheme] -> [Grapheme] -> InsertMode
IMode [Grapheme]
xs [Grapheme]
ys
skipLeft, skipRight :: (Char -> Bool) -> InsertMode -> InsertMode
skipLeft :: (Char -> Bool) -> InsertMode -> InsertMode
skipLeft f :: Char -> Bool
f (IMode xs :: [Grapheme]
xs ys :: [Grapheme]
ys) = let (ws :: [Grapheme]
ws,zs :: [Grapheme]
zs) = (Grapheme -> Bool) -> [Grapheme] -> LineChars
forall a. (a -> Bool) -> [a] -> ([a], [a])
span (Char -> Bool
f (Char -> Bool) -> (Grapheme -> Char) -> Grapheme -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Grapheme -> Char
baseChar) [Grapheme]
xs
in [Grapheme] -> [Grapheme] -> InsertMode
IMode [Grapheme]
zs ([Grapheme] -> [Grapheme]
forall a. [a] -> [a]
reverse [Grapheme]
ws [Grapheme] -> [Grapheme] -> [Grapheme]
forall a. [a] -> [a] -> [a]
++ [Grapheme]
ys)
skipRight :: (Char -> Bool) -> InsertMode -> InsertMode
skipRight f :: Char -> Bool
f (IMode xs :: [Grapheme]
xs ys :: [Grapheme]
ys) = let (ws :: [Grapheme]
ws,zs :: [Grapheme]
zs) = (Grapheme -> Bool) -> [Grapheme] -> LineChars
forall a. (a -> Bool) -> [a] -> ([a], [a])
span (Char -> Bool
f (Char -> Bool) -> (Grapheme -> Char) -> Grapheme -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Grapheme -> Char
baseChar) [Grapheme]
ys
in [Grapheme] -> [Grapheme] -> InsertMode
IMode ([Grapheme] -> [Grapheme]
forall a. [a] -> [a]
reverse [Grapheme]
ws [Grapheme] -> [Grapheme] -> [Grapheme]
forall a. [a] -> [a] -> [a]
++ [Grapheme]
xs) [Grapheme]
zs
transposeChars :: InsertMode -> InsertMode
transposeChars :: InsertMode -> InsertMode
transposeChars (IMode (x :: Grapheme
x:xs :: [Grapheme]
xs) (y :: Grapheme
y:ys :: [Grapheme]
ys)) = [Grapheme] -> [Grapheme] -> InsertMode
IMode (Grapheme
xGrapheme -> [Grapheme] -> [Grapheme]
forall a. a -> [a] -> [a]
:Grapheme
yGrapheme -> [Grapheme] -> [Grapheme]
forall a. a -> [a] -> [a]
:[Grapheme]
xs) [Grapheme]
ys
transposeChars (IMode (y :: Grapheme
y:x :: Grapheme
x:xs :: [Grapheme]
xs) []) = [Grapheme] -> [Grapheme] -> InsertMode
IMode (Grapheme
xGrapheme -> [Grapheme] -> [Grapheme]
forall a. a -> [a] -> [a]
:Grapheme
yGrapheme -> [Grapheme] -> [Grapheme]
forall a. a -> [a] -> [a]
:[Grapheme]
xs) []
transposeChars im :: InsertMode
im = InsertMode
im
insertGraphemes :: [Grapheme] -> InsertMode -> InsertMode
insertGraphemes :: [Grapheme] -> InsertMode -> InsertMode
insertGraphemes s :: [Grapheme]
s (IMode xs :: [Grapheme]
xs ys :: [Grapheme]
ys) = [Grapheme] -> [Grapheme] -> InsertMode
IMode ([Grapheme] -> [Grapheme]
forall a. [a] -> [a]
reverse [Grapheme]
s [Grapheme] -> [Grapheme] -> [Grapheme]
forall a. [a] -> [a] -> [a]
++ [Grapheme]
xs) [Grapheme]
ys
replaceCharIM :: Char -> InsertMode -> InsertMode
replaceCharIM :: Char -> InsertMode -> InsertMode
replaceCharIM c :: Char
c im :: InsertMode
im
| Char -> Bool
isCombiningChar Char
c = case InsertMode
im of
IMode [] [] -> InsertMode
im
IMode [] (y :: Grapheme
y:ys :: [Grapheme]
ys) -> [Grapheme] -> [Grapheme] -> InsertMode
IMode [] (Grapheme -> Char -> Grapheme
addCombiner Grapheme
y Char
cGrapheme -> [Grapheme] -> [Grapheme]
forall a. a -> [a] -> [a]
:[Grapheme]
ys)
IMode (x :: Grapheme
x:xs :: [Grapheme]
xs) ys :: [Grapheme]
ys -> [Grapheme] -> [Grapheme] -> InsertMode
IMode (Grapheme -> Char -> Grapheme
addCombiner Grapheme
x Char
cGrapheme -> [Grapheme] -> [Grapheme]
forall a. a -> [a] -> [a]
:[Grapheme]
xs) [Grapheme]
ys
| Bool
otherwise = let g :: Grapheme
g = Char -> Grapheme
baseGrapheme Char
c
in case InsertMode
im of
IMode xs :: [Grapheme]
xs [] -> [Grapheme] -> [Grapheme] -> InsertMode
IMode (Grapheme
gGrapheme -> [Grapheme] -> [Grapheme]
forall a. a -> [a] -> [a]
:[Grapheme]
xs) []
IMode xs :: [Grapheme]
xs (_:ys :: [Grapheme]
ys) -> [Grapheme] -> [Grapheme] -> InsertMode
IMode (Grapheme
gGrapheme -> [Grapheme] -> [Grapheme]
forall a. a -> [a] -> [a]
:[Grapheme]
xs) [Grapheme]
ys
data CommandMode = CMode [Grapheme] Grapheme [Grapheme] | CEmpty
deriving Int -> CommandMode -> ShowS
[CommandMode] -> ShowS
CommandMode -> [Char]
(Int -> CommandMode -> ShowS)
-> (CommandMode -> [Char])
-> ([CommandMode] -> ShowS)
-> Show CommandMode
forall a.
(Int -> a -> ShowS) -> (a -> [Char]) -> ([a] -> ShowS) -> Show a
showList :: [CommandMode] -> ShowS
$cshowList :: [CommandMode] -> ShowS
show :: CommandMode -> [Char]
$cshow :: CommandMode -> [Char]
showsPrec :: Int -> CommandMode -> ShowS
$cshowsPrec :: Int -> CommandMode -> ShowS
Show
instance LineState CommandMode where
beforeCursor :: [Grapheme] -> CommandMode -> [Grapheme]
beforeCursor prefix :: [Grapheme]
prefix CEmpty = [Grapheme]
prefix
beforeCursor prefix :: [Grapheme]
prefix (CMode xs :: [Grapheme]
xs _ _) = [Grapheme]
prefix [Grapheme] -> [Grapheme] -> [Grapheme]
forall a. [a] -> [a] -> [a]
++ [Grapheme] -> [Grapheme]
forall a. [a] -> [a]
reverse [Grapheme]
xs
afterCursor :: CommandMode -> [Grapheme]
afterCursor CEmpty = []
afterCursor (CMode _ c :: Grapheme
c ys :: [Grapheme]
ys) = Grapheme
cGrapheme -> [Grapheme] -> [Grapheme]
forall a. a -> [a] -> [a]
:[Grapheme]
ys
instance Result CommandMode where
toResult :: CommandMode -> [Char]
toResult CEmpty = ""
toResult (CMode xs :: [Grapheme]
xs c :: Grapheme
c ys :: [Grapheme]
ys) = [Grapheme] -> [Char]
graphemesToString ([Grapheme] -> [Char]) -> [Grapheme] -> [Char]
forall a b. (a -> b) -> a -> b
$ [Grapheme] -> [Grapheme]
forall a. [a] -> [a]
reverse [Grapheme]
xs [Grapheme] -> [Grapheme] -> [Grapheme]
forall a. [a] -> [a] -> [a]
++ (Grapheme
cGrapheme -> [Grapheme] -> [Grapheme]
forall a. a -> [a] -> [a]
:[Grapheme]
ys)
instance Save CommandMode where
save :: CommandMode -> InsertMode
save = CommandMode -> InsertMode
insertFromCommandMode
restore :: InsertMode -> CommandMode
restore = InsertMode -> CommandMode
enterCommandModeRight
instance Move CommandMode where
goLeft :: CommandMode -> CommandMode
goLeft (CMode (x :: Grapheme
x:xs :: [Grapheme]
xs) c :: Grapheme
c ys :: [Grapheme]
ys) = [Grapheme] -> Grapheme -> [Grapheme] -> CommandMode
CMode [Grapheme]
xs Grapheme
x (Grapheme
cGrapheme -> [Grapheme] -> [Grapheme]
forall a. a -> [a] -> [a]
:[Grapheme]
ys)
goLeft cm :: CommandMode
cm = CommandMode
cm
goRight :: CommandMode -> CommandMode
goRight (CMode xs :: [Grapheme]
xs c :: Grapheme
c (y :: Grapheme
y:ys :: [Grapheme]
ys)) = [Grapheme] -> Grapheme -> [Grapheme] -> CommandMode
CMode (Grapheme
cGrapheme -> [Grapheme] -> [Grapheme]
forall a. a -> [a] -> [a]
:[Grapheme]
xs) Grapheme
y [Grapheme]
ys
goRight cm :: CommandMode
cm = CommandMode
cm
moveToStart :: CommandMode -> CommandMode
moveToStart (CMode xs :: [Grapheme]
xs c :: Grapheme
c ys :: [Grapheme]
ys) = let zs :: [Grapheme]
zs = [Grapheme] -> [Grapheme]
forall a. [a] -> [a]
reverse [Grapheme]
xs [Grapheme] -> [Grapheme] -> [Grapheme]
forall a. [a] -> [a] -> [a]
++ (Grapheme
cGrapheme -> [Grapheme] -> [Grapheme]
forall a. a -> [a] -> [a]
:[Grapheme]
ys) in [Grapheme] -> Grapheme -> [Grapheme] -> CommandMode
CMode [] ([Grapheme] -> Grapheme
forall a. [a] -> a
head [Grapheme]
zs) ([Grapheme] -> [Grapheme]
forall a. [a] -> [a]
tail [Grapheme]
zs)
moveToStart CEmpty = CommandMode
CEmpty
moveToEnd :: CommandMode -> CommandMode
moveToEnd (CMode xs :: [Grapheme]
xs c :: Grapheme
c ys :: [Grapheme]
ys) = let zs :: [Grapheme]
zs = [Grapheme] -> [Grapheme]
forall a. [a] -> [a]
reverse [Grapheme]
ys [Grapheme] -> [Grapheme] -> [Grapheme]
forall a. [a] -> [a] -> [a]
++ (Grapheme
cGrapheme -> [Grapheme] -> [Grapheme]
forall a. a -> [a] -> [a]
:[Grapheme]
xs) in [Grapheme] -> Grapheme -> [Grapheme] -> CommandMode
CMode ([Grapheme] -> [Grapheme]
forall a. [a] -> [a]
tail [Grapheme]
zs) ([Grapheme] -> Grapheme
forall a. [a] -> a
head [Grapheme]
zs) []
moveToEnd CEmpty = CommandMode
CEmpty
deleteChar :: CommandMode -> CommandMode
deleteChar :: CommandMode -> CommandMode
deleteChar (CMode xs :: [Grapheme]
xs _ (y :: Grapheme
y:ys :: [Grapheme]
ys)) = [Grapheme] -> Grapheme -> [Grapheme] -> CommandMode
CMode [Grapheme]
xs Grapheme
y [Grapheme]
ys
deleteChar (CMode (x :: Grapheme
x:xs :: [Grapheme]
xs) _ []) = [Grapheme] -> Grapheme -> [Grapheme] -> CommandMode
CMode [Grapheme]
xs Grapheme
x []
deleteChar _ = CommandMode
CEmpty
replaceChar :: Char -> CommandMode -> CommandMode
replaceChar :: Char -> CommandMode -> CommandMode
replaceChar c :: Char
c (CMode xs :: [Grapheme]
xs d :: Grapheme
d ys :: [Grapheme]
ys)
| Bool -> Bool
not (Char -> Bool
isCombiningChar Char
c) = [Grapheme] -> Grapheme -> [Grapheme] -> CommandMode
CMode [Grapheme]
xs (Char -> Grapheme
baseGrapheme Char
c) [Grapheme]
ys
| Bool
otherwise = [Grapheme] -> Grapheme -> [Grapheme] -> CommandMode
CMode [Grapheme]
xs (Grapheme -> Char -> Grapheme
addCombiner Grapheme
d Char
c) [Grapheme]
ys
replaceChar _ CEmpty = CommandMode
CEmpty
pasteGraphemesBefore, pasteGraphemesAfter :: [Grapheme] -> CommandMode -> CommandMode
pasteGraphemesBefore :: [Grapheme] -> CommandMode -> CommandMode
pasteGraphemesBefore [] = CommandMode -> CommandMode
forall a. a -> a
id
pasteGraphemesBefore s :: [Grapheme]
s = InsertMode -> CommandMode
enterCommandMode (InsertMode -> CommandMode)
-> (CommandMode -> InsertMode) -> CommandMode -> CommandMode
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Grapheme] -> InsertMode -> InsertMode
insertGraphemes [Grapheme]
s (InsertMode -> InsertMode)
-> (CommandMode -> InsertMode) -> CommandMode -> InsertMode
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CommandMode -> InsertMode
insertFromCommandMode
pasteGraphemesAfter :: [Grapheme] -> CommandMode -> CommandMode
pasteGraphemesAfter [] = CommandMode -> CommandMode
forall a. a -> a
id
pasteGraphemesAfter s :: [Grapheme]
s = InsertMode -> CommandMode
enterCommandMode (InsertMode -> CommandMode)
-> (CommandMode -> InsertMode) -> CommandMode -> CommandMode
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Grapheme] -> InsertMode -> InsertMode
insertGraphemes [Grapheme]
s (InsertMode -> InsertMode)
-> (CommandMode -> InsertMode) -> CommandMode -> InsertMode
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CommandMode -> InsertMode
appendFromCommandMode
enterCommandMode, enterCommandModeRight :: InsertMode -> CommandMode
enterCommandMode :: InsertMode -> CommandMode
enterCommandMode (IMode (x :: Grapheme
x:xs :: [Grapheme]
xs) ys :: [Grapheme]
ys) = [Grapheme] -> Grapheme -> [Grapheme] -> CommandMode
CMode [Grapheme]
xs Grapheme
x [Grapheme]
ys
enterCommandMode (IMode [] (y :: Grapheme
y:ys :: [Grapheme]
ys)) = [Grapheme] -> Grapheme -> [Grapheme] -> CommandMode
CMode [] Grapheme
y [Grapheme]
ys
enterCommandMode _ = CommandMode
CEmpty
enterCommandModeRight :: InsertMode -> CommandMode
enterCommandModeRight (IMode xs :: [Grapheme]
xs (y :: Grapheme
y:ys :: [Grapheme]
ys)) = [Grapheme] -> Grapheme -> [Grapheme] -> CommandMode
CMode [Grapheme]
xs Grapheme
y [Grapheme]
ys
enterCommandModeRight (IMode (x :: Grapheme
x:xs :: [Grapheme]
xs) []) = [Grapheme] -> Grapheme -> [Grapheme] -> CommandMode
CMode [Grapheme]
xs Grapheme
x []
enterCommandModeRight _ = CommandMode
CEmpty
insertFromCommandMode, appendFromCommandMode :: CommandMode -> InsertMode
insertFromCommandMode :: CommandMode -> InsertMode
insertFromCommandMode CEmpty = InsertMode
emptyIM
insertFromCommandMode (CMode xs :: [Grapheme]
xs c :: Grapheme
c ys :: [Grapheme]
ys) = [Grapheme] -> [Grapheme] -> InsertMode
IMode [Grapheme]
xs (Grapheme
cGrapheme -> [Grapheme] -> [Grapheme]
forall a. a -> [a] -> [a]
:[Grapheme]
ys)
appendFromCommandMode :: CommandMode -> InsertMode
appendFromCommandMode CEmpty = InsertMode
emptyIM
appendFromCommandMode (CMode xs :: [Grapheme]
xs c :: Grapheme
c ys :: [Grapheme]
ys) = [Grapheme] -> [Grapheme] -> InsertMode
IMode (Grapheme
cGrapheme -> [Grapheme] -> [Grapheme]
forall a. a -> [a] -> [a]
:[Grapheme]
xs) [Grapheme]
ys
withCommandMode :: (InsertMode -> InsertMode) -> CommandMode -> CommandMode
withCommandMode :: (InsertMode -> InsertMode) -> CommandMode -> CommandMode
withCommandMode f :: InsertMode -> InsertMode
f = InsertMode -> CommandMode
enterCommandModeRight (InsertMode -> CommandMode)
-> (CommandMode -> InsertMode) -> CommandMode -> CommandMode
forall b c a. (b -> c) -> (a -> b) -> a -> c
. InsertMode -> InsertMode
f (InsertMode -> InsertMode)
-> (CommandMode -> InsertMode) -> CommandMode -> InsertMode
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CommandMode -> InsertMode
insertFromCommandMode
data ArgMode s = ArgMode {ArgMode s -> Int
arg :: Int, ArgMode s -> s
argState :: s}
instance Functor ArgMode where
fmap :: (a -> b) -> ArgMode a -> ArgMode b
fmap f :: a -> b
f am :: ArgMode a
am = ArgMode a
am {argState :: b
argState = a -> b
f (ArgMode a -> a
forall s. ArgMode s -> s
argState ArgMode a
am)}
instance LineState s => LineState (ArgMode s) where
beforeCursor :: [Grapheme] -> ArgMode s -> [Grapheme]
beforeCursor _ am :: ArgMode s
am = let pre :: [Grapheme]
pre = (Char -> Grapheme) -> [Char] -> [Grapheme]
forall a b. (a -> b) -> [a] -> [b]
map Char -> Grapheme
baseGrapheme ([Char] -> [Grapheme]) -> [Char] -> [Grapheme]
forall a b. (a -> b) -> a -> b
$ "(arg: " [Char] -> ShowS
forall a. [a] -> [a] -> [a]
++ Int -> [Char]
forall a. Show a => a -> [Char]
show (ArgMode s -> Int
forall s. ArgMode s -> Int
arg ArgMode s
am) [Char] -> ShowS
forall a. [a] -> [a] -> [a]
++ ") "
in [Grapheme] -> s -> [Grapheme]
forall s. LineState s => [Grapheme] -> s -> [Grapheme]
beforeCursor [Grapheme]
pre (ArgMode s -> s
forall s. ArgMode s -> s
argState ArgMode s
am)
afterCursor :: ArgMode s -> [Grapheme]
afterCursor = s -> [Grapheme]
forall s. LineState s => s -> [Grapheme]
afterCursor (s -> [Grapheme]) -> (ArgMode s -> s) -> ArgMode s -> [Grapheme]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ArgMode s -> s
forall s. ArgMode s -> s
argState
instance Result s => Result (ArgMode s) where
toResult :: ArgMode s -> [Char]
toResult = s -> [Char]
forall s. Result s => s -> [Char]
toResult (s -> [Char]) -> (ArgMode s -> s) -> ArgMode s -> [Char]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ArgMode s -> s
forall s. ArgMode s -> s
argState
instance Save s => Save (ArgMode s) where
save :: ArgMode s -> InsertMode
save = s -> InsertMode
forall s. Save s => s -> InsertMode
save (s -> InsertMode) -> (ArgMode s -> s) -> ArgMode s -> InsertMode
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ArgMode s -> s
forall s. ArgMode s -> s
argState
restore :: InsertMode -> ArgMode s
restore = Int -> s -> ArgMode s
forall s. Int -> s -> ArgMode s
startArg 0 (s -> ArgMode s) -> (InsertMode -> s) -> InsertMode -> ArgMode s
forall b c a. (b -> c) -> (a -> b) -> a -> c
. InsertMode -> s
forall s. Save s => InsertMode -> s
restore
startArg :: Int -> s -> ArgMode s
startArg :: Int -> s -> ArgMode s
startArg = Int -> s -> ArgMode s
forall s. Int -> s -> ArgMode s
ArgMode
addNum :: Int -> ArgMode s -> ArgMode s
addNum :: Int -> ArgMode s -> ArgMode s
addNum n :: Int
n am :: ArgMode s
am
| ArgMode s -> Int
forall s. ArgMode s -> Int
arg ArgMode s
am Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= 1000 = ArgMode s
am
| Bool
otherwise = ArgMode s
am {arg :: Int
arg = ArgMode s -> Int
forall s. ArgMode s -> Int
arg ArgMode s
am Int -> Int -> Int
forall a. Num a => a -> a -> a
* 10 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
n}
applyArg :: (s -> s) -> ArgMode s -> s
applyArg :: (s -> s) -> ArgMode s -> s
applyArg f :: s -> s
f am :: ArgMode s
am = Int -> (s -> s) -> s -> s
forall a. Int -> (a -> a) -> a -> a
repeatN (ArgMode s -> Int
forall s. ArgMode s -> Int
arg ArgMode s
am) s -> s
f (ArgMode s -> s
forall s. ArgMode s -> s
argState ArgMode s
am)
repeatN :: Int -> (a -> a) -> a -> a
repeatN :: Int -> (a -> a) -> a -> a
repeatN n :: Int
n f :: a -> a
f | Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= 1 = a -> a
f
| Bool
otherwise = a -> a
f (a -> a) -> (a -> a) -> a -> a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> (a -> a) -> a -> a
forall a. Int -> (a -> a) -> a -> a
repeatN (Int
nInt -> Int -> Int
forall a. Num a => a -> a -> a
-1) a -> a
f
applyCmdArg :: (InsertMode -> InsertMode) -> ArgMode CommandMode -> CommandMode
applyCmdArg :: (InsertMode -> InsertMode) -> ArgMode CommandMode -> CommandMode
applyCmdArg f :: InsertMode -> InsertMode
f am :: ArgMode CommandMode
am = (InsertMode -> InsertMode) -> CommandMode -> CommandMode
withCommandMode (Int -> (InsertMode -> InsertMode) -> InsertMode -> InsertMode
forall a. Int -> (a -> a) -> a -> a
repeatN (ArgMode CommandMode -> Int
forall s. ArgMode s -> Int
arg ArgMode CommandMode
am) InsertMode -> InsertMode
f) (ArgMode CommandMode -> CommandMode
forall s. ArgMode s -> s
argState ArgMode CommandMode
am)
newtype Message = Message {Message -> [Char]
messageText :: String}
instance LineState Message where
beforeCursor :: [Grapheme] -> Message -> [Grapheme]
beforeCursor _ = [Char] -> [Grapheme]
stringToGraphemes ([Char] -> [Grapheme])
-> (Message -> [Char]) -> Message -> [Grapheme]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Message -> [Char]
messageText
afterCursor :: Message -> [Grapheme]
afterCursor _ = []
data Password = Password {Password -> [Char]
passwordState :: [Char],
Password -> Maybe Char
passwordChar :: Maybe Char}
instance LineState Password where
beforeCursor :: [Grapheme] -> Password -> [Grapheme]
beforeCursor prefix :: [Grapheme]
prefix p :: Password
p
= [Grapheme]
prefix [Grapheme] -> [Grapheme] -> [Grapheme]
forall a. [a] -> [a] -> [a]
++ ([Char] -> [Grapheme]
stringToGraphemes
([Char] -> [Grapheme]) -> [Char] -> [Grapheme]
forall a b. (a -> b) -> a -> b
$ case Password -> Maybe Char
passwordChar Password
p of
Nothing -> []
Just c :: Char
c -> Int -> Char -> [Char]
forall a. Int -> a -> [a]
replicate ([Char] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length ([Char] -> Int) -> [Char] -> Int
forall a b. (a -> b) -> a -> b
$ Password -> [Char]
passwordState Password
p) Char
c)
afterCursor :: Password -> [Grapheme]
afterCursor _ = []
instance Result Password where
toResult :: Password -> [Char]
toResult = ShowS
forall a. [a] -> [a]
reverse ShowS -> (Password -> [Char]) -> Password -> [Char]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Password -> [Char]
passwordState
addPasswordChar :: Char -> Password -> Password
addPasswordChar :: Char -> Password -> Password
addPasswordChar c :: Char
c p :: Password
p = Password
p {passwordState :: [Char]
passwordState = Char
c Char -> ShowS
forall a. a -> [a] -> [a]
: Password -> [Char]
passwordState Password
p}
deletePasswordChar :: Password -> Password
deletePasswordChar :: Password -> Password
deletePasswordChar (Password (_:cs :: [Char]
cs) m :: Maybe Char
m) = [Char] -> Maybe Char -> Password
Password [Char]
cs Maybe Char
m
deletePasswordChar p :: Password
p = Password
p
atStart, atEnd :: (Char -> Bool) -> InsertMode -> Bool
atStart :: (Char -> Bool) -> InsertMode -> Bool
atStart f :: Char -> Bool
f (IMode (x :: Grapheme
x:_) (y :: Grapheme
y:_)) = Bool -> Bool
not (Char -> Bool
f (Grapheme -> Char
baseChar Grapheme
x)) Bool -> Bool -> Bool
&& Char -> Bool
f (Grapheme -> Char
baseChar Grapheme
y)
atStart _ _ = Bool
False
atEnd :: (Char -> Bool) -> InsertMode -> Bool
atEnd f :: Char -> Bool
f (IMode _ (y1 :: Grapheme
y1:y2 :: Grapheme
y2:_)) = Char -> Bool
f (Grapheme -> Char
baseChar Grapheme
y1) Bool -> Bool -> Bool
&& Bool -> Bool
not (Char -> Bool
f (Grapheme -> Char
baseChar Grapheme
y2))
atEnd _ _ = Bool
False
overChar, beforeChar, afterChar :: (Char -> Bool) -> InsertMode -> Bool
overChar :: (Char -> Bool) -> InsertMode -> Bool
overChar f :: Char -> Bool
f (IMode _ (y :: Grapheme
y:_)) = Char -> Bool
f (Grapheme -> Char
baseChar Grapheme
y)
overChar _ _ = Bool
False
beforeChar :: (Char -> Bool) -> InsertMode -> Bool
beforeChar f :: Char -> Bool
f (IMode _ (_:y :: Grapheme
y:_)) = Char -> Bool
f (Grapheme -> Char
baseChar Grapheme
y)
beforeChar _ _ = Bool
False
afterChar :: (Char -> Bool) -> InsertMode -> Bool
afterChar f :: Char -> Bool
f (IMode (x :: Grapheme
x:_) _) = Char -> Bool
f (Grapheme -> Char
baseChar Grapheme
x)
afterChar _ _ = Bool
False
goRightUntil, goLeftUntil :: (InsertMode -> Bool) -> InsertMode -> InsertMode
goRightUntil :: (InsertMode -> Bool) -> InsertMode -> InsertMode
goRightUntil f :: InsertMode -> Bool
f = InsertMode -> InsertMode
loop (InsertMode -> InsertMode)
-> (InsertMode -> InsertMode) -> InsertMode -> InsertMode
forall b c a. (b -> c) -> (a -> b) -> a -> c
. InsertMode -> InsertMode
forall s. Move s => s -> s
goRight
where
loop :: InsertMode -> InsertMode
loop im :: InsertMode
im@(IMode _ ys :: [Grapheme]
ys) | [Grapheme] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Grapheme]
ys Bool -> Bool -> Bool
|| InsertMode -> Bool
f InsertMode
im = InsertMode
im
| Bool
otherwise = InsertMode -> InsertMode
loop (InsertMode -> InsertMode
forall s. Move s => s -> s
goRight InsertMode
im)
goLeftUntil :: (InsertMode -> Bool) -> InsertMode -> InsertMode
goLeftUntil f :: InsertMode -> Bool
f = InsertMode -> InsertMode
loop (InsertMode -> InsertMode)
-> (InsertMode -> InsertMode) -> InsertMode -> InsertMode
forall b c a. (b -> c) -> (a -> b) -> a -> c
. InsertMode -> InsertMode
forall s. Move s => s -> s
goLeft
where
loop :: InsertMode -> InsertMode
loop im :: InsertMode
im@(IMode xs :: [Grapheme]
xs _) | [Grapheme] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Grapheme]
xs Bool -> Bool -> Bool
|| InsertMode -> Bool
f InsertMode
im = InsertMode
im
| Bool
otherwise = InsertMode -> InsertMode
loop (InsertMode -> InsertMode
forall s. Move s => s -> s
goLeft InsertMode
im)