1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
|
use {
super::{
argparse::Mode,
subprocess::{stream_subproc, SubprocCommand},
types::Die,
},
futures::stream::{Stream, StreamExt},
std::{
collections::HashMap,
env::{self, current_exe},
ffi::OsString,
path::PathBuf,
process::Stdio,
},
tokio::{io::ErrorKind, process::Command},
which::which,
};
async fn reset_term() -> Result<(), Die> {
if let Ok(path) = which("tput") {
let status = Command::new(&path)
.kill_on_drop(true)
.stdin(Stdio::null())
.arg("reset")
.status()
.await
.map_err(|e| Die::IO(path, e.kind()))?;
if status.success() {
return Ok(());
}
}
if let Ok(path) = which("reset") {
let status = Command::new(&path)
.kill_on_drop(true)
.stdin(Stdio::null())
.status()
.await
.map_err(|e| Die::IO(path, e.kind()))?;
if status.success() {
return Ok(());
}
}
Err(Die::IO(PathBuf::from("reset"), ErrorKind::NotFound))
}
pub fn stream_fzf_proc(
bin: PathBuf,
args: Vec<String>,
stream: impl Stream<Item = Result<OsString, Die>> + Unpin,
) -> impl Stream<Item = Result<(), Die>> {
let execute = format!("abort+execute:{}\x04{{+f}}", Mode::PATCH);
let mut arguments = vec![
"--read0".to_owned(),
"--print0".to_owned(),
"-m".to_owned(),
"--ansi".to_owned(),
"--preview-window=70%:wrap".to_owned(),
format!("--bind=enter:{execute}"),
format!("--bind=double-click:{execute}"),
format!("--preview={}\x04{{+f}}", Mode::PREVIEW),
];
arguments.extend(args);
let mut fzf_env = HashMap::new();
fzf_env.insert(
Mode::ARGV.to_owned(),
env::args().collect::<Vec<_>>().join("\x04"),
);
fzf_env.insert(
"SHELL".to_owned(),
current_exe()
.or_else(|_| which(env!("CARGO_PKG_NAME")))
.map_or_else(
|_| env!("CARGO_PKG_NAME").to_owned(),
|path| format!("{}", path.display()),
),
);
fzf_env.insert("LC_ALL".to_owned(), "C-UTF8".to_owned());
let cmd = SubprocCommand {
prog: bin,
args: arguments,
env: fzf_env,
};
stream_subproc(cmd, stream).then(|line| async {
match line {
Ok(o) => Ok(o),
Err(Die::BadExit(_, 130)) => Err(Die::Interrupt),
e => {
let _ = reset_term().await;
e
}
}
})
}
|