diff --git a/Options/Applicative.hs b/Options/Applicative.hs index 75f1c9a..f412062 100644 --- a/Options/Applicative.hs +++ b/Options/Applicative.hs @@ -20,6 +20,9 @@ module Options.Applicative ( -- | Utilities to build parsers out of basic primitives. module Options.Applicative.Builder, + -- | Common completion functions. + module Options.Applicative.Builder.Completer, + -- | Utilities to run parsers and display a help text. module Options.Applicative.Extra, ) where @@ -29,4 +32,5 @@ import Control.Applicative import Options.Applicative.Common import Options.Applicative.Builder +import Options.Applicative.Builder.Completer import Options.Applicative.Extra diff --git a/Options/Applicative/Builder.hs b/Options/Applicative/Builder.hs index 6a6155e..592a057 100644 --- a/Options/Applicative/Builder.hs +++ b/Options/Applicative/Builder.hs @@ -76,10 +76,10 @@ module Options.Applicative.Builder ( import Control.Applicative import Control.Monad -import Data.List import Data.Maybe import Data.Monoid +import Options.Applicative.Builder.Completer import Options.Applicative.Common import Options.Applicative.Types @@ -212,14 +212,14 @@ command cmd pinfo = fieldMod $ \p -> -- | Add a list of possible values for an argument argValues :: HasCompleter f => [String] -> Mod f a -argValues xs = fieldMod $ modCompleter (<> listCompleter xs) +argValues xs = completer (listCompleter xs) -- | Add a completer to an argument. -- -- A completer is a function String -> IO String which, given a partial -- argument, returns all possible completions for that argument. -completer :: (String -> IO [String]) -> Mod ArgumentFields a -completer f = fieldMod $ modCompleter (<> Completer f) +completer :: HasCompleter f => Completer -> Mod f a +completer f = fieldMod $ modCompleter (<> f) -- parsers -- @@ -263,10 +263,6 @@ subparser m = mkParser d g rdr CommandFields cmds = f (CommandFields []) rdr = CmdReader (map fst cmds) (`lookup` cmds) -listCompleter :: [String] -> Completer -listCompleter ss = Completer $ \s -> return - [ x | x <- ss, s `isPrefixOf` x ] - -- | Builder for an argument parser. argument :: (String -> Maybe a) -> Mod ArgumentFields a -> Parser a argument p (Mod f d g) = mkParser d g (ArgReader rdr) diff --git a/Options/Applicative/Builder/Completer.hs b/Options/Applicative/Builder/Completer.hs new file mode 100644 index 0000000..717d6ec --- /dev/null +++ b/Options/Applicative/Builder/Completer.hs @@ -0,0 +1,28 @@ +module Options.Applicative.Builder.Completer + ( listIOCompleter + , listCompleter + , fileCompleter + , dirCompleter + ) where + +import Control.Applicative +import Control.Monad +import Data.List +import Options.Applicative.Types +import System.Directory + +listIOCompleter :: IO [String] -> Completer +listIOCompleter ss = Completer $ \s -> + filter (isPrefixOf s) <$> ss + +listCompleter :: [String] -> Completer +listCompleter = listIOCompleter . pure + +fileCompleter :: Completer +fileCompleter = listIOCompleter $ + getDirectoryContents "." + +dirCompleter :: Completer +dirCompleter = listIOCompleter $ do + files <- getDirectoryContents "." + filterM doesDirectoryExist files diff --git a/optparse-applicative.cabal b/optparse-applicative.cabal index a6cc95f..125d96b 100644 --- a/optparse-applicative.cabal +++ b/optparse-applicative.cabal @@ -85,7 +85,8 @@ library Options.Applicative.Utils other-modules: Options.Applicative.Internal build-depends: base == 4.*, - transformers >= 0.2 && < 0.4 + transformers >= 0.2 && < 0.4, + directory == 1.1.* test-suite tests type: exitcode-stdio-1.0 hs-source-dirs: tests