]> git.r.bdr.sh - rbdr/nota.nvim/blame - lua/tasks.lua
Add rescheduling tasks
[rbdr/nota.nvim] / lua / tasks.lua
CommitLineData
56292c79
RBR
1-------------------------------------------------------------------------------
2-- Tools to deal with tasks
3-------------------------------------------------------------------------------
503d09fc
RBR
4local Tasks = {}
5local Configuration = require('configuration')
2cc29448
RBR
6local Notes = require('notes')
7local Util = require('util')
503d09fc
RBR
8local api = vim.api
9-------------------------------------------------------------------------------
10-- Internal Functions
11-------------------------------------------------------------------------------
2cc29448
RBR
12local unchecked_pattern = '^(%s*)%- %[ %]'
13local unchecked_important_pattern = '^(%s*)%* %[ %]'
14local checked_pattern = '^(%s*)%- %[x%]'
15local checked_important_pattern = '^(%s*)%* %[x%]'
16
17local function open(path)
18 local parent = Util.directory_name(path)
19 Util.ensure_directory_exists(parent)
20 vim.cmd('edit ' .. path)
21end
22
23local function open_inbox()
24 local path = Configuration.path_for(Configuration.configuration.tasks.inbox)
25 open(path)
26end
27local function open_someday()
28 local path = Configuration.path_for(Configuration.configuration.tasks.someday)
29 open(path)
30end
56292c79
RBR
31-------------------------------------------------------------------------------
32-- Public Interface
33-------------------------------------------------------------------------------
34
35--- Toggles a task completion status
503d09fc
RBR
36function Tasks.toggle()
37 local line_number = api.nvim_win_get_cursor(0)[1]
38 local line = api.nvim_get_current_line()
39
503d09fc
RBR
40 if line:match(unchecked_pattern) then
41 line = line:gsub(unchecked_pattern, '%1- [x]', 1)
42 elseif line:match(unchecked_important_pattern) then
43 line = line:gsub(unchecked_important_pattern, '%1* [x]', 1)
44 elseif line:match(checked_pattern) then
45 line = line:gsub(checked_pattern, '%1- [ ]', 1)
46 elseif line:match(checked_important_pattern) then
47 line = line:gsub(checked_important_pattern, '%1* [ ]', 1)
48 end
49
50 api.nvim_buf_set_lines(0, line_number - 1, line_number, false, {line})
51end
52
53--- Toggles a task completion status
54function Tasks.toggle_importance()
55 local line_number = api.nvim_win_get_cursor(0)[1]
56 local line = api.nvim_get_current_line()
57
503d09fc
RBR
58 if line:match(unchecked_pattern) then
59 line = line:gsub(unchecked_pattern, '%1* [ ]', 1)
60 elseif line:match(unchecked_important_pattern) then
61 line = line:gsub(unchecked_important_pattern, '%1- [ ]', 1)
62 elseif line:match(checked_pattern) then
63 line = line:gsub(checked_pattern, '%1* [x]', 1)
64 elseif line:match(checked_important_pattern) then
65 line = line:gsub(checked_important_pattern, '%1- [x]', 1)
66 end
67
68 api.nvim_buf_set_lines(0, line_number - 1, line_number, false, {line})
56292c79
RBR
69end
70
71--- Inserts a new task at the cursor location
503d09fc
RBR
72function Tasks.insert()
73 vim.cmd('normal! o- [ ] ')
74 vim.cmd('startinsert!')
56292c79
RBR
75end
76
77--- Captures a new task into the inbox
503d09fc 78function Tasks.capture()
2cc29448
RBR
79 local prefix = '- [ ] '
80 open_inbox()
81 vim.cmd('normal! Go'..prefix)
82 vim.cmd('startinsert!')
56292c79
RBR
83end
84
85--- Tag a task
503d09fc
RBR
86function Tasks.tag()
87 error('Not yet implemented')
56292c79
RBR
88end
89
90--- Reschedule a task for today
503d09fc 91function Tasks.reschedule_for_today()
2cc29448
RBR
92 local today = os.date('%Y-%m-%d')
93 Tasks.reschedule(today)
56292c79
RBR
94end
95
96--- Reschedule a task for tomorrow
503d09fc 97function Tasks.reschedule_for_tomorrow()
2cc29448
RBR
98 local tomorrow = os.date('%Y-%m-%d', os.time() + 24*60*60)
99 Tasks.reschedule(tomorrow)
56292c79
RBR
100end
101
102--- Reschedule a task for someday
503d09fc 103function Tasks.reschedule_for_someday()
2cc29448 104 Tasks.reschedule('someday')
56292c79
RBR
105end
106
107--- Reschedule a task for an arbitrary date
503d09fc 108function Tasks.reschedule(new_date)
2cc29448
RBR
109
110 if not new_date or new_date == '' then
111 new_date = vim.fn.input('Reschedule for which date (YYYY-mm-dd): ')
112 end
113
114 if not Util.is_valid_date(new_date) and new_date ~= 'someday' then
115 api.nvim_err_writeln(new_date .. ' is not a valid date in the format YYYY-mm-dd')
116 return
117 end
118
119 local line_number = api.nvim_win_get_cursor(0)[1]
120 local buffer = api.nvim_get_current_buf()
121 local line = api.nvim_get_current_line()
122 local filename = vim.fn.expand('%:t:r')
123
124 if line:match(unchecked_pattern) or line:match(unchecked_important_pattern) then
125 if Util.is_before_today(filename) and line:match(unchecked_pattern) then
126 local rescheduled_line = line:gsub(unchecked_pattern, '%1- [>' .. new_date .. ']', 1)
127 api.nvim_buf_set_lines(0, line_number - 1, line_number, false, {rescheduled_line})
128 elseif Util.is_before_today(filename) and line:match(unchecked_important_pattern) then
129 local rescheduled_line = line:gsub(unchecked_important_pattern, '%1* [>' .. new_date .. ']', 1)
130 api.nvim_buf_set_lines(0, line_number - 1, line_number, false, {rescheduled_line})
131 else
132 api.nvim_buf_set_lines(buffer, line_number - 1, line_number, false, {})
133 end
134
135 vim.cmd('write')
136
137 if new_date == 'someday' then
138 open_someday()
139 else
140 Notes.open_daily(new_date)
141 end
142
143 local line_count = api.nvim_buf_line_count(0)
144 api.nvim_buf_set_lines(0, line_count, line_count, false, {line})
145 api.nvim_win_set_cursor(0, {line_count, 0})
146 else
147 api.nvim_err_writeln('Reschedule only works on open tasks')
148 end
56292c79
RBR
149end
150
503d09fc 151return Tasks