From 9d19ecd3cf52806baf8e8d523cd0674bea035917 Mon Sep 17 00:00:00 2001 From: Anton Parkhomenko Date: Sun, 4 Jul 2021 14:55:09 +0300 Subject: [PATCH 1/6] Allow Agenda.tags to list TODOs only --- lua/orgmode/agenda/init.lua | 15 +++++++++++--- lua/orgmode/init.lua | 8 ++++++-- lua/orgmode/parser/root.lua | 39 +++++++++++++++++++++++++++++-------- 3 files changed, 49 insertions(+), 13 deletions(-) diff --git a/lua/orgmode/agenda/init.lua b/lua/orgmode/agenda/init.lua index 0c01f1f44..59e5761cc 100644 --- a/lua/orgmode/agenda/init.lua +++ b/lua/orgmode/agenda/init.lua @@ -306,17 +306,26 @@ function Agenda:search(clear_search) end -- TODO: Add PROP/TODO Query -function Agenda:tags(clear_search) +function Agenda:tags(clear_search, tags, todo_only) if clear_search then self.last_search = '' end - local tags = vim.fn.input('Match: ', self.last_search, 'customlist,v:lua.orgmode.autocomplete_agenda_filter_tags') + + if not tags then + tags = vim.fn.input('Match: ', self.last_search, 'customlist,v:lua.orgmode.autocomplete_agenda_filter_tags') + end if vim.trim(tags) == '' then return utils.echo_warning('Invalid tag.') end local headlines = {} for _, orgfile in ipairs(Files.all()) do - for _, headline in ipairs(orgfile:get_headlines_with_tags(tags)) do + local headlines_filtered + if todo_only then + headlines_filtered = orgfile:get_unfinished_todo_entries_with_tags(tags) + else + headlines_filtered = orgfile:get_headlines_with_tags(tags) + end + for _, headline in ipairs(headlines_filtered) do table.insert(headlines, headline) end end diff --git a/lua/orgmode/init.lua b/lua/orgmode/init.lua index 3bfd6db05..f48b867ee 100644 --- a/lua/orgmode/init.lua +++ b/lua/orgmode/init.lua @@ -62,14 +62,18 @@ local function reload(file) end ---@param opts table -local function action(cmd, opts) +local function action(cmd, opts, multiple) local parts = vim.split(cmd, '.', true) if not instance or #parts < 2 then return end instance:init() if instance[parts[1]] and instance[parts[1]][parts[2]] then local item = instance[parts[1]] local method = item[parts[2]] - return method(item, opts) + if multiple then + return method(item, unpack(opts)) + else + return method(item, opts) + end end end diff --git a/lua/orgmode/parser/root.lua b/lua/orgmode/parser/root.lua index 8319e8449..0ae870639 100644 --- a/lua/orgmode/parser/root.lua +++ b/lua/orgmode/parser/root.lua @@ -177,6 +177,26 @@ function Root:get_opened_unfinished_headlines() end, self.items) end +function Root:get_unfinished_todo_entries_with_tags(tags) + if self.is_archive_file then return {} end + local taglist = Root:_parse_taglist(tags) + + return vim.tbl_filter(function(item) + if item.type ~= Types.HEADLINE or item:is_archived() or not item:is_todo() or not item.tags or #item.tags == 0 then + return false + end + + local has_tag = true + for _, tag in ipairs(taglist) do + if not vim.tbl_contains(item.tags, tag) then + has_tag = false + break + end + end + return has_tag + end, self.items) +end + function Root:get_unfinished_todo_entries() if self.is_archive_file then return {} end @@ -211,14 +231,7 @@ end function Root:get_headlines_with_tags(tags) if self.is_archive_file then return {} end - - local taglist = vim.tbl_map(function(tag) - return vim.trim(tag) - end , vim.split(tags, '+', true)) - - taglist = vim.tbl_filter(function(t) - return t ~= '' - end, taglist) + local taglist = Root:_parse_taglist(tags) if #taglist == 0 then return {} end @@ -286,4 +299,14 @@ function Root:get_archive_file_location() return Config:parse_archive_location(self.file) end +function Root:_parse_taglist(tags) + local taglist = vim.tbl_map(function(tag) + return vim.trim(tag) + end , vim.split(tags, '+', true)) + + return vim.tbl_filter(function(t) + return t ~= '' + end, taglist) +end + return Root From f0c280b05bddffd7272aab51b3ffe14decd02ff2 Mon Sep 17 00:00:00 2001 From: Anton Parkhomenko Date: Sun, 4 Jul 2021 15:13:04 +0300 Subject: [PATCH 2/6] Simplify argument passing --- lua/orgmode/agenda/init.lua | 12 ++++++++---- lua/orgmode/init.lua | 8 ++------ 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/lua/orgmode/agenda/init.lua b/lua/orgmode/agenda/init.lua index 59e5761cc..ba3cab6f7 100644 --- a/lua/orgmode/agenda/init.lua +++ b/lua/orgmode/agenda/init.lua @@ -306,13 +306,17 @@ function Agenda:search(clear_search) end -- TODO: Add PROP/TODO Query -function Agenda:tags(clear_search, tags, todo_only) - if clear_search then +function Agenda:tags(options) + local tags + options = options or {} + if options.clear_search then self.last_search = '' end - if not tags then + if not options.tags then tags = vim.fn.input('Match: ', self.last_search, 'customlist,v:lua.orgmode.autocomplete_agenda_filter_tags') + else + tags = options.tags end if vim.trim(tags) == '' then return utils.echo_warning('Invalid tag.') @@ -320,7 +324,7 @@ function Agenda:tags(clear_search, tags, todo_only) local headlines = {} for _, orgfile in ipairs(Files.all()) do local headlines_filtered - if todo_only then + if options.todo_only then headlines_filtered = orgfile:get_unfinished_todo_entries_with_tags(tags) else headlines_filtered = orgfile:get_headlines_with_tags(tags) diff --git a/lua/orgmode/init.lua b/lua/orgmode/init.lua index f48b867ee..3bfd6db05 100644 --- a/lua/orgmode/init.lua +++ b/lua/orgmode/init.lua @@ -62,18 +62,14 @@ local function reload(file) end ---@param opts table -local function action(cmd, opts, multiple) +local function action(cmd, opts) local parts = vim.split(cmd, '.', true) if not instance or #parts < 2 then return end instance:init() if instance[parts[1]] and instance[parts[1]][parts[2]] then local item = instance[parts[1]] local method = item[parts[2]] - if multiple then - return method(item, unpack(opts)) - else - return method(item, opts) - end + return method(item, opts) end end From 9a99e091eaf3f853c180266d37c3cfc5f3d33273 Mon Sep 17 00:00:00 2001 From: Anton Parkhomenko Date: Sun, 4 Jul 2021 15:35:15 +0300 Subject: [PATCH 3/6] Rename options to opts for consistency --- lua/orgmode/agenda/init.lua | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/lua/orgmode/agenda/init.lua b/lua/orgmode/agenda/init.lua index ba3cab6f7..4c31dd50f 100644 --- a/lua/orgmode/agenda/init.lua +++ b/lua/orgmode/agenda/init.lua @@ -306,17 +306,17 @@ function Agenda:search(clear_search) end -- TODO: Add PROP/TODO Query -function Agenda:tags(options) +function Agenda:tags(opts) local tags - options = options or {} - if options.clear_search then + opts = opts or {} + if opts.clear_search then self.last_search = '' end - if not options.tags then + if not opts.tags then tags = vim.fn.input('Match: ', self.last_search, 'customlist,v:lua.orgmode.autocomplete_agenda_filter_tags') else - tags = options.tags + tags = opts.tags end if vim.trim(tags) == '' then return utils.echo_warning('Invalid tag.') @@ -324,7 +324,7 @@ function Agenda:tags(options) local headlines = {} for _, orgfile in ipairs(Files.all()) do local headlines_filtered - if options.todo_only then + if opts.todo_only then headlines_filtered = orgfile:get_unfinished_todo_entries_with_tags(tags) else headlines_filtered = orgfile:get_headlines_with_tags(tags) From dcac7b4fafc7465b505f98502c4d7496028ed33c Mon Sep 17 00:00:00 2001 From: Anton Parkhomenko Date: Sun, 4 Jul 2021 18:28:59 +0300 Subject: [PATCH 4/6] Add M option --- lua/orgmode/agenda/init.lua | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lua/orgmode/agenda/init.lua b/lua/orgmode/agenda/init.lua index 4c31dd50f..b4e076b16 100644 --- a/lua/orgmode/agenda/init.lua +++ b/lua/orgmode/agenda/init.lua @@ -389,7 +389,8 @@ function Agenda:prompt() { label = '', separator = '-', length = 34 }, { label = 'Agenda for current week or day', key = 'a', action = function() return self:agenda() end }, { label = 'List of all TODO entries', key = 't', action = function() return self:todos() end }, - { label = 'Match a TAGS query', key = 'm', action = function() return self:tags(true) end }, + { label = 'Match a TAGS query', key = 'm', action = function() return self:tags({clear_search = true, tags = nil, todo_only = false}) end }, + { label = 'Like M, but only TODO entries', key = 'M', action = function() return self:tags({clear_search = true, tags = nil, todo_only = true}) end }, { label = 'Search for keywords', key = 's', action = function() return self:search(true) end }, { label = 'Quit', key = 'q' }, { label = '', separator = ' ', length = 1 }, From 3cd0b963a2af4b9818c26b9fa7a6c2357a9a3ac0 Mon Sep 17 00:00:00 2001 From: Anton Parkhomenko Date: Mon, 5 Jul 2021 06:28:06 +0300 Subject: [PATCH 5/6] Address feedback --- lua/orgmode/agenda/init.lua | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/lua/orgmode/agenda/init.lua b/lua/orgmode/agenda/init.lua index b4e076b16..f93382d9c 100644 --- a/lua/orgmode/agenda/init.lua +++ b/lua/orgmode/agenda/init.lua @@ -307,16 +307,15 @@ end -- TODO: Add PROP/TODO Query function Agenda:tags(opts) - local tags opts = opts or {} + local tags = opts.tags + if opts.clear_search then self.last_search = '' end - if not opts.tags then + if not tags then tags = vim.fn.input('Match: ', self.last_search, 'customlist,v:lua.orgmode.autocomplete_agenda_filter_tags') - else - tags = opts.tags end if vim.trim(tags) == '' then return utils.echo_warning('Invalid tag.') From e35966093bdbbc4758f16e69fb130f67d58af8ad Mon Sep 17 00:00:00 2001 From: Anton Parkhomenko Date: Mon, 5 Jul 2021 09:28:04 +0300 Subject: [PATCH 6/6] Fix message --- lua/orgmode/agenda/init.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lua/orgmode/agenda/init.lua b/lua/orgmode/agenda/init.lua index f93382d9c..c09d36b9d 100644 --- a/lua/orgmode/agenda/init.lua +++ b/lua/orgmode/agenda/init.lua @@ -389,7 +389,7 @@ function Agenda:prompt() { label = 'Agenda for current week or day', key = 'a', action = function() return self:agenda() end }, { label = 'List of all TODO entries', key = 't', action = function() return self:todos() end }, { label = 'Match a TAGS query', key = 'm', action = function() return self:tags({clear_search = true, tags = nil, todo_only = false}) end }, - { label = 'Like M, but only TODO entries', key = 'M', action = function() return self:tags({clear_search = true, tags = nil, todo_only = true}) end }, + { label = 'Like m, but only TODO entries', key = 'M', action = function() return self:tags({clear_search = true, tags = nil, todo_only = true}) end }, { label = 'Search for keywords', key = 's', action = function() return self:search(true) end }, { label = 'Quit', key = 'q' }, { label = '', separator = ' ', length = 1 },