Skip to content

Commit 1f41121

Browse files
feat(agenda): Add org-agenda-show-future-repeats
Closes #484
1 parent b7bcb90 commit 1f41121

File tree

7 files changed

+61
-2
lines changed

7 files changed

+61
-2
lines changed

docs/configuration.org

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -842,6 +842,19 @@ Show time grid in agenda. See [[#org_agenda_time_grid][org_agenda_time_grid]] fo
842842
Label value for the current time in the agenda time grid.
843843
See [[#org_agenda_time_grid][org_agenda_time_grid]] for time grid configuration or [[#org_agenda_use_time_grid][org_agenda_use_time_grid]] to disable the grid.
844844

845+
*** org_agenda_show_future_repeats
846+
:PROPERTIES:
847+
:CUSTOM_ID: org_agenda_show_future_repeats
848+
:END:
849+
- Type: =boolean | number | 'next'=
850+
- Default: =true=
851+
How many future repeated tasks to show in agenda.
852+
Possible values:
853+
- =true= - Show all future repeats (default)
854+
- =false= - Do not show future repeats
855+
- =number= - Show only given number of future repeats
856+
- ='next'= - Show only the next repeat
857+
845858

846859
*** org_capture_templates
847860
:PROPERTIES:

lua/orgmode/agenda/agenda_item.lua

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,8 @@ function AgendaItem:new(headline_date, headline, date, index)
4040
opts.repeats_on_date = false
4141
opts.is_same_day = headline_date:is_same(date, 'day')
4242
if not opts.is_same_day then
43-
opts.repeats_on_date = headline_date:repeats_on(date)
43+
local repeat_count = config:get_repeat_count()
44+
opts.repeats_on_date = headline_date:repeats_on(date, repeat_count)
4445
opts.is_same_day = opts.repeats_on_date
4546
end
4647
opts.is_in_date_range = headline_date:is_none() and headline_date:is_in_date_range(date)

lua/orgmode/config/_meta.lua

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,7 @@
219219
---@field org_agenda_sorting_strategy? table<'agenda' | 'todo' | 'tags', OrgAgendaSortingStrategy[]> Sorting strategy for the agenda view. See docs for default value
220220
---@field org_agenda_remove_tags? boolean If true, tags will be removed from the all agenda views. Default: false
221221
---@field org_agenda_use_time_grid? boolean If true, Render time grid in agenda as set by org_agenda_time_grid. Default: true
222+
---@field org_agenda_show_future_repeats? boolean | 'next' If true, show all future repeats. If `next`, show only next repeat. If false, do hnot show any repeats. Default: true
222223
---@field org_agenda_time_grid? OrgAgendaTimeGridOpts Agenda time grid configuration. Default: { type = { 'daily', 'today', 'require-timed' }, times = { 800, 1000, 1200, 1400, 1600, 1800, 2000 }, time_separator = '┄┄┄┄┄', time_label = '┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄' }
223224
---@field org_agenda_current_time_string? string String to indicate current time on the time grid. Default: '<- now -----------------------------------------------'
224225
---@field org_priority_highest? string | number Highest priority level. Default: 'A'

lua/orgmode/config/defaults.lua

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ local DefaultConfig = {
4242
},
4343
org_agenda_current_time_string = '<- now -----------------------------------------------',
4444
org_agenda_use_time_grid = true,
45+
org_agenda_show_future_repeats = true,
4546
org_priority_highest = 'A',
4647
org_priority_default = 'B',
4748
org_priority_lowest = 'C',

lua/orgmode/config/init.lua

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -546,6 +546,34 @@ function Config:use_property_inheritance(property_name)
546546
end
547547
end
548548

549+
-- Return repeat count depending on `org_agenda_show_future_repeats` value.
550+
-- If nil, repeat infinitely.
551+
-- @return number|nil
552+
function Config:get_repeat_count()
553+
if self.org_agenda_show_future_repeats == true then
554+
return nil
555+
end
556+
557+
if self.org_agenda_show_future_repeats == false then
558+
return 0
559+
end
560+
561+
if self.org_agenda_show_future_repeats == 'next' then
562+
return 1
563+
end
564+
if type(self.org_agenda_show_future_repeats) == 'number' and self.org_agenda_show_future_repeats >= 0 then
565+
return self.org_agenda_show_future_repeats
566+
end
567+
568+
utils.echo_error({
569+
'Invalid value for `org_agenda_show_future_repeats`',
570+
'Either boolean, positive number or "next" expected',
571+
'Defaulting to "true"',
572+
})
573+
574+
return nil
575+
end
576+
549577
---@param filetype_name string
550578
---@param use_ftmatch? boolean Use vim.filetype.match to detect filetype
551579
function Config:detect_filetype(filetype_name, use_ftmatch)

lua/orgmode/objects/date.lua

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1007,16 +1007,25 @@ function OrgDate:apply_repeater()
10071007
end
10081008

10091009
---@param date OrgDate
1010+
---@param repeat_count number | nil
10101011
---@return boolean
1011-
function OrgDate:repeats_on(date)
1012+
function OrgDate:repeats_on(date, repeat_count)
10121013
local repeater = self:get_repeater()
10131014
if not repeater then
10141015
return false
10151016
end
1017+
if repeat_count == 0 then
1018+
return false
1019+
end
10161020
repeater = repeater:gsub('^%.', ''):gsub('^%+%+', '+')
10171021
local repeat_date = self:start_of('day')
10181022
local date_start = date:start_of('day')
1023+
local counter = 0
10191024
while repeat_date.timestamp < date_start.timestamp do
1025+
if repeat_count and counter >= repeat_count then
1026+
break
1027+
end
1028+
counter = counter + 1
10201029
repeat_date = repeat_date:adjust(repeater)
10211030
end
10221031
return repeat_date:is_same(date, 'day')

tests/plenary/object/date_spec.lua

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -472,6 +472,12 @@ describe('Date object', function()
472472
local friday = Date.from_string('2021-05-14 Fri ++1w')
473473
assert.is.True(friday:repeats_on(friday:add({ week = 1 })))
474474
assert.is.False(friday:repeats_on(friday:add({ day = 5 })))
475+
476+
-- Check it handles the repeat count
477+
local thursday = Date.from_string('2021-05-13 +1d')
478+
assert.are.same('+1d', thursday:get_repeater())
479+
assert.is.True(thursday:repeats_on(thursday:add({ day = 1 }), 1))
480+
assert.is.False(thursday:repeats_on(thursday:add({ day = 2 }), 1))
475481
end)
476482

477483
it('should apply different types of repeaters to the date', function()

0 commit comments

Comments
 (0)