cengels / dlog

Inverted command line time tracking.
https://crates.io/crates/dlog
GNU General Public License v3.0
5 stars 1 forks source link

implementing disjunction for tags / projects? #2

Open mhuesch opened 3 years ago

mhuesch commented 3 years ago

hi! love dlog - use it daily to track time on projects.

I am wondering if you have thoughts on how tricky it might be to implement disjunction on tags/projects. I would like to say "show me a summary of tasks associated with both project :foo and project :bar". right now I believe there's only conjuction? (as in, I can only see entries which are associated with both :foo and :bar).

I wonder if the trickiest bit is shifting from a notion of "conjunction only" in the command line interface, as expressing AND and OR and parsing them properly into a tree is a bit tricky. then, some logic might have to change here to support adding OR?

any thoughts would be appreciated - thanks.

cengels commented 3 years ago

Hello there! It's always nice to hear when you—as the project creator—are not the only one using the thing you built. I'm glad to hear you like it.

I have some thoughts on how to implement your suggestion. The notation could look like this: dlog summary <activity>:<project_1>:<project_2> to say: "show me all entries related to the (optional) activity on projects 1 and 2". This can be chained with an infinite number of projects. The resulting table could then print the entries of all the projects separately as well as an aggregated sum of all time spent on all projects in total. That way I don't think we would need to handle AND and OR parsing separately.

However, for this to be an acceptable solution I would also need a way to do the same for multiple activities (as opposed to just projects). Since there is currently no special token that indicates an activity (like the + for tags or the : for projects), I'm unsure of what the best syntax for this in the CLI would be. My best idea so far is to just chain them separated by spaces, like this: dlog summary <activity_1> <activity_2> or dlog summary <activity_1>:<project> <activity_2>. Since this could then be combined with projects again though, this sort of syntax could get complicated quickly. Any thoughts on this would be appreciated.

The quick-and-dirty implementation would see dlog parsing the filter string into a Vec<EntryCore> (right now it's just one EntryCore. That way each activity-project pair would get parsed into one EntryCore and then added to the Vec for later filtering. I don't like that solution too much though since we'd have to handle the tags on a per-activity-project-pair basis as well. A new data structure might be better.

Since we're here already, we might as well think about tags as well. Right now all tags need to exist on each entry or the entry will be filtered out, but maybe it would be a good idea to add OR chaining to tags as well. I have absolutely no idea on a possible syntax for this though, and I also don't want to inflate the dlog syntax too much with this sort of thing or it will get too confusing for new users.

Basically, I think more discourse and brainstorming is required before anyone can start working on this.

mhuesch commented 3 years ago

hi, sorry about ghosting on this :bow:

I had a specific need to total up hours disjunctively, thought about implementing the feature you outlined, then got overwhelmed with potential yak-shaving.

I ended up writing a small utility to parse the HH:MM:SS output of each project, compute the sum, and then render it back to HH:MM:SS format. and then losing track of this open loop...

I think that solving this in full generality is kinda tricky, but would have an elegant (in terms of the implementation) solution - full AND & OR with arbitrary nesting. tho, I think the elegance there would be confusing in exactly the unfriendly-to-beginners way you want to avoid. also it probably requires a significant rework of some internal structures...

solving it in a less-fully-general way seems doomed to encounter limitations of not handling edge cases, which makes me not so excited about it - seems better to just have a secondary script, like I now have, to fill in gaps.

so I guess that makes me think this ticket might stall out.