Comments (10)
The argument ws
is the "words" which have been passed in on the command line, as split by the shell. If I recall, we don't actually need i
, the index of the word which the user pressed tab on, because the completion scripts cut the completion up to the caret position anyway.
In filter_names, ns
is the names of the sub-commands which the subparser has. The function filter_names
makes sure that the user could want the completion for a particular command by seeing if the current text at the position of the token is a prefix of the sub command name.
from optparse-applicative.
thanks ! I thought about "words" after postiung this but still was not sure.
I am now adapting the bashCompletionQuery for haskeline and there is the drop on this line that confuses me:
Also with the following parser (i.e., a subparser):
mainParser :: Parser CommandArgs
mainParser = subparser (
commandGroup "Generic"
<> command "help" helpParser
<> command "quit" quit
<> commandGroup "Loader commands"
<> command "load-csv" CL.piLoadCsv
)
where
helpParser = info (pure ArgsHelp) (progDesc "Display help")
do you know if bashCompletionQuery would generate completion for all commands ? in my tests, it seems to autocomplete only the first argument but not the subsequent ones because runParserInfo
returns Nothing
(while I would expect it to retreive at least one more Parser).
from optparse-applicative.
I'm not sure I follow sorry, but yes, the completion system sensibly completes within subparsers as well.
from optparse-applicative.
It doesn't seem to do it for me, let's say I have this Parser
mainParser :: Parser CommandArgs
mainParser = subparser (
commandGroup "Generic"
<> command "quit" quit
<> command "load-csv" CL.piLoadCsv
<> command "load-pcap" CL.piLoadPcapOpts
and then I try to aucomplete in haskeline (my code is a slightly modified version of bashCompletionQuery
adapted to haskeline), only "load-csv" or "load-pcap" will be completed, not the arguments of the children parser piLoadCsv and piLoadPcapOpts (e.g., let's say I type load-pcap to
with "toto" as a possible completion, it should autocomplete to load-pcap toto
but right now mapParser just evals the top-level parser).
The completion code relies on runParserInfo
that relies on mapParser
.
If I call mapParser on my top-level parser:
debugParser :: ArgumentReachability -> Option x -> String
debugParser reachability opt = case optMain opt of
OptReader ns _ _ -> "optreader"
FlagReader ns _ -> "flagReader"
ArgReader rdr -> "argreader"
-- >>= \x -> return $ Completion x "argreader help" True
CmdReader _ ns p -> "cmdreader"
let out = mapParser debugParser mainParser
putStrLn $ "out=" ++ show out
It displays only "cmdReader" even though piLoadCsv
has argument parsers too. I would expect mapParser to enter each child parser ?
That's why I've tried to modify treeMapParser
to get into all the children subparsers:
@@ -268,16 +275,22 @@ treeMapParser g = simplify . go False g
has_default :: Parser a -> Bool
has_default p = isJust (evalParser p)
+ -- genLeaf :: (String -> Maybe (Parser a)) -> String -> OptTree b
+ genLeaf fn arg = case fn arg of
+ Nothing -> Nothing
+ Just p -> Just $ infoParser p
+
go :: Bool
-> (forall x. ArgumentReachability -> Option x -> b)
-> Parser a
-> OptTree b
go _ _ (NilP _) = MultNode []
go r f (OptP opt)
- | optVisibility opt > Internal
- = Leaf (f (ArgumentReachability r) opt)
- | otherwise
- = MultNode []
+ | optVisibility opt > Internal = case opt of
+ -- AltP
+ (Option (CmdReader _ ns fn) _) -> MultNode $ [Leaf (f (ArgumentReachability r) opt)] ++ ( map (\x -> go r f x ) (catMaybes $ map (genLeaf fn) ns ))
+ _else -> Leaf (f (ArgumentReachability r) opt)
+ | otherwise = MultNode []
go r f (MultP p1 p2) =
MultNode [go r f p1, go r' f p2]
where r' = r || hasArg p1
it seems better as now mapParser
does now collect the options of each parser.
The CmdReader (Maybe String) [String] (String -> Maybe (ParserInfo a))
is a bit annoying though. Why not CmdReader (Maybe String) Map String ParserInfo
?
from optparse-applicative.
I don't really know what to say regarding your Haskeline version. The bash and zsh shells work here, here's an example I have lying around. This is with zsh.
The sub command compile
completes, then once in the subcommand its options complete as well.
My guess is that your lexing and splitting of the input words is not quite right.
from optparse-applicative.
I've changed optparse-applicative's examples/Cabal.hs to an executable to test the zsh completion.
It seemed to work. Back to my code, I noticed that when typing the full command name, completion would work, but it would fail when the command was half-typed. I tracked it down to
and the following seems to do the trick:
diff --git a/src/Options/Applicative/Common.hs b/src/Options/Applicative/Common.hs
index c40f3c4..4edbd05 100644
--- a/src/Options/Applicative/Common.hs
+++ b/src/Options/Applicative/Common.hs
@@ -208,7 +208,9 @@ runParser policy isCmdStart p args = case args of
(arg : argt) -> do
(mp', args') <- do_step arg argt
case mp' of
- Nothing -> hoistMaybe result <|> parseError arg p
+ Nothing ->
+ trace "ERROR" hoistMaybe result <|> exitP isCmdStart policy p Nothing
Just p' -> runParser (newPolicy arg) CmdCont p' args'
where
result =
In terms of API, an idea I like from haskeline would be to return a completion datatype(https://hackage.haskell.org/package/haskeline-0.8.2/docs/System-Console-Haskeline-Completion.html#t:Completion) in
newtype Completer = Completer { runCompleter :: String -> IO [String] }
=> newtype Completer = Completer { runCompleter :: String -> IO [Completion] }
.
optparse-applicative could return the completion and its description and toggle what to display depending on "Richness" ?
from optparse-applicative.
another thing that is annoying is that let's say I have my positional argument with a <> completeWith ["toto", "tata"]
modifier, there is no validation of the resulting value during runCompletion. Let's say my previous command load-pcap
expects as argument "toto" or "tata" I wouldl ike to trigger the completion if the value isn't one of those but right now optparse accepts any value.
from optparse-applicative.
Yeah... using a type which included an optional richness would be a lot better that just a string which gets a sentinal tab in it. We would allow users to also supply rich completions where they're supported... don't know I didn't do that the first time round.
Obviously until a better API for shells is developed we would have to smash in the tab in eventually, but we would push it to the boundary.
from optparse-applicative.
so I found the issue with eitherReader, it throws an ErrorMsg (which doesn't contian the parser) so runCompletion returns a Nothing instead of the parser with the error. I've hacked the searchArg function so that upon any error it gets rewritten with a ParseError that actually contains the parser:
ArgReader rdr -> let
tmp = runExcept $ runReaderT (unReadM $ crReader rdr) arg
in
-- rewrite the error so that completion can access the parser
fmap pure . lift . lift $ either (const $ exitP CmdStart AllPositionals parser Nothing) return tmp
This way I can access the parser that failed during autocompletion, and display the available completions. This hack may break other stuff but it solves the last (big) issue I had with live completion. I am running after a deadline but once I get more time, I can submit PRs if there is interest. Out of the box completion with haskeline would be a neat feature IMO (or at least making it easier).
from optparse-applicative.
closing as I got it working as I wanted in the end. thanks for the help throughout !
from optparse-applicative.
Related Issues (20)
- URL completer? HOT 6
- Support for parsing RawFilePath HOT 1
- Showing help on empty with inline subcommands HOT 6
- Listification (like `some1`) does not change the `metavar` to plural HOT 2
- Add ability to group aliases in --help HOT 2
- Offer a positional parser HOT 2
- Parse in interactive program HOT 2
- Export `requote` from `Options.Applicative.Builder.Completer` HOT 2
- Options shown in Global section can include unreachable alternatives. HOT 4
- Add Semigroup/Monoid to Parser HOT 7
- Ignore unused flags HOT 2
- Parser HOT 1
- (Question) Is there value in storing CLI output in a text file and using it as a golden test? HOT 1
- Is it possible to automatically show in help which values are valid for an option? HOT 3
- Stack executable built against `optparse-applicative-0.17.1.0` 'hangs' HOT 20
- Ansi annotations aren't being rendered.
- How do I print help info with colored command names? HOT 14
- v0.18: `text` no longer exported from `Options.Applicative.Help.Pretty` HOT 4
- Default command and command alias
- Apply style for command groups HOT 3
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from optparse-applicative.