用rust编写的CLI工具第一次使用completion of fish出现错误

问题描述 投票:0回答:2

问题描述:

我写了一个wsl的CLI工具来学习rust。 它可以使用 Windows 的 explorer.exe 打开文件。 我称之为“op”。

问题是每次我打开一个新的 wsl 和 在鱼壳中输入“op”, 并使用“Tab”来完成, 然后会出现错误:

> op error: the directory does not exist
Oops: command not found
- (line 1):
Oops "./completion"
^~~^
from sourcing file -
        called on line 1 of file /usr/share/fish/completions/op.fish
from sourcing file /usr/share/fish/completions/op.fish

(文本'op'是彩色的,其他是白色的)

/usr/share/fish/completions/op.fish:

op completion fish | source

似乎与 fish shell (3.6.0) 有关(bash 没有错误,因为没有完成)。但是这个错误只会出现一次,之后命令“op”就会像预期的那样有意义。

我在这本书之后有一个'minigrep'。它运行完美,没有错误。

源码(main.rs):

// This is a minimal frame
// The complete code is in https://github.com/GlekoMa/op
use std::env;
use std::path::Path;
use std::process::Command;

fn main() {
    // 0. get env args
    let args: Vec<String> = env::args().collect();

    // 1. convert args[1] to Path
    let path = Path::new(&args[1]);

    // 2. parse path to parent and file_name
    let parent = path.parent().unwrap();
    let file_name = path.file_name().unwrap().to_str().unwrap();

    // 3. cd parent path
    env::set_current_dir(parent).unwrap();

    // 4. execute open (using exeplorer.exe) cmd
    let cmd_open = format!("explorer.exe {file_name}");
    Command::new("sh").arg("-c").arg(cmd_open).output().unwrap();
}

预期行为:

键入“op”并使用“Tab”完成不会引发任何错误。


更新和解决方案

感谢@faho,这个错误的来源(与 rust 源代码无关)描述如下:

/usr/share/fish/completions不知何故有一个补全鱼脚本op.fish(一般是同名软件生成的)。 但是我的“op”没有生成它,所以这个 op.fish 与我的“op”发生冲突。

有两种简单的修复方法:

  1. 重命名“op”(不是通过别名而是通过重建)。

  2. 将空文件写入 ~/.config/fish/completions/op.fish 以便 fish 加载它而不是 /usr/share/fish/completions/op.fish。

我已经使用了第二种方式,现在“op”效果很好!

rust command-line-interface fish
2个回答
5
投票

您的代码有调试打印:

https://github.com/GlekoMa/op/blob/7ae843acbd37a3f64b162aaf4b984094c7be0aa8/src/main.rs#L17

println!("Oops {:?}", path); // This code is for debug.

这会打印出

Oops ...
,所以 fish 会,因为您告诉它
source
输出,尝试将其作为命令运行,而命令“Oops”将不存在,因此它会打印错误。

这只会在完成加载时发生,鱼通常会在您第一次尝试完成某事时这样做。

删除调试语句,在生成补全时不要打印它(即你得到

completion
子命令),而是将它打印到 stderr(这意味着它会在加载补全时显示!)或者在它前面加上前缀
//
发表评论。


0
投票

我在创建一个最小的可重现示例时找到了错误的来源:

我用相同的代码创建了一个新项目,发现它运行完美,没有这个错误!

所以我删除了文件 /usr/share/fish/completions/op.fish 并尝试在新终端中运行“op”。这次没有出现错误。

为我的愚蠢道歉!

© www.soinside.com 2019 - 2024. All rights reserved.