From af2c61fa3f6882aa56def1315775f9c9ca887392 Mon Sep 17 00:00:00 2001 From: "borja (aider)" Date: Tue, 29 Apr 2025 10:31:42 +0200 Subject: [PATCH] feat: use autocommands for filetype-specific setup --- lua/todoer/init.lua | 245 ++++++++++++++++++++++++-------------------- plugin/todoer.lua | 11 +- 2 files changed, 143 insertions(+), 113 deletions(-) diff --git a/lua/todoer/init.lua b/lua/todoer/init.lua index f73fc8d..7b16a19 100644 --- a/lua/todoer/init.lua +++ b/lua/todoer/init.lua @@ -1,140 +1,165 @@ -- Create the module table local M = {} --- add new todo line when previous is already a todo -local function press_enter() - local current_line = vim.api.nvim_get_current_line() - local index, spaces = string.find(current_line, "^%s*") - - -- Check if the current line matches the pattern - local pattern = "^%- %[[ x]%] .*$" - local match = string.match(current_line, pattern) - - if match then - if string.len(current_line) >= 7 then - vim.api.nvim_feedkeys("\n- [ ] ", "n", true) +-- Default configuration +local defaults = { + filetypes = { "markdown", "text", "norg" }, -- Filetypes to activate the plugin for +} + +-- Internal function to set up buffer-local keymaps +local function setup_buffer_keymaps() + -- add new todo line when previous is already a todo + local function press_enter() + local current_line = vim.api.nvim_get_current_line() + local index, spaces = string.find(current_line, "^%s*") + + -- Check if the current line matches the pattern + local pattern = "^%- %[[ x]%] .*$" + local match = string.match(current_line, pattern) + + if match then + if string.len(current_line) >= 7 then + vim.api.nvim_feedkeys("\n- [ ] ", "n", true) + else + -- go to normal mode before removing the content of the line + vim.api.nvim_feedkeys(vim.api.nvim_eval('"\\"'), "n", true) + vim.api.nvim_feedkeys("_", "n", true) + vim.api.nvim_feedkeys("C", "n", true) + vim.api.nvim_feedkeys("\n", "n", true) + -- vim.api.nvim_set_current_line("") + end else - -- go to normal mode before removing the content of the line - vim.api.nvim_feedkeys(vim.api.nvim_eval('"\\"'), "n", true) - vim.api.nvim_feedkeys("_", "n", true) - vim.api.nvim_feedkeys("C", "n", true) vim.api.nvim_feedkeys("\n", "n", true) - -- vim.api.nvim_set_current_line("") end - else - vim.api.nvim_feedkeys("\n", "n", true) end -end --- indent line if tab is pressed when line is a todo -local function press_tab() - local current_line = vim.api.nvim_get_current_line() + -- indent line if tab is pressed when line is a todo + local function press_tab() + local current_line = vim.api.nvim_get_current_line() - -- Check if current line matches the patterns - local openpattern = "%- %[[ ]%]" - local closedpattern = "%- %[[x]%]" + -- Check if current line matches the patterns + local openpattern = "%- %[[ ]%]" + local closedpattern = "%- %[[x]%]" - if string.match(current_line, openpattern) or string.match(current_line, closedpattern) then - print("tab pressed, allegedly") - vim.api.nvim_feedkeys("C-t", "i", true) + if string.match(current_line, openpattern) or string.match(current_line, closedpattern) then + print("tab pressed, allegedly") + vim.api.nvim_feedkeys("C-t", "i", true) + end end -end - --- indent line if shift tab is pressed when line is a todo -local function press_shift_tab() - local current_line = vim.api.nvim_get_current_line() - -- Check if current line matches the patterns - local openpattern = "%- %[[ ]%]" - local closedpattern = "%- %[[x]%]" + -- indent line if shift tab is pressed when line is a todo + local function press_shift_tab() + local current_line = vim.api.nvim_get_current_line() - if string.match(current_line, openpattern) or string.match(current_line, closedpattern) then - print("shift tab pressed, allegedly") - vim.api.nvim_feedkeys("C-d", "i", true) - end -end + -- Check if current line matches the patterns + local openpattern = "%- %[[ ]%]" + local closedpattern = "%- %[[x]%]" --- function that checks if the current line starts with the string "- [ ]" or "- [x]" and toggles the x -local function toggle_todo() - local openpattern = "%- %[[ ]%]" - local closedpattern = "%- %[[x]%]" - local titleopenpattern = "# %[[ ]%]" - local titleclosedpattern = "# %[[x]%]" - - local line = vim.api.nvim_get_current_line() - - if string.match(line, openpattern) then - line = string.gsub(line, openpattern, "- [x]") - vim.api.nvim_set_current_line(line) - elseif string.match(line, closedpattern) then - line = string.gsub(line, closedpattern, "- [ ]") - vim.api.nvim_set_current_line(line) - elseif string.match(line, titleopenpattern) then - line = string.gsub(line, titleopenpattern, "# [x]") - vim.api.nvim_set_current_line(line) - elseif string.match(line, titleclosedpattern) then - line = string.gsub(line, titleclosedpattern, "# [ ]") - vim.api.nvim_set_current_line(line) + if string.match(current_line, openpattern) or string.match(current_line, closedpattern) then + print("shift tab pressed, allegedly") + vim.api.nvim_feedkeys("C-d", "i", true) + end end -end --- function that checks if the current line doesn't start with the string "- [ ] " and, if it doesn't, adds the string at the beginning of the line -local function add_todo() - local openpattern = "^%s*%- %[[ ]%]" - local closedpattern = "^%s*%- %[[x]%]" + -- function that checks if the current line starts with the string "- [ ]" or "- [x]" and toggles the x + local function toggle_todo() + local openpattern = "%- %[[ ]%]" + local closedpattern = "%- %[[x]%]" + local titleopenpattern = "# %[[ ]%]" + local titleclosedpattern = "# %[[x]%]" - local line = vim.api.nvim_get_current_line() - local index, spaces = string.find(line, "^%s*") + local line = vim.api.nvim_get_current_line() - if index == 1 and not string.match(line, openpattern) and not string.match(line, closedpattern) then - if index == 1 and spaces == 0 then - line = "- [ ] " .. line + if string.match(line, openpattern) then + line = string.gsub(line, openpattern, "- [x]") vim.api.nvim_set_current_line(line) - vim.api.nvim_feedkeys("A", "n", true) - elseif index == 1 and spaces > 0 then - local trimedline = string.sub(line, spaces + 1) - local spacestring = "" - for x = 1, spaces, 1 do - spacestring = spacestring .. " " - end - line = spacestring .. "- [ ] " .. trimedline + elseif string.match(line, closedpattern) then + line = string.gsub(line, closedpattern, "- [ ]") + vim.api.nvim_set_current_line(line) + elseif string.match(line, titleopenpattern) then + line = string.gsub(line, titleopenpattern, "# [x]") + vim.api.nvim_set_current_line(line) + elseif string.match(line, titleclosedpattern) then + line = string.gsub(line, titleclosedpattern, "# [ ]") vim.api.nvim_set_current_line(line) end end -end --- function that checks if the current line starts with the string "- [ ]" or "- [x]" and, if it does, removes that string from the line -local function remove_todo() - local openpattern = "%- %[[ ]%]" - local closedpattern = "%- %[[x]%]" - local line = vim.api.nvim_get_current_line() - -- local index, spaces = string.find(line, "^%s*") - - if string.match(line, openpattern) or string.match(line, closedpattern) then - print("encontrado") - line = string.gsub(line, openpattern, "") - line = string.gsub(line, closedpattern, "") - vim.api.nvim_set_current_line(line) + -- function that checks if the current line doesn't start with the string "- [ ] " and, if it doesn't, adds the string at the beginning of the line + local function add_todo() + local openpattern = "^%s*%- %[[ ]%]" + local closedpattern = "^%s*%- %[[x]%]" + + local line = vim.api.nvim_get_current_line() + local index, spaces = string.find(line, "^%s*") + + if index == 1 and not string.match(line, openpattern) and not string.match(line, closedpattern) then + if index == 1 and spaces == 0 then + line = "- [ ] " .. line + vim.api.nvim_set_current_line(line) + vim.api.nvim_feedkeys("A", "n", true) + elseif index == 1 and spaces > 0 then + local trimedline = string.sub(line, spaces + 1) + local spacestring = "" + for x = 1, spaces, 1 do + spacestring = spacestring .. " " + end + line = spacestring .. "- [ ] " .. trimedline + vim.api.nvim_set_current_line(line) + end + end + end + + -- function that checks if the current line starts with the string "- [ ]" or "- [x]" and, if it does, removes that string from the line + local function remove_todo() + local openpattern = "%- %[[ ]%]" + local closedpattern = "%- %[[x]%]" + local line = vim.api.nvim_get_current_line() + -- local index, spaces = string.find(line, "^%s*") + + if string.match(line, openpattern) or string.match(line, closedpattern) then + print("encontrado") + line = string.gsub(line, openpattern, "") + line = string.gsub(line, closedpattern, "") + vim.api.nvim_set_current_line(line) + end end + + -- Set up buffer-local keymaps + -- Use buffer = 0 to target the current buffer + local map_opts = { noremap = true, silent = true, buffer = 0 } + local expr_map_opts = { noremap = true, expr = true, silent = true, buffer = 0 } + + vim.keymap.set("n", "t", function() end, { desc = "+TODOs", buffer = 0 }) -- Placeholder, keep silent=false if needed + vim.keymap.set("i", "", press_enter, { desc = "Todoer: Handle Enter", expr = true, buffer = 0 }) -- Keep expr=true, noremap=true is default + vim.keymap.set("i", "", press_tab, { desc = "Todoer: Handle Tab", expr = true, buffer = 0 }) -- Keep expr=true + vim.keymap.set("i", "", press_shift_tab, { desc = "Todoer: Handle Shift-Tab", expr = true, buffer = 0 }) -- Keep expr=true + vim.keymap.set("n", "tt", toggle_todo, { desc = "Todoer: Toggle TODO", buffer = 0 }) + vim.keymap.set("n", "ta", add_todo, { desc = "Todoer: Add TODO", buffer = 0 }) + vim.keymap.set("n", "td", remove_todo, { desc = "Todoer: Remove TODO", buffer = 0 }) + + -- Optional: Notify that keymaps are set for this buffer + -- vim.notify("Todoer keymaps activated for this buffer", vim.log.levels.INFO) end --- Setup function --- This function will be called by the user to configure and activate the plugin --- For now, it just sets up the default keymaps +-- Setup function: Called by the user in their config function M.setup(opts) - -- opts is a placeholder for future configuration options - opts = opts or {} - - -- Set up the keymaps - vim.keymap.set("n", "t", function() end, { desc = "+TODOs" }) - vim.keymap.set("i", "", press_enter, { desc = "On enter", noremap = true, expr = true }) - vim.keymap.set("i", "", press_tab, { desc = "On tab", noremap = true, expr = true }) - vim.keymap.set("i", "S-Tab", press_shift_tab, { desc = "On shift tab", noremap = true, expr = true }) - vim.keymap.set("n", "tt", toggle_todo, { desc = "Toggle TODO" }) - vim.keymap.set("n", "ta", add_todo, { desc = "Add TODO" }) - vim.keymap.set("n", "td", remove_todo, { desc = "Remove TODO" }) - - print("Todoer setup complete!") -- Added a print statement for confirmation + -- Merge user options with defaults + local config = vim.tbl_deep_extend("force", {}, defaults, opts or {}) + + -- Create an autocommand group to ensure we can clear it later if needed + local group = vim.api.nvim_create_augroup("TodoerUserSetup", { clear = true }) + + -- Create the autocommand + vim.api.nvim_create_autocmd("FileType", { + group = group, + pattern = config.filetypes, -- Use filetypes from config + desc = "Setup Todoer keymaps for specific filetypes", + callback = function() + -- Call the function that sets up buffer-local keymaps + setup_buffer_keymaps() + end, + }) end -- Return the module table diff --git a/plugin/todoer.lua b/plugin/todoer.lua index 0073d57..132787b 100644 --- a/plugin/todoer.lua +++ b/plugin/todoer.lua @@ -1,3 +1,8 @@ --- Load the main module and call its setup function. --- This will execute the setup logic inside lua/todoer/init.lua immediately. -require('todoer').setup() +-- This file is intentionally left blank or can contain comments. +-- The plugin is now activated by calling require('todoer').setup() +-- in the user's Neovim configuration (e.g., init.lua or via a plugin manager). + +-- Example user configuration (e.g., in init.lua or using lazy.nvim): +-- require('todoer').setup({ +-- filetypes = { 'markdown', 'txt' } -- Optional: override default filetypes +-- })