Skip to content

Commit

Permalink
feat: Publish event when heading is toggled with <prefix>*
Browse files Browse the repository at this point in the history
  • Loading branch information
kristijanhusak committed Jan 21, 2025
1 parent 42a4ccf commit 8b92e84
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 20 deletions.
21 changes: 21 additions & 0 deletions lua/orgmode/events/types/heading_toggled.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
---@class OrgHeadingToggledEvent: OrgEvent
---@field headline? OrgHeadline
---@field line? number
---@field action 'line_to_headline' | 'headline_to_line' | 'line_to_child_headline'
local HeadingToggledEvent = {
type = 'orgmode.heading_toggled',
}
HeadingToggledEvent.__index = HeadingToggledEvent

---@param line number
---@param action 'line_to_headline' | 'headline_to_line' | 'line_to_child_headline'
---@param headline? OrgHeadline
function HeadingToggledEvent:new(line, action, headline)
return setmetatable({
line = line,
headline = headline,
action = action,
}, self)
end

return HeadingToggledEvent
1 change: 1 addition & 0 deletions lua/orgmode/events/types/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,5 @@ return {
TodoChanged = require('orgmode.events.types.todo_changed_event'),
HeadlinePromoted = require('orgmode.events.types.headline_promoted_event'),
HeadlineDemoted = require('orgmode.events.types.headline_demoted_event'),
HeadingToggled = require('orgmode.events.types.heading_toggled'),
}
48 changes: 28 additions & 20 deletions lua/orgmode/org/mappings.lua
Original file line number Diff line number Diff line change
Expand Up @@ -348,35 +348,43 @@ function OrgMappings:todo_prev_state()
end

function OrgMappings:toggle_heading()
local line = vim.fn.getline('.')
-- TODO: allow nil
local line_number = vim.fn.line('.')
local line = vim.fn.getline(line_number)
local parent = self.files:get_closest_headline_or_nil()

local set_line_and_dispatch_event = function(line_content, action)
vim.fn.setline(line_number, line_content)
EventManager.dispatch(
events.HeadingToggled:new(line_number, action, self.files:get_closest_headline_or_nil({ line_number, 0 }))
)
end
-- Convert to headline
if not parent then
line = '* ' .. line
vim.fn.setline('.', line)
return
return set_line_and_dispatch_event('* ' .. line, 'line_to_headline')
end

-- Convert headline to plain text
if parent:get_range().start_line == vim.api.nvim_win_get_cursor(0)[1] then
line = line:gsub('^%*+%s', '')
else
line = line:gsub('^(%s*)', '')
if line:match('^[%*-]%s') then -- handle lists
line = line:gsub('^[%*-]%s', '') -- strip bullet
local todo_keywords = config:get_todo_keywords()
line = line:gsub('^%[([X%s])%]%s', function(checkbox_state)
if checkbox_state == 'X' then
return todo_keywords:first_by_type('DONE').value .. ' '
else
return todo_keywords:first_by_type('TODO').value .. ' '
end
end)
end
return set_line_and_dispatch_event(line, 'headline_to_line')
end

line = string.rep('*', parent:get_level() + 1) .. ' ' .. line
line = line:gsub('^(%s*)', '')
if line:match('^[%*-]%s') then -- handle lists
line = line:gsub('^[%*-]%s', '') -- strip bullet
local todo_keywords = config:get_todo_keywords()
line = line:gsub('^%[([X%s])%]%s', function(checkbox_state)
if checkbox_state == 'X' then
return todo_keywords:first_by_type('DONE').value .. ' '
else
return todo_keywords:first_by_type('TODO').value .. ' '
end
end)
end

vim.fn.setline('.', line)
line = string.rep('*', parent:get_level() + 1) .. ' ' .. line

return set_line_and_dispatch_event(line, 'line_to_child_headline')
end

---Prompt for a note
Expand Down

0 comments on commit 8b92e84

Please sign in to comment.