1 -------------------------------------------------------------------------------
2 -- Tools to deal with tasks
3 -------------------------------------------------------------------------------
5 local Configuration = require('configuration')
6 local Notes = require('notes')
7 local Util = require('util')
9 -------------------------------------------------------------------------------
11 -------------------------------------------------------------------------------
12 local unchecked_pattern = '^(%s*)%- %[ %]'
13 local unchecked_important_pattern = '^(%s*)%* %[ %]'
14 local checked_pattern = '^(%s*)%- %[x%]'
15 local checked_important_pattern = '^(%s*)%* %[x%]'
17 local function open(path)
18 local parent = Util.directory_name(path)
19 Util.ensure_directory_exists(parent)
20 vim.cmd('edit ' .. path)
23 local function open_inbox()
24 local path = Configuration.path_for(Configuration.configuration.tasks.inbox)
27 local function open_someday()
28 local path = Configuration.path_for(Configuration.configuration.tasks.someday)
31 -------------------------------------------------------------------------------
33 -------------------------------------------------------------------------------
35 --- Toggles a task completion status
36 function Tasks.toggle()
37 local line_number = api.nvim_win_get_cursor(0)[1]
38 local line = api.nvim_get_current_line()
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)
50 api.nvim_buf_set_lines(0, line_number - 1, line_number, false, {line})
53 --- Toggles a task completion status
54 function Tasks.toggle_importance()
55 local line_number = api.nvim_win_get_cursor(0)[1]
56 local line = api.nvim_get_current_line()
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)
68 api.nvim_buf_set_lines(0, line_number - 1, line_number, false, {line})
71 --- Inserts a new task at the cursor location
72 function Tasks.insert()
73 vim.cmd('normal! o- [ ] ')
74 vim.cmd('startinsert!')
77 --- Captures a new task into the inbox
78 function Tasks.capture()
79 local prefix = '- [ ] '
81 vim.cmd('normal! Go'..prefix)
82 vim.cmd('startinsert!')
87 error('Not yet implemented')
90 --- Reschedule a task for today
91 function Tasks.reschedule_for_today()
92 local today = os.date('%Y-%m-%d')
93 Tasks.reschedule(today)
96 --- Reschedule a task for tomorrow
97 function Tasks.reschedule_for_tomorrow()
98 local tomorrow = os.date('%Y-%m-%d', os.time() + 24*60*60)
99 Tasks.reschedule(tomorrow)
102 --- Reschedule a task for someday
103 function Tasks.reschedule_for_someday()
104 Tasks.reschedule('someday')
107 --- Reschedule a task for an arbitrary date
108 function Tasks.reschedule(new_date)
110 if not new_date or new_date == '' then
111 new_date = vim.fn.input('Reschedule for which date (YYYY-mm-dd): ')
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')
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')
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})
132 api.nvim_buf_set_lines(buffer, line_number - 1, line_number, false, {})
137 if new_date == 'someday' then
140 Notes.open_daily(new_date)
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})
147 api.nvim_err_writeln('Reschedule only works on open tasks')