diff --git a/lua/orgmode/agenda/init.lua b/lua/orgmode/agenda/init.lua index 0c01f1f44..c09d36b9d 100644 --- a/lua/orgmode/agenda/init.lua +++ b/lua/orgmode/agenda/init.lua @@ -306,17 +306,29 @@ function Agenda:search(clear_search) end -- TODO: Add PROP/TODO Query -function Agenda:tags(clear_search) - if clear_search then +function Agenda:tags(opts) + opts = opts or {} + local tags = opts.tags + + if opts.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 opts.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 @@ -376,7 +388,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 }, 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