Skip to content

Commit

Permalink
add the ability to set file operation colors
Browse files Browse the repository at this point in the history
Signed-off-by: Luterán Lajos <[email protected]>
  • Loading branch information
luteran42 committed Feb 24, 2024
1 parent 386943c commit 53c6aba
Show file tree
Hide file tree
Showing 9 changed files with 162 additions and 54 deletions.
8 changes: 6 additions & 2 deletions config/theme.toml
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,12 @@ fg = "light_yellow"
bold = true

[mark]
fg = "red"
bold = true
cut.fg = "red"
cut.bold = true
copy.fg = "rgb(235, 104, 65)" # orange
copy.bold = true
symlink.fg = "rgb(254, 132, 172)" # pink
symlink.bold = true

[selection.prefix]
prefix = " "
Expand Down
73 changes: 50 additions & 23 deletions src/commands/file_ops.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,45 +7,68 @@ use crate::fs::JoshutoDirList;
use crate::io::{FileOperation, FileOperationOptions, IoWorkerThread};

fn new_local_state(context: &mut AppContext, file_op: FileOperation) -> Option<()> {
mark_entries(context);
let list = context.tab_context_ref().curr_tab_ref().curr_list_ref()?;
if list.iter().any(|entry| entry.is_marked()) {
let selected = list.get_selected_paths();
let mut local_state = LocalStateContext::new();
local_state.set_paths(selected.into_iter());
local_state.set_file_op(file_op);

context.set_local_state(local_state);
Some(())
} else {
None
}
let selected = list.get_selected_paths();
let mut local_state = LocalStateContext::new();
local_state.set_paths(selected.into_iter());
local_state.set_file_op(file_op);

context.set_local_state(local_state);
Some(())
}

fn mark_entries(context: &mut AppContext) {
fn mark_entries(context: &mut AppContext, op: &str) {
let tab = context.tab_context_mut().curr_tab_mut();

if let Some(curr_list) = tab.curr_list_mut() {
if curr_list.selected_count() != 0 {
curr_list.iter_mut().for_each(|entry| {
if entry.is_permanent_selected() {
entry.set_mark_selected(true);
curr_list.iter_mut().for_each(|entry| {
entry.set_mark_cut_selected(false);
entry.set_mark_copy_selected(false);
entry.set_mark_sym_selected(false);
});

match curr_list.selected_count() {
count if count != 0 => {
curr_list.iter_mut().for_each(|entry| match op {
"cut" if entry.is_permanent_selected() => entry.set_mark_cut_selected(true),
"copy" if entry.is_permanent_selected() => entry.set_mark_copy_selected(true),
"symlink" if entry.is_permanent_selected() => entry.set_mark_sym_selected(true),
_ => {}
});
}
_ => {
if let Some(entry) = curr_list.curr_entry_mut() {
match op {
"cut" => entry.set_mark_cut_selected(true),
"copy" => entry.set_mark_copy_selected(true),
"symlink" => entry.set_mark_sym_selected(true),
_ => {}
}
}
})
} else if let Some(entry) = curr_list.curr_entry_mut() {
entry.set_mark_selected(true);
}
}
}
}

fn unmark_entries(curr_tab: &mut JoshutoDirList) {
if curr_tab.selected_count() != 0 {
curr_tab.iter_mut().for_each(|entry| {
if entry.is_marked() {
entry.set_mark_selected(false);
if entry.is_marked_cut() {
entry.set_mark_cut_selected(false)
} else if entry.is_marked_copy() {
entry.set_mark_copy_selected(false)
} else if entry.is_marked_sym() {
entry.set_mark_sym_selected(false)
}
})
} else if let Some(entry) = curr_tab.curr_entry_mut() {
entry.set_mark_selected(false);
if entry.is_marked_cut() {
entry.set_mark_cut_selected(false)
} else if entry.is_marked_copy() {
entry.set_mark_copy_selected(false)
} else if entry.is_marked_sym() {
entry.set_mark_sym_selected(false)
}
}
}

Expand All @@ -69,21 +92,25 @@ fn unmark_and_cancel_all(context: &mut AppContext) -> AppResult {
}

pub fn cut(context: &mut AppContext) -> AppResult {
mark_entries(context, "cut");
new_local_state(context, FileOperation::Cut);
Ok(())
}

pub fn copy(context: &mut AppContext) -> AppResult {
mark_entries(context, "copy");
new_local_state(context, FileOperation::Copy);
Ok(())
}

pub fn symlink_absolute(context: &mut AppContext) -> AppResult {
mark_entries(context, "symlink");
new_local_state(context, FileOperation::Symlink { relative: false });
Ok(())
}

pub fn symlink_relative(context: &mut AppContext) -> AppResult {
mark_entries(context, "symlink");
new_local_state(context, FileOperation::Symlink { relative: true });
Ok(())
}
Expand Down
11 changes: 9 additions & 2 deletions src/config/clean/theme/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ pub struct AppTheme {
pub regular: AppStyle,
pub selection: AppStyle,
pub visual_mode_selection: AppStyle,
pub mark: AppStyle,
pub mark: HashMap<String, AppStyle>,
pub directory: AppStyle,
pub executable: AppStyle,
pub link: AppStyle,
Expand Down Expand Up @@ -53,7 +53,14 @@ impl From<AppThemeRaw> for AppTheme {
let tabs = raw.tabs;
let selection = raw.selection.to_style_theme();
let visual_mode_selection = raw.visual_mode_selection.to_style_theme();
let mark = raw.mark.to_style_theme();
let mark: HashMap<String, AppStyle> = raw
.mark
.iter()
.map(|(k, v)| {
let style = v.to_style_theme();
(k.clone(), style)
})
.collect();
let executable = raw.executable.to_style_theme();
let regular = raw.regular.to_style_theme();
let directory = raw.directory.to_style_theme();
Expand Down
2 changes: 1 addition & 1 deletion src/config/raw/theme/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ pub struct AppThemeRaw {
#[serde(default)]
pub visual_mode_selection: AppStyleRaw,
#[serde(default)]
pub mark: AppStyleRaw,
pub mark: HashMap<String, AppStyleRaw>,
#[serde(default)]
pub directory: AppStyleRaw,
#[serde(default)]
Expand Down
10 changes: 8 additions & 2 deletions src/fs/dirlist.rs
Original file line number Diff line number Diff line change
Expand Up @@ -222,8 +222,14 @@ impl JoshutoDirList {
self.contents.iter().filter(|e| e.is_selected()).count()
}

pub fn marked_count(&self) -> usize {
self.contents.iter().filter(|e| e.is_marked()).count()
pub fn marked_cut_count(&self) -> usize {
self.contents.iter().filter(|e| e.is_marked_cut()).count()
}
pub fn marked_copy_count(&self) -> usize {
self.contents.iter().filter(|e| e.is_marked_copy()).count()
}
pub fn marked_sym_count(&self) -> usize {
self.contents.iter().filter(|e| e.is_marked_sym()).count()
}

pub fn iter_selected(&self) -> impl Iterator<Item = &JoshutoDirEntry> {
Expand Down
34 changes: 27 additions & 7 deletions src/fs/entry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@ pub struct JoshutoDirEntry {
/// Temporarily selected by the visual mode range
visual_mode_selected: bool,
/// Marked for file ops
marked: bool,
marked_cut: bool,
marked_copy: bool,
marked_sym: bool,
}

impl JoshutoDirEntry {
Expand Down Expand Up @@ -62,7 +64,9 @@ impl JoshutoDirEntry {
metadata,
permanent_selected: false,
visual_mode_selected: false,
marked: false,
marked_cut: false,
marked_copy: false,
marked_sym: false,
})
}

Expand All @@ -83,7 +87,11 @@ impl JoshutoDirEntry {
}

pub fn is_selected(&self) -> bool {
self.permanent_selected || self.visual_mode_selected || self.marked
self.permanent_selected
|| self.visual_mode_selected
|| self.marked_cut
|| self.marked_copy
|| self.marked_sym
}

pub fn is_permanent_selected(&self) -> bool {
Expand All @@ -94,8 +102,14 @@ impl JoshutoDirEntry {
self.visual_mode_selected
}

pub fn is_marked(&self) -> bool {
self.marked
pub fn is_marked_cut(&self) -> bool {
self.marked_cut
}
pub fn is_marked_copy(&self) -> bool {
self.marked_copy
}
pub fn is_marked_sym(&self) -> bool {
self.marked_sym
}

pub fn set_permanent_selected(&mut self, selected: bool) {
Expand All @@ -106,8 +120,14 @@ impl JoshutoDirEntry {
self.visual_mode_selected = visual_mode_selected;
}

pub fn set_mark_selected(&mut self, mark_selected: bool) {
self.marked = mark_selected;
pub fn set_mark_cut_selected(&mut self, mark_selected: bool) {
self.marked_cut = mark_selected;
}
pub fn set_mark_copy_selected(&mut self, mark_selected: bool) {
self.marked_copy = mark_selected;
}
pub fn set_mark_sym_selected(&mut self, mark_selected: bool) {
self.marked_sym = mark_selected;
}

pub fn get_ext(&self) -> &str {
Expand Down
8 changes: 6 additions & 2 deletions src/history.rs
Original file line number Diff line number Diff line change
Expand Up @@ -195,11 +195,15 @@ pub fn create_dirlist_with_history(
for entry in contents.iter_mut() {
if let Some(former_entry) = former_entries_by_file_name.get(entry.file_name()) {
if preserve_selection {
entry.set_mark_selected(former_entry.is_marked());
entry.set_mark_cut_selected(former_entry.is_marked_cut());
entry.set_mark_copy_selected(former_entry.is_marked_copy());
entry.set_mark_sym_selected(former_entry.is_marked_sym());
entry.set_permanent_selected(former_entry.is_permanent_selected());
entry.set_visual_mode_selected(former_entry.is_visual_mode_selected());
} else {
entry.set_mark_selected(false);
entry.set_mark_cut_selected(false);
entry.set_mark_copy_selected(false);
entry.set_mark_sym_selected(false);
entry.set_permanent_selected(false);
entry.set_visual_mode_selected(false);
}
Expand Down
46 changes: 38 additions & 8 deletions src/ui/widgets/tui_footer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,13 @@ impl<'a> Widget for TuiFooter<'a> {
.add_modifier(THEME_T.selection.modifier);

let selection_style = permanent_selected_style();
let mark_style = mark_selected_style();
let mark_cut_style = mark_selected_style("cut");
let mark_copy_style = mark_selected_style("copy");
let mark_sym_style = mark_selected_style("symlink");
let selected_count = self.dirlist.selected_count();
let marked_count = self.dirlist.marked_count();
let marked_cut_count = self.dirlist.marked_cut_count();
let marked_copy_count = self.dirlist.marked_copy_count();
let marked_sym_count = self.dirlist.marked_sym_count();

match self.dirlist.get_index() {
Some(i) if i < self.dirlist.len() => {
Expand Down Expand Up @@ -105,22 +109,48 @@ impl<'a> Widget for TuiFooter<'a> {
if selected_count > 0 {
format!("{} selected", selected_count)
} else {
" ".to_string()
"".to_string()
},
selection_style,
),
Span::raw(if marked_count > 0 {
Span::raw(if marked_cut_count > 0 {
" | ".to_string()
} else {
"".to_string()
}),
Span::styled(
if marked_count > 0 {
format!("{} marked", marked_count)
if marked_cut_count > 0 {
format!("{} marked -> cut", marked_cut_count)
} else {
" ".to_string()
"".to_string()
},
mark_style,
mark_cut_style,
),
Span::raw(if marked_copy_count > 0 {
" | ".to_string()
} else {
"".to_string()
}),
Span::styled(
if marked_copy_count > 0 {
format!("{} marked -> copy", marked_copy_count)
} else {
"".to_string()
},
mark_copy_style,
),
Span::raw(if marked_sym_count > 0 {
" | ".to_string()
} else {
"".to_string()
}),
Span::styled(
if marked_sym_count > 0 {
format!("{} marked -> symlink", marked_sym_count)
} else {
"".to_string()
},
mark_sym_style,
),
];

Expand Down
24 changes: 17 additions & 7 deletions src/util/style.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,14 @@ pub fn entry_style(entry: &JoshutoDirEntry) -> Style {
let filetype = metadata.file_type();
let linktype = metadata.link_type();

if entry.is_marked() {
return mark_selected_style();
if entry.is_marked_cut() {
return mark_selected_style("cut");
}
if entry.is_marked_copy() {
return mark_selected_style("copy");
}
if entry.is_marked_sym() {
return mark_selected_style("symlink");
}
if entry.is_permanent_selected() {
return permanent_selected_style();
Expand Down Expand Up @@ -75,11 +81,15 @@ pub fn permanent_selected_style() -> Style {
.add_modifier(THEME_T.selection.modifier)
}

pub fn mark_selected_style() -> Style {
Style::default()
.fg(THEME_T.mark.fg)
.bg(THEME_T.mark.bg)
.add_modifier(THEME_T.mark.modifier)
pub fn mark_selected_style(file_op: &str) -> Style {
if let Some(mark) = THEME_T.mark.get(file_op) {
Style::default()
.fg(mark.fg)
.bg(mark.bg)
.add_modifier(mark.modifier)
} else {
Style::default()
}
}

pub fn symlink_valid_style() -> Style {
Expand Down

0 comments on commit 53c6aba

Please sign in to comment.