Skip to content

Commit 71880f3

Browse files
committed
feature: add support for cookies
fix nvim-orgmode#81
1 parent 9cf968e commit 71880f3

File tree

2 files changed

+75
-0
lines changed

2 files changed

+75
-0
lines changed

lua/orgmode/init.lua

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,9 @@ function Org:setup_autocmds()
5555
)
5656
vim.cmd([[autocmd FileType org call luaeval('require("orgmode").reload(_A)', expand('<afile>:p'))]])
5757
vim.cmd([[autocmd CursorHold,CursorHoldI *.org,*.org_archive lua require('orgmode.org.diagnostics').report()]])
58+
vim.cmd(
59+
[[autocmd BufWinEnter,FileChangedShellPost,TextChanged,TextChangedI *.org,*.org_archive lua require('orgmode.org.syntax').add_cookies()]]
60+
)
5861
vim.cmd([[augroup END]])
5962
vim.cmd([[command! OrgDiagnostics lua require('orgmode.org.diagnostics').print()]])
6063
end

lua/orgmode/org/syntax.lua

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
local Files = require('orgmode.parser.files')
22
local config = require('orgmode.config')
3+
local utils = require('orgmode.utils')
4+
5+
local cookie_namespace = vim.api.nvim_create_namespace('orgmode-cookies')
6+
local cookie_query = vim.treesitter.parse_query('org', '(cookie) @cookie')
7+
local checkbox_query = vim.treesitter.parse_query('org', '(list (listitem (checkbox) @checkbox))')
8+
local list_in_body_query = vim.treesitter.parse_query('org', '(body (list) @list)')
39

410
local function load_code_blocks()
511
local file = vim.api.nvim_buf_get_name(0)
@@ -36,7 +42,73 @@ local function add_todo_keywords_to_spellgood()
3642
end
3743
end
3844

45+
local function _display_cookie_virt_text(cookie, checked, total)
46+
local row, column = cookie:start()
47+
local cookie_text = vim.treesitter.get_node_text(cookie, 0)
48+
49+
-- TODO: fix this in treesitter
50+
local _, leading_spaces = cookie_text:find('^%s+')
51+
cookie_text = vim.trim(cookie_text)
52+
53+
local text
54+
if cookie_text == '[/]' then
55+
text = string.format('[%d/%d]', checked, total)
56+
else
57+
text = string.format('[%d%%]', (100 * checked) / total)
58+
end
59+
vim.api.nvim_buf_set_extmark(0, cookie_namespace, row, column + (leading_spaces or 0), {
60+
-- TODO: make highlight group configurable
61+
virt_text = { { text, 'Error' } },
62+
virt_text_pos = 'overlay',
63+
hl_mode = 'combine',
64+
})
65+
end
66+
67+
local function _get_cookie_checked_and_total(parent)
68+
local parent_type = parent:type()
69+
local start_row, _, end_row, _ = parent:range()
70+
local checked, total = 0, 0
71+
for _, checkbox in checkbox_query:iter_captures(parent, 0, start_row, end_row + 1) do
72+
local closest_parent = utils.get_closest_parent_of_type(checkbox, parent_type)
73+
if closest_parent and closest_parent == parent then -- only count direct children
74+
local checkbox_text = vim.treesitter.get_node_text(checkbox, 0)
75+
if checkbox_text:match('%[[x|X]%]') then
76+
checked = checked + 1
77+
end
78+
total = total + 1
79+
end
80+
end
81+
82+
return checked, total
83+
end
84+
85+
local function add_cookies()
86+
local parser = vim.treesitter.get_parser(0, 'org')
87+
local root = parser:parse()[1]:root()
88+
89+
vim.api.nvim_buf_clear_namespace(0, cookie_namespace, 0, -1)
90+
91+
for _, cookie in cookie_query:iter_captures(root, 0, 0, -1) do
92+
local parent = cookie:parent()
93+
local checked, total = 0, 0
94+
if parent:type() == 'headline' then
95+
parent = parent:parent()
96+
local start_row, _, end_row, _ = parent:range()
97+
for _, list in list_in_body_query:iter_captures(parent, 0, start_row, end_row + 1) do
98+
local c_checked, c_total = _get_cookie_checked_and_total(list)
99+
checked = checked + c_checked
100+
total = total + c_total
101+
end
102+
else
103+
checked, total = _get_cookie_checked_and_total(parent)
104+
end
105+
106+
_display_cookie_virt_text(cookie, checked, total)
107+
end
108+
end
109+
39110
return {
40111
load_code_blocks = load_code_blocks,
41112
add_todo_keywords_to_spellgood = add_todo_keywords_to_spellgood,
113+
add_cookies = add_cookies,
42114
}

0 commit comments

Comments
 (0)