Compare commits
5 Commits
d744fb8457
...
3d389e8d52
Author | SHA1 | Date |
---|---|---|
xeruf | 3d389e8d52 | |
xeruf | 28d1f4c983 | |
xeruf | 93fde86169 | |
xeruf | 769b9578fe | |
xeruf | c27ccb8282 |
|
@ -65,8 +65,8 @@ where
|
|||
|
||||
/// Build a task with informational output and optional labeled kind
|
||||
pub(crate) fn build_task(name: &str, tags: Vec<Tag>, kind: Option<(&str, Kind)>) -> EventBuilder {
|
||||
info!("Created {}task \"{name}\" with tags [{}]",
|
||||
kind.map(|k| k.0).unwrap_or_default(),
|
||||
info!("Created {} \"{name}\" with tags [{}]",
|
||||
kind.map(|k| k.0).unwrap_or("task"),
|
||||
tags.iter().map(format_tag).join(", "));
|
||||
EventBuilder::new(kind.map(|k| k.1).unwrap_or(TASK_KIND), name, tags)
|
||||
}
|
||||
|
|
24
src/main.rs
24
src/main.rs
|
@ -25,7 +25,6 @@ use tokio::sync::mpsc;
|
|||
use tokio::sync::mpsc::Sender;
|
||||
use tokio::time::error::Elapsed;
|
||||
use tokio::time::timeout;
|
||||
use xdg::BaseDirectories;
|
||||
|
||||
use crate::helpers::*;
|
||||
use crate::kinds::{BASIC_KINDS, PROPERTY_COLUMNS, PROP_KINDS, TRACKING_KIND};
|
||||
|
@ -169,7 +168,7 @@ async fn main() -> Result<()> {
|
|||
);
|
||||
builder.init();
|
||||
|
||||
let config_dir = or_warn!(BaseDirectories::new(), "Could not determine config directory")
|
||||
let config_dir = or_warn!(xdg::BaseDirectories::new(), "Could not determine config directory")
|
||||
.and_then(|d| or_warn!(d.create_config_directory("mostr"), "Could not create config directory"))
|
||||
.unwrap_or(PathBuf::new());
|
||||
let keysfile = config_dir.join("key");
|
||||
|
@ -438,18 +437,27 @@ async fn main() -> Result<()> {
|
|||
Some(',') =>
|
||||
match arg {
|
||||
None => {
|
||||
tasks.get_current_task().map_or_else(
|
||||
|| info!("With a task selected, use ,NOTE to attach NOTE and , to list all its notes"),
|
||||
|task| println!("{}", task.description_events().map(|e| format!("{} {}", format_timestamp_local(&e.created_at), e.content)).join("\n")),
|
||||
);
|
||||
continue 'repl;
|
||||
match tasks.get_current_task() {
|
||||
None => {
|
||||
info!("With a task selected, use ,NOTE to attach NOTE and , to list all its notes");
|
||||
tasks.recurse_activities = !tasks.recurse_activities;
|
||||
info!("Toggled activities recursion to {}", tasks.recurse_activities);
|
||||
}
|
||||
Some(task) => {
|
||||
println!("{}",
|
||||
task.description_events()
|
||||
.map(|e| format!("{} {}", format_timestamp_local(&e.created_at), e.content))
|
||||
.join("\n"));
|
||||
continue 'repl;
|
||||
}
|
||||
}
|
||||
}
|
||||
Some(arg) => {
|
||||
if arg.len() < CHARACTER_THRESHOLD {
|
||||
warn!("Note needs at least {CHARACTER_THRESHOLD} characters!");
|
||||
continue 'repl;
|
||||
}
|
||||
tasks.make_note(arg)
|
||||
tasks.make_note(arg);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -94,9 +94,10 @@ impl Task {
|
|||
self.event.kind == TASK_KIND
|
||||
}
|
||||
|
||||
/// Whether this is an actionable task - false if stateless
|
||||
pub(crate) fn is_task(&self) -> bool {
|
||||
self.is_task_kind() ||
|
||||
self.states().next().is_some()
|
||||
self.props.iter().any(|event| State::try_from(event.kind).is_ok())
|
||||
}
|
||||
|
||||
fn states(&self) -> impl DoubleEndedIterator<Item=TaskState> + '_ {
|
||||
|
@ -134,7 +135,7 @@ impl Task {
|
|||
self.state().unwrap_or_else(|| self.default_state())
|
||||
}
|
||||
|
||||
/// Returns None for a stateless task.
|
||||
/// Returns None for activities.
|
||||
pub(crate) fn state_label(&self) -> Option<ColoredString> {
|
||||
self.state()
|
||||
.or_else(|| Some(self.default_state()).filter(|_| self.is_task()))
|
||||
|
|
71
src/tasks.rs
71
src/tasks.rs
|
@ -68,7 +68,7 @@ pub(crate) struct TasksRelay {
|
|||
view: Vec<EventId>,
|
||||
search_depth: usize,
|
||||
view_depth: usize,
|
||||
pub(crate) recurse_stateless_tasks: bool,
|
||||
pub(crate) recurse_activities: bool,
|
||||
|
||||
/// Currently active tags
|
||||
tags: BTreeSet<Tag>,
|
||||
|
@ -169,7 +169,7 @@ impl TasksRelay {
|
|||
state: Default::default(),
|
||||
search_depth: 4,
|
||||
view_depth: 0,
|
||||
recurse_stateless_tasks: true,
|
||||
recurse_activities: true,
|
||||
|
||||
sender,
|
||||
overflow: Default::default(),
|
||||
|
@ -388,9 +388,12 @@ impl TasksRelay {
|
|||
if !self.state.matches(task) {
|
||||
return vec![]
|
||||
}
|
||||
let mut new_depth = depth - 1;
|
||||
if sparse && new_depth > self.view_depth && self.filter(task) {
|
||||
new_depth = self.view_depth;
|
||||
let mut new_depth = depth;
|
||||
if !self.recurse_activities || task.is_task() {
|
||||
new_depth = depth - 1;
|
||||
if sparse && new_depth > self.view_depth && self.filter(task) {
|
||||
new_depth = self.view_depth;
|
||||
}
|
||||
}
|
||||
if new_depth > 0 {
|
||||
let mut children = self.resolve_tasks_rec(self.tasks.children_of(&task), sparse, new_depth);
|
||||
|
@ -450,7 +453,7 @@ impl TasksRelay {
|
|||
if current.is_empty() {
|
||||
println!("No tasks here matching{}", self.get_prompt_suffix());
|
||||
} else {
|
||||
println!("Found some matching tasks beyond specified search depth:");
|
||||
println!("Found matching tasks beyond specified search depth:");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1082,26 +1085,25 @@ impl TasksRelay {
|
|||
Some(self.set_state_for(*id, comment, state))
|
||||
}
|
||||
|
||||
pub(crate) fn make_note(&mut self, note: &str) {
|
||||
pub(crate) fn make_note(&mut self, note: &str) -> EventId {
|
||||
if let Some(id) = self.get_position_ref() {
|
||||
if self.get_by_id(id).is_some_and(|t| t.is_task()) {
|
||||
let prop = build_prop(Kind::TextNote, note.trim(), *id);
|
||||
self.submit(prop);
|
||||
return;
|
||||
return self.submit(prop)
|
||||
}
|
||||
}
|
||||
let (input, tags) = extract_tags(note.trim());
|
||||
self.submit(
|
||||
build_task(input, tags, Some(("stateless ", Kind::TextNote)))
|
||||
build_task(input, tags, Some(("activity", Kind::TextNote)))
|
||||
.add_tags(self.parent_tag())
|
||||
.add_tags(self.tags.iter().cloned())
|
||||
);
|
||||
)
|
||||
}
|
||||
|
||||
// Properties
|
||||
|
||||
pub(crate) fn set_view_depth(&mut self, depth: usize) {
|
||||
info!("Changed view depth to {depth}");
|
||||
info!("Showing {depth} subtask levels");
|
||||
self.view_depth = depth;
|
||||
}
|
||||
|
||||
|
@ -1112,7 +1114,7 @@ impl TasksRelay {
|
|||
} else {
|
||||
info!("Changed search depth to {depth}");
|
||||
}
|
||||
self.view_depth = depth;
|
||||
self.search_depth = depth;
|
||||
}
|
||||
|
||||
pub(crate) fn get_columns(&mut self) -> &mut Vec<String> {
|
||||
|
@ -1500,6 +1502,7 @@ mod tasks_test {
|
|||
tasks.move_to(Some(parent));
|
||||
let pin = tasks.make_task("pin");
|
||||
|
||||
tasks.search_depth = 1;
|
||||
assert_eq!(tasks.filtered_tasks(None, true).len(), 2);
|
||||
assert_eq!(tasks.filtered_tasks(None, false).len(), 2);
|
||||
assert_eq!(tasks.filtered_tasks(Some(&zero), false).len(), 0);
|
||||
|
@ -1515,17 +1518,18 @@ mod tasks_test {
|
|||
assert_eq!(tasks.filtered_tasks(Some(&zero), false), vec![tasks.get_by_id(&pin).unwrap()]);
|
||||
|
||||
tasks.move_to(None);
|
||||
assert_eq!(tasks.view_depth, 1);
|
||||
assert_eq!(tasks.view_depth, 0);
|
||||
assert_tasks!(tasks, [pin, test, parent]);
|
||||
tasks.set_view_depth(2);
|
||||
tasks.set_view_depth(1);
|
||||
assert_tasks!(tasks, [pin, test]);
|
||||
tasks.add_tag("tag".to_string());
|
||||
assert_tasks!(tasks, [test]);
|
||||
assert_eq!(tasks.filtered_tasks(None, true), vec![tasks.get_by_id(&test).unwrap()]);
|
||||
|
||||
tasks.submit(EventBuilder::new(Kind::Bookmarks, "", []));
|
||||
tasks.clear_filters();
|
||||
assert_tasks!(tasks, [pin, test]);
|
||||
tasks.set_view_depth(1);
|
||||
tasks.set_view_depth(0);
|
||||
assert_tasks!(tasks, [test, parent]);
|
||||
}
|
||||
|
||||
|
@ -1534,7 +1538,8 @@ mod tasks_test {
|
|||
let mut tasks = stub_tasks();
|
||||
tasks.make_task_and_enter("proc: tags", State::Procedure);
|
||||
assert_eq!(tasks.get_own_events_history().count(), 1);
|
||||
let side = tasks.submit(build_task("side", vec![tasks.make_event_tag(&tasks.get_current_task().unwrap().event, MARKER_DEPENDS)], None));
|
||||
let side = tasks.submit(
|
||||
build_task("side", vec![tasks.make_event_tag(&tasks.get_current_task().unwrap().event, MARKER_DEPENDS)], None));
|
||||
assert_eq!(tasks.visible_tasks(),
|
||||
Vec::<&Task>::new());
|
||||
let sub_id = tasks.make_task("sub");
|
||||
|
@ -1632,18 +1637,19 @@ mod tasks_test {
|
|||
fn test_depth() {
|
||||
let mut tasks = stub_tasks();
|
||||
|
||||
let t1 = tasks.make_task("t1");
|
||||
let task1 = tasks.get_by_id(&t1).unwrap();
|
||||
assert_eq!(tasks.view_depth, 1);
|
||||
assert_eq!(task1.pure_state(), State::Open);
|
||||
let t1 = tasks.make_note("t1");
|
||||
let activity_t1 = tasks.get_by_id(&t1).unwrap();
|
||||
assert!(!activity_t1.is_task());
|
||||
assert_eq!(tasks.view_depth, 0);
|
||||
assert_eq!(activity_t1.pure_state(), State::Open);
|
||||
debug!("{:?}", tasks);
|
||||
assert_eq!(tasks.visible_tasks().len(), 1);
|
||||
tasks.view_depth = 0;
|
||||
tasks.search_depth = 0;
|
||||
assert_eq!(tasks.visible_tasks().len(), 0);
|
||||
|
||||
tasks.move_to(Some(t1));
|
||||
assert_position!(tasks, t1);
|
||||
tasks.view_depth = 2;
|
||||
tasks.search_depth = 2;
|
||||
assert_eq!(tasks.visible_tasks().len(), 0);
|
||||
let t11 = tasks.make_task("t11: tag");
|
||||
assert_eq!(tasks.visible_tasks().len(), 1);
|
||||
|
@ -1678,17 +1684,28 @@ mod tasks_test {
|
|||
assert_tasks!(tasks, [t111, t12]);
|
||||
tasks.set_view(vec![t11]);
|
||||
assert_tasks!(tasks, [t11]); // No more depth applied to view
|
||||
tasks.set_view_depth(1);
|
||||
tasks.set_search_depth(1); // resets view
|
||||
assert_tasks!(tasks, [t111, t12]);
|
||||
tasks.set_view_depth(0);
|
||||
assert_tasks!(tasks, [t11, t12]);
|
||||
|
||||
tasks.move_to(None);
|
||||
assert_tasks!(tasks, [t1]);
|
||||
tasks.view_depth = 2;
|
||||
assert_tasks!(tasks, [t11, t12]);
|
||||
tasks.view_depth = 3;
|
||||
tasks.recurse_activities = false;
|
||||
assert_tasks!(tasks, [t1]);
|
||||
tasks.view_depth = 1;
|
||||
assert_tasks!(tasks, [t11, t12]);
|
||||
tasks.view_depth = 2;
|
||||
assert_tasks!(tasks, [t111, t12]);
|
||||
tasks.view_depth = 9;
|
||||
assert_tasks!(tasks, [t111, t12]);
|
||||
|
||||
tasks.add_tag("tag".to_string());
|
||||
tasks.view_depth = 0;
|
||||
assert_tasks!(tasks, [t11]);
|
||||
tasks.search_depth = 0;
|
||||
assert_eq!(tasks.view, []);
|
||||
assert_tasks!(tasks, []);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
Loading…
Reference in New Issue