This repository has been archived on 2022-05-13. You can view files and clone it, but cannot push or open issues or pull requests.
chronometrist/TODO.org

229 lines
16 KiB
Org Mode
Raw Normal View History

#+TITLE: The Chronometrist TODO List
#+AUTHOR: contrapunctus
2019-08-09 02:05:47 +00:00
1. [-] Move time operations into a chronometrist-time file
2. -report - highlight the current day
2019-08-04 19:20:13 +00:00
2019-10-25 07:45:55 +00:00
* v0.3.0 [100%]
1. [X] +Release or+ bundle plist-pp.el
2. [X] -report - error opening when clocked in
2019-08-09 18:06:48 +00:00
* Chronometrist
1. implement point restore for =chronometrist=/=chronometrist-report=/=chronometrist-statistics= in a kill-buffer-hook, so it works whenever the buffer is killed, not just when we call the command.
** Bugs [57%]
1. [X] fix -current-task to return correct results if the last one crosses a midnight
2. [ ] Clocking-in/out doesn't result in updated display, sometimes (2019-09-12)
2019-11-02 15:57:55 +00:00
3. [ ] Sorting by clicking the columns makes non-tabular data disappear
* Advise ~tabulated-list-col-sort~ to run either ~chronometrist-refresh~ or the relevant ~-print-non-tabular~ afterwards
4. [X] kv-accept with no key values should not modify file
5. [ ] kv-add and tags-add should not remove other keys from last sexp
6. [X] kv-accept with no key values -> Chronometrist buffer not updated
* timer will only refresh when clocked in...
7. [X] regression - no value history
2020-03-23 14:08:15 +00:00
8. [ ] Possible to add the same key-value twice
* Clock in, clock out, add key-value and accept, delete :stop time and save, clock out again, accept the already-inserted key-value - duplicate!
2020-07-23 22:08:17 +00:00
** Features [16%]
1. [ ] Create chronometrist-unused-projects-list + chronometrist-projects-list.
2. [ ] New commands
1. [ ] *Kill/discard* (bind to 'k') - which will delete the interval currently being recorded.
- Most conservative option - it will only operate on the project at point, and will only kill for a clocked-in project.
- Somewhat less conservative option - it will operate on the currently clocked-in project, no matter where point is.
- It _should_ ask for confirmation.
- Alternatively, or as a complement - an *undo command*, which will undo your last action (clock in or clock out).
- Undo and redo seem like the best bets.
3. [ ] Hook enhancement - can we supply the whole plist (including tags and key-values) to the task-start hooks, so users can have even smarter hook functions?
* That would mean ensuring that -kv-read runs before other hooks.
* Actually, it should be trivial to access the last expression in the file, so maybe this is unnecessary.
2019-09-20 05:56:21 +00:00
4. [ ] key-values and tags should work regardless of what hook they're called from, to give users the option to modify behaviour (does clock in start after you've finished adding details, or before?)
5. [ ] Expandable items - show intervals for task today
* [ ] Switch between intervals and tag-combination breakdown
6. [X] Revisit 'no reason' commands - maybe we should ask for tags and key-values with the regular commands, and skip them with the 'no reason' variants?
2019-11-29 04:42:40 +00:00
*** Key-values [66%]
2019-09-20 05:56:21 +00:00
1. [X] bug - value-history appears in chronological rather than reverse chronological order
2. [X] generate history hash table from chronometrist-file.
* [X] generate value history hash table from chronometrist-file
* [X] change "press X to quit" in prompt to suggest keys for ido, helm, and ivy
2019-11-29 04:42:40 +00:00
3. [ ] create text button to add key-values to last entry (whether clocked in or out)
4. [X] insert value as string if it contains spaces and isn't a list
2019-09-20 05:56:21 +00:00
* Sometimes you want single-word values to be converted to a string, too. Maybe check for capital letters too?
* Preserve type in history?
* Might create inconsistency in prompts? We don't want to expect Lisp knowledge from users.
* Ask user to define types for keys, and handle the syntax for them behind the scenes?
2019-11-29 04:42:40 +00:00
5. [ ] when reading values, add quit keybinding (consistent with output of ~chronometrist-kv-completion-quit-key~) by passing MAP to ~read-from-minibuffer~
6. [X] bug - missing values in history
7. [X] enh - remove key-values from suggestions which have already been added
8. [ ] enh - create custom variable to auto-insert key-values used in previous task of same :name in the key-value buffer.
9. [X] bug - incorrect indenting in -kv-buffer
10. [X] bug - I think -append-to-last-expr is eating key-values
2019-09-20 05:56:21 +00:00
* to reproduce - clock-in, add tags, add key-values, clock-out, keep tags - kv-add buffer has (), whereas it should have the earlier key-values.
2019-11-29 04:42:40 +00:00
11. bug - key-values from clock-in expression not displayed, shows () instead
2019-09-20 05:56:21 +00:00
* cause - if -kv-add is run after chronometrist-out, ~chronometrist-current-task~ will return nil
2019-11-29 04:42:40 +00:00
12. [ ] observe interaction of -kv-add with next function in hook which modifies window configuration
* code which deletes the window, or switches to a new buffer, interferes with the key-value addition flow
2019-09-21 05:20:13 +00:00
* [ ] add a kv-finished-hook? (run after kv-accept/reject)
2019-11-29 04:42:40 +00:00
13. how do we handle a blank string as a plist value?
2019-09-20 05:56:21 +00:00
* some way to require the user to enter a non-empty value (e.g. like the 'require-match' argument to completing-read, except read-from-minibuffer doesn't have that...)
* discard last-entered key?
2019-11-29 04:42:40 +00:00
14. +optimize - going through key (?) and value histories (M-p/M-n) takes a while. Is this because we're using lists?+
2019-11-02 15:57:55 +00:00
* It doesn't, it's the delay from the hash table update from the fs watch
2019-11-29 04:42:40 +00:00
15. [X] bug - tag history starts at the beginning (wtf?), value history is empty (wtf?)
2019-11-02 15:57:55 +00:00
* Does not occur on master, only on dev
* Does not occur if you disable lexical binding (introduced in 4e89836)
**** Values
What forms can they take?
1. Integers, floating point numbers - easy to identify via regexp
2. If it starts and ends with "(" and ")" or "[" and "]", it's a list or a vector
3. otherwise - string
Observations
* This means you can't enter symbols via prompt. Can be added if the demand is there...
* This also means you can't have multiple atom values for a keyword...but that's irrelevant, because plists can't have multiple values anyway. :)
*** Tags [100%]
2019-09-20 05:56:21 +00:00
1. [X] generate history from chronometrist-file
* [X] narrow it down to the :name
2. [X] write tags to last expression
3. [X] show task name in prompt
4. [X] bug - tags being added twice
** Code [28%]
1. [ ] Write tests (in buttercup)
2. refactor repetitive calls to (format "%04d-%02d-%02d" (elt seq a) (elt seq b) (elt seq c))
3. See if it is possible to store buttons in a variable, so *-print-non-tabular functions can be made shorter and less imperative. (see ~make-text-button~)
4. Merge all event-querying functions so that they always operate on an entire hash table (so no 'day' variants),
5. [ ] Use ~substitute-command-keys~ instead of ~chronometrist-format-keybinds~
6. [ ] recreate -events-clean, remove splitting code from -events-populate
* How should we deal with the active event?
* Earlier, we would add a closing entry and update that on a timer.
7. [ ] Make docstrings consistent - describe inputs and then the return value, in that order.
8. [ ] ~chronometrist-seconds->alert-string~ can probably be replaced by ~org-duration-from-minutes~ - read the format for FMT
9. [X] Decouple storage-related code from rest of the program.
10. [X] See if using iteration constructs (especially ~loop~) can lead to nicer code than nested maps
2019-11-29 04:42:40 +00:00
+1. use variables instead of hardcoded numbers to determine spacing+
* Don't see the benefit
+6. Timeclock already _has_ hooks! :| Why do we re-implement them?+
2019-08-30 17:09:30 +00:00
- I don't know of a way to know the project being clocked into using timeclock hooks.
- With v0.2.0 Chronometrist also has a before-project-stop-functions, which runs before the project is stopped, and can control whether the project actually is stopped.
** Maybe
1. Add a new kind of plist - =(:name "NAME" :time "TIME" ...)=
To record events for which the time interval is not relevant. These won't be shown in =chronometrist= - perhaps in a different buffer.
* Optimization
2020-06-24 21:19:48 +00:00
** Cache
+ Lessons from the parsimonious-reading branch - iterating =read= over the whole file is fast; splitting the events is not.
+ Things we need to read the whole file for - task list, tag/key/value history.
+ Fill =chronometrist-events= only as much as the buffer needing split events requires. e.g. for =chronometrist=, just a day; for =chronometrist-report=, a week; etc.
+ Anything requiring split events will first look in =chronometrist-events=, and if not found, will read from the file and update =chronometrist-events=.
+ When the file changes, use the file byte length and hash strategy described below to know whether to keep the cache.
+ Save cache to a file, so that event splitting is avoided by reading from that.
*** Thoughts
+ =chronometrist-key-value-cache= would basically be the entire file, if =chronometrist-history-suggestion-limit= is nil.
+ history generation for tags/keys/values - which involve the most parsing - doesn't actually need the events to be split at midnights. Why not make that a keyword argument to =chronometrist-sexp-read=, so it's faster for that?
** Ideas to make -refresh-file faster
1. Support multiple files, so we read and process lesser data when one of them changes.
2. Make file writing async
3. Don't refresh from file when clocking in.
4. Only write to the file when Emacs is idle or being killed, and store data in memory (in the events hash table) in the meantime
5. What if commands both write to the file /and/ add to the hash table, so we don't have to re-read the file and re-populate the table for commands? The expensive reading+parsing could be avoided for commands, and only take place for the user changing the file.
* [ ] jonasw - store length and hash of previous file, see if the new file has the same hash until old-length bytes.
* Rather than storing and hashing the full length, we could do it until (before) the last s-expression (or last N s-expressions?). That way, we know if the last expression (or last N expressions) have changed.
* Or even the first expression of the current date. That way, we just re-read the events for today. Because chronometrist-events uses dates as keys, it's easy to work on the basis of dates.
6. [ ] Don't generate tag/keyword/value history from the entire log, just from the last N days (where N is user-customizable).
7. [ ] Just why are we reading the whole file? ~chronometrist~ should not read more than a day; ~chronometrist-report~ should not read more than a week at a time, and so on. Make a branch which works on this logic, see if it is faster.
2019-09-18 06:13:45 +00:00
* chronometrist-report
** Features
1. [ ] Expandable items - show tag-combination-based breakdown
2019-09-18 06:13:45 +00:00
** Migration [100%]
1. [X] next/previous weeks
2019-11-29 04:42:40 +00:00
2020-07-21 08:51:45 +00:00
* Certain [0%]
** Bugs [0%]
1. [ ] With tags and key-value query functions in before-out-functions, clock in Task A -> clock in Task B -> prompted for tags and key values for Task A, add some -> they get added to Task B 😱
2. [ ] I clocked into a task -
#+BEGIN_SRC
(:name "Arrangement/new edition"
:tags (new edition)
:start "2020-08-17T00:33:24+0530")
#+END_SRC
I added some key values to it. What it should have looked like -
#+BEGIN_SRC
(:name "Arrangement/new edition"
:tags (new edition)
:composer "Schubert, Franz"
:song "Die schöne Müllerin"
:start "2020-08-17T00:33:24+0530"
:stop "2020-08-17T01:22:40+0530")
#+END_SRC
What it actually looked like -
#+BEGIN_SRC
(:name "Arrangement/new edition"
:tags (new edition)
:composer "Schubert, Franz"
:song "Die schöne Müllerin"
:start "2020-08-17T00:33:24+0530"
...)
#+END_SRC
And of course, that results in an error trying to process it.
** chronometrist [0%]
1. [ ] Add =:stop= time when we call =chronometrist-kv-accept=, not when we quit the key-value prompt.
2. [ ] Implement undo/redo by running undo-tree commands on chronometrist.sexp
* [ ] Possibly show what changes would be made, and prompt the user to confirm it.
3. [ ] *Convert* current interval - change the =:name= of the currently clocked-in interval. Tags and key-values may be re-queried. Clock-in hook functions will be run again with the new task as the argument.
4. [ ] *Rename* a project (updating all records)
5. [ ] *Delete* a project (erasing all records)
6. [ ] *Hide* a project (don't show it in any Chronometrist-* buffer, effectively deleting it non-destructively)
7. [ ] *Reset* current interval - update the =:start= time to the current time.
** Code quality [0%]
2020-08-11 19:37:00 +00:00
1. [ ] Remove duplication between =chronometrist-toggle-task= and =chronometrist-toggle-task-button=
2. [ ] Make functions more test-friendly. Quite a few can get away with returning values instead of writing to a file - this will make it easier to test them. Other functions can handle the file operations for them.
3. [ ] Rewrite using cl-loop
2020-07-21 08:51:45 +00:00
1. [ ] chronometrist-statistics-entries-internal
2. [ ] chronometrist-statistics-count-active-days
2020-08-11 19:37:00 +00:00
4. [ ] Write integration tests using ecukes.
2020-07-21 08:51:45 +00:00
1. Some feature definitions already exist in features/, write step definitions for them.
2020-08-11 19:37:00 +00:00
2020-07-20 02:13:36 +00:00
** Documentation [0%]
1. [ ] Move usage and customization sections to manual.org
(The user may not see the README, if they are installing from MELPA.)
1. [ ] convert README to Org
2. [ ] transclude these sections from the manual to the readme
2. [ ] Make Texinfo documentation
2020-08-11 19:42:14 +00:00
+ [ ] setup auto-export of Org to texinfo - git pre-commit hook?
2020-07-20 02:13:36 +00:00
3. [ ] Link identifiers in manual.org to the source.
2020-08-11 19:42:14 +00:00
* [ ] For HTML export, link to GitHub using line number anchors.
* [ ] Try to make describe-function/helpful-at-point work with Org ~inline~ =code= syntax. Then we won't need to make links.
* Incidentally, a link like =[[elisp:(describe-function 'file-notify-add-watch)][file-notify-add-watch]]=...
1. if opened from an Org buffer, shows the return value in the echo area, which is ugly
2. is exported to Info as
: file-notify-add-watch ((describe-function 'file-notify-add-watch))
...yuck :\
* Currently using file: links with text search - =[file:../elisp/file.el::defun identifier (]=, =[file:../elisp/file.el::defvar identifier (]=, etc.
2020-08-11 19:42:14 +00:00
4. [ ] Fix heading link to "midnight-spanning events" - jumps to the correct heading in HTML export, but jumps to its own self in Org mode.
5. [ ] Figure out some way to hide package prefixes in identifiers in Org mode (without actually affecting the contents, a la nameless-mode)
2020-07-21 14:02:04 +00:00
** UX [12%]
1. [ ] Don't suggest nil when asking for first project on first run
2. [ ] When starting a project with time of "-" (i.e. not worked on today until now), immediately set time to 0 instead of waiting for the first timer refresh
3. [ ] Mouse commands should work only on buttons.
4. [X] Button actions should accept prefix arguments and behave exactly like their keyboard counterparts.
5. [ ] mouse-3 should clock-out without asking for reason.
6. [ ] Some way to ask for the reason just before starting a project. Even when clocking out, the reason is asked /before/ clocking out, which adds time to the project.
7. [ ] Allow calling chronometrist-in/out from anywhere-within-Emacs (a la timeclock) as well as from the chronometrist buffer.
8. [ ] =chronometrist-timer= - if =chronometrist-file= is being edited (buffer exists and modified), don't refresh - this will (hopefully) prevent Emacs from going crazy with errors in trying to parse malformed data.
2020-08-16 18:37:04 +00:00
* Maybe [0%]
** UX [0%]
1. [ ] Provide a command which tries to auto-configure Chronometrist keys in a way which is consistent with the user's other keymaps.
2020-08-16 18:37:04 +00:00
2. [ ] Do basic checks on values of all customizable variables when they are changed by the user, and provide meaningful errors if they can't be used by the program.
3. [ ] Task-sensitive value suggestions - if you use the key :comment for two different tasks, and don't want the values for :comment in one task being suggested for :comment in another...
* The problem is that sometimes you /do/ want that, and changing it can lead to duplication of user effort.
* Maybe make it a switch, enabled by default.
* ...or a list of keys to exclude from the context-sensitivity?
** chronometrist-goals [%]
2020-07-21 08:51:45 +00:00
1. [ ] Colorize times in Chronometrist buffer
- untouched project with target defined - red
- target ±5 minutes - green
- target*2 and above - red