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
97
98
99
100
101
102
103
104
105
106
107
108
109
110
|
use super::change_directory::change_directory;
use super::sub_process::current_filenames;
use crate::commands::cursor_move;
use crate::context::AppContext;
use crate::error::{AppError, AppErrorKind, AppResult};
use crate::ui::AppBackend;
use shell_words::split;
use std::process::{Command, Stdio};
pub fn custom_search(
context: &mut AppContext,
backend: &mut AppBackend,
words: &[String],
interactive: bool,
) -> AppResult {
let custom_command = context
.config_ref()
.custom_commands
.as_slice()
.iter()
.find(|x| x.name == words[0])
.ok_or(AppError::new(
AppErrorKind::InvalidParameters,
"No custom command with given name".into(),
))?
.command
.clone();
let current_filenames = current_filenames(context);
let text = custom_command.replace("%s", ¤t_filenames.join(" "));
let text = text.replace(
"%text",
&words
.iter()
.skip(1)
.cloned()
.collect::<Vec<String>>()
.join(" "),
);
let mut command_with_args: Vec<String> = split(&text).map_err(|_| {
AppError::new(
AppErrorKind::InvalidParameters,
"Command cannot be splitted".into(),
)
})?;
let mut cmd = Command::new(command_with_args.remove(0));
command_with_args.into_iter().for_each(|x| {
cmd.arg(x);
});
let cmd_result = if interactive {
backend.terminal_drop();
let cmd_result = cmd
.stdin(Stdio::piped())
.stdout(Stdio::piped())
.spawn()?
.wait_with_output()?;
backend.terminal_restore(context.config_ref().mouse_support)?;
cmd_result
} else {
cmd.output()?
};
if cmd_result.status.success() {
let returned_text = std::str::from_utf8(&cmd_result.stdout)
.map_err(|_| {
AppError::new(
AppErrorKind::ParseError,
"Could not get command result as utf8".into(),
)
})?
.trim_end();
let path = std::path::Path::new(returned_text);
change_directory(
context,
path.parent().ok_or(AppError::new(
AppErrorKind::ParseError,
"Could not get parent directory".into(),
))?,
)?;
if let Some(current_dir_items) = context.tab_context_ref().curr_tab_ref().curr_list_ref() {
let position = current_dir_items
.iter()
.enumerate()
.find(|x| x.1.file_name() == path.file_name().unwrap_or_default())
.map(|x| x.0)
.unwrap_or_default();
cursor_move::cursor_move(context, position);
}
Ok(())
} else {
let returned_text = std::str::from_utf8(&cmd_result.stderr).map_err(|_| {
AppError::new(
AppErrorKind::ParseError,
"Could not get command result as utf8".into(),
)
})?;
Err(AppError::new(
AppErrorKind::ParseError,
format!("Command failed: {}", returned_text),
))
}
}
|