Skip to content

Commit 1657948

Browse files
seflueSebastian Flügge
and
Sebastian Flügge
authored
feat(priority): improve priority cycling (#817)
Co-authored-by: Sebastian Flügge <[email protected]>
1 parent 05d6983 commit 1657948

File tree

7 files changed

+163
-32
lines changed

7 files changed

+163
-32
lines changed

lua/orgmode/api/headline.lua

+4-2
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,8 @@ function OrgHeadline:priority_up()
113113
local headline = org.files:get_closest_headline()
114114
local current_priority = headline:get_priority()
115115
local prio_range = config:get_priority_range()
116-
local priority_state = PriorityState:new(current_priority, prio_range)
116+
local start_with_default = config.org_priority_start_cycle_with_default
117+
local priority_state = PriorityState:new(current_priority, prio_range, start_with_default)
117118
return headline:set_priority(priority_state:increase())
118119
end)
119120
end
@@ -125,7 +126,8 @@ function OrgHeadline:priority_down()
125126
local headline = org.files:get_closest_headline()
126127
local current_priority = headline:get_priority()
127128
local prio_range = config:get_priority_range()
128-
local priority_state = PriorityState:new(current_priority, prio_range)
129+
local start_with_default = config.org_priority_start_cycle_with_default
130+
local priority_state = PriorityState:new(current_priority, prio_range, start_with_default)
129131
return headline:set_priority(priority_state:decrease())
130132
end)
131133
end

lua/orgmode/config/defaults.lua

+1
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ local DefaultConfig = {
3232
org_priority_highest = 'A',
3333
org_priority_default = 'B',
3434
org_priority_lowest = 'C',
35+
org_priority_start_cycle_with_default = true,
3536
org_archive_location = '%s_archive::',
3637
org_tags_column = -80,
3738
org_use_tag_inheritance = true,

lua/orgmode/config/init.lua

+5-1
Original file line numberDiff line numberDiff line change
@@ -345,7 +345,11 @@ function Config:get_priorities()
345345
[self.opts.org_priority_highest] = { type = 'highest', hl_group = '@org.priority.highest' },
346346
}
347347

348-
local current_prio = PriorityState:new(self.opts.org_priority_highest, self:get_priority_range())
348+
local current_prio = PriorityState:new(
349+
self.opts.org_priority_highest,
350+
self:get_priority_range(),
351+
self.org_priority_start_cycle_with_default
352+
)
349353
while current_prio:as_num() < current_prio:default_as_num() do
350354
current_prio:decrease()
351355
priorities[current_prio.priority] = { type = 'high', hl_group = '@org.priority.high' }

lua/orgmode/objects/priority_state.lua

+15-7
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,20 @@ local utils = require('orgmode.utils')
44
---@field high_priority string
55
---@field low_priority string
66
---@field priority string
7+
---@field start_with_default boolean
78
---@field default_priority string
89
local PriorityState = {}
910

1011
---@param priority string
1112
---@param prio_range { highest: string, lowest: string, default: string }
12-
function PriorityState:new(priority, prio_range)
13+
function PriorityState:new(priority, prio_range, start_with_default)
1314
local o = {}
1415

1516
o.high_priority = tostring(prio_range.highest)
1617
o.low_priority = tostring(prio_range.lowest)
1718
o.default_priority = tostring(prio_range.default)
1819
o.priority = tostring(priority or o.default_priority)
20+
o.start_with_default = start_with_default
1921

2022
setmetatable(o, self)
2123
self.__index = self
@@ -54,9 +56,12 @@ end
5456

5557
---@return string
5658
function PriorityState:increase()
57-
if self.priority == self.high_priority then
58-
self.priority = ''
59-
elseif self.priority == '' then
59+
if self.priority == '' then
60+
self.priority = self.default_priority
61+
if not self.start_with_default then
62+
self.priority = self:_apply(-1)
63+
end
64+
elseif self.priority == self.high_priority then
6065
self.priority = self.low_priority
6166
else
6267
self.priority = self:_apply(-1)
@@ -67,9 +72,12 @@ end
6772

6873
---@return string
6974
function PriorityState:decrease()
70-
if self.priority == self.low_priority then
71-
self.priority = ''
72-
elseif self.priority == '' then
75+
if self.priority == '' then
76+
self.priority = self.default_priority
77+
if not self.start_with_default then
78+
self.priority = self:_apply(1)
79+
end
80+
elseif self.priority == self.low_priority then
7381
self.priority = self.high_priority
7482
else
7583
self.priority = self:_apply(1)

lua/orgmode/org/mappings.lua

+1-1
Original file line numberDiff line numberDiff line change
@@ -323,7 +323,7 @@ function OrgMappings:set_priority(direction)
323323
local headline = self.files:get_closest_headline()
324324
local current_priority = headline:get_priority()
325325
local prio_range = config:get_priority_range()
326-
local priority_state = PriorityState:new(current_priority, prio_range)
326+
local priority_state = PriorityState:new(current_priority, prio_range, config.org_priority_start_cycle_with_default)
327327

328328
local new_priority = direction
329329
if direction == 'up' then

tests/plenary/api/api_spec.lua

+106-6
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ local api = require('orgmode.api')
33
local Date = require('orgmode.objects.date')
44
local OrgId = require('orgmode.org.id')
55
local orgmode = require('orgmode')
6+
local config = require('orgmode.config')
67

78
describe('Api', function()
89
---@return OrgApiFile
@@ -109,7 +110,7 @@ describe('Api', function()
109110
assert.is.True(vim.fn.getline(5):match(':PERSONAL:HEALTH:$') ~= nil)
110111
end)
111112

112-
it('should toggle priority up and down', function()
113+
it('should cycle upwards through priorities, starting with default', function()
113114
helpers.create_file({
114115
'#TITLE: First file',
115116
'',
@@ -125,24 +126,123 @@ describe('Api', function()
125126
local current_file = cur_file()
126127
local headline = current_file.headlines[2]
127128
assert.are.same('', headline.priority)
128-
headline:priority_up():wait()
129-
assert.are.same('C', cur_file().headlines[2].priority)
130-
assert.is.True(vim.fn.getline(5):match('%[#C%]') ~= nil)
129+
assert.are.same(true, config.org_priority_start_cycle_with_default)
130+
assert.are.same('B', config.org_priority_default)
131+
131132
headline:priority_up():wait()
132133
assert.are.same('B', cur_file().headlines[2].priority)
133134
assert.is.True(vim.fn.getline(5):match('%[#B%]') ~= nil)
134135
headline:priority_up():wait()
135136
assert.are.same('A', cur_file().headlines[2].priority)
136137
assert.is.True(vim.fn.getline(5):match('%[#A%]') ~= nil)
137138
headline:priority_up():wait()
138-
assert.are.same('', cur_file().headlines[2].priority)
139-
assert.is.True(vim.fn.getline(5):match('%[.*%]') == nil)
139+
assert.are.same('C', cur_file().headlines[2].priority)
140+
assert.is.True(vim.fn.getline(5):match('%[#C%]') ~= nil)
141+
headline:priority_up():wait()
142+
assert.are.same('B', cur_file().headlines[2].priority)
143+
assert.is.True(vim.fn.getline(5):match('%[#B%]') ~= nil)
144+
end)
145+
146+
it('should cycle downwards through priorities, starting with default', function()
147+
helpers.create_file({
148+
'#TITLE: First file',
149+
'',
150+
'* TODO Test orgmode :WORK:OFFICE:',
151+
' DEADLINE: <2021-07-21 Wed 22:02>',
152+
'** TODO Second level :NESTEDTAG:',
153+
' DEADLINE: <2021-07-21 Wed 22:02>',
154+
'* DONE Some task',
155+
' DEADLINE: <2021-07-21 Wed 22:02>',
156+
})
157+
158+
assert.is.True(#api.load() > 1)
159+
local current_file = cur_file()
160+
local headline = current_file.headlines[2]
161+
assert.are.same('', headline.priority)
162+
assert.are.same(true, config.org_priority_start_cycle_with_default)
163+
assert.are.same('B', config.org_priority_default)
164+
165+
headline:priority_down():wait()
166+
assert.are.same('B', cur_file().headlines[2].priority)
167+
assert.is.True(vim.fn.getline(5):match('%[#B%]') ~= nil)
168+
headline:priority_down():wait()
169+
assert.are.same('C', cur_file().headlines[2].priority)
170+
assert.is.True(vim.fn.getline(5):match('%[#C%]') ~= nil)
140171
headline:priority_down():wait()
141172
assert.are.same('A', cur_file().headlines[2].priority)
142173
assert.is.True(vim.fn.getline(5):match('%[#A%]') ~= nil)
143174
headline:priority_down():wait()
144175
assert.are.same('B', cur_file().headlines[2].priority)
145176
assert.is.True(vim.fn.getline(5):match('%[#B%]') ~= nil)
177+
end)
178+
179+
it('should enable priority at default + 1', function()
180+
helpers.create_file({
181+
'#TITLE: First file',
182+
'',
183+
'* TODO Test orgmode :WORK:OFFICE:',
184+
' DEADLINE: <2021-07-21 Wed 22:02>',
185+
'** TODO Second level :NESTEDTAG:',
186+
' DEADLINE: <2021-07-21 Wed 22:02>',
187+
'* DONE Some task',
188+
' DEADLINE: <2021-07-21 Wed 22:02>',
189+
})
190+
191+
assert.is.True(#api.load() > 1)
192+
local current_file = cur_file()
193+
local headline = current_file.headlines[2]
194+
assert.are.same('', headline.priority)
195+
assert.are.same('B', config.org_priority_default)
196+
config.org_priority_start_cycle_with_default = false
197+
198+
headline:priority_up():wait()
199+
assert.are.same('A', cur_file().headlines[2].priority)
200+
assert.is.True(vim.fn.getline(5):match('%[#A%]') ~= nil)
201+
end)
202+
203+
it('should enable priority at default + 1', function()
204+
helpers.create_file({
205+
'#TITLE: First file',
206+
'',
207+
'* TODO Test orgmode :WORK:OFFICE:',
208+
' DEADLINE: <2021-07-21 Wed 22:02>',
209+
'** TODO Second level :NESTEDTAG:',
210+
' DEADLINE: <2021-07-21 Wed 22:02>',
211+
'* DONE Some task',
212+
' DEADLINE: <2021-07-21 Wed 22:02>',
213+
})
214+
215+
assert.is.True(#api.load() > 1)
216+
local current_file = cur_file()
217+
local headline = current_file.headlines[2]
218+
assert.are.same('', headline.priority)
219+
assert.are.same('B', config.org_priority_default)
220+
config.org_priority_start_cycle_with_default = false
221+
222+
headline:priority_down():wait()
223+
assert.are.same('C', cur_file().headlines[2].priority)
224+
assert.is.True(vim.fn.getline(5):match('%[#C%]') ~= nil)
225+
end)
226+
227+
it('should set/unset priorities', function()
228+
helpers.create_file({
229+
'#TITLE: First file',
230+
'',
231+
'* TODO Test orgmode :WORK:OFFICE:',
232+
' DEADLINE: <2021-07-21 Wed 22:02>',
233+
'** TODO Second level :NESTEDTAG:',
234+
' DEADLINE: <2021-07-21 Wed 22:02>',
235+
'* DONE Some task',
236+
' DEADLINE: <2021-07-21 Wed 22:02>',
237+
})
238+
239+
assert.is.True(#api.load() > 1)
240+
local current_file = cur_file()
241+
local headline = current_file.headlines[2]
242+
assert.are.same('', headline.priority)
243+
244+
cur_file().headlines[2]:set_priority('B'):wait()
245+
assert.is.True(vim.fn.getline(5):match('%[#B%]') ~= nil)
146246
cur_file().headlines[2]:set_priority('C'):wait()
147247
assert.is.True(vim.fn.getline(5):match('%[#C%]') ~= nil)
148248
cur_file().headlines[2]:set_priority('A'):wait()

tests/plenary/object/priority_state_spec.lua

+31-15
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,11 @@ describe('Priority state', function()
1919
end
2020

2121
local create_priority = function(prio)
22-
return PriorityState:new(prio, config:get_priority_range())
22+
return PriorityState:new(prio, config:get_priority_range(), true)
23+
end
24+
25+
local create_priority_non_default = function(prio)
26+
return PriorityState:new(prio, config:get_priority_range(), false)
2327
end
2428

2529
it('should increase single numeric priority', function()
@@ -48,28 +52,28 @@ describe('Priority state', function()
4852
assert.are.same('C', priority:decrease())
4953
end)
5054

51-
it('should change to empty priority when numeric increased beyond highest', function()
55+
it('should change to lowest priority when numeric increased beyond highest', function()
5256
numeric_config()
5357
local priority = create_priority('1')
54-
assert.are.same('', priority:increase())
58+
assert.are.same('15', priority:increase())
5559
end)
5660

57-
it('should change to empty priority when numeric decreased beyond lowest', function()
61+
it('should change to highest priority when numeric decreased beyond lowest', function()
5862
numeric_config()
5963
local priority = create_priority('15')
60-
assert.are.same('', priority:decrease())
64+
assert.are.same('1', priority:decrease())
6165
end)
6266

63-
it('should change to empty priority when alpha increased beyond highest', function()
67+
it('should change to lowest priority when alpha increased beyond highest', function()
6468
alpha_config()
6569
local priority = create_priority('A')
66-
assert.are.same('', priority:increase())
70+
assert.are.same('D', priority:increase())
6771
end)
6872

69-
it('should change to empty priority when alpha decreased beyond lowest', function()
73+
it('should change to highest priority when alpha decreased beyond lowest', function()
7074
alpha_config()
7175
local priority = create_priority('D')
72-
assert.are.same('', priority:decrease())
76+
assert.are.same('A', priority:decrease())
7377
end)
7478

7579
it('should convert numeric priorities to a string for comparison', function()
@@ -100,25 +104,37 @@ describe('Priority state', function()
100104
alpha_config()
101105
local higher = create_priority('A')
102106
local lower = create_priority('B')
103-
assert.Is.True(higher:get_sort_value() > lower:get_sort_value())
107+
assert.is.True(higher:get_sort_value() > lower:get_sort_value())
104108
end)
105109

106110
it('should compare numeric priorities correctly', function()
107111
numeric_config()
108112
local higher = create_priority(1)
109113
local lower = create_priority(2)
110-
assert.Is.True(higher:get_sort_value() > lower:get_sort_value())
114+
assert.is.True(higher:get_sort_value() > lower:get_sort_value())
111115
end)
112116

113-
it('should change to highest priority if priority increased and currently empty', function()
117+
it('should change to default priority if priority increased and currently empty', function()
114118
alpha_config()
115119
local priority = create_priority('')
116-
assert.are.same('D', priority:increase())
120+
assert.are.same('C', priority:increase())
117121
end)
118122

119-
it('should change to lowest priority if priority decreased and currently empty', function()
123+
it('should change to default priority if priority decreased and currently empty', function()
120124
alpha_config()
121125
local priority = create_priority('')
122-
assert.are.same('A', priority:decrease())
126+
assert.are.same('C', priority:decrease())
127+
end)
128+
129+
it('should change to default + 1 priority if priority increased and currently empty', function()
130+
alpha_config()
131+
local priority = create_priority_non_default('')
132+
assert.are.same('B', priority:increase())
133+
end)
134+
135+
it('should change to default - 1 priority if priority decreased and currently empty', function()
136+
alpha_config()
137+
local priority = create_priority_non_default('')
138+
assert.are.same('D', priority:decrease())
123139
end)
124140
end)

0 commit comments

Comments
 (0)