From a7d02e60b2a346bce801a3f3265b8337ec31630f Mon Sep 17 00:00:00 2001 From: xeruf <27jf@pm.me> Date: Sun, 11 Aug 2024 10:58:34 +0300 Subject: [PATCH] feat(tasks): make sorting by property customizable --- src/main.rs | 19 ++++++++++++------- src/tasks.rs | 46 ++++++++++++++++++++++++++++++++-------------- 2 files changed, 44 insertions(+), 21 deletions(-) diff --git a/src/main.rs b/src/main.rs index a9ce310..ba91132 100644 --- a/src/main.rs +++ b/src/main.rs @@ -21,7 +21,7 @@ use xdg::BaseDirectories; use crate::helpers::*; use crate::kinds::{KINDS, PROPERTY_COLUMNS, TRACKING_KIND}; use crate::task::State; -use crate::tasks::{StateFilter, Tasks}; +use crate::tasks::{PropertyCollection, StateFilter, Tasks}; mod helpers; mod task; @@ -277,21 +277,26 @@ async fn main() { tasks.flush() } - Some(':') => - if let Some(digit) = iter.next().and_then(|s| s.to_digit(10)) { + Some(':') => { + let next = iter.next(); + if let Some(':') = next { + // TODO reverse order if present + tasks.add_sorting_property(iter.collect()) + } else if let Some(digit) = next.and_then(|s| s.to_digit(10)) { let index = (digit as usize).saturating_sub(1); let remaining = iter.collect::().trim().to_string(); if remaining.is_empty() { - tasks.remove_column(index); + tasks.get_columns().remove_at(index); } else { - tasks.add_or_remove_property_column_at_index(remaining, index); + tasks.get_columns().add_or_remove_at(remaining, index); } } else if let Some(arg) = arg { - tasks.add_or_remove_property_column(arg); + tasks.get_columns().add_or_remove(arg.to_string()); } else { println!("{}", PROPERTY_COLUMNS); continue; - }, + } + } Some(',') => match arg { diff --git a/src/tasks.rs b/src/tasks.rs index 4d52dc4..5251fb2 100644 --- a/src/tasks.rs +++ b/src/tasks.rs @@ -1,4 +1,4 @@ -use std::collections::{BTreeSet, HashMap}; +use std::collections::{BTreeSet, HashMap, VecDeque}; use std::fmt::{Display, Formatter}; use std::io::{Error, stdout, Write}; use std::iter::once; @@ -31,7 +31,7 @@ pub(crate) struct Tasks { /// The task properties currently visible properties: Vec, /// The task properties sorted by - sorting: Vec, + sorting: VecDeque, /// Negative: Only Leaf nodes /// Zero: Only Active node /// Positive: Go down the respective level @@ -123,10 +123,10 @@ impl Tasks { "rpath".into(), "desc".into(), ], - sorting: vec![ + sorting: VecDeque::from([ "state".into(), "name".into(), - ], + ]), position: None, // TODO persist position view: Default::default(), tags: Default::default(), @@ -788,29 +788,47 @@ impl Tasks { info!("Changed view depth to {depth}"); } - pub(crate) fn remove_column(&mut self, index: usize) { - let col = self.properties.remove(index); + pub(crate) fn get_columns(&mut self) -> &mut Vec { + &mut self.properties + } + + pub(crate) fn add_sorting_property(&mut self, property: String) { + self.sorting.push_front(property); + self.sorting.truncate(4); + info!("Now sorting by {:?}", self.sorting); + } +} + +pub trait PropertyCollection { + fn remove_at(&mut self, index: usize); + fn add_or_remove(&mut self, value: T); + fn add_or_remove_at(&mut self, value: T, index: usize); +} +impl PropertyCollection for Vec +where T: Display, T: Eq, T: Clone { + fn remove_at(&mut self, index: usize) { + let col = self.remove(index); info!("Removed property column \"{col}\""); } - pub(crate) fn add_or_remove_property_column(&mut self, property: &str) { - match self.properties.iter().position(|s| s == property) { + fn add_or_remove(&mut self, property: T) { + match self.iter().position(|s| s == &property) { None => { - self.properties.push(property.to_string()); info!("Added property column \"{property}\""); + self.push(property); } Some(index) => { - self.properties.remove(index); + self.remove_at(index); } } } - pub(crate) fn add_or_remove_property_column_at_index(&mut self, property: String, index: usize) { - if self.properties.get(index) == Some(&property) { - self.properties.remove(index); + fn add_or_remove_at(&mut self, property: T, index: usize) { + if self.get(index) == Some(&property) { + self.remove_at(index); } else { info!("Added property column \"{property}\" at position {}", index + 1); - self.properties.insert(index, property); + self.insert(index, property); } } }