summaryrefslogtreecommitdiffstats
path: root/src/commands/delete_files.rs
blob: 9e302b0da26b2a800e4de118cd6d2e5dbe4811f8 (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
89
90
91
92
93
94
95
96
use std::fs;
use std::path;

use termion::event::Key;

use crate::commands::{CursorMoveStub, JoshutoCommand, JoshutoRunnable, ReloadDirList};
use crate::context::JoshutoContext;
use crate::error::JoshutoResult;
use crate::ui::TuiBackend;

use crate::ui::widgets::TuiPrompt;

#[derive(Clone, Debug)]
pub struct DeleteFiles;

impl DeleteFiles {
    pub fn new() -> Self {
        DeleteFiles
    }
    pub const fn command() -> &'static str {
        "delete_files"
    }

    pub fn remove_files(paths: &[&path::PathBuf]) -> std::io::Result<()> {
        for path in paths {
            if let Ok(metadata) = fs::symlink_metadata(path) {
                if metadata.is_dir() {
                    fs::remove_dir_all(&path)?;
                } else {
                    fs::remove_file(&path)?;
                }
            }
        }
        Ok(())
    }

    fn delete_files(context: &mut JoshutoContext, backend: &mut TuiBackend) -> std::io::Result<()> {
        let curr_tab = &context.tabs[context.curr_tab_index];
        let paths = match curr_tab.curr_list_ref() {
            Some(s) => s.get_selected_paths(),
            None => Vec::new(),
        };
        let paths_len = paths.len();

        if paths_len == 0 {
            return Err(std::io::Error::new(
                std::io::ErrorKind::Other,
                "no files selected",
            ));
        }

        let ch = {
            let prompt_str = format!("Delete {} files? (Y/n)", paths_len);
            let mut prompt = TuiPrompt::new(&prompt_str);
            prompt.get_key(backend, &context)
        };

        if ch == Key::Char('y') || ch == Key::Char('\n') {
            if paths_len > 1 {
                let ch = {
                    let prompt_str = "Are you sure? (y/N)";
                    let mut prompt = TuiPrompt::new(prompt_str);
                    prompt.get_key(backend, &context)
                };
                if ch == Key::Char('y') {
                    Self::remove_files(&paths)?;
                    ReloadDirList::reload(context.curr_tab_index, context)?;
                    let msg = format!("Deleted {} files", paths_len);
                    context.message_queue.push_back(msg);
                }
            } else {
                Self::remove_files(&paths)?;
                ReloadDirList::reload(context.curr_tab_index, context)?;
                let msg = format!("Deleted {} files", paths_len);
                context.message_queue.push_back(msg);
            }
        }
        Ok(())
    }
}

impl JoshutoCommand for DeleteFiles {}

impl std::fmt::Display for DeleteFiles {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        f.write_str(Self::command())
    }
}

impl JoshutoRunnable for DeleteFiles {
    fn execute(&self, context: &mut JoshutoContext, backend: &mut TuiBackend) -> JoshutoResult<()> {
        Self::delete_files(context, backend)?;
        CursorMoveStub::new().execute(context, backend)?;
        Ok(())
    }
}