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 = Prim.pushCompFunc >>> liftByline
popCompletionFunction :: MonadByline m => m ()
popCompletionFunction = liftByline Prim.popCompFunc
data CompLoc
=
CompHead
|
CompTail
|
CompAny
completionFromList ::
forall m.
Applicative m =>
CompLoc ->
[Text] ->
CompletionFunc m
completionFromList loc ts (left, right) =
case loc of
CompHead ->
if Text.null left || Text.all (isSpace >>> not) left
then go (left, right)
else pure (mempty, mempty)
CompTail ->
if Text.any isSpace left
then completeLastWord (left, right)
else pure (mempty, mempty)
CompAny ->
completeLastWord (left, right)
where
go :: CompletionFunc m
go (left, _) =
if Text.null left
then pure ("", completions ts)
else pure ("", completions (filter (Text.isPrefixOf left) ts))
completeLastWord :: CompletionFunc m
completeLastWord (left, right) =
let word = Text.takeWhileEnd (isSpace >>> not) left
prefix = Text.dropEnd (Text.length word) left
in go (word, right) <&> first (const prefix)
completions :: [Text] -> [Completion]
completions = map (\t -> Completion t t True)