Skip to content

Commit b4e7fbd

Browse files
Add api for agenda
1 parent a61b374 commit b4e7fbd

File tree

5 files changed

+96
-18
lines changed

5 files changed

+96
-18
lines changed

lua/orgmode/agenda/filter.lua

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,8 @@ function AgendaFilter:_matches_include(headline)
127127
end
128128

129129
---@param filter string
130-
function AgendaFilter:parse(filter)
130+
---@param skip_check? boolean do not check if given values exist in the current view
131+
function AgendaFilter:parse(filter, skip_check)
131132
filter = filter or ''
132133
self.value = filter
133134
self.tags = {}
@@ -144,15 +145,18 @@ function AgendaFilter:parse(filter)
144145
end
145146
local val = vim.trim(tag_cat)
146147
if val ~= '' then
147-
if self.available_tags[val] then
148+
if self.available_tags[val] or skip_check then
148149
table.insert(self.tags, { operator = operator, value = val })
149-
elseif self.available_categories[val] then
150+
elseif self.available_categories[val] or skip_check then
150151
table.insert(self.categories, { operator = operator, value = val })
151152
end
152153
end
153154
end
154155
self.term = search_term or ''
155156
self.applying = true
157+
if skip_check then
158+
self.parsed = true
159+
end
156160
end
157161

158162
function AgendaFilter:reset()

lua/orgmode/agenda/init.lua

Lines changed: 13 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -31,46 +31,43 @@ function Agenda:new(opts)
3131
return data
3232
end
3333

34-
function Agenda:agenda()
35-
self:open_window()
36-
local view = AgendaView:new({ filters = self.filters }):build()
34+
function Agenda:agenda(opts)
35+
local view = AgendaView:new(vim.tbl_deep_extend('force', opts or {}, {
36+
filters = self.filters,
37+
})):build()
3738
self.views = { view }
3839
return self:_render()
3940
end
4041

4142
-- TODO: Introduce searching ALL/DONE
4243
function Agenda:todos()
43-
self:open_window()
4444
local view = AgendaTodosView:new({ filters = self.filters }):build()
4545
self.views = { view }
4646
return self:_render()
4747
end
4848

4949
function Agenda:search()
50-
self:open_window()
5150
local view = AgendaSearchView:new({ filters = self.filters }):build()
5251
self.views = { view }
5352
return self:_render()
5453
end
5554

56-
function Agenda:tags()
57-
self:open_window()
58-
local view = AgendaTagsView:new({ filters = self.filters }):build()
55+
function Agenda:tags(opts)
56+
local view = AgendaTagsView:new(vim.tbl_deep_extend('force', opts or {}, {
57+
filters = self.filters,
58+
})):build()
5959
self.views = { view }
6060
return self:_render()
6161
end
6262

6363
function Agenda:tags_todo()
64-
self:open_window()
65-
local view = AgendaTagsView:new({ todo_only = true, filters = self.filters }):build()
66-
self.views = { view }
67-
return self:_render()
64+
return self:tags({ todo_only = true })
6865
end
6966

7067
function Agenda:open_window()
7168
local opened = self:is_opened()
7269
if opened then
73-
return
70+
return opened
7471
end
7572

7673
utils.open_window('orgagenda', math.max(34, config.org_agenda_min_height), config.win_split_mode)
@@ -79,6 +76,7 @@ function Agenda:open_window()
7976
vim.cmd([[setlocal buftype=nofile bufhidden=wipe nobuflisted nolist noswapfile nowrap nospell]])
8077
vim.w.org_window_pos = vim.fn.win_screenpos(0)
8178
config:setup_mappings('agenda')
79+
return vim.fn.win_getid()
8280
end
8381

8482
function Agenda:prompt()
@@ -109,7 +107,7 @@ function Agenda:prompt()
109107
label = 'Like m, but only TODO entries',
110108
key = 'M',
111109
action = function()
112-
return self:tags_todo()
110+
return self:tags({ todo_only = true })
113111
end,
114112
},
115113
{
@@ -135,7 +133,7 @@ function Agenda:_render(skip_rebuild)
135133
end
136134
local opened = self:is_opened()
137135
if not opened then
138-
self:open_window()
136+
opened = self:open_window()
139137
end
140138
vim.cmd(vim.fn.win_id2win(opened) .. 'wincmd w')
141139
if vim.w.org_window_split_mode == 'horizontal' then

lua/orgmode/api/agenda.lua

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
local Date = require('orgmode.objects.date')
2+
local orgmode = require('orgmode')
3+
4+
---@class OrgAgenda
5+
local OrgAgenda = {}
6+
7+
---@alias OrgAgendaFilter string see Filters to apply to the current view. See `:help orgmode-org_agenda_filter` for more information
8+
9+
local function get_date(date, name)
10+
if not date then
11+
return nil
12+
end
13+
if type(date) == Date then
14+
return date
15+
end
16+
if type(date) == 'string' then
17+
return Date.from_string(date)
18+
end
19+
20+
error(('Invalid format for "%s" date in Org Agenda'):format(name))
21+
end
22+
23+
---@class OrgAgendaOptions
24+
---@field filters? OrgAgendaFilter
25+
---@field from? string | Date
26+
---@field span? number | 'day' | 'week' | 'month' | 'year'
27+
28+
---@param options? OrgAgendaOptions
29+
function OrgAgenda.agenda(options)
30+
options = options or {}
31+
local org = orgmode.instance()
32+
org:init()
33+
if options.filters and options.filters ~= '' then
34+
org.agenda.filters:parse(options.filters, true)
35+
end
36+
local from = get_date(options.from, 'from')
37+
org.agenda:agenda({
38+
from = from,
39+
span = options.span,
40+
})
41+
end
42+
43+
---@class OrgAgendaTodosOptions
44+
---@field filters? OrgAgendaFilter
45+
46+
---@param options? OrgAgendaTodosOptions
47+
function OrgAgenda.todos(options)
48+
options = options or {}
49+
local org = orgmode.instance()
50+
org:init()
51+
if options.filters and options.filters ~= '' then
52+
org.agenda.filters:parse(options.filters, true)
53+
end
54+
org.agenda:todos()
55+
end
56+
57+
---@class OrgAgendaTagsOptions
58+
---@field filters? OrgAgendaFilter
59+
---@field todo_only? boolean
60+
61+
---@param options? OrgAgendaTagsOptions
62+
function OrgAgenda.tags(options)
63+
options = options or {}
64+
local org = orgmode.instance()
65+
org:init()
66+
if options.filters and options.filters ~= '' then
67+
org.agenda.filters:parse(options.filters, true)
68+
end
69+
org.agenda:tags({
70+
todo_only = options.todo_only,
71+
})
72+
end
73+
74+
return OrgAgenda

lua/orgmode/parser/files.lua

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -309,6 +309,7 @@ function Files.ensure_loaded()
309309
if Files.loaded then
310310
return true
311311
end
312+
Files.load()
312313
vim.wait(5000, function()
313314
return Files.loaded
314315
end, 5)

scripts/gendoc.lua

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ minidoc.generate(
1010
'lua/orgmode/api/init.lua',
1111
'lua/orgmode/api/file.lua',
1212
'lua/orgmode/api/headline.lua',
13+
'lua/orgmode/api/agenda.lua',
1314
'lua/orgmode/api/position.lua',
1415
},
1516
'doc/orgmode_api.txt'

0 commit comments

Comments
 (0)