5

我正在构建一个brainfuck 编译器。可执行文件接受两个命令$ brainfuck compile ...$ brainfuck run. 我希望可执行文件在按选项卡时自动完成。例如,写入$ 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 page here上有一个部分,但我不是很明白。

该功能看起来与我已经在使用的功能completeWith :: Options.Applicative.Builder.Internal.HasCompleter f => [String] -> Mod f a非常相似。command :: String -> ParserInfo a -> Mod CommandFields a所以我想我可以使用它并将它们与它们结合起来,<>但事实证明这CommandFields不是HasCompleter.

你应该如何让自动完成工作?

4

2 回答 2

2

在 RTFM 之后,我发现了如何配置自动完成。 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")
  <**> helper

action是关于如何自动完成的指令。"file"表示自动完成任何文件或目录。有关更多信息,请参阅页面。

为了让这些自动完成功能生效,您需要生成一个脚本并确保该脚本是有源的。/etc/bash_completion.d/按照惯例,它在使用 bash 时放在下面。

brainfuck --bash-completion-script `which brainfuck` | sudo tee /etc/bash_completion.d/brainfuck

在我的程序被调用的情况下brainfuck

于 2019-12-01T13:39:54.100 回答
0

我没有对此进行测试,但是在阅读了文档之后,在我看来,通过调用execParserin main,您的程序会自动支持命令完成所需的选项。您只需要--bash-completion-script按照文档中的说明运行程序以生成 shell 脚本,然后将该脚本加载到 bash。

于 2019-11-30T17:35:08.180 回答