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
|
use std::fs::OpenOptions;
use std::io::{self, Write};
use crate::verbs::{Verb, VerbExecutor};
use crate::app::AppStateCmdResult;
use crate::app_context::AppContext;
use crate::browser_states::BrowserState;
use crate::external::Launchable;
use crate::help_states::HelpState;
use crate::screens::Screen;
use crate::task_sync::TaskLifetime;
use crate::tree_options::{OptionBool, TreeOptions};
impl VerbExecutor for BrowserState {
fn execute_verb(
&self,
verb: &Verb,
screen: &Screen,
con: &AppContext,
) -> io::Result<AppStateCmdResult> {
let tree = match &self.filtered_tree {
Some(tree) => &tree,
None => &self.tree,
};
let line = &tree.selected_line();
Ok(match verb.exec_pattern.as_ref() {
":back" => AppStateCmdResult::PopState,
":focus" => {
AppStateCmdResult::from_optional_state(BrowserState::new(
tree.selected_line().path.clone(),
tree.options.clone(),
screen,
&TaskLifetime::unlimited(),
))
}
":help" => AppStateCmdResult::NewState(Box::new(HelpState::new(screen))),
":open" => AppStateCmdResult::Launch(Launchable::opener(&line.target())?),
":parent" => match &line.target().parent() {
Some(path) => {
AppStateCmdResult::from_optional_state(BrowserState::new(
path.to_path_buf(),
tree.options.clone(),
screen,
&TaskLifetime::unlimited(),
))
}
None => AppStateCmdResult::DisplayError("no parent found".to_string()),
},
":print_path" => {
if let Some(ref output_path) = con.launch_args.file_export_path {
// an output path was provided, we write to it
let f = OpenOptions::new().append(true).open(output_path)?;
writeln!(&f, "{}", line.target().to_string_lossy())?;
AppStateCmdResult::Quit
} else {
// no output path provided. We write on stdout, but we must
// do it after app closing to have the normal terminal
let mut launchable = Launchable::from(vec![line.target().to_string_lossy().to_string()])?;
launchable.just_print = true;
AppStateCmdResult::Launch(launchable)
}
}
":toggle_files" => {
self.with_new_options(screen, &|o: &mut TreeOptions| o.only_folders ^= true)
}
":toggle_hidden" => self.with_new_options(screen, &|o| o.show_hidden ^= true),
":toggle_git_ignore" => self.with_new_options(screen, &|options| {
options.respect_git_ignore = match options.respect_git_ignore {
OptionBool::Auto => {
if tree.nb_gitignored > 0 {
OptionBool::No
} else {
OptionBool::Yes
}
}
OptionBool::Yes => OptionBool::No,
OptionBool::No => OptionBool::Yes,
};
}),
":toggle_perm" => self.with_new_options(screen, &|o| o.show_permissions ^= true),
":toggle_sizes" => self.with_new_options(screen, &|o| o.show_sizes ^= true),
":toggle_trim_root" => self.with_new_options(screen, &|o| o.trim_root ^= true),
":quit" => AppStateCmdResult::Quit,
_ => verb.to_cmd_result(&line.target(), con)?,
})
}
}
|