]>
Commit | Line | Data |
---|---|---|
56292c79 RBR |
1 | ------------------------------------------------------------------------------- |
2 | -- Tools to deal with task views | |
3 | ------------------------------------------------------------------------------- | |
503d09fc RBR |
4 | local TaskViews = {} |
5 | local Util = require('util') | |
6 | local Configuration = require('configuration') | |
7 | local api = vim.api | |
8 | ------------------------------------------------------------------------------- | |
9 | -- Internal Functions | |
10 | ------------------------------------------------------------------------------- | |
11 | local function get_this_weeks_files() | |
12 | local today = os.time() | |
13 | local day_of_week = os.date('*t', today).wday | |
14 | local week_start = today - (day_of_week - 2) * 86400 | |
15 | local filenames = {} | |
16 | ||
17 | for i = 0, 6 do | |
18 | local date = os.date('*t', week_start + i * 86400) | |
19 | table.insert(filenames, string.format('%04d-%02d-%02d.md', date.year, date.month, date.day)) | |
20 | end | |
21 | ||
22 | return filenames | |
23 | end | |
24 | ||
25 | local function find_tasks(completed, important) | |
26 | local file_directory_path = Configuration.path_for(Configuration.configuration.periodic_locations.daily) | |
27 | ||
28 | local completed_fragment = '(\\s|x)' | |
29 | if completed == 1 then | |
30 | completed_fragment = 'x' | |
31 | elseif completed == 0 then | |
32 | completed_fragment = '\\s' | |
33 | end | |
34 | ||
35 | local important_fragment = '(\\-|\\*)' | |
36 | if important == 1 then | |
37 | important_fragment = '\\*' | |
38 | elseif important == 0 then | |
39 | important_fragment = '\\-' | |
40 | end | |
41 | ||
42 | ||
43 | local pattern = '^\\s*' .. important_fragment .. '\\s\\[' .. completed_fragment .. ']' | |
44 | ||
45 | local command = string.format('rg --vimgrep \'%s\' \'%s\'', pattern, file_directory_path) | |
46 | local results = vim.fn.systemlist(command) | |
47 | ||
48 | if vim.v.shell_error == 0 then | |
49 | local items = {} | |
50 | for _, line in ipairs(results) do | |
51 | local filename, lnum, col, text = line:match('([^:]+):(%d+):(%d+):(.*)') | |
52 | table.insert(items, { | |
53 | filename = filename, | |
54 | lnum = tonumber(lnum), | |
55 | col = tonumber(col), | |
56 | text = text, | |
57 | }) | |
58 | end | |
59 | ||
60 | -- Set location list for the current window and open it | |
61 | vim.fn.setloclist(0, items) | |
62 | vim.cmd('lopen') | |
63 | end | |
64 | end | |
65 | ||
66 | local function populate_quicklist_with_files(filenames) | |
67 | local uv = vim.loop | |
68 | local items = {} | |
69 | local task_pattern = '^%s*%- %[[ ]?x?%]' | |
70 | local important_task_pattern = '^%s*%* %[[ ]?x?%]' | |
71 | ||
72 | local file_directory_path = Configuration.path_for(Configuration.configuration.periodic_locations.daily) | |
73 | Util.ensure_directory_exists(file_directory_path) | |
74 | ||
75 | for _, filename in ipairs(filenames) do | |
76 | local daily_note = Util.join(file_directory_path, filename) | |
77 | local stat = uv.fs_stat(daily_note) | |
78 | ||
79 | if stat then -- File exists | |
80 | local file, err = io.open(daily_note, 'r') | |
81 | if file then | |
82 | local set_header = 0 | |
83 | local line_number = 0 | |
84 | for line in file:lines() do | |
85 | line_number = line_number + 1 | |
86 | if line:match(task_pattern) or line:match(important_task_pattern) then | |
87 | if set_header == 0 then | |
88 | local header = string.sub(filename:match('([^/\\]+)$'), 1, -4) | |
89 | table.insert(items, {filename = '', lnum = 0, text = header}) | |
90 | set_header = 1 | |
91 | end | |
92 | table.insert(items, {filename = daily_note, text = line, lnum = line_number}) | |
93 | end | |
94 | end | |
95 | file:close() | |
96 | end | |
97 | end | |
98 | end | |
99 | vim.fn.setloclist(0, {}, ' ', {title = 'Weekly Tasks', items = items}) | |
100 | vim.cmd('lopen') | |
101 | end | |
102 | ||
56292c79 RBR |
103 | ------------------------------------------------------------------------------- |
104 | -- Public Interface | |
105 | ------------------------------------------------------------------------------- | |
106 | ||
107 | --- Opens the agenda view to show tasks | |
503d09fc RBR |
108 | function TaskViews.open_agenda() |
109 | local week_filenames = get_this_weeks_files() | |
110 | populate_quicklist_with_files(week_filenames) | |
56292c79 RBR |
111 | end |
112 | ||
113 | --- Opens the view to show open tasks | |
503d09fc RBR |
114 | function TaskViews.open_open() |
115 | find_tasks(0) | |
116 | end | |
117 | ||
118 | --- Opens the view to show open important tasks | |
119 | function TaskViews.open_open_important() | |
120 | find_tasks(0, 1) | |
56292c79 RBR |
121 | end |
122 | ||
123 | --- Opens the view to search the journal | |
503d09fc RBR |
124 | function TaskViews.open_journal() |
125 | local pattern = '^\\s*(\\*|\\-)\\s\\[x]' | |
126 | -- local pattern = 'hell' | |
127 | local success, module = pcall(require, 'fzf-lua') | |
128 | if success then | |
129 | local notes_path = Configuration.path_for() | |
130 | Util.ensure_directory_exists(notes_path) | |
131 | module.files({ cwd = notes_path, cmd = 'rg --line-number --no-heading -- \'' .. pattern ..'\''}) | |
132 | else | |
133 | api.nvim_err_writeln('This feature requires optional dependency fzf-lua') | |
134 | end | |
56292c79 RBR |
135 | end |
136 | ||
503d09fc | 137 | return TaskViews |