I'm building a brainfuck compiler. The executable accepts two commands $ brainfuck compile ... and $ brainfuck run. I want the executable to auto complete when pressing tab. E.g. writing $ brainfuck com and then pressing tab should generate $ brainfuck compile.
data Command = Compile CompileArgs | Run RunArgs
deriving (Show)
main :: IO ()
main = execute =<< execParser opts
where
opts = info (helper <*> argsParser) fullDesc
execute :: Command -> IO ()
execute (Compile args) = compile args
execute (Run args) = run args
argsParser :: Parser Command
argsParser = subparser (compileCommand <> runCommand)
where
compileCommand = command "compile" $ info compileOptions $ progDesc "Compile brainfuck to an executable"
runCommand = command "run" $ info runOptions $ progDesc "Execute brainfuck code"
There is a section on optparse's github page here, but I don't really understand it.
The function completeWith :: Options.Applicative.Builder.Internal.HasCompleter f => [String] -> Mod f a looks quite similar to command :: String -> ParserInfo a -> Mod CommandFields a which I'm already using. So I figured I could use it and just combine them with <> but it turns out that CommandFields is not an instance of HasCompleter.
How are you supposed to get the auto completion to work?
After RTFM'ing a bit I found out how to configure the auto completion.
completeWithis applied when constructing the parsers for the individual arguments. Like so:actionis an instruction to bash on how auto complete."file"means auto complete with any file or directory. See this page for more info.In order for these auto completions to kick in you need to generate a script and make sure that script is sourced. By convention it's placed under
/etc/bash_completion.d/when using bash.in my case where my program is called
brainfuck.