summaryrefslogtreecommitdiffstats
path: root/src/commands/subdir_fzf.rs
blob: 6bae11a285d68f7ff14828fd2534bc66616467b7 (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
use std::path::{Path, PathBuf};
use std::process::{Command, Stdio};

use crate::config::option::CaseSensitivity;
use crate::context::AppContext;
use crate::error::JoshutoResult;
use crate::ui::AppBackend;

use super::change_directory::change_directory;

pub fn subdir_fzf(context: &mut AppContext, backend: &mut AppBackend) -> JoshutoResult {
    backend.terminal_drop();

    let mut cmd = Command::new("fzf");
    cmd.stdout(Stdio::piped());

    let case_sensitivity = context
        .config_ref()
        .search_options_ref()
        .fzf_case_sensitivity;

    match case_sensitivity {
        CaseSensitivity::Insensitive => {
            cmd.arg("-i");
        }
        CaseSensitivity::Sensitive => {
            cmd.arg("+i");
        }
        // fzf uses smart-case match by default
        CaseSensitivity::Smart => {}
    }

    let fzf = cmd.spawn()?;

    let fzf_output = fzf.wait_with_output();

    match fzf_output {
        Ok(output) if output.status.success() => {
            if let Ok(selected) = std::str::from_utf8(&output.stdout) {
                let path: PathBuf = PathBuf::from(selected);
                fzf_change_dir(context, path.as_path())?;
            }
        }
        _ => {}
    }

    backend.terminal_restore()?;

    Ok(())
}

pub fn fzf_change_dir(context: &mut AppContext, path: &Path) -> JoshutoResult {
    if path.is_dir() {
        change_directory(context, path)?;
    } else if let Some(parent) = path.parent() {
        let file_name = path
            .file_name()
            .and_then(|name| name.to_str())
            .unwrap()
            .trim();
        change_directory(context, parent)?;

        let index = match context.tab_context_ref().curr_tab_ref().curr_list_ref() {
            Some(curr_list) => curr_list
                .iter()
                .enumerate()
                .find(|(_, e)| e.file_name() == file_name)
                .map(|(i, _)| i),
            None => None,
        };

        if let Some(index) = index {
            let ui_context = context.ui_context_ref().clone();
            let display_options = context.config_ref().display_options_ref().clone();
            if let Some(curr_list) = context.tab_context_mut().curr_tab_mut().curr_list_mut() {
                curr_list.set_index(Some(index), &ui_context, &display_options);
            }
        }
    }
    Ok(())
}