local header_regex = "^(#+) (.+)" local todo_symbols = { " ", "-", "X", "D" } local table_lenght = function(T) local count = 0 for _ in pairs(T) do count = count + 1 end return count end local get_todo = function(line) local todo = nil local index = nil for n, v in ipairs(todo_symbols) do if v == "-" then v = "%-" end local ul = "^%s*[+*-]%s+%[" .. v .. "%]%s+" local ol = "^%s*%d+%.%s+%[" .. v .. "%]%s+" if line:match(ul, nil) or line:match(ol, nil) then todo = v index = n end end return todo, index end local M = {} M.headerControl = function(action) local current_line = vim.api.nvim_get_current_line() local row = vim.api.nvim_win_get_cursor(0)[1] if current_line:match(header_regex) then if action == "promote" then if current_line:match("^# (.+)") then vim.notify("You can't promote this header anymore") return end vim.api.nvim_buf_set_text(0, row - 1, 0, row - 1, 1, { "" }) elseif action == "demote" then if current_line:match("^###### (.+)") then vim.notify("You can't demote this header anymore") return end vim.api.nvim_buf_set_text(0, row - 1, 0, row - 1, 0, { "#" }) end end end M.toggleTodo = function() local current_line = vim.api.nvim_get_current_line() local row = vim.api.nvim_win_get_cursor(0)[1] local todo, index = get_todo(current_line) if todo then local symbol = todo_symbols[index + 1] -- make sure symbol is set to first character if index is too big if index == table_lenght(todo_symbols) then symbol = todo_symbols[1] end local first, last = current_line:find("%[" .. todo .. "%]") vim.api.nvim_buf_set_text(0, row - 1, first, row - 1, last - 1, { symbol }) end end return M