fzf、stdin 和从 rust 调用程序时出现问题:

Trouble with fzf, stdin and invoking a program from rust:

当我尝试 fzf | myprogram 时,我遇到了这种非常奇怪的行为,myprogram 又调用了 vim。当 vim 启动时,stty 设置出现了问题。我能够在 zsh & bash、config & no config、linux & macOS 中重现这一点。最小复制:

cargo new myprogram

src/main.rs

use std::io;

fn main() {
    let mut file_name = String::new();
    io::stdin()
        .read_line(&mut file_name)
        .expect("Failed to read from stdin");
    file_name.retain(|c| !c.is_whitespace());

    println!("{}", file_name);
    std::process::Command::new("/bin/bash")
        .arg("-c")
        .arg(format!("vim {}", file_name))
        .spawn()
        .expect("Error: Failed to run editor")
        .wait()
        .unwrap()
        .success();
}

为了方便我一般是:cargo install --path .

当我 fzf | myprogram 能够 select 一个文件时,它会按预期在 vim 中打开。但是在 insert 模式下,当我退格时,我看到:^?。当我退出 vim 和 ^C 时它不起作用,它只是插入 ^C 个字符。每个换行符的格式都不正确,通常很难读取任何输出。

经过一番研究,我发现了 reset 命令。当我调用 reset 时,它在每种测试情况下都输出相同的内容:

重置

Erase set to delete.
Kill set to control-U (^U).
Interrupt set to control-C (^C).

我尝试了一些方法来读取 stdin 并调用 vim,但这个问题似乎仍然存在。

这是怎么回事?

@Masklinn 启发我创建了一个仅使用 catxargs 的示例,令我惊讶的是它也不起作用!

然后我遇到了 this post,它解释了 vim 在启动时修改当前终端,并且在关闭时尝试恢复启动时的配置。除非以非标准方式调用它,否则它不会恢复到正确的状态。

我所有的问题都通过告诉 rust 启动 vim 解决了,比如:

bash -c '</dev/tty vim "$@"'

而不是喜欢:

bash -c 'vim "$@"'