Skip to content

Commit a4adf7e

Browse files
refactor: use treesitter to set plan dates
1 parent 2e5fda4 commit a4adf7e

File tree

8 files changed

+190
-309
lines changed

8 files changed

+190
-309
lines changed

lua/orgmode/events/types/todo_changed_event.lua

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ local TodoChangedEvent = {
1111
---@param section Section
1212
---@param headline Headline
1313
---@param old_todo_state? string
14-
---@param is_done? string
14+
---@param is_done? boolean
1515
function TodoChangedEvent:new(section, headline, old_todo_state, is_done)
1616
local obj = setmetatable({}, self)
1717
self.__index = self

lua/orgmode/org/mappings.lua

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ function OrgMappings:archive()
5050
archive_location,
5151
vim.schedule_wrap(function()
5252
Files.update_file(archive_location, function()
53-
local archived_headline = ts_org.find_headline(item.title, true)
53+
local archived_headline = ts_org.find_headline_by_title(item.title, true)
5454
if archived_headline then
5555
archived_headline:set_property('ARCHIVE_TIME', Date.now():to_string())
5656
archived_headline:set_property('ARCHIVE_FILE', file.filename)
@@ -396,7 +396,7 @@ function OrgMappings:_todo_change_state(direction)
396396
local log_note = config.org_log_done == 'note'
397397
local log_time = config.org_log_done == 'time'
398398
local should_log_time = log_note or log_time
399-
local indent = config:get_indent(item.level + 1)
399+
local indent = config:get_indent(headline:level() + 1)
400400

401401
local get_note = function(note)
402402
if note == nil then
@@ -414,15 +414,16 @@ function OrgMappings:_todo_change_state(direction)
414414
local repeater_dates = item:get_repeater_dates()
415415
if #repeater_dates == 0 then
416416
if should_log_time and item:is_done() and not was_done then
417-
headline:add_closed_date()
417+
headline:set_closed_date()
418418
item = Files.get_closest_headline()
419419

420420
if log_note then
421421
dispatchEvent()
422422
return self.capture.closing_note:open():next(function(note)
423423
local valid_note = get_note(note)
424424
if valid_note then
425-
vim.fn.append(item:get_todo_note_line_number(), valid_note)
425+
local append_line = headline:get_append_line()
426+
vim.api.nvim_buf_set_lines(0, append_line, append_line, false, valid_note)
426427
end
427428
end)
428429
end
@@ -458,8 +459,8 @@ function OrgMappings:_todo_change_state(direction)
458459
if not note then
459460
return
460461
end
461-
local properties_end_line = headline:properties():end_()
462-
vim.api.nvim_buf_set_lines(0, properties_end_line, properties_end_line, false, note)
462+
local append_line = headline:get_append_line()
463+
vim.api.nvim_buf_set_lines(0, append_line, append_line, false, note)
463464
end)
464465
end
465466

lua/orgmode/parser/section.lua

Lines changed: 0 additions & 140 deletions
Original file line numberDiff line numberDiff line change
@@ -321,67 +321,6 @@ function Section:get_repeater_dates()
321321
end, self.dates)
322322
end
323323

324-
---@deprecated use treesitter.headline.set_property
325-
---@param properties table
326-
---@return table
327-
function Section:add_properties(properties)
328-
if self.properties.valid then
329-
local start = vim.api.nvim_call_function('getline', { self.properties.range.start_line })
330-
local indent = start:match('^%s*')
331-
for name, val in pairs(properties) do
332-
if self.properties.items[name:lower()] then
333-
local properties_content = self.root:get_node_text_list(self.properties.node)
334-
for i, content in ipairs(properties_content) do
335-
if content:lower():match('^%s*:' .. name:lower() .. ':.*$') then
336-
local new_line = content:gsub(vim.pesc(self.properties.items[name:lower()]), val)
337-
vim.api.nvim_call_function('setline', { self.properties.range.start_line + i - 1, new_line })
338-
break
339-
end
340-
end
341-
else
342-
vim.api.nvim_call_function('append', {
343-
self.properties.range.start_line,
344-
string.format('%s:%s: %s', indent, name, val),
345-
})
346-
end
347-
end
348-
return {
349-
is_new = false,
350-
indent = indent,
351-
}
352-
end
353-
354-
local properties_line = self:get_content_start_line_number()
355-
local indent = config:get_indent(self.level + 1)
356-
local content = { string.format('%s:PROPERTIES:', indent) }
357-
358-
for name, val in pairs(properties) do
359-
table.insert(content, string.format('%s:%s: %s', indent, name, val))
360-
end
361-
362-
table.insert(content, string.format('%s:END:', indent))
363-
vim.api.nvim_call_function('append', { properties_line, content })
364-
return {
365-
is_new = true,
366-
end_line = properties_line + #content,
367-
indent = indent,
368-
}
369-
end
370-
371-
function Section:get_content_start_line_number()
372-
if self:has_planning() then
373-
return self.range.start_line + 1
374-
end
375-
return self.range.start_line
376-
end
377-
378-
function Section:get_todo_note_line_number()
379-
if self.properties.valid then
380-
return self.properties.range.end_line
381-
end
382-
return self:get_content_start_line_number()
383-
end
384-
385324
---@return boolean
386325
function Section:is_first_section()
387326
if not self.parent then
@@ -494,46 +433,6 @@ function Section:promote(amount, promote_child_sections)
494433
end
495434
end
496435

497-
function Section:add_closed_date()
498-
local closed_date = self:get_closed_date()
499-
if closed_date then
500-
return nil
501-
end
502-
return self:_add_planning_date(Date.now(), 'CLOSED')
503-
end
504-
505-
---@param date Date
506-
function Section:add_scheduled_date(date)
507-
local scheduled_date = self:get_scheduled_date()
508-
if scheduled_date then
509-
return self:_update_date(scheduled_date, date)
510-
end
511-
return self:_add_planning_date(date, 'SCHEDULED', true)
512-
end
513-
514-
---@param date Date
515-
function Section:add_deadline_date(date)
516-
local deadline_date = self:get_deadline_date()
517-
if deadline_date then
518-
return self:_update_date(deadline_date, date)
519-
end
520-
return self:_add_planning_date(date, 'DEADLINE', true)
521-
end
522-
523-
function Section:remove_closed_date()
524-
local closed_date = self:get_closed_date()
525-
if not closed_date then
526-
return nil
527-
end
528-
local planning_linenr = self.range.start_line + 1
529-
local planning_line = vim.api.nvim_call_function('getline', { planning_linenr })
530-
local new_line = planning_line:gsub('%s*CLOSED:%s*[%[<]' .. vim.pesc(closed_date:to_string()) .. '[%]>]', '')
531-
if vim.trim(new_line) == '' then
532-
return vim.api.nvim_call_function('deletebufline', { vim.api.nvim_get_current_buf(), planning_linenr })
533-
end
534-
return vim.api.nvim_call_function('setline', { planning_linenr, new_line })
535-
end
536-
537436
---@return boolean
538437
function Section:has_planning()
539438
for _, date in ipairs(self.dates) do
@@ -619,43 +518,4 @@ function Section:get_title()
619518
return title
620519
end
621520

622-
function Section:_update_date(date, new_date)
623-
date = date:set({
624-
year = new_date.year,
625-
month = new_date.month,
626-
day = new_date.day,
627-
})
628-
local line = vim.api.nvim_call_function('getline', { date.range.start_line })
629-
local view = vim.fn.winsaveview()
630-
local new_line =
631-
string.format('%s%s%s', line:sub(1, date.range.start_col), date:to_string(), line:sub(date.range.end_col))
632-
vim.api.nvim_call_function('setline', {
633-
date.range.start_line,
634-
new_line,
635-
})
636-
vim.fn.winrestview(view)
637-
return true
638-
end
639-
640-
---@param date Date
641-
---@param type string
642-
---@param active? boolean
643-
---@return string
644-
function Section:_add_planning_date(date, type, active)
645-
local date_string = date:to_wrapped_string(active)
646-
if self:has_planning() then
647-
local planning_linenr = self.range.start_line + 1
648-
return vim.api.nvim_call_function('setline', {
649-
planning_linenr,
650-
string.format('%s %s: %s', vim.api.nvim_call_function('getline', { planning_linenr }), type, date_string),
651-
})
652-
end
653-
654-
local indent = config:get_indent(self.level + 1)
655-
return vim.api.nvim_call_function('append', {
656-
self.range.start_line,
657-
string.format('%s%s: %s', indent, type, date_string),
658-
})
659-
end
660-
661521
return Section

lua/orgmode/treesitter/headline.lua

Lines changed: 44 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -150,8 +150,9 @@ end
150150
-- and if it's in done state
151151
-- @return Node, string, boolean
152152
function Headline:todo()
153-
local keywords = config.todo_keywords.ALL
154-
local done_keywords = config.todo_keywords.DONE
153+
local todo_keywords = config:get_todo_keywords()
154+
local keywords = todo_keywords.ALL
155+
local done_keywords = todo_keywords.DONE
155156

156157
-- A valid keyword can only be the first child
157158
local todo_node = self:item():named_child(0)
@@ -170,6 +171,35 @@ function Headline:todo()
170171
end
171172
end
172173

174+
function Headline:todo_keyword()
175+
local node, word = self:todo()
176+
if not node then
177+
return {
178+
value = '',
179+
type = '',
180+
node = nil,
181+
}
182+
end
183+
184+
local todo_keywords = config:get_todo_keywords()
185+
return {
186+
value = word,
187+
type = todo_keywords.KEYS[word].type,
188+
node = node,
189+
}
190+
end
191+
192+
---@return boolean
193+
function Headline:is_todo()
194+
local _, _, is_done = self:todo()
195+
return not is_done
196+
end
197+
198+
---@return boolean
199+
function Headline:is_done()
200+
return not self:is_todo()
201+
end
202+
173203
function Headline:title()
174204
local title = query.get_node_text(self:item(), 0) or ''
175205
local todo, word = self:todo()
@@ -179,7 +209,7 @@ function Headline:title()
179209
return title
180210
end
181211

182-
---@return userdata
212+
---@return userdata|nil
183213
function Headline:plan()
184214
local section = self.headline:parent()
185215
for _, node in ipairs(ts_utils.get_named_children(section)) do
@@ -189,7 +219,7 @@ function Headline:plan()
189219
end
190220
end
191221

192-
---@return userdata
222+
---@return userdata|nil
193223
function Headline:properties()
194224
local section = self.headline:parent()
195225
for _, node in ipairs(ts_utils.get_named_children(section)) do
@@ -306,12 +336,13 @@ function Headline:set_scheduled_date(date)
306336
return self:_add_date('SCHEDULED', date, true)
307337
end
308338

309-
function Headline:add_closed_date()
339+
---@param date? Date
340+
function Headline:set_closed_date(date)
310341
local dates = self:dates()
311342
if dates['CLOSED'] then
312343
return
313344
end
314-
return self:_add_date('CLOSED', Date.now(), false)
345+
return self:_add_date('CLOSED', date or Date.now(), false)
315346
end
316347

317348
function Headline:remove_closed_date()
@@ -401,13 +432,12 @@ function Headline:_add_date(type, date, active)
401432
if vim.tbl_isempty(dates) then
402433
local indent = config:get_indent(self:level() + 1)
403434
local start_line = self.headline:start()
404-
return vim.api.nvim_call_function('append', {
405-
start_line + 1,
406-
string.format('%s%s', indent, text),
407-
})
435+
vim.fn.append(start_line + 1, ('%s%s'):format(indent, text))
436+
return self:refresh()
408437
end
409438
if dates[type] then
410-
return tree_utils.set_node_text(dates[type], text, true)
439+
tree_utils.set_node_text(dates[type], text, true)
440+
return self:refresh()
411441
end
412442

413443
local keys = vim.tbl_keys(dates)
@@ -423,6 +453,7 @@ function Headline:_add_date(type, date, active)
423453
end
424454
local ptext = query.get_node_text(last_child, 0)
425455
tree_utils.set_node_text(last_child, ptext .. ' ' .. text)
456+
return self:refresh()
426457
end
427458

428459
---@param type string | "DEADLINE" | "SCHEDULED" | "CLOSED"
@@ -435,8 +466,9 @@ function Headline:_remove_date(type)
435466
local line_nr = dates[type]:start() + 1
436467
tree_utils.set_node_text(dates[type], '', true)
437468
if vim.trim(vim.fn.getline(line_nr)) == '' then
438-
return vim.api.nvim_call_function('deletebufline', { vim.api.nvim_get_current_buf(), line_nr })
469+
vim.fn.deletebufline(vim.api.nvim_get_current_buf(), line_nr)
439470
end
471+
return self:refresh()
440472
end
441473

442474
---@param text table|string

0 commit comments

Comments
 (0)