diff options
author | qkzk <qkzk@users.noreply.github.com> | 2022-09-30 21:34:03 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-09-30 21:34:03 +0200 |
commit | 777cfbd6fe1992e40b5c9c5592c39f2df56ac77f (patch) | |
tree | e98e1a96a8f459c013c76758a38d8648fa947045 | |
parent | 9229c2038d1898a1fca2a74abf85d77760548acc (diff) | |
parent | 4d9cecf3f68cb932a2f037a8989f862808da6c93 (diff) |
Merge pull request #15 from qkzk/sortingsorting
Sorting
-rw-r--r-- | config.yaml | 1 | ||||
-rw-r--r-- | readme.md | 6 | ||||
-rw-r--r-- | src/config.rs | 5 | ||||
-rw-r--r-- | src/fileinfo.rs | 37 | ||||
-rw-r--r-- | src/main.rs | 49 |
5 files changed, 77 insertions, 21 deletions
diff --git a/config.yaml b/config.yaml index 593647d..a8d8ccf 100644 --- a/config.yaml +++ b/config.yaml @@ -38,3 +38,4 @@ keybindings: regex_match: w jump: j nvim: i + sort_by: O @@ -56,6 +56,7 @@ - [x] confirmation for cut/paste, copy/paste, delete - [x] bugfix: strange behavior after leaving a mode, wrong files are flagged - not in the right index or something - [x] bugfix: can navigate outside file list +- [ ] sorting : filename, size, date, type ## TODO @@ -69,9 +70,6 @@ - https://github.com/KillTheMule/nvim-rs/blob/master/examples/basic.rs - https://neovim.io/doc/user/api.html - [ ] display / event separation. use async and message passing between coroutines -- [ ] sorting - - [ ] kind of sorts : filename, size, date, type - - [ ] key for alterning sorting ## BUGS @@ -86,3 +84,5 @@ ### filepicker in vim - [fff](https://github.com/dylanaraps/fff) + + diff --git a/src/config.rs b/src/config.rs index 5a0cbbe..aba352b 100644 --- a/src/config.rs +++ b/src/config.rs @@ -118,6 +118,7 @@ pub struct Keybindings { pub regex_match: char, pub jump: char, pub nvim: char, + pub sort_by: char, } impl Keybindings { @@ -188,6 +189,9 @@ impl Keybindings { if let Some(nvim) = yaml["nvim"].as_str().map(|s| s.to_string()) { self.nvim = nvim.chars().next().unwrap_or('i'); } + if let Some(nvim) = yaml["sort_by"].as_str().map(|s| s.to_string()) { + self.nvim = nvim.chars().next().unwrap_or('O'); + } } pub fn new() -> Self { @@ -214,6 +218,7 @@ impl Keybindings { regex_match: 'w', jump: 'j', nvim: 'i', + sort_by: 'O', } } } diff --git a/src/fileinfo.rs b/src/fileinfo.rs index 0a713db..d6cc1dd 100644 --- a/src/fileinfo.rs +++ b/src/fileinfo.rs @@ -6,6 +6,25 @@ use std::path; use users::get_user_by_uid; +#[derive(Debug, Clone)] +pub enum SortBy { + Filename, + Date, + Size, + Extension, +} + +impl SortBy { + pub fn by_key(&self, file: &FileInfo) -> String { + match *self { + Self::Filename => file.filename.clone(), + Self::Date => file.system_time.clone(), + Self::Size => file.file_size.clone(), + Self::Extension => file.extension.clone(), + } + } +} + #[derive(Debug, Clone, Copy)] pub enum FileKind { NormalFile, @@ -63,6 +82,7 @@ pub struct FileInfo { pub system_time: String, pub is_selected: bool, pub file_kind: FileKind, + pub extension: String, } impl FileInfo { @@ -77,6 +97,7 @@ impl FileInfo { let file_kind = FileKind::new(direntry); let dir_symbol = file_kind.extract_dir_symbol(); + let extension = get_extension_from_filename(&filename).unwrap_or("").into(); Ok(FileInfo { path, @@ -88,6 +109,7 @@ impl FileInfo { system_time, is_selected, file_kind, + extension, }) } @@ -121,6 +143,7 @@ pub struct PathContent { pub files: Vec<FileInfo>, pub selected: usize, pub show_hidden: bool, + pub sort_by: SortBy, } impl PathContent { @@ -142,7 +165,8 @@ impl PathContent { }) .map(|direntry| FileInfo::new(&direntry.unwrap()).unwrap()) .collect(); - files.sort_by_key(|file| file.filename.clone()); + let sort_by = SortBy::Filename; + files.sort_by_key(|file| sort_by.by_key(file)); let selected: usize = 0; if !files.is_empty() { files[selected].select(); @@ -153,9 +177,14 @@ impl PathContent { files, selected, show_hidden, + sort_by, } } + pub fn sort(&mut self) { + self.files.sort_by_key(|file| self.sort_by.by_key(file)); + } + fn owner_column_width(&self) -> usize { let mut owner_size_btreeset = std::collections::BTreeSet::new(); for file in self.files.iter() { @@ -280,3 +309,9 @@ fn human_size(bytes: u64) -> String { ); human_size } + +fn get_extension_from_filename(filename: &str) -> Option<&str> { + path::Path::new(filename) + .extension() + .and_then(std::ffi::OsStr::to_str) +} diff --git a/src/main.rs b/src/main.rs index dfd1044..06c0fc1 100644 --- a/src/main.rs +++ b/src/main.rs @@ -17,7 +17,7 @@ use tuikit::term::{Term, TermHeight}; // use fm::args::Args; use fm::config::{load_config, str_to_tuikit, Colors, Config}; -use fm::fileinfo::{FileInfo, FileKind, PathContent}; +use fm::fileinfo::{FileInfo, FileKind, PathContent, SortBy}; pub mod fileinfo; @@ -64,6 +64,7 @@ use clap::Parser; /// g: GOTO{n} /// w: REGEXMATCH{n} /// j: JUMP{n} +/// O: SORT{n} /// Enter: Execute mode then NORMAL{n} /// Esc: NORMAL{n} struct Args { @@ -83,17 +84,10 @@ struct Args { const WINDOW_PADDING: usize = 4; const WINDOW_MARGIN_TOP: usize = 1; const EDIT_BOX_OFFSET: usize = 10; +const SORT_CURSOR_OFFSET: usize = 29; const MAX_PERMISSIONS: u32 = 0o777; static CONFIG_PATH: &str = "~/.config/fm/config.yaml"; -// static USAGE: &str = " -// FM: dired inspired File Manager -// -// dired [flags] [path] -// flags: -// -a display hidden files -// -h show help and exit -// "; static HELP_LINES: &str = " Default key bindings: @@ -132,6 +126,7 @@ o: xdg-open this file g: GOTO w: REGEXMATCH j: JUMP + O: SORT Enter: Execute mode then NORMAL Esc: NORMAL "; @@ -222,6 +217,7 @@ enum Mode { RegexMatch, Jump, NeedConfirmation, + Sort, } impl fmt::Debug for Mode { @@ -239,6 +235,7 @@ impl fmt::Debug for Mode { Mode::RegexMatch => write!(f, "Regex : "), Mode::Jump => write!(f, "Jump : "), Mode::NeedConfirmation => write!(f, "Y/N :"), + Mode::Sort => write!(f, "(N)ame (D)ate (S)ize (E)xt : "), } } } @@ -603,6 +600,8 @@ impl Status { self.event_jump(); } else if c == self.config.keybindings.nvim { self.event_nvim_filepicker(); + } else if c == self.config.keybindings.sort_by { + self.mode = Mode::Sort; } } Mode::Help => { @@ -620,6 +619,24 @@ impl Status { self.last_edition = LastEdition::Nothing; self.mode = Mode::Normal; } + Mode::Sort => { + self.mode = Mode::Normal; + match c { + 'n' => self.path_content.sort_by = SortBy::Filename, + 'd' => self.path_content.sort_by = SortBy::Date, + 's' => self.path_content.sort_by = SortBy::Size, + 'e' => self.path_content.sort_by = SortBy::Extension, + _ => { + return; + } + } + if !self.path_content.files.is_empty() { + self.path_content.files[self.file_index].unselect(); + self.path_content.sort(); + self.event_home(); + self.path_content.select_index(0); + } + } } } @@ -837,7 +854,7 @@ impl Status { Mode::Goto => self.exec_goto(), Mode::RegexMatch => self.exec_regex(), Mode::Jump => self.exec_jump(), - Mode::Normal | Mode::NeedConfirmation | Mode::Help => (), + Mode::Normal | Mode::NeedConfirmation | Mode::Help | Mode::Sort => (), } self.input_string_cursor_index = 0; @@ -1108,14 +1125,9 @@ impl Display { let first_row: String = match status.mode { Mode::Normal => { format!( - "h: {}, s: {} wt: {} wb: {} m: {:?} - c: {:?} - {}", - status.height, + "Path: {} -- {} files", + status.path_content.path.to_str().unwrap(), status.path_content.files.len(), - status.window.top, - status.window.bottom, - status.mode, - status.args, - status.path_content.path.to_str().unwrap() ) } Mode::NeedConfirmation => { @@ -1159,6 +1171,9 @@ impl Display { Mode::NeedConfirmation => { let _ = self.term.set_cursor(0, status.last_edition.offset()); } + Mode::Sort => { + let _ = self.term.set_cursor(0, SORT_CURSOR_OFFSET); + } _ => { let _ = self .term |