module Byline.Completion
(
CompletionFunc,
Completion (..),
CompLoc (..),
completionFromList,
pushCompletionFunction,
popCompletionFunction,
)
where
import Byline.Internal.Completion
import Byline.Internal.Eval (MonadByline (..))
import qualified Byline.Internal.Prim as Prim
import Data.Char (isSpace)
import qualified Data.Text as Text
pushCompletionFunction :: MonadByline m => CompletionFunc IO -> m ()
pushCompletionFunction :: forall (m :: * -> *). MonadByline m => CompletionFunc IO -> m ()
pushCompletionFunction = forall (m :: * -> *).
MonadFree PrimF m =>
CompletionFunc IO -> m ()
Prim.pushCompFunc forall {k} (cat :: k -> k -> *) (a :: k) (b :: k) (c :: k).
Category cat =>
cat a b -> cat b c -> cat a c
>>> forall (m :: * -> *) a. MonadByline m => F PrimF a -> m a
liftByline
popCompletionFunction :: MonadByline m => m ()
popCompletionFunction :: forall (m :: * -> *). MonadByline m => m ()
popCompletionFunction = forall (m :: * -> *) a. MonadByline m => F PrimF a -> m a
liftByline forall (m :: * -> *). MonadFree PrimF m => m ()
Prim.popCompFunc
data CompLoc
=
CompHead
|
CompTail
|
CompAny
completionFromList ::
forall m.
Applicative m =>
CompLoc ->
[Text] ->
CompletionFunc m
completionFromList :: forall (m :: * -> *).
Applicative m =>
CompLoc -> [Text] -> CompletionFunc m
completionFromList CompLoc
loc [Text]
ts (Text
left, Text
right) =
case CompLoc
loc of
CompLoc
CompHead ->
if Text -> Bool
Text.null Text
left Bool -> Bool -> Bool
|| (Char -> Bool) -> Text -> Bool
Text.all (Char -> Bool
isSpace forall {k} (cat :: k -> k -> *) (a :: k) (b :: k) (c :: k).
Category cat =>
cat a b -> cat b c -> cat a c
>>> Bool -> Bool
not) Text
left
then CompletionFunc m
go (Text
left, Text
right)
else forall (f :: * -> *) a. Applicative f => a -> f a
pure (forall a. Monoid a => a
mempty, forall a. Monoid a => a
mempty)
CompLoc
CompTail ->
if (Char -> Bool) -> Text -> Bool
Text.any Char -> Bool
isSpace Text
left
then CompletionFunc m
completeLastWord (Text
left, Text
right)
else forall (f :: * -> *) a. Applicative f => a -> f a
pure (forall a. Monoid a => a
mempty, forall a. Monoid a => a
mempty)
CompLoc
CompAny ->
CompletionFunc m
completeLastWord (Text
left, Text
right)
where
go :: CompletionFunc m
go :: CompletionFunc m
go (Text
left, Text
_) =
if Text -> Bool
Text.null Text
left
then forall (f :: * -> *) a. Applicative f => a -> f a
pure (Text
"", [Text] -> [Completion]
completions [Text]
ts)
else forall (f :: * -> *) a. Applicative f => a -> f a
pure (Text
"", [Text] -> [Completion]
completions (forall a. (a -> Bool) -> [a] -> [a]
filter (Text -> Text -> Bool
Text.isPrefixOf Text
left) [Text]
ts))
completeLastWord :: CompletionFunc m
completeLastWord :: CompletionFunc m
completeLastWord (Text
left, Text
right) =
let word :: Text
word = (Char -> Bool) -> Text -> Text
Text.takeWhileEnd (Char -> Bool
isSpace forall {k} (cat :: k -> k -> *) (a :: k) (b :: k) (c :: k).
Category cat =>
cat a b -> cat b c -> cat a c
>>> Bool -> Bool
not) Text
left
prefix :: Text
prefix = Int -> Text -> Text
Text.dropEnd (Text -> Int
Text.length Text
word) Text
left
in CompletionFunc m
go (Text
word, Text
right) forall (f :: * -> *) a b. Functor f => f a -> (a -> b) -> f b
<&> forall (p :: * -> * -> *) a b c.
Bifunctor p =>
(a -> b) -> p a c -> p b c
first (forall a b. a -> b -> a
const Text
prefix)
completions :: [Text] -> [Completion]
completions :: [Text] -> [Completion]
completions = forall a b. (a -> b) -> [a] -> [b]
map (\Text
t -> Text -> Text -> Bool -> Completion
Completion Text
t Text
t Bool
True)