我正在构建一个brainfuck编译器。可执行文件接受两个命令$ brainfuck compile ...和$ brainfuck run。我希望可执行文件在按tab时自动完成。例如,编写$ brainfuck com,然后按Tab键应该会生成$ 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"在optparse的github页面here上有一个部分,但我并不真正理解它。
函数completeWith :: Options.Applicative.Builder.Internal.HasCompleter f => [String] -> Mod f a看起来与我已经在使用的command :: String -> ParserInfo a -> Mod CommandFields a非常相似。所以我想我可以使用它并将它们与<>结合起来,但事实证明CommandFields不是HasCompleter的实例。
你应该如何让自动补全起作用呢?
发布于 2019-12-01 21:39:54
在RTFM‘’ing了一点之后,我发现了如何配置自动完成。当为各个参数构造解析器时,将应用completeWith。如下所示:
data CompileArgs = CompileArgs
{
debug :: Bool,
optimizations :: OptimizationLevel,
file :: String
}
deriving (Show, Read)
compileArgsParser :: Parser CompileArgs
compileArgsParser = CompileArgs
<$> switch (
long "debug" <>
help "Outputs object and assembly files")
<*> option auto (
long "optimization-level" <>
value All <>
metavar "LEVEL" <>
help "all | none, default: all" <>
completeWith ["all", "none"])
<*> argument str (
metavar "FILE" <>
help "brainfuck source code" <>
action "file")
<**> helperaction是一个关于如何自动完成的指令。"file"表示自动完成任何文件或目录。有关更多信息,请参阅this页面。
为了让这些自动补全生效,您需要生成一个脚本,并确保该脚本是源代码。按照惯例,当使用bash时,它被放在/etc/bash_completion.d/下。
brainfuck --bash-completion-script `which brainfuck` | sudo tee /etc/bash_completion.d/brainfuck在我的例子中,我的程序名为brainfuck。
发布于 2019-12-01 01:35:08
我没有对此进行测试,但在阅读了文档之后,我发现通过在main中调用execParser,您的程序会自动支持命令完成所需的选项。您只需要按照文档所述使用--bash-completion-script运行您的程序,以生成一个shell脚本,然后将该脚本加载到bash。
https://stackoverflow.com/questions/59117975
复制相似问题