Skip to content

Commit 48c41e3

Browse files
committed
Use tree sitter for tag manipulation
1 parent 6216995 commit 48c41e3

File tree

2 files changed

+62
-34
lines changed

2 files changed

+62
-34
lines changed

lua/orgmode/org/mappings.lua

Lines changed: 16 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -65,23 +65,28 @@ function OrgMappings:archive()
6565
end
6666

6767
function OrgMappings:set_tags()
68-
local headline = Files.get_closest_headline()
69-
local own_tags = headline:get_own_tags()
70-
local tags = vim.fn.OrgmodeInput('Tags: ', utils.tags_to_string(own_tags), Files.autocomplete_tags)
71-
return self:_set_headline_tags(headline, tags)
68+
local headline = Headline:new(tree_utils.closest_headline())
69+
local _, current_tags = headline:tags()
70+
71+
local tags = vim.fn.OrgmodeInput('Tags: ', current_tags, Files.autocomplete_tags)
72+
73+
return headline:set_tags(tags)
7274
end
7375

7476
function OrgMappings:toggle_archive_tag()
75-
local headline = Files.get_closest_headline()
76-
local own_tags = headline:get_own_tags()
77-
if vim.tbl_contains(own_tags, 'ARCHIVE') then
78-
own_tags = vim.tbl_filter(function(tag)
77+
local headline = Headline:new(tree_utils.closest_headline())
78+
local _, current_tags = headline:tags()
79+
80+
local parsed = utils.parse_tags_string(current_tags)
81+
if vim.tbl_contains(parsed, 'ARCHIVE') then
82+
parsed = vim.tbl_filter(function(tag)
7983
return tag ~= 'ARCHIVE'
80-
end, own_tags)
84+
end, parsed)
8185
else
82-
table.insert(own_tags, 'ARCHIVE')
86+
table.insert(parsed, 'ARCHIVE')
8387
end
84-
return self:_set_headline_tags(headline, utils.tags_to_string(own_tags))
88+
89+
return headline:set_tags(utils.tags_to_string(parsed))
8590
end
8691

8792
function OrgMappings:cycle()
@@ -849,28 +854,6 @@ function OrgMappings:_adjust_date(amount, span, fallback)
849854
return vim.api.nvim_feedkeys(utils.esc(fallback), 'n', true)
850855
end
851856

852-
function OrgMappings:_set_headline_tags(headline, tags_string)
853-
local tags = tags_string:gsub('^:+', ''):gsub(':+$', ''):gsub(':+', ':')
854-
if tags ~= '' then
855-
tags = ':' .. tags .. ':'
856-
end
857-
local line_without_tags = headline.line
858-
:gsub(vim.pesc(utils.tags_to_string(headline:get_own_tags())) .. '%s*$', '')
859-
:gsub('%s*$', '')
860-
861-
local to_col = config.org_tags_column
862-
if to_col < 0 then
863-
local tags_width = vim.api.nvim_strwidth(tags)
864-
to_col = math.abs(to_col) - tags_width
865-
end
866-
867-
local line_width = vim.api.nvim_strwidth(line_without_tags)
868-
spaces = math.max(to_col - line_width, 1)
869-
870-
local new_line = string.format('%s%s%s', line_without_tags, string.rep(' ', spaces), tags):gsub('%s*$', '')
871-
return vim.fn.setline(headline.range.start_line, new_line)
872-
end
873-
874857
---@return string|nil
875858
function OrgMappings:_get_link_under_cursor()
876859
local found_link = nil

lua/orgmode/treesitter/headline.lua

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,51 @@ function Headline:priority()
2121
return self:parse('%[#(%w+)%]')
2222
end
2323

24+
function Headline:tags()
25+
local node = self.headline:field('tags')[1]
26+
local text = ''
27+
if node then
28+
text = query.get_node_text(node, 0)
29+
end
30+
return node, text
31+
end
32+
33+
function Headline:set_tags(tags)
34+
local predecessor = nil
35+
for _, node in ipairs(ts_utils.get_named_children(self.headline)) do
36+
if node:type() ~= 'tag_list' then
37+
predecessor = node
38+
end
39+
end
40+
41+
local pred_end_row, pred_end_col, _ = predecessor:end_()
42+
local end_col = vim.api.nvim_strwidth(vim.fn.getline(pred_end_row + 1))
43+
44+
local text = ''
45+
tags = vim.trim(tags):gsub('^:', ''):gsub(':$', '')
46+
if tags ~= '' then
47+
tags = ':' .. tags .. ':'
48+
49+
local to_col = config.org_tags_column
50+
if to_col < 0 then
51+
local tags_width = vim.api.nvim_strwidth(tags)
52+
to_col = math.abs(to_col) - tags_width
53+
end
54+
55+
local spaces = math.max(to_col - pred_end_col, 1)
56+
text = string.rep(' ', spaces) .. tags
57+
end
58+
59+
vim.api.nvim_buf_set_text(0, pred_end_row, pred_end_col, pred_end_row, end_col, { text })
60+
end
61+
62+
function Headline:align_tags()
63+
local current_tags, current_text = self:tags()
64+
if current_tags then
65+
self:set_tags(current_text)
66+
end
67+
end
68+
2469
function Headline:set_priority(priority)
2570
local current_priority = self:priority()
2671
if current_priority then
@@ -84,7 +129,7 @@ function Headline:dates()
84129
local plan = self:plan()
85130
local dates = {}
86131
for _, node in ipairs(ts_utils.get_named_children(plan)) do
87-
local name = vim.treesitter.query.get_node_text(node:named_child(0), 0)
132+
local name = query.get_node_text(node:named_child(0), 0)
88133
dates[name] = node
89134
end
90135
return dates

0 commit comments

Comments
 (0)