{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE ExistentialQuantification #-}

module Talash.Brick.Internal (twoColumnText , columns , searchWidget , searchWidgetAux , headingAndBody , listWithHighlights , columnsWithHighlights
                             , MatchSetG (..) , Searcher (..) , SearchEvent (..) , SearchEnv (..) ,  EventHooks (..) , AppSettingsG (..)
                             , SearchEventSized (..) , SearcherSized (..)
                             , queryEditor , matches , matcher , numMatches , eventSource , theme , hooks , chunkSize , maximumMatches , eventStrategy
                             , matchedTop , totMatches , term , getQuery , defHooks , theMain , initialSearcher , generateSearchEvent
                             , handleKeyEvent , handleSearch , selectedElement , renderList , module Export) where

import Brick as Export
import Brick.BChan as Export (BChan , newBChan , writeBChan)
import Brick.Widgets.Border as Export (border, vBorder, hBorder, borderAttr)
import Brick.Widgets.Border.Style as Export
import Brick.Widgets.Center as Export (vCenter, center)
import Brick.Widgets.Edit  as Export (editor , editorText, renderEditor, Editor, handleEditorEvent, getEditContents, applyEdit )
import Brick.Widgets.List as Export (Splittable (..) , List, list ,handleListEvent, handleListEventVi, listAttr, listSelectedAttr, listSelectedElement , listSelectedL
                                    , listReplace , listElements, GenericList (listElements, listSelected) , listMoveUp , listMoveDown , slice)
import qualified Brick.Widgets.List as L
import qualified Data.Set as DS
import qualified Data.Text as T
import qualified Data.Vector.Unboxed as U
import qualified Data.Vector.Unboxed.Sized as S
import Graphics.Vty as Export (defAttr, cyan, white, blue, withStyle, bold, brightMagenta, black, magenta, brightBlue, Attr, defaultConfig, mkVty, green, standardIOConfig)
import qualified Graphics.Vty as V
import Graphics.Vty.Config (inputFd)
import Graphics.Vty.Input.Events as Export
import Lens.Micro (_head , (^?))
import Lens.Micro.TH as Export ( makeLenses )
import System.Posix.IO
import System.Posix.Terminal
import Talash.Chunked as Export
import Talash.Intro

newtype MatchSetG a = MatchSetG (DS.Set a) deriving forall a. Eq a => a -> MatchSetG a -> Bool
forall a. Num a => MatchSetG a -> a
forall a. Ord a => MatchSetG a -> a
forall m. Monoid m => MatchSetG m -> m
forall a. MatchSetG a -> Bool
forall a. MatchSetG a -> Int
forall a. MatchSetG a -> [a]
forall a. (a -> a -> a) -> MatchSetG a -> a
forall m a. Monoid m => (a -> m) -> MatchSetG a -> m
forall b a. (b -> a -> b) -> b -> MatchSetG a -> b
forall a b. (a -> b -> b) -> b -> MatchSetG a -> b
forall (t :: * -> *).
(forall m. Monoid m => t m -> m)
-> (forall m a. Monoid m => (a -> m) -> t a -> m)
-> (forall m a. Monoid m => (a -> m) -> t a -> m)
-> (forall a b. (a -> b -> b) -> b -> t a -> b)
-> (forall a b. (a -> b -> b) -> b -> t a -> b)
-> (forall b a. (b -> a -> b) -> b -> t a -> b)
-> (forall b a. (b -> a -> b) -> b -> t a -> b)
-> (forall a. (a -> a -> a) -> t a -> a)
-> (forall a. (a -> a -> a) -> t a -> a)
-> (forall a. t a -> [a])
-> (forall a. t a -> Bool)
-> (forall a. t a -> Int)
-> (forall a. Eq a => a -> t a -> Bool)
-> (forall a. Ord a => t a -> a)
-> (forall a. Ord a => t a -> a)
-> (forall a. Num a => t a -> a)
-> (forall a. Num a => t a -> a)
-> Foldable t
product :: forall a. Num a => MatchSetG a -> a
$cproduct :: forall a. Num a => MatchSetG a -> a
sum :: forall a. Num a => MatchSetG a -> a
$csum :: forall a. Num a => MatchSetG a -> a
minimum :: forall a. Ord a => MatchSetG a -> a
$cminimum :: forall a. Ord a => MatchSetG a -> a
maximum :: forall a. Ord a => MatchSetG a -> a
$cmaximum :: forall a. Ord a => MatchSetG a -> a
elem :: forall a. Eq a => a -> MatchSetG a -> Bool
$celem :: forall a. Eq a => a -> MatchSetG a -> Bool
length :: forall a. MatchSetG a -> Int
$clength :: forall a. MatchSetG a -> Int
null :: forall a. MatchSetG a -> Bool
$cnull :: forall a. MatchSetG a -> Bool
toList :: forall a. MatchSetG a -> [a]
$ctoList :: forall a. MatchSetG a -> [a]
foldl1 :: forall a. (a -> a -> a) -> MatchSetG a -> a
$cfoldl1 :: forall a. (a -> a -> a) -> MatchSetG a -> a
foldr1 :: forall a. (a -> a -> a) -> MatchSetG a -> a
$cfoldr1 :: forall a. (a -> a -> a) -> MatchSetG a -> a
foldl' :: forall b a. (b -> a -> b) -> b -> MatchSetG a -> b
$cfoldl' :: forall b a. (b -> a -> b) -> b -> MatchSetG a -> b
foldl :: forall b a. (b -> a -> b) -> b -> MatchSetG a -> b
$cfoldl :: forall b a. (b -> a -> b) -> b -> MatchSetG a -> b
foldr' :: forall a b. (a -> b -> b) -> b -> MatchSetG a -> b
$cfoldr' :: forall a b. (a -> b -> b) -> b -> MatchSetG a -> b
foldr :: forall a b. (a -> b -> b) -> b -> MatchSetG a -> b
$cfoldr :: forall a b. (a -> b -> b) -> b -> MatchSetG a -> b
foldMap' :: forall m a. Monoid m => (a -> m) -> MatchSetG a -> m
$cfoldMap' :: forall m a. Monoid m => (a -> m) -> MatchSetG a -> m
foldMap :: forall m a. Monoid m => (a -> m) -> MatchSetG a -> m
$cfoldMap :: forall m a. Monoid m => (a -> m) -> MatchSetG a -> m
fold :: forall m. Monoid m => MatchSetG m -> m
$cfold :: forall m. Monoid m => MatchSetG m -> m
Foldable

instance Splittable MatchSetG where
  splitAt :: forall a. Int -> MatchSetG a -> (MatchSetG a, MatchSetG a)
splitAt Int
n (MatchSetG Set a
s) = (forall a. Set a -> MatchSetG a
MatchSetG Set a
p , forall a. Set a -> MatchSetG a
MatchSetG Set a
q)
    where
      (Set a
p,Set a
q) = forall a. Int -> Set a -> (Set a, Set a)
DS.splitAt Int
n Set a
s

data SearchEventSized n a = SearchEventSized  { forall (n :: Nat) a. SearchEventSized n a -> MatcherSized n a
_matcherEv :: {-# UNPACK #-} !(MatcherSized n a)
                                                -- | The (maximum possible) number of matches. See the note on `_numMatches`.
                                              , forall (n :: Nat) a. SearchEventSized n a -> Int
_totMatches :: {-# UNPACK #-} !Int
                                              -- | The term which was searched for.
                                              , forall (n :: Nat) a. SearchEventSized n a -> Text
_term :: {-# UNPACK #-} !Text
                                              , -- | The matches received.
                                                forall (n :: Nat) a. SearchEventSized n a -> MatchSetSized n
_matchedTop :: !(MatchSetSized n)}
makeLenses ''SearchEventSized

data SearchEvent a = forall n. KnownNat n => SearchEvent (SearchEventSized n a)

data SearcherSized n a = SearcherSized { -- | The editor to get the query from.
                                         forall (n :: Nat) a. SearcherSized n a -> Editor Text Bool
_queryEditor :: Editor Text Bool
                                       , forall (n :: Nat) a.
SearcherSized n a
-> GenericList Bool MatchSetG (ScoredMatchSized n)
_matches :: GenericList Bool MatchSetG (ScoredMatchSized n)
                                       , forall (n :: Nat) a. SearcherSized n a -> MatcherSized n a
_matcher :: MatcherSized n a
                                       , forall (n :: Nat) a. SearcherSized n a -> Int
_numMatches :: Int
                                       , forall (n :: Nat) a. SearcherSized n a -> BChan (SearchEvent a)
_eventSource :: BChan (SearchEvent a) -- ^ The BChan from which the app receives search events.
                                       }
makeLenses ''SearcherSized

data Searcher a = forall n. KnownNat n => Searcher {()
getSearcher :: SearcherSized n a}

{-# INLINE generateSearchEvent #-}
generateSearchEvent :: forall m a b c. KnownNat m => (SearchReport -> Bool) -> BChan (SearchEvent a) -> c -> SearchReport -> MatcherSized m a -> MatchSetSized m -> IO ()
generateSearchEvent :: forall (m :: Nat) a b c.
KnownNat m =>
(SearchReport -> Bool)
-> BChan (SearchEvent a)
-> c
-> SearchReport
-> MatcherSized m a
-> MatchSetSized m
-> IO ()
generateSearchEvent SearchReport -> Bool
p BChan (SearchEvent a)
b c
_ = SearchReport -> MatcherSized m a -> MatchSetSized m -> IO ()
go
  where
    go :: SearchReport -> MatcherSized m a -> MatchSetSized m -> IO ()
go SearchReport
r MatcherSized m a
m = forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (SearchReport -> Bool
p SearchReport
r) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. BChan a -> a -> IO ()
writeBChan BChan (SearchEvent a)
b forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a (n :: Nat).
KnownNat n =>
SearchEventSized n a -> SearchEvent a
SearchEvent forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (n :: Nat) a.
MatcherSized n a
-> Int -> Text -> MatchSetSized n -> SearchEventSized n a
SearchEventSized MatcherSized m a
m (SearchReport
r forall s a. s -> Getting a s a -> a
^. Lens' SearchReport Int
nummatches) (SearchReport
r forall s a. s -> Getting a s a -> a
^. Lens' SearchReport Text
searchedTerm)

-- | Event hooks are almost direct translations of the events from vty i.e. see `Event`.
data EventHooks a = EventHooks { forall a. EventHooks a -> Key -> [Modifier] -> EventM Bool a ()
keyHook :: Key -> [Modifier] -> EventM Bool a ()
                               , forall a. EventHooks a -> ByteString -> EventM Bool a ()
pasteHook :: ByteString -> EventM Bool a ()
                               , forall a. EventHooks a -> Int -> Int -> EventM Bool a ()
resizeHook :: Int -> Int -> EventM Bool a ()
                               , forall a.
EventHooks a
-> Int -> Int -> Button -> [Modifier] -> EventM Bool a ()
mouseDownHook :: Int -> Int -> Button -> [Modifier] -> EventM Bool a ()
                               , forall a.
EventHooks a -> Int -> Int -> Maybe Button -> EventM Bool a ()
mouseUpHook   :: Int -> Int -> Maybe Button -> EventM Bool a ()
                               , forall a. EventHooks a -> EventM Bool a ()
focusLostHook :: EventM Bool a ()
                               , forall a. EventHooks a -> EventM Bool a ()
focusGainedHook :: EventM Bool a ()}

data AppSettingsG (n :: Nat) a b t   =   AppSettings { forall (n :: Nat) a b t. AppSettingsG n a b t -> t
_theme :: t
                                                     , forall (n :: Nat) a b t.
AppSettingsG n a b t
-> ReaderT (SearchEnv n a b) EventHooks (Searcher a)
_hooks :: ReaderT (SearchEnv n a b) EventHooks (Searcher a) -- ^ The event hooks which can make use of the search environment.
                                                     , forall (n :: Nat) a b t. AppSettingsG n a b t -> Proxy n
_chunkSize :: Proxy n
                                                     , forall (n :: Nat) a b t. AppSettingsG n a b t -> Int
_maximumMatches :: Int
                                                     , forall (n :: Nat) a b t.
AppSettingsG n a b t -> SearchReport -> Bool
_eventStrategy :: SearchReport -> Bool}
makeLenses ''AppSettingsG

defHooks :: EventHooks a
defHooks :: forall a. EventHooks a
defHooks = forall a.
(Key -> [Modifier] -> EventM Bool a ())
-> (ByteString -> EventM Bool a ())
-> (Int -> Int -> EventM Bool a ())
-> (Int -> Int -> Button -> [Modifier] -> EventM Bool a ())
-> (Int -> Int -> Maybe Button -> EventM Bool a ())
-> EventM Bool a ()
-> EventM Bool a ()
-> EventHooks a
EventHooks (forall a b. a -> b -> a
const forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. a -> b -> a
const (forall (f :: * -> *) a. Applicative f => a -> f a
pure ())) (forall a b. a -> b -> a
const (forall (f :: * -> *) a. Applicative f => a -> f a
pure ())) (forall a b. a -> b -> a
const forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. a -> b -> a
const (forall (f :: * -> *) a. Applicative f => a -> f a
pure ())) (forall a b. a -> b -> a
const forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. a -> b -> a
const forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. a -> b -> a
const forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. a -> b -> a
const (forall (f :: * -> *) a. Applicative f => a -> f a
pure ()))
                                (forall a b. a -> b -> a
const forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. a -> b -> a
const forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. a -> b -> a
const (forall (f :: * -> *) a. Applicative f => a -> f a
pure ())) (forall (f :: * -> *) a. Applicative f => a -> f a
pure ()) (forall (f :: * -> *) a. Applicative f => a -> f a
pure ())

getQuery :: SearcherSized n a -> Text
getQuery :: forall (n :: Nat) a. SearcherSized n a -> Text
getQuery SearcherSized n a
s = forall a. a -> Maybe a -> a
fromMaybe Text
"" forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. [a] -> Maybe a
listToMaybe forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall t n. Monoid t => Editor t n -> [t]
getEditContents forall a b. (a -> b) -> a -> b
$ SearcherSized n a
s forall s a. s -> Getting a s a -> a
^. forall (n :: Nat) a. Lens' (SearcherSized n a) (Editor Text Bool)
queryEditor

twoColumnText :: Int -> Text -> Text -> Widget n
twoColumnText :: forall n. Int -> Text -> Text -> Widget n
twoColumnText Int
n Text
t1 Text
t2 =  forall n. Widget n -> Widget n
joinBorders forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall n. Int -> Widget n -> Widget n
vLimit Int
1 forall a b. (a -> b) -> a -> b
$ forall {n}. Int -> Text -> Widget n
go Int
n Text
t1 forall n. Widget n -> Widget n -> Widget n
<+> forall {n}. Int -> Text -> Widget n
go Int
100 Text
t2
  where
    go :: Int -> Text -> Widget n
go Int
m Text
t = forall n. Int -> Widget n -> Widget n
hLimitPercent Int
m forall a b. (a -> b) -> a -> b
$ forall n. Int -> Widget n -> Widget n
padLeftRight Int
2 (forall n. Text -> Widget n
txt Text
t) forall n. Widget n -> Widget n -> Widget n
<+> forall n. Char -> Widget n
fill Char
' '

columns :: (a -> Widget n) -> [AttrName] -> [Int] -> [a] -> Widget n
columns :: forall a n.
(a -> Widget n) -> [AttrName] -> [Int] -> [a] -> Widget n
columns a -> Widget n
f [AttrName]
as [Int]
ls = forall n. Int -> Widget n -> Widget n
vLimit Int
1 forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall n. [Widget n] -> Widget n
hBox forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b c d. (a -> b -> c -> d) -> [a] -> [b] -> [c] -> [d]
zipWith3 (\AttrName
a Int
l a
t -> forall n. Int -> Widget n -> Widget n
hLimitPercent Int
l forall a b. (a -> b) -> a -> b
$ (forall n. Padding -> Widget n -> Widget n
padRight (Int -> Padding
Pad Int
2) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall n. AttrName -> Widget n -> Widget n
withAttr AttrName
a forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> Widget n
f forall a b. (a -> b) -> a -> b
$ a
t) forall n. Widget n -> Widget n -> Widget n
<+> forall n. Char -> Widget n
fill Char
' ') [AttrName]
as [Int]
ls

searchWidget :: (Ord n , Show n) => Bool -> Text -> Editor Text n -> Widget n
searchWidget :: forall n.
(Ord n, Show n) =>
Bool -> Text -> Editor Text n -> Widget n
searchWidget Bool
b Text
p Editor Text n
e = forall n. [Widget n] -> Widget n
hBox [forall n. AttrName -> Widget n -> Widget n
withAttr (String -> AttrName
attrName String
"Prompt") (forall n. Int -> Widget n -> Widget n
padLeftRight Int
2 forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall n. Text -> Widget n
txt forall a b. (a -> b) -> a -> b
$ Text
p) , forall n. Int -> Widget n -> Widget n
padLeftRight Int
2 (forall n t.
(Ord n, Show n, Monoid t, TextWidth t, GenericTextZipper t) =>
([t] -> Widget n) -> Bool -> Editor t n -> Widget n
renderEditor (forall n. [Widget n] -> Widget n
hBox forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
map forall n. Text -> Widget n
txt) Bool
b Editor Text n
e)]

searchWidgetAux :: (Ord n , Show n) => Bool -> Text -> Editor Text n -> Widget n -> Widget n
searchWidgetAux :: forall n.
(Ord n, Show n) =>
Bool -> Text -> Editor Text n -> Widget n -> Widget n
searchWidgetAux Bool
b Text
p Editor Text n
e Widget n
w = forall n. [Widget n] -> Widget n
hBox [forall n. AttrName -> Widget n -> Widget n
withAttr (String -> AttrName
attrName String
"Prompt") (forall n. Int -> Widget n -> Widget n
padLeftRight Int
2 forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall n. Text -> Widget n
txt forall a b. (a -> b) -> a -> b
$ Text
p) , forall n. Int -> Widget n -> Widget n
padLeftRight Int
2 (forall n t.
(Ord n, Show n, Monoid t, TextWidth t, GenericTextZipper t) =>
([t] -> Widget n) -> Bool -> Editor t n -> Widget n
renderEditor (forall n. [Widget n] -> Widget n
hBox forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
map forall n. Text -> Widget n
txt) Bool
b Editor Text n
e) , Widget n
w]

highlightAlternate :: (a -> Widget n) -> [a] -> Widget n
highlightAlternate :: forall a n. (a -> Widget n) -> [a] -> Widget n
highlightAlternate a -> Widget n
f = forall n. [Widget n] -> Widget n
hBox forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith (\Bool
b a
e -> if Bool
b then forall n. AttrName -> Widget n -> Widget n
withAttr (String -> AttrName
attrName String
"Highlight") (a -> Widget n
f a
e) else a -> Widget n
f a
e) (forall a. [a] -> [a]
cycle [Bool
False , Bool
True])

headingAndBody :: Text -> Text -> Widget n
headingAndBody :: forall n. Text -> Text -> Widget n
headingAndBody Text
h Text
b = forall n. AttrName -> Widget n -> Widget n
withAttr (String -> AttrName
attrName String
"Heading") (forall n. Text -> Widget n
txt Text
h) forall n. Widget n -> Widget n -> Widget n
<=> forall n. Text -> Widget n
txtWrap Text
b

listWithHighlights :: (Ord n , Show n , KnownNat m , KnownNat l) => SearchEnv l a (Widget n) -> Text
                                                        -> MatcherSized m a -> Bool -> GenericList n MatchSetG (ScoredMatchSized m) -> Widget n
listWithHighlights :: forall n (m :: Nat) (l :: Nat) a.
(Ord n, Show n, KnownNat m, KnownNat l) =>
SearchEnv l a (Widget n)
-> Text
-> MatcherSized m a
-> Bool
-> GenericList n MatchSetG (ScoredMatchSized m)
-> Widget n
listWithHighlights SearchEnv l a (Widget n)
env Text
c 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 (\Bool
s ScoredMatchSized m
e -> forall n. [Widget n] -> Widget n
hBox [forall n. Text -> Widget n
txtLine (if Bool
s then Text
c else Text
"  ") , forall n. [Widget n] -> Widget n
hBox forall b c a. (b -> c) -> (a -> b) -> a -> c
. ScoredMatchSized m -> [Widget n]
go forall a b. (a -> b) -> a -> b
$! ScoredMatchSized m
e])
  where
    go :: ScoredMatchSized m -> [Widget n]
go (ScoredMatchSized Down Int
_ ChunkIndex
i Vector m Int
v) = (SearchEnv l a (Widget n)
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) (\Bool
b Text
e -> if Bool
b then forall n. AttrName -> Widget n -> Widget n
withAttr (String -> AttrName
attrName String
"Highlight") (forall n. Text -> Widget n
txtLine Text
e) else forall n. Text -> Widget n
txtLine Text
e) MatcherSized m a
m ((SearchEnv l a (Widget n)
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
! ChunkIndex
i) Vector m Int
v

columnsWithHighlights :: Text -> (a -> [[Text]]) -> [AttrName] -> [Int] -> Bool -> a -> Widget n
columnsWithHighlights :: forall a n.
Text
-> (a -> [[Text]]) -> [AttrName] -> [Int] -> Bool -> a -> Widget n
columnsWithHighlights Text
c a -> [[Text]]
f [AttrName]
as [Int]
ls Bool
s a
e = (forall n. Text -> Widget n
txt (if Bool
s then Text
c else Text
"  ") forall n. Widget n -> Widget n -> Widget n
<+>) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a n.
(a -> Widget n) -> [AttrName] -> [Int] -> [a] -> Widget n
columns (forall a n. (a -> Widget n) -> [a] -> Widget n
highlightAlternate forall n. Text -> Widget n
txt) [AttrName]
as [Int]
ls forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> [[Text]]
f forall a b. (a -> b) -> a -> b
$! a
e

theMain :: Ord n => App b e n -> BChan e -> b -> IO b
theMain :: forall n b e. Ord n => App b e n -> BChan e -> b -> IO b
theMain App b e n
a BChan e
b b
s = (\Vty
v -> forall n e s.
Ord n =>
Vty -> IO Vty -> Maybe (BChan e) -> App s e n -> s -> IO s
customMain Vty
v (forall (f :: * -> *) a. Applicative f => a -> f a
pure Vty
v) (forall a. a -> Maybe a
Just BChan e
b) App b e n
a b
s) forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Config -> IO Vty
mkVty forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<<(\Config
c -> (\Fd
fd -> Config
c {inputFd :: Maybe Fd
inputFd = forall a. a -> Maybe a
Just Fd
fd}) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> IO Fd
termFd) forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< IO Config
standardIOConfig
  where
    termFd :: IO Fd
termFd = (\String
f -> String -> OpenMode -> Maybe FileMode -> OpenFileFlags -> IO Fd
openFd String
f OpenMode
ReadOnly forall a. Maybe a
Nothing (Bool -> Bool -> Bool -> Bool -> Bool -> OpenFileFlags
OpenFileFlags Bool
False Bool
False Bool
False Bool
False Bool
False)) forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< IO String
getControllingTerminalName

drawListElements :: (Ord n, Show n, Foldable t, Splittable t) => (Int -> Bool -> a -> Widget n) -> Bool -> GenericList n t a  -> Widget n
drawListElements :: forall n (t :: * -> *) a.
(Ord n, Show n, Foldable t, Splittable t) =>
(Int -> Bool -> a -> Widget n)
-> Bool -> GenericList n t a -> Widget n
drawListElements Int -> Bool -> a -> Widget n
drawElem Bool
foc GenericList n t a
l =
    forall n. Size -> Size -> RenderM n (Result n) -> Widget n
Widget Size
Greedy Size
Greedy forall a b. (a -> b) -> a -> b
$ do
        Context n
c <- forall n. RenderM n (Context n)
getContext
        let es :: t a
es = forall (t :: * -> *) a. Splittable t => Int -> Int -> t a -> t a
slice Int
start (Int
numPerHeight forall a. Num a => a -> a -> a
* Int
2) (GenericList n t a
lforall s a. s -> Getting a s a -> a
^. forall n (t1 :: * -> *) e1 (t2 :: * -> *) e2.
Lens (GenericList n t1 e1) (GenericList n t2 e2) (t1 e1) (t2 e2)
L.listElementsL)
            idx :: Int
idx = forall a. a -> Maybe a -> a
fromMaybe Int
0 (GenericList n t a
lforall s a. s -> Getting a s a -> a
^. forall n (t :: * -> *) e. Lens' (GenericList n t e) (Maybe Int)
L.listSelectedL)
            start :: Int
start = forall a. Ord a => a -> a -> a
max Int
0 forall a b. (a -> b) -> a -> b
$ Int
idx forall a. Num a => a -> a -> a
- Int
numPerHeight forall a. Num a => a -> a -> a
+ Int
1
            numPerHeight :: Int
numPerHeight = Int
1 forall a. Num a => a -> a -> a
+ (Context n
cforall s a. s -> Getting a s a -> a
^.forall n. Lens' (Context n) Int
availHeightL forall a. Num a => a -> a -> a
- Int
1) forall a. Integral a => a -> a -> a
`div` (GenericList n t a
lforall s a. s -> Getting a s a -> a
^. forall n (t :: * -> *) e. Lens' (GenericList n t e) Int
L.listItemHeightL)
            off :: Int
off = Int
start forall a. Num a => a -> a -> a
* (GenericList n t a
lforall s a. s -> Getting a s a -> a
^. forall n (t :: * -> *) e. Lens' (GenericList n t e) Int
L.listItemHeightL)
            drawElement :: Int -> a -> Widget n
drawElement Int
j a
e =
                let isSelected :: Bool
isSelected = forall a. a -> Maybe a
Just Int
j forall a. Eq a => a -> a -> Bool
== GenericList n t a
lforall s a. s -> Getting a s a -> a
^.forall n (t :: * -> *) e. Lens' (GenericList n t e) (Maybe Int)
listSelectedL
                    elemWidget :: Widget n
elemWidget = Int -> Bool -> a -> Widget n
drawElem Int
j Bool
isSelected a
e
                    selItemAttr :: Widget n -> Widget n
selItemAttr = forall n. AttrName -> Widget n -> Widget n
withDefAttr AttrName
listSelectedAttr
                    makeVisible :: Widget n -> Widget n
makeVisible = if Bool
isSelected
                                  then forall n. Widget n -> Widget n
visible forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall n. Widget n -> Widget n
selItemAttr
                                  else forall a. a -> a
id
                in Widget n -> Widget n
makeVisible Widget n
elemWidget
        forall n. Widget n -> RenderM n (Result n)
render forall a b. (a -> b) -> a -> b
$ forall n.
(Ord n, Show n) =>
n -> ViewportType -> Widget n -> Widget n
viewport (GenericList n t a
lforall s a. s -> Getting a s a -> a
^. forall n1 (t :: * -> *) e n2.
Lens (GenericList n1 t e) (GenericList n2 t e) n1 n2
L.listNameL) ViewportType
Vertical forall a b. (a -> b) -> a -> b
$
                 forall n. Location -> Widget n -> Widget n
translateBy ((Int, Int) -> Location
Location (Int
0, Int
off)) forall a b. (a -> b) -> a -> b
$ forall n. [Widget n] -> Widget n
vBox forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith Int -> a -> Widget n
drawElement [Int
start ..] forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (t :: * -> *) a. Foldable t => t a -> [a]
toList forall a b. (a -> b) -> a -> b
$ t a
es

selectedElementInternal :: (Foldable t, Splittable t) => GenericList n t a -> Maybe (Int, a)
selectedElementInternal :: forall (t :: * -> *) n a.
(Foldable t, Splittable t) =>
GenericList n t a -> Maybe (Int, a)
selectedElementInternal GenericList n t a
l = do
    Int
sel <- GenericList n t a
lforall s a. s -> Getting a s a -> a
^.forall n (t :: * -> *) e. Lens' (GenericList n t e) (Maybe Int)
listSelectedL
    let (t a
_, t a
xs) = forall (t :: * -> *) a. Splittable t => Int -> t a -> (t a, t a)
L.splitAt Int
sel (GenericList n t a
l forall s a. s -> Getting a s a -> a
^. forall n (t1 :: * -> *) e1 (t2 :: * -> *) e2.
Lens (GenericList n t1 e1) (GenericList n t2 e2) (t1 e1) (t2 e2)
L.listElementsL)
    (Int
sel,) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (t :: * -> *) a. Foldable t => t a -> [a]
toList t a
xs forall s a. s -> Getting (First a) s a -> Maybe a
^? forall s a. Cons s s a a => Traversal' s a
_head

{-# INLINE renderListWithIndex #-}
renderListWithIndex :: (Ord n, Show n, Foldable t, Splittable t) => (Int -> Bool -> a -> Widget n) -> Bool -> GenericList n t a -> Widget n
renderListWithIndex :: forall n (t :: * -> *) a.
(Ord n, Show n, Foldable t, Splittable t) =>
(Int -> Bool -> a -> Widget n)
-> Bool -> GenericList n t a -> Widget n
renderListWithIndex Int -> Bool -> a -> Widget n
drawElem Bool
foc = forall n. AttrName -> Widget n -> Widget n
withDefAttr AttrName
listAttr forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall n (t :: * -> *) a.
(Ord n, Show n, Foldable t, Splittable t) =>
(Int -> Bool -> a -> Widget n)
-> Bool -> GenericList n t a -> Widget n
drawListElements Int -> Bool -> a -> Widget n
drawElem Bool
foc

renderList :: (Foldable t, Splittable t, Ord n, Show n) => (Bool -> e -> Widget n) -> Bool -> GenericList n t e -> Widget n
renderList :: forall (t :: * -> *) n e.
(Foldable t, Splittable t, Ord n, Show n) =>
(Bool -> e -> Widget n) -> Bool -> GenericList n t e -> Widget n
renderList Bool -> e -> Widget n
drawElem = forall n (t :: * -> *) a.
(Ord n, Show n, Foldable t, Splittable t) =>
(Int -> Bool -> a -> Widget n)
-> Bool -> GenericList n t a -> Widget n
renderListWithIndex forall a b. (a -> b) -> a -> b
$ forall a b. a -> b -> a
const Bool -> e -> Widget n
drawElem

handleQuery :: KnownNat n => SearchEnv n a c -> Key -> [Modifier] -> Searcher b -> EventM Bool (Searcher b) ()
handleQuery :: forall (n :: Nat) a c b.
KnownNat n =>
SearchEnv n a c
-> Key -> [Modifier] -> Searcher b -> EventM Bool (Searcher b) ()
handleQuery SearchEnv n a c
env Key
k [Modifier]
m (Searcher SearcherSized n b
s) = forall s (m :: * -> *). MonadState s m => s -> m ()
put forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a (n :: Nat). KnownNat n => SearcherSized n a -> Searcher a
Searcher forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< SearcherSized n b -> EventM Bool (Searcher b) (SearcherSized n b)
editStep forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< (forall a n b s. a -> EventM n a b -> EventM n s a
nestEventM' SearcherSized n b
s forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (m :: * -> *) (n :: * -> *) s t c.
Zoom m n s t =>
LensLike' (Zoomed m c) t s -> m c -> n c
zoom forall (n :: Nat) a. Lens' (SearcherSized n a) (Editor Text Bool)
queryEditor forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall n t e.
(Eq n, DecodeUtf8 t, Eq t, GenericTextZipper t) =>
BrickEvent n e -> EventM n (Editor t n) ()
handleEditorEvent forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall n e. Event -> BrickEvent n e
VtyEvent forall a b. (a -> b) -> a -> b
$ Key -> [Modifier] -> Event
EvKey Key
k [Modifier]
m)
  where
    editStep :: SearcherSized n b -> EventM Bool (Searcher b) (SearcherSized n b)
editStep SearcherSized n b
ns = Text -> EventM Bool (Searcher b) ()
sendStep (forall (n :: Nat) a. SearcherSized n a -> Text
getQuery SearcherSized n b
ns) forall (f :: * -> *) a b. Functor f => f a -> b -> f b
$> SearcherSized n b
ns
    sendStep :: Text -> EventM Bool (Searcher b) ()
sendStep Text
nq = forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless (Text
nq forall a. Eq a => a -> a -> Bool
== forall (n :: Nat) a. SearcherSized n a -> Text
getQuery SearcherSized n b
s) forall a b. (a -> b) -> a -> b
$ 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 c
env Text
nq)

-- | Handling of keypresses. The default bindings are
--  @Enter@ exits the app with the current selection.
--  @Esc@ exits without any selection
--  @Up@ , @Down@ , @PageUp@ and @PageDown@ move through the matches.
-- All others keys are used for editing the query. See `handleEditorEvent` for details.
{-# INLINE handleKeyEvent #-}
handleKeyEvent :: (KnownNat n) => SearchEnv n a c -> Key -> [Modifier] -> EventM Bool (Searcher b) ()
handleKeyEvent :: forall (n :: Nat) a c b.
KnownNat n =>
SearchEnv n a c -> Key -> [Modifier] -> EventM Bool (Searcher b) ()
handleKeyEvent SearchEnv n a c
env Key
k [Modifier]
m
  | Key
k forall a. Eq a => a -> a -> Bool
== Key
KEnter                                  , forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Modifier]
m = forall n s. EventM n s ()
halt
  | Key
k forall a. Eq a => a -> a -> Bool
== Key
KEsc                                    , forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Modifier]
m = forall s (m :: * -> *). MonadState s m => (s -> s) -> m ()
modify (\(Searcher SearcherSized n b
s) -> 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.
Lens'
  (SearcherSized n a)
  (GenericList Bool MatchSetG (ScoredMatchSized n))
matches forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall n (t :: * -> *) e. Lens' (GenericList n t e) (Maybe Int)
listSelectedL) forall s t a b. ASetter s t a b -> b -> s -> t
.~ forall a. Maybe a
Nothing) forall a b. (a -> b) -> a -> b
$ SearcherSized n b
s) forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall n s. EventM n s ()
halt
  | Key
k forall a. Eq a => a -> a -> Bool
== Char -> Key
KChar Char
'\t'                              , forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Modifier]
m = forall s (m :: * -> *). MonadState s m => (s -> s) -> m ()
modify (\(Searcher SearcherSized n b
s) -> forall a (n :: Nat). KnownNat n => SearcherSized n a -> Searcher a
Searcher forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall s t a b. ASetter s t a b -> (a -> b) -> s -> t
over forall (n :: Nat) a.
Lens'
  (SearcherSized n a)
  (GenericList Bool MatchSetG (ScoredMatchSized n))
matches forall (t :: * -> *) n e.
(Foldable t, Splittable t) =>
GenericList n t e -> GenericList n t e
listMoveDown forall a b. (a -> b) -> a -> b
$ SearcherSized n b
s)
  | Key
k forall a. Eq a => a -> a -> Bool
== Key
KBackTab                                , forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Modifier]
m = forall s (m :: * -> *). MonadState s m => (s -> s) -> m ()
modify (\(Searcher SearcherSized n b
s) -> forall a (n :: Nat). KnownNat n => SearcherSized n a -> Searcher a
Searcher forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall s t a b. ASetter s t a b -> (a -> b) -> s -> t
over forall (n :: Nat) a.
Lens'
  (SearcherSized n a)
  (GenericList Bool MatchSetG (ScoredMatchSized n))
matches forall (t :: * -> *) n e.
(Foldable t, Splittable t) =>
GenericList n t e -> GenericList n t e
listMoveUp forall a b. (a -> b) -> a -> b
$ SearcherSized n b
s)
  | Key
k forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [Key
KUp , Key
KDown , Key
KPageUp , Key
KPageDown] , forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Modifier]
m = (\(Searcher SearcherSized n b
s) -> forall s (m :: * -> *). MonadState s m => s -> m ()
put forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a (n :: Nat). KnownNat n => SearcherSized n a -> Searcher a
Searcher forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< (forall a n b s. a -> EventM n a b -> EventM n s a
nestEventM' SearcherSized n b
s forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (m :: * -> *) (n :: * -> *) s t c.
Zoom m n s t =>
LensLike' (Zoomed m c) t s -> m c -> n c
zoom forall (n :: Nat) a.
Lens'
  (SearcherSized n a)
  (GenericList Bool MatchSetG (ScoredMatchSized n))
matches forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (t :: * -> *) n e.
(Foldable t, Splittable t, Ord n) =>
Event -> EventM n (GenericList n t e) ()
handleListEvent forall a b. (a -> b) -> a -> b
$ Key -> [Modifier] -> Event
EvKey Key
k [Modifier]
m)) forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< forall s (m :: * -> *). MonadState s m => m s
get
  | Bool
otherwise                                             = forall (n :: Nat) a c b.
KnownNat n =>
SearchEnv n a c
-> Key -> [Modifier] -> Searcher b -> EventM Bool (Searcher b) ()
handleQuery SearchEnv n a c
env Key
k [Modifier]
m forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< forall s (m :: * -> *). MonadState s m => m s
get

-- | The initial state of the searcher. The editor is empty.
initialSearcher :: SearchEnv n a c -> BChan (SearchEvent a) -> SearcherSized 0 a
initialSearcher :: forall (n :: Nat) a c.
SearchEnv n a c -> BChan (SearchEvent a) -> SearcherSized 0 a
initialSearcher SearchEnv n a c
env = forall (n :: Nat) a.
Editor Text Bool
-> GenericList Bool MatchSetG (ScoredMatchSized n)
-> MatcherSized n a
-> Int
-> BChan (SearchEvent a)
-> SearcherSized n a
SearcherSized (forall n. n -> Maybe Int -> Text -> Editor Text n
editorText Bool
True (forall a. a -> Maybe a
Just Int
1) Text
"") (forall (t :: * -> *) n e.
Foldable t =>
n -> t e -> Int -> GenericList n t e
list Bool
False (forall a. Set a -> MatchSetG a
MatchSetG forall a. Set a
DS.empty) Int
0) forall a. MatcherSized 0 a
emptyMatcher Int
0

{-# INLINE  handleSearchSized #-}
handleSearchSized :: (KnownNat n , KnownNat m) => SearcherSized n a -> SearchEventSized m a -> SearcherSized m a
handleSearchSized :: forall (n :: Nat) (m :: Nat) a.
(KnownNat n, KnownNat m) =>
SearcherSized n a -> SearchEventSized m a -> SearcherSized m a
handleSearchSized SearcherSized n a
s SearchEventSized m a
e = forall (n :: Nat) a.
Editor Text Bool
-> GenericList Bool MatchSetG (ScoredMatchSized n)
-> MatcherSized n a
-> Int
-> BChan (SearchEvent a)
-> SearcherSized n a
SearcherSized (SearcherSized n a
s forall s a. s -> Getting a s a -> a
^. forall (n :: Nat) a. Lens' (SearcherSized n a) (Editor Text Bool)
queryEditor) (forall (t :: * -> *) n e.
Foldable t =>
n -> t e -> Int -> GenericList n t e
list Bool
False (forall a. Set a -> MatchSetG a
MatchSetG (SearchEventSized m a
e forall s a. s -> Getting a s a -> a
^. forall (n :: Nat) a. Lens' (SearchEventSized n a) (MatchSetSized n)
matchedTop)) Int
0)
                                      (SearchEventSized m a
e forall s a. s -> Getting a s a -> a
^. forall (n :: Nat) a a.
Lens
  (SearchEventSized n a)
  (SearchEventSized n a)
  (MatcherSized n a)
  (MatcherSized n a)
matcherEv) (SearchEventSized m a
e forall s a. s -> Getting a s a -> a
^. forall (n :: Nat) a. Lens' (SearchEventSized n a) Int
totMatches) (SearcherSized n a
s forall s a. s -> Getting a s a -> a
^. forall (n :: Nat) a.
Lens' (SearcherSized n a) (BChan (SearchEvent a))
eventSource)

{-# INLINE  handleSearch #-}
handleSearch :: SearchEvent a -> EventM Bool (Searcher a) ()
handleSearch :: forall a. SearchEvent a -> EventM Bool (Searcher a) ()
handleSearch (SearchEvent SearchEventSized n a
e) = forall s (m :: * -> *). MonadState s m => (s -> s) -> m ()
modify (\(Searcher SearcherSized n a
s) -> if (SearchEventSized n a
e forall s a. s -> Getting a s a -> a
^. forall (n :: Nat) a. Lens' (SearchEventSized n a) Text
term forall a. Eq a => a -> a -> Bool
== forall (n :: Nat) a. SearcherSized n a -> Text
getQuery SearcherSized n a
s) then forall a (n :: Nat). KnownNat n => SearcherSized n a -> Searcher a
Searcher (forall (n :: Nat) (m :: Nat) a.
(KnownNat n, KnownNat m) =>
SearcherSized n a -> SearchEventSized m a -> SearcherSized m a
handleSearchSized SearcherSized n a
s SearchEventSized n a
e) else forall a (n :: Nat). KnownNat n => SearcherSized n a -> Searcher a
Searcher SearcherSized n a
s)

selectedElement :: KnownNat n => Chunks n -> Searcher a -> Maybe Text
selectedElement :: forall (n :: Nat) a.
KnownNat n =>
Chunks n -> Searcher a -> Maybe Text
selectedElement Chunks n
c (Searcher SearcherSized n a
s) = (forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
map ((Chunks n
c forall (n :: Nat). KnownNat n => Chunks n -> ChunkIndex -> Text
!) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (n :: Nat). ScoredMatchSized n -> ChunkIndex
chunkIndex forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a, b) -> b
snd) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (t :: * -> *) n a.
(Foldable t, Splittable t) =>
GenericList n t a -> Maybe (Int, a)
selectedElementInternal forall b c a. (b -> c) -> (a -> b) -> a -> c
. (forall s a. s -> Getting a s a -> a
^. forall (n :: Nat) a.
Lens'
  (SearcherSized n a)
  (GenericList Bool MatchSetG (ScoredMatchSized n))
matches)) SearcherSized n a
s

txtLine :: Text -> Widget n
txtLine :: forall n. Text -> Widget n
txtLine Text
s =
    forall n. Size -> Size -> RenderM n (Result n) -> Widget n
Widget Size
Fixed Size
Fixed forall a b. (a -> b) -> a -> b
$ do
      Context n
c <- forall n. RenderM n (Context n)
getContext
      forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ (forall n. Lens' (Result n) Image
imageL forall s t a b. ASetter s t a b -> b -> s -> t
.~ (Attr -> Text -> Image
V.text' (Context n
cforall s a. s -> Getting a s a -> a
^.forall r n. Getting r (Context n) Attr
attrL) Text
s)) forall n. Result n
emptyResult