optparse-applicative bash 自动完成如何工作?
How does optparse-applicative bash autocompletion work?
我正在构建一个 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
.
的实例
你应该如何让自动完成工作?
我没有对此进行测试,但在阅读文档后,在我看来,通过在 main
中调用 execParser
,您的程序会自动支持命令完成所需的选项。您只需要 运行 您的程序使用 --bash-completion-script
作为文档生成一个 shell 脚本,然后将该脚本加载到 bash。
在 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
是对 bash 如何自动完成的说明。 "file"
表示自动完成任何文件或目录。有关详细信息,请参阅 this 页面。
为了启动这些自动完成功能,您需要生成一个脚本并确保该脚本是源代码。按照惯例,当使用 bash.
时,它位于 /etc/bash_completion.d/
下
brainfuck --bash-completion-script `which brainfuck` | sudo tee /etc/bash_completion.d/brainfuck
在我的例子中,我的程序被称为 brainfuck
。
我正在构建一个 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
.
你应该如何让自动完成工作?
我没有对此进行测试,但在阅读文档后,在我看来,通过在 main
中调用 execParser
,您的程序会自动支持命令完成所需的选项。您只需要 运行 您的程序使用 --bash-completion-script
作为文档生成一个 shell 脚本,然后将该脚本加载到 bash。
在 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
是对 bash 如何自动完成的说明。 "file"
表示自动完成任何文件或目录。有关详细信息,请参阅 this 页面。
为了启动这些自动完成功能,您需要生成一个脚本并确保该脚本是源代码。按照惯例,当使用 bash.
时,它位于/etc/bash_completion.d/
下
brainfuck --bash-completion-script `which brainfuck` | sudo tee /etc/bash_completion.d/brainfuck
在我的例子中,我的程序被称为 brainfuck
。