Indicate Timer is Running
It would be nice to have an something in the mode line to indicate the timer is running.
At least would be nice to indicate this in the project lest via an asterisk or something.
Yeah, I've been thinking that a mode line indicator would be nice, but it's difficult to provide much useful information without taking up too much space. Around here even the short project ids are too long for my taste for the mode line.
Showing the tracked time for the currently running timer would be nice, especially when working on some timeboxed issue. Could show the project, task and description in the tooltip when mousing over.
But I haven't gotten round to figuring out how to do this. I'm using doom-modeline myself, so I'd have to start doing it for vanilla emacs before figuring out how to get it in doom-modeline too.
In the project list? It should indicate the current timer with a > in the reaper buffer?
In the project list? It should indicate the current timer with a > in the reaper buffer?
I do not see this.
I do not see this.
Now that's interesting. I've had an intermittent bug where I would loose the indicator, and pressing g wouldn't make it show. But only at random times, and changing entry would make the problem go away, making it rather difficult to debug.
OK, just noticed that if I refresh the buffer (g) when point is after the currently running timer, the -> doesn't get inserted, but if it's on or before, it does. Which makes it obvious what the problem is...
Fixed in d073fa8d00411af58fced861b7236aaa23b0692d. Is that enough indication for you @sshaw?
I'd still like a mode line indicator at some point, though.
Funny you mention that! I've just recently added tab-bar-mode into my config along with a segment for displaying current Harvest tasks with it here
Which looks like:

There will be a cleaner way to "force update" the timer statuses, as well as scope to customize the format. I can attempt to come up with a more PR-able implementation "at some point soon" ™️?
@elken that would be awesome...
I'm using doom-mode-line myself and must admit that I'm pretty fuzzy on the whole mode-line configuration thing, both in doom-mode-line and vanilla emacs.
Everyone has blind spots :D Regular emacs is basically just a string that you append things to, doom-modeline is mostly the same just with fancier features like clickable buttons and tooltips.
I'll see what I can do in the near future :D
Just a (late) update, I've finally gotten around to this, and I've trimmed my setup quite a bit now.
I'm still planning to either PR a clean version here or making an extension package, which would you prefer @xendk ?
@elken Definitely something like that I had in mind, but isn't using async, which I gather starts an entirely new Emacs process, a bit heavy-handed? I guess the (reaper-refresh-entries) ensures that the modeline will catch changes outside Emacs, but personally I can live with using cached data. I would just let the existing timer in reaper deal with both updating the buffer and the modeline.
I guess we could make the requests to harvest asynchronous by starting a process running curl, but it would require some refactoring.
Don't know if you've noticed, but I've made a few changes the last couple of week, don't think anything directly impacts your work though, apart from (reaper-entry-hours) being useful. But I can see that a (reaper-get-running-timer-entry) could be handy.
a bit heavy-handed?
Not so much, it's a very minute impact and has the advantage of not blocking while ensuring that it's constantly up-to-date.
I would just let the existing timer in reaper deal with both updating the buffer and the modeline.
My previous implementation wouldn't properly handle the harvest timer changing outside of emacs, and every minute it would freeze emacs. Not good.
I guess we could make the requests to harvest asynchronous by starting a process running curl, but it would require some refactoring.
Using async-start is fine, but making it async with curl in the separate process would also be good.
Don't know if you've noticed, but I've made a few changes the last couple of week
I have not! I'll skim through the commits when I have some time
But I can see that a (reaper-get-running-timer-entry) could be handy.
You mean duration? Yes, I was surprised to see it wasn't included :stuck_out_tongue:
My previous implementation wouldn't properly handle the harvest timer changing outside of emacs, and every minute it would freeze emacs. Not good.
But how many users is changing the timers outside of Emacs? The point of reaper is to avoid having to change out of Emacs to deal with timetracking, so I kind of expect users to use it exclusively. I guess the freeze was because you called (reaper-refresh-entries), which freezes Emacs for the duration of the request. Another detail is that the reaper buffer in the local Emacs will get out of sync with the modeline, as it only refreshes when asked.
I guess the freeze was because you called (reaper-refresh-entries), which freezes Emacs for the duration of the request
Originally I had advice around reaper--update-timer to nil timeemtries to force a fresh pull. Personally I think this should be async, any network request should be really. But I can appreciate it might be a large refactor, so I'll have a think on how to approch it :)
Think our Harvest use is different. I find the initial pull and the built-in pull in start/stop/etc. quite sufficient most days. I might do a manual pull when I know I've started a timer while away from the computer, but I don't mind that.
As I leave Emacs running for days, I'd rather avoid having it make network requests in the background when no timer is running. It might not be considered much by today's standards, but I like showing a bit of restraint with resources.
Would be nice to run all network requests async, but getting the entries would be a good start (fetching projects and tasks have to be synchronous as it's invoked by functions that need them now). But there seem to be no need for curl, as we have (url-retrieve) which is asynchronous. So it's figuring that out and make reaper have a "loading" as default.
Ah, to few hours in a day....
Think our Harvest use is different
Slightly I think, most of my start/stops come from JIRA tickets until I sort my org-jira <=> reaper workflow out so for now it's just a modeline component and a useful reminder in my editor :P
I will try and make a solution that satisfies everyone though, rather than a separate package.
Slightly I think, most of my start/stops come from JIRA tickets until I sort my org-jira <=> reaper workflow out so for now it's just a modeline component and a useful reminder in my editor :P
So you're tracking on Jira issues too. Do I remember correctly that the integration basically just preselects a project and add the issue ID to the notes?
We're doing it a bit differently. Developers just copy the issue ID to the notes, and we have a tool that runs through everybody's entries that creates mirror worklog entries in Jira, and adds the issue title to the Harvest entry (to make Harvest reports more readable).
I will try and make a solution that satisfies everyone though, rather than a separate package.
OK, a couple of pointers: Rather than eval'ing from the modeline, create a mode-line-reaper variable, defaulted to nothing (probably want to autoload that), and update it from reaper--update-timer. Means we'll only be running a timer when reaper is actively being used.
I'll look into fetching timeentries asynchronously. For starters it'll be handy being able open the reaper buffer and swap to another window while fetching entries. And you should be able to start your own timer that just calls reaper-refresh without blocking Emacs, if you want to keep an eye on the outside world. And when I've figured out asynchronies requests, I might as well preload the project and task list when opening reaper, so that doesn't slow down the first entry creation.
@elken I've implemented async fetching of time entries in https://github.com/xendk/reaper/tree/async . Give it a spin.
Fetching project/tasks async will require a bit more, as it still need to be synchronous when triggered from reaper-start-new-timer and other functions that need the result immediately.
Do I remember correctly that the integration basically just preselects a project and add the issue ID to the notes?
Basically, there's some more fields I have to send through the API but it's basically the same.
Do I remember correctly that the integration basically just preselects a project and add the issue ID to the notes?
Nice! I'll have a look when I can.
(time makes fools of us all)
I've finally gotten around to refactoring my work emacs setup a bit to use the recently merged async stuff. Will try and pop back in a day or so to update on the performance of it :D
EDIT: Config link