forked from janek/mostr
feat(tasks): make sorting by property customizable
This commit is contained in:
parent
55792ca34f
commit
a7d02e60b2
19
src/main.rs
19
src/main.rs
|
@ -21,7 +21,7 @@ use xdg::BaseDirectories;
|
||||||
use crate::helpers::*;
|
use crate::helpers::*;
|
||||||
use crate::kinds::{KINDS, PROPERTY_COLUMNS, TRACKING_KIND};
|
use crate::kinds::{KINDS, PROPERTY_COLUMNS, TRACKING_KIND};
|
||||||
use crate::task::State;
|
use crate::task::State;
|
||||||
use crate::tasks::{StateFilter, Tasks};
|
use crate::tasks::{PropertyCollection, StateFilter, Tasks};
|
||||||
|
|
||||||
mod helpers;
|
mod helpers;
|
||||||
mod task;
|
mod task;
|
||||||
|
@ -277,21 +277,26 @@ async fn main() {
|
||||||
tasks.flush()
|
tasks.flush()
|
||||||
}
|
}
|
||||||
|
|
||||||
Some(':') =>
|
Some(':') => {
|
||||||
if let Some(digit) = iter.next().and_then(|s| s.to_digit(10)) {
|
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 index = (digit as usize).saturating_sub(1);
|
||||||
let remaining = iter.collect::<String>().trim().to_string();
|
let remaining = iter.collect::<String>().trim().to_string();
|
||||||
if remaining.is_empty() {
|
if remaining.is_empty() {
|
||||||
tasks.remove_column(index);
|
tasks.get_columns().remove_at(index);
|
||||||
} else {
|
} 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 {
|
} else if let Some(arg) = arg {
|
||||||
tasks.add_or_remove_property_column(arg);
|
tasks.get_columns().add_or_remove(arg.to_string());
|
||||||
} else {
|
} else {
|
||||||
println!("{}", PROPERTY_COLUMNS);
|
println!("{}", PROPERTY_COLUMNS);
|
||||||
continue;
|
continue;
|
||||||
},
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Some(',') =>
|
Some(',') =>
|
||||||
match arg {
|
match arg {
|
||||||
|
|
46
src/tasks.rs
46
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::fmt::{Display, Formatter};
|
||||||
use std::io::{Error, stdout, Write};
|
use std::io::{Error, stdout, Write};
|
||||||
use std::iter::once;
|
use std::iter::once;
|
||||||
|
@ -31,7 +31,7 @@ pub(crate) struct Tasks {
|
||||||
/// The task properties currently visible
|
/// The task properties currently visible
|
||||||
properties: Vec<String>,
|
properties: Vec<String>,
|
||||||
/// The task properties sorted by
|
/// The task properties sorted by
|
||||||
sorting: Vec<String>,
|
sorting: VecDeque<String>,
|
||||||
/// Negative: Only Leaf nodes
|
/// Negative: Only Leaf nodes
|
||||||
/// Zero: Only Active node
|
/// Zero: Only Active node
|
||||||
/// Positive: Go down the respective level
|
/// Positive: Go down the respective level
|
||||||
|
@ -123,10 +123,10 @@ impl Tasks {
|
||||||
"rpath".into(),
|
"rpath".into(),
|
||||||
"desc".into(),
|
"desc".into(),
|
||||||
],
|
],
|
||||||
sorting: vec![
|
sorting: VecDeque::from([
|
||||||
"state".into(),
|
"state".into(),
|
||||||
"name".into(),
|
"name".into(),
|
||||||
],
|
]),
|
||||||
position: None, // TODO persist position
|
position: None, // TODO persist position
|
||||||
view: Default::default(),
|
view: Default::default(),
|
||||||
tags: Default::default(),
|
tags: Default::default(),
|
||||||
|
@ -788,29 +788,47 @@ impl Tasks {
|
||||||
info!("Changed view depth to {depth}");
|
info!("Changed view depth to {depth}");
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn remove_column(&mut self, index: usize) {
|
pub(crate) fn get_columns(&mut self) -> &mut Vec<String> {
|
||||||
let col = self.properties.remove(index);
|
&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<T> {
|
||||||
|
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 <T> PropertyCollection<T> for Vec<T>
|
||||||
|
where T: Display, T: Eq, T: Clone {
|
||||||
|
fn remove_at(&mut self, index: usize) {
|
||||||
|
let col = self.remove(index);
|
||||||
info!("Removed property column \"{col}\"");
|
info!("Removed property column \"{col}\"");
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn add_or_remove_property_column(&mut self, property: &str) {
|
fn add_or_remove(&mut self, property: T) {
|
||||||
match self.properties.iter().position(|s| s == property) {
|
match self.iter().position(|s| s == &property) {
|
||||||
None => {
|
None => {
|
||||||
self.properties.push(property.to_string());
|
|
||||||
info!("Added property column \"{property}\"");
|
info!("Added property column \"{property}\"");
|
||||||
|
self.push(property);
|
||||||
}
|
}
|
||||||
Some(index) => {
|
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) {
|
fn add_or_remove_at(&mut self, property: T, index: usize) {
|
||||||
if self.properties.get(index) == Some(&property) {
|
if self.get(index) == Some(&property) {
|
||||||
self.properties.remove(index);
|
self.remove_at(index);
|
||||||
} else {
|
} else {
|
||||||
info!("Added property column \"{property}\" at position {}", index + 1);
|
info!("Added property column \"{property}\" at position {}", index + 1);
|
||||||
self.properties.insert(index, property);
|
self.insert(index, property);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue