{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE ExistentialQuantification #-}
module Talash.Brick.Columns (
Searcher (..) , SearchEvent (..) , SearchEnv (..) , EventHooks (..) , AppTheme (..)
, AppSettings (..) , AppSettingsG (..) , SearchFunctions , CaseSensitivity (..)
, searchApp , defSettings , selected , selectedIndex , runApp
, query , prevQuery , allMatches , matches , numMatches
, matchedTop , totalMatches , term
, searchFunctions , candidates , eventSource
, prompt , themeAttrs , borderStyle
, theme , hooks
, handleKeyEvent , handleSearch , searcherWidget , initialSearcher , partsColumns , runApp' , selected' , selectedIndex') where
import qualified Data.Text as T
import Data.Vector (elemIndex)
import GHC.Compact (Compact , compact , getCompact)
import Talash.Brick.Internal
import Talash.Intro hiding (on ,replicate , take)
data AppTheme = AppTheme { AppTheme -> Text
_prompt :: Text
, AppTheme -> [AttrName]
_columnAttrs :: [AttrName]
, AppTheme -> [Int]
_columnLimits :: [Int]
, AppTheme -> [(AttrName, Attr)]
_themeAttrs :: [(AttrName, Attr)]
, AppTheme -> BorderStyle
_borderStyle :: BorderStyle
}
makeLenses ''AppTheme
type AppSettings n a = AppSettingsG n a Text AppTheme
data ColumnsIso a = ColumnsIso { forall a. ColumnsIso a -> a -> [Text]
_toColumns :: a -> [Text] , forall a. ColumnsIso a -> [Text] -> a
_fromColumns :: [Text] -> a}
makeLenses ''ColumnsIso
searcherWidget :: (KnownNat n , KnownNat m) => AppTheme -> SearchEnv n a Text -> SearcherSized m a -> Widget Bool
searcherWidget :: forall (n :: Nat) (m :: Nat) a.
(KnownNat n, KnownNat m) =>
AppTheme -> SearchEnv n a Text -> SearcherSized m a -> Widget Bool
searcherWidget AppTheme
t SearchEnv n a Text
env SearcherSized m a
s = forall n. Widget n -> Widget n
joinBorders forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall n. Widget n -> Widget n
border forall a b. (a -> b) -> a -> b
$ forall n.
(Ord n, Show n) =>
Bool -> Text -> Editor Text n -> Widget n -> Widget n
searchWidgetAux Bool
True (AppTheme
t forall s a. s -> Getting a s a -> a
^. Lens' AppTheme Text
prompt) (SearcherSized m a
s forall s a. s -> Getting a s a -> a
^. forall (n :: Nat) a. Lens' (SearcherSized n a) (Editor Text Bool)
queryEditor) (forall n. AttrName -> Widget n -> Widget n
withAttr (String -> AttrName
attrName String
"Stats") forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall n. Text -> Widget n
txt forall a b. (a -> b) -> a -> b
$ (String -> Text
T.pack forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Show a => a -> String
show forall a b. (a -> b) -> a -> b
$ SearcherSized m a
s forall s a. s -> Getting a s a -> a
^. forall (n :: Nat) a. Lens' (SearcherSized n a) Int
numMatches))
forall n. Widget n -> Widget n -> Widget n
<=> forall n. Widget n
hBorder forall n. Widget n -> Widget n -> Widget n
<=> forall n. Widget n -> Widget n
joinBorders (forall n (m :: Nat) (l :: Nat) a.
(Ord n, Show n, KnownNat m, KnownNat l) =>
SearchEnv l a Text
-> Text
-> [AttrName]
-> [Int]
-> MatcherSized m a
-> Bool
-> GenericList n MatchSetG (ScoredMatchSized m)
-> Widget n
makeColumns SearchEnv n a Text
env Text
"➜ " (AppTheme
t forall s a. s -> Getting a s a -> a
^. Lens' AppTheme [AttrName]
columnAttrs) (AppTheme
t forall s a. s -> Getting a s a -> a
^. Lens' AppTheme [Int]
columnLimits) (SearcherSized m a
s forall s a. s -> Getting a s a -> a
^. forall (n :: Nat) a. Lens' (SearcherSized n a) (MatcherSized n a)
matcher) Bool
False (SearcherSized m a
s forall s a. s -> Getting a s a -> a
^. forall (n :: Nat) a.
Lens'
(SearcherSized n a)
(GenericList Bool MatchSetG (ScoredMatchSized n))
matches))
defThemeAttrs :: [(AttrName, Attr)]
defThemeAttrs :: [(AttrName, Attr)]
defThemeAttrs = [ (AttrName
listSelectedAttr, Attr -> Style -> Attr
withStyle (Color -> Attr
bg Color
white) Style
bold) , (String -> AttrName
attrName String
"Prompt" , Attr -> Style -> Attr
withStyle (Color
white Color -> Color -> Attr
`on` Color
blue) Style
bold)
, (String -> AttrName
attrName String
"Highlight" , Attr -> Style -> Attr
withStyle (Color -> Attr
fg Color
blue) Style
bold) , (String -> AttrName
attrName String
"Stats" , Color -> Attr
fg Color
blue) , (AttrName
borderAttr , Color -> Attr
fg Color
cyan)]
defTheme ::AppTheme
defTheme :: AppTheme
defTheme = AppTheme {_prompt :: Text
_prompt = Text
"Find: " , _columnAttrs :: [AttrName]
_columnAttrs = forall a. a -> [a]
repeat forall a. Monoid a => a
mempty , _columnLimits :: [Int]
_columnLimits = forall a. a -> [a]
repeat Int
50 , _themeAttrs :: [(AttrName, Attr)]
_themeAttrs = [(AttrName, Attr)]
defThemeAttrs
, _borderStyle :: BorderStyle
_borderStyle = BorderStyle
unicodeRounded}
{-# INLINE defSettings#-}
defSettings :: KnownNat n => AppSettings n a
defSettings :: forall (n :: Nat) a. KnownNat n => AppSettings n a
defSettings = forall (n :: Nat) a b t.
t
-> ReaderT (SearchEnv n a b) EventHooks (Searcher a)
-> Proxy n
-> Int
-> (SearchReport -> Bool)
-> AppSettingsG n a b t
AppSettings AppTheme
defTheme (forall r (m :: * -> *) a. (r -> m a) -> ReaderT r m a
ReaderT (\SearchEnv n a Text
e -> forall a. EventHooks a
defHooks {keyHook :: Key -> [Modifier] -> EventM Bool (Searcher a) ()
keyHook = forall (n :: Nat) a c b.
KnownNat n =>
SearchEnv n a c -> Key -> [Modifier] -> EventM Bool (Searcher b) ()
handleKeyEvent SearchEnv n a Text
e})) forall {k} (t :: k). Proxy t
Proxy Int
1024 (\SearchReport
r -> SearchReport
r forall s a. s -> Getting a s a -> a
^. Lens' SearchReport Ocassion
ocassion forall a. Eq a => a -> a -> Bool
== Ocassion
QueryDone)
searchApp :: KnownNat n => AppSettings n a -> SearchEnv n a Text -> App (Searcher a) (SearchEvent a) Bool
searchApp :: forall (n :: Nat) a.
KnownNat n =>
AppSettings n a
-> SearchEnv n a Text -> App (Searcher a) (SearchEvent a) Bool
searchApp (AppSettings AppTheme
th ReaderT (SearchEnv n a Text) EventHooks (Searcher a)
hks Proxy n
_ Int
_ SearchReport -> Bool
_) SearchEnv n a Text
env = App {appDraw :: Searcher a -> [Widget Bool]
appDraw = Searcher a -> [Widget Bool]
ad , appChooseCursor :: Searcher a -> [CursorLocation Bool] -> Maybe (CursorLocation Bool)
appChooseCursor = forall s n. s -> [CursorLocation n] -> Maybe (CursorLocation n)
showFirstCursor , appHandleEvent :: BrickEvent Bool (SearchEvent a) -> EventM Bool (Searcher a) ()
appHandleEvent = forall {n}.
BrickEvent n (SearchEvent a) -> EventM Bool (Searcher a) ()
he , appStartEvent :: EventM Bool (Searcher a) ()
appStartEvent = EventM Bool (Searcher a) ()
as , appAttrMap :: Searcher a -> AttrMap
appAttrMap = forall {b}. b -> AttrMap
am}
where
ad :: Searcher a -> [Widget Bool]
ad (Searcher SearcherSized n a
s) = (forall a. a -> [a] -> [a]
:[]) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall n. BorderStyle -> Widget n -> Widget n
withBorderStyle (AppTheme
th forall s a. s -> Getting a s a -> a
^. Lens' AppTheme BorderStyle
borderStyle) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (n :: Nat) (m :: Nat) a.
(KnownNat n, KnownNat m) =>
AppTheme -> SearchEnv n a Text -> SearcherSized m a -> Widget Bool
searcherWidget AppTheme
th SearchEnv n a Text
env forall a b. (a -> b) -> a -> b
$ SearcherSized n a
s
as :: EventM Bool (Searcher a) ()
as = forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (forall (n :: Nat) a b.
KnownNat n =>
SearchEnv n a b -> Text -> IO ()
sendQuery SearchEnv n a Text
env Text
"")
am :: b -> AttrMap
am = forall a b. a -> b -> a
const forall a b. (a -> b) -> a -> b
$ Attr -> [(AttrName, Attr)] -> AttrMap
attrMap Attr
defAttr (AppTheme
th forall s a. s -> Getting a s a -> a
^. Lens' AppTheme [(AttrName, Attr)]
themeAttrs)
hk :: EventHooks (Searcher a)
hk = forall r (m :: * -> *) a. ReaderT r m a -> r -> m a
runReaderT ReaderT (SearchEnv n a Text) EventHooks (Searcher a)
hks SearchEnv n a Text
env
he :: BrickEvent n (SearchEvent a) -> EventM Bool (Searcher a) ()
he (VtyEvent (EvKey Key
k [Modifier]
m)) = forall a. EventHooks a -> Key -> [Modifier] -> EventM Bool a ()
keyHook EventHooks (Searcher a)
hk Key
k [Modifier]
m
he (VtyEvent (EvMouseDown Int
i Int
j Button
b [Modifier]
m)) = forall a.
EventHooks a
-> Int -> Int -> Button -> [Modifier] -> EventM Bool a ()
mouseDownHook EventHooks (Searcher a)
hk Int
i Int
j Button
b [Modifier]
m
he (VtyEvent (EvMouseUp Int
i Int
j Maybe Button
b )) = forall a.
EventHooks a -> Int -> Int -> Maybe Button -> EventM Bool a ()
mouseUpHook EventHooks (Searcher a)
hk Int
i Int
j Maybe Button
b
he (VtyEvent (EvPaste ByteString
b )) = forall a. EventHooks a -> ByteString -> EventM Bool a ()
pasteHook EventHooks (Searcher a)
hk ByteString
b
he (VtyEvent Event
EvGainedFocus ) = forall a. EventHooks a -> EventM Bool a ()
focusGainedHook EventHooks (Searcher a)
hk
he (VtyEvent Event
EvLostFocus ) = forall a. EventHooks a -> EventM Bool a ()
focusLostHook EventHooks (Searcher a)
hk
he (AppEvent SearchEvent a
e) = forall a. SearchEvent a -> EventM Bool (Searcher a) ()
handleSearch SearchEvent a
e
he BrickEvent n (SearchEvent a)
_ = forall (f :: * -> *) a. Applicative f => a -> f a
pure ()
partsColumns :: [Text] -> [[Text]]
partsColumns :: [Text] -> [[Text]]
partsColumns = forall a. [a] -> [a] -> [a]
initDef [] forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall b a. (b -> Maybe (a, b)) -> b -> [a]
unfoldr (\[Text]
l -> if forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Text]
l then forall a. Maybe a
Nothing else forall a. a -> Maybe a
Just forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Text] -> ([Text], [Text])
go forall a b. (a -> b) -> a -> b
$ [Text]
l)
where
go :: [Text] -> ([Text], [Text])
go [Text]
x = forall (p :: * -> * -> *) a b c d.
Bifunctor p =>
(a -> b) -> (c -> d) -> p a c -> p b d
bimap ([Text]
f forall a. Semigroup a => a -> a -> a
<>) (forall b a. b -> (a -> b) -> Maybe a -> b
maybe [Text]
s' (forall a. a -> [a] -> [a]
: [Text]
s')) ([Text], Maybe Text)
hs
where
([Text]
f , [Text]
s) = forall a. (a -> Bool) -> [a] -> ([a], [a])
break (Text -> Text -> Bool
T.isInfixOf Text
"\n") [Text]
x
s' :: [Text]
s' = forall a. [a] -> [a] -> [a]
tailDef [] [Text]
s
hs :: ([Text], Maybe Text)
hs = forall b a. b -> (a -> b) -> Maybe a -> b
maybe ([] , forall a. Maybe a
Nothing) (forall (p :: * -> * -> *) a b c d.
Bifunctor p =>
(a -> b) -> (c -> d) -> p a c -> p b d
bimap (forall a. a -> [a] -> [a]
:[]) (Text -> Text -> Maybe Text
T.stripPrefix Text
"\n") forall b c a. (b -> c) -> (a -> b) -> a -> c
. HasCallStack => Text -> Text -> (Text, Text)
T.breakOn Text
"\n") forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. [a] -> Maybe a
headMay forall a b. (a -> b) -> a -> b
$ [Text]
s
makeColumns :: (Ord n , Show n , KnownNat m , KnownNat l) => SearchEnv l a Text -> Text -> [AttrName] -> [Int]
-> MatcherSized m a -> Bool -> GenericList n MatchSetG (ScoredMatchSized m) -> Widget n
makeColumns :: forall n (m :: Nat) (l :: Nat) a.
(Ord n, Show n, KnownNat m, KnownNat l) =>
SearchEnv l a Text
-> Text
-> [AttrName]
-> [Int]
-> MatcherSized m a
-> Bool
-> GenericList n MatchSetG (ScoredMatchSized m)
-> Widget n
makeColumns SearchEnv l a Text
env Text
c [AttrName]
as [Int]
ls MatcherSized m a
m = forall (t :: * -> *) n e.
(Foldable t, Splittable t, Ord n, Show n) =>
(Bool -> e -> Widget n) -> Bool -> GenericList n t e -> Widget n
renderList (forall a n.
Text
-> (a -> [[Text]]) -> [AttrName] -> [Int] -> Bool -> a -> Widget n
columnsWithHighlights Text
c ScoredMatchSized m -> [[Text]]
mp [AttrName]
as [Int]
ls)
where
mp :: ScoredMatchSized m -> [[Text]]
mp ScoredMatchSized m
s = [Text] -> [[Text]]
partsColumns forall a b. (a -> b) -> a -> b
$ (SearchEnv l a Text
env forall s a. s -> Getting a s a -> a
^. forall (n :: Nat) a b1 b2.
Lens
(SearchEnv n a b1)
(SearchEnv n a b2)
(SearchFunctions a b1)
(SearchFunctions a b2)
searchFunctions forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b (n :: Nat).
KnownNat n =>
SimpleGetter
(SearchFunctions a b)
((Bool -> Text -> b)
-> MatcherSized n a -> Text -> Vector n Int -> [b])
display) (forall a b. a -> b -> a
const forall a. a -> a
id) MatcherSized m a
m ((SearchEnv l a Text
env forall s a. s -> Getting a s a -> a
^. forall (n :: Nat) a b. Lens' (SearchEnv n a b) (Chunks n)
candidates) forall (n :: Nat). KnownNat n => Chunks n -> ChunkIndex -> Text
! forall (n :: Nat). ScoredMatchSized n -> ChunkIndex
chunkIndex ScoredMatchSized m
s) (forall (n :: Nat). ScoredMatchSized n -> Vector n Int
matchData ScoredMatchSized m
s)
runApp' :: KnownNat n => AppSettings n a -> SearchFunctions a Text -> Chunks n -> IO (Searcher a)
runApp' :: forall (n :: Nat) a.
KnownNat n =>
AppSettings n a
-> SearchFunctions a Text -> Chunks n -> IO (Searcher a)
runApp' AppSettings n a
s SearchFunctions a Text
f Chunks n
c = (\BChan (SearchEvent a)
b -> (\SearchEnv n a Text
env -> forall (n :: Nat) a b. KnownNat n => SearchEnv n a b -> IO ()
startSearcher SearchEnv n a Text
env forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> forall a b. IO a -> IO b -> IO a
finally (forall n b e. Ord n => App b e n -> BChan e -> b -> IO b
theMain (forall (n :: Nat) a.
KnownNat n =>
AppSettings n a
-> SearchEnv n a Text -> App (Searcher a) (SearchEvent a) Bool
searchApp AppSettings n a
s SearchEnv n a Text
env) BChan (SearchEvent a)
b forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a (n :: Nat). KnownNat n => SearcherSized n a -> Searcher a
Searcher forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (n :: Nat) a c.
SearchEnv n a c -> BChan (SearchEvent a) -> SearcherSized 0 a
initialSearcher SearchEnv n a Text
env forall a b. (a -> b) -> a -> b
$ BChan (SearchEvent a)
b) (forall (n :: Nat) a b. KnownNat n => SearchEnv n a b -> IO ()
stopSearcher SearchEnv n a Text
env))
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< forall (n :: Nat) a b.
KnownNat n =>
SearchFunctions a b
-> Int
-> (forall (n1 :: Nat) (m :: Nat).
(KnownNat n1, KnownNat m) =>
Chunks n1
-> SearchReport -> MatcherSized m a -> MatchSetSized m -> IO ())
-> Chunks n
-> IO (SearchEnv n a b)
searchEnv SearchFunctions a Text
f (AppSettings n a
s forall s a. s -> Getting a s a -> a
^. forall (n :: Nat) a b t. Lens' (AppSettingsG n a b t) Int
maximumMatches) (forall (m :: Nat) a b c.
KnownNat m =>
(SearchReport -> Bool)
-> BChan (SearchEvent a)
-> c
-> SearchReport
-> MatcherSized m a
-> MatchSetSized m
-> IO ()
generateSearchEvent (AppSettings n a
s forall s a. s -> Getting a s a -> a
^. forall (n :: Nat) a b t.
Lens' (AppSettingsG n a b t) (SearchReport -> Bool)
eventStrategy) BChan (SearchEvent a)
b) Chunks n
c) forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< forall a. Int -> IO (BChan a)
newBChan Int
8
runApp :: KnownNat n => AppSettings n a -> SearchFunctions a Text -> Vector [Text] -> IO (Searcher a)
runApp :: forall (n :: Nat) a.
KnownNat n =>
AppSettings n a
-> SearchFunctions a Text -> Vector [Text] -> IO (Searcher a)
runApp AppSettings n a
s SearchFunctions a Text
f = forall (n :: Nat) a.
KnownNat n =>
AppSettings n a
-> SearchFunctions a Text -> Chunks n -> IO (Searcher a)
runApp' AppSettings n a
s SearchFunctions a Text
f forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (n :: Nat). KnownNat n => Vector Text -> Chunks n
makeChunks forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
map [Text] -> Text
T.unlines
selected' :: KnownNat n => AppSettings n a -> SearchFunctions a Text -> Chunks n -> IO (Maybe [Text])
selected' :: forall (n :: Nat) a.
KnownNat n =>
AppSettings n a
-> SearchFunctions a Text -> Chunks n -> IO (Maybe [Text])
selected' AppSettings n a
s SearchFunctions a Text
f = (\Chunks n
c -> forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
map (forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
map Text -> [Text]
T.lines forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (n :: Nat) a.
KnownNat n =>
Chunks n -> Searcher a -> Maybe Text
selectedElement Chunks n
c) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (n :: Nat) a.
KnownNat n =>
AppSettings n a
-> SearchFunctions a Text -> Chunks n -> IO (Searcher a)
runApp' AppSettings n a
s SearchFunctions a Text
f forall a b. (a -> b) -> a -> b
$ Chunks n
c) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Compact a -> a
getCompact forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=< forall a. a -> IO (Compact a)
compact forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (n :: Nat). KnownNat n => Chunks n -> Chunks n
forceChunks
selected :: KnownNat n => AppSettings n a -> SearchFunctions a Text -> Vector [Text] -> IO (Maybe [Text])
selected :: forall (n :: Nat) a.
KnownNat n =>
AppSettings n a
-> SearchFunctions a Text -> Vector [Text] -> IO (Maybe [Text])
selected AppSettings n a
s SearchFunctions a Text
f = forall (n :: Nat) a.
KnownNat n =>
AppSettings n a
-> SearchFunctions a Text -> Chunks n -> IO (Maybe [Text])
selected' AppSettings n a
s SearchFunctions a Text
f forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (n :: Nat). KnownNat n => Vector Text -> Chunks n
makeChunks forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
map [Text] -> Text
T.unlines
selectedIso :: KnownNat n => ColumnsIso a -> AppSettings n b -> SearchFunctions b Text -> Vector a -> IO (Maybe a)
selectedIso :: forall (n :: Nat) a b.
KnownNat n =>
ColumnsIso a
-> AppSettings n b
-> SearchFunctions b Text
-> Vector a
-> IO (Maybe a)
selectedIso (ColumnsIso a -> [Text]
from [Text] -> a
to) AppSettings n b
s SearchFunctions b Text
f = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
map (forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
map [Text] -> a
to) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (n :: Nat) a.
KnownNat n =>
AppSettings n a
-> SearchFunctions a Text -> Chunks n -> IO (Maybe [Text])
selected' AppSettings n b
s SearchFunctions b Text
f forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (n :: Nat). KnownNat n => Vector Text -> Chunks n
makeChunks forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
map ([Text] -> Text
T.unlines forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> [Text]
from)
selectedIndex' :: KnownNat n => AppSettings n a -> SearchFunctions a Text -> Vector Text -> IO (Maybe Int)
selectedIndex' :: forall (n :: Nat) a.
KnownNat n =>
AppSettings n a
-> SearchFunctions a Text -> Vector Text -> IO (Maybe Int)
selectedIndex' AppSettings n a
s SearchFunctions a Text
f Vector Text
v = ((forall a. Eq a => a -> Vector a -> Maybe Int
`elemIndex` Vector Text
v) forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Text] -> Text
T.unlines forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<<) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (n :: Nat) a.
KnownNat n =>
AppSettings n a
-> SearchFunctions a Text -> Chunks n -> IO (Maybe [Text])
selected' AppSettings n a
s SearchFunctions a Text
f (forall (n :: Nat). KnownNat n => Vector Text -> Chunks n
makeChunks Vector Text
v)
selectedIndex :: KnownNat n => AppSettings n a -> SearchFunctions a Text -> Vector [Text] -> IO (Maybe Int)
selectedIndex :: forall (n :: Nat) a.
KnownNat n =>
AppSettings n a
-> SearchFunctions a Text -> Vector [Text] -> IO (Maybe Int)
selectedIndex AppSettings n a
s SearchFunctions a Text
f = forall (n :: Nat) a.
KnownNat n =>
AppSettings n a
-> SearchFunctions a Text -> Vector Text -> IO (Maybe Int)
selectedIndex' AppSettings n a
s SearchFunctions a Text
f forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
map [Text] -> Text
T.unlines