-
-
Notifications
You must be signed in to change notification settings - Fork 162
Improve order of the todo agenda #842
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Improve order of the todo agenda #842
Conversation
As the order of the org_todo_keywords define the order of the todo in the agenda, a user may want to have a default TODO state different than the first one in the org_todo_keywords list
47ba087
to
8a1acbf
Compare
If you like the implementation I can add the documentation of the new configuration option |
Is this how Emacs does the sorting, or just something that you think would be good to add? IIRC sort is not changed when clocking in/out. |
I've never used Emacs so it's my personal opinion :S , I can also add options to configure the non default behaviours if you want |
Thanks @lyz-code for the effort. I like the attempt to provide a better agenda sorting then the current one. Because this implementation is the personal flavor of @lyz-code, my question to you, @kristijanhusak would be: Would you be open that we provide an option, where the user can define a closure, which does the sorting? Than we provide a default implementation, which mirrors the Emacs behavior and a couple of helper functions accessible from the options, so the user can easily implement their own sorting flavor? |
@seflue since I plan to add custom agenda commands in the following months, for now I'm thinking to attach the sorting function to the |
@kristijanhusak Would you also do that with the Can you elaborate a bit more on your plan of custom agenda commands? I have some requirements to the agenda which made me already thinking of writing my own agenda plugin - but I didn't find the time yet to seriously design something decent. But I would be happy to give feedback on what you have in mind. |
@seflue yes, for both todos and agenda views. I would just attach them to the exported module, and allow monkey patching. This would be a temporary thing. Regarding the agenda commands, I plan to integrate them as similar as possible to what Emacs does. I'm still not 100% sure what it supports since I need to investigate further, but that's the idea. We can add some things on top of it, but it will need to align with the general structure. |
Ok, I attached both to the exported module in ad88620. Now you can do this in your configuration to modify it, until we add the custom agenda commands: local agenda = require('orgmode.agenda.views.agenda')
agenda._sort = function(agenda_items)
table.sort(agenda_items, function(a, b)
-- Sort logic
end)
return agenda_items
end
require('orgmode').setup({})
|
Wow what a new year's present (✿◠‿◠) thank you both @kristijanhusak and @seflue. I've tried doing what you suggested but it doesn't work for me, probably I'm doing something wrong. Maybe the issue is that I use the agenda in the return {
{
"nvim-orgmode/orgmode",
url = "https://github.com/lyz-code/orgmode",
event = "VeryLazy",
keys = {
{
"gt",
function()
vim.notify("Opening today's agenda", vim.log.levels.INFO)
require("orgmode.api.agenda").tags({
query = "+t/-INACTIVE-DONE-REJECTED",
todo_only = true,
})
end,
desc = "Open orgmode agenda for today",
},
...
},
config = function()
local agenda = require("orgmode.agenda.views.agenda")
agenda._sort = function(todos)
table.sort(todos, function(a, b)
-- Tasks marked as clocked_in appear first
if a:is_clocked_in() then
return true
end
if b:is_clocked_in() then
return false
end
-- Then tasks are sorted by their priority
if a:get_priority_sort_value() ~= b:get_priority_sort_value() then
return a:get_priority_sort_value() > b:get_priority_sort_value()
end
-- Then tasks are sorted by their TODO keyword
local a_keyword = a:get_todo()
local b_keyword = b:get_todo()
if (a_keyword and b_keyword) and (a_keyword ~= b_keyword) then
return a:get_todo_sort_value() < b:get_todo_sort_value()
end
-- Then tasks which have a DEADLINE have priority over SCHEDULED over nothing
local a_deadline = a:get_deadline_date()
local a_scheduled = a:get_scheduled_date()
local b_deadline = b:get_deadline_date()
local b_scheduled = b:get_scheduled_date()
-- If both have deadlines, earlier deadline comes first
if a_deadline and b_deadline then
return a_deadline < b_deadline
end
-- If only one has deadline, it comes first
if a_deadline then
return true
end
if b_deadline then
return false
end
-- If both have scheduled dates, earlier date comes first
if a_scheduled and b_scheduled then
return a_scheduled < b_scheduled
end
-- If only one has scheduled date, it comes first
if a_scheduled then
return true
end
if b_scheduled then
return false
end
-- Then tasks are sorted by their category keyword
return a:get_category() < b:get_category()
end)
return todos
end
-- Setup orgmode
require("orgmode").setup({
org_agenda_files = {
...
}
})
}, Also I've noticed that your commit has not added the functionality to sort the todo keywords. I feel it might be a useful thing to have, so for example you can sort DOING and WAITING over TODO in your agendas. Don't you think so? |
@lyz-code with the recent addition of custom commands you can set up custom sorting. Your case can be partially solved with this configuration: org_agenda_sorting_strategy = {
todo = { 'clocked-up', 'todo-state-up', 'priority-down', 'category-keep'}
} Deadline and scheduled sorting is not yet added, but I plan to add it. |
OMG @kristijanhusak it's so beautiful! One question though, is there a way to use these configurations when calling it from the api?
For example, how would I be able to edit the default values when using: {
"gm",
function()
vim.notify("Opening the month's agenda", vim.log.levels.INFO)
require("orgmode.api.agenda").tags({
query = "+m/-INACTIVE-DONE-REJECTED",
todo_only = true,
})
end,
desc = "Open orgmode agenda for month objectives",
}, I'm already used to my short bindings An alternative question would be how could I launch a custom agenda command with a chosen keybindings from the api? thank you so so much for developing this |
Another question (if you want me to open independent issues for each of them tell me please). A side effect I've saw when I implemented the sort by TODO feature is that for example I have: org_todo_keywords = {
"WAITING(w)",
"DOING(d)",
"READY(r)",
"TODO(t)",
"INACTIVE(i)",
"|",
"DONE(e)",
"REJECTED(j)",
"DUPLICATE(u)",
}, Because that's the order I'd like the elements to show up in my agendas, the problem is that as the first element is That's why in this PR I added the |
I added all those options to the agenda api. Regarding your second question, I need to check how that's generally handled in emacs. |
From what I see, emacs also sets the first todo item when converting a checkbox to a heading, which does make sense. From my understanding, you use |
Yep @kristijanhusak that's right, I changed the order of my I've checked that Is there any way to launch a custom command from the api? |
Yes, just pushed it. |
In addition to custom functions for sorting it would be nice to have custom functions for filtering. For example I was thinking of making an agenda view of the headlines that I have clocked in today or to get all headlines that have been done today (either state DONE or state TODO and a LAST_REPEAT>yesterday (btw I tried searching using |
Clock in could be matched only with a custom function one it's added, but for last repeat you can do it. Dates needs to be matched in this format according to spec: |
Hi @kristijanhusak is there anything I can do to help you in the implementation of the default TODO keyword on new created elements? |
@lyz-code I don't plan to add that feature directly, but I added an event to be fired when the heading is toggled, and you can write some custom code to do what you desire. local EventManager = require('orgmode.events')
EventManager.listen(EventManager.event.HeadingToggled, function(event)
---@cast event OrgHeadingToggledEvent
if event.headline then
event.headline:set_todo('PROGRESS')
end
end) This will automatically set headline todo keyword to
|
Thanks for the solution @kristijanhusak , I love that you're adding events, it will help a lot when developing plugins. I've checked that your snippet worked when converting from plain line converted to top level headline or from line to child headline. However when I use Is there any event I can use to handle this case? |
Hi @kristijanhusak do you want me to open a new issue to ask how to handle the case of the previous comment? |
Yes, please open up a separate issue. |
As with all my PRs, I'm really a noob at Lua trying to do my best. I'd appreciate any suggestions to improve the code.
Until it's merged users can use my fork