summaryrefslogtreecommitdiffstats
path: root/src/browser_verbs.rs
blob: ae1c3d6adaddb64e377c77ec53e925c712292752 (plain)
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)?,
        })
    }
}