Compare commits

...

57 Commits
spaces ... main

Author SHA1 Message Date
borja ee351d8435 cambia gitignore 2 months ago
borja (aider) 5ffa18860e docs: update README with known issues and debugging info 2 months ago
borja (aider) d75ccc32eb feat: add debug logging for tab indentation issues 2 months ago
borja (aider) e50f7f0b43 refactor: replace feedkeys with direct buffer operations for tab indentation 2 months ago
borja (aider) dce228f70a docs: add comprehensive README for todoer.nvim plugin 2 months ago
borja (aider) 12bae73dfd fix: prevent incorrect unindent on <CR> using nvim_input('<Ignore>') 2 months ago
borja (aider) 3f3ec3df1a fix: support all list markers for tab indentation 2 months ago
borja (aider) 16615aeb43 refactor: Improve get_line_details parsing to fix empty TODOs 2 months ago
borja (aider) d56f7be564 chore: add debug notifications to press_enter 2 months ago
borja (aider) a9753a2c19 feat: add remove TODO markup functionality 2 months ago
borja (aider) e7f6d63fde fix: prevent E565 error on <CR> by removing expr=true 2 months ago
borja (aider) 1a5ba4378c feat: Outdent empty TODO lines on Enter press 2 months ago
borja (aider) c7252424d7 refactor: generalize toggle_todo pattern for multiple markers 2 months ago
borja (aider) ea13e19e55 fix: Avoid error when checking line content 2 months ago
borja (aider) 50507dd706 fix: prevent double indent on enter for non-empty todos 2 months ago
borja (aider) d1a2f0d378 fix: replace vim.fn.strbytes with Lua # operator 2 months ago
borja (aider) 7df445bd74 feat: add <leader>ti/ta/to mappings for TODO creation 2 months ago
borja (aider) af2c61fa3f feat: use autocommands for filetype-specific setup 2 months ago
borja (aider) 68d467089b refactor: implement setup function and move keymaps 2 months ago
borja (aider) c970c39ec9 refactor: Restructure plugin into lua/ module 2 months ago
borja 600b961f6f añade gitignore 2 months ago
Borja FMS a61f83248f nombre en mayúsculas a ver si triguerea algo 12 months ago
Borja FMS ca773ddbfa cambia nombre a TODOs 12 months ago
Borja FMS 2743447f90 vuelve a lo normal 12 months ago
Borja FMS 250efda5d0 prueba otra vez con una string 12 months ago
brobert 9b73c145b3 revert 12 months ago
brobert 962238d18a intenta añadir icono en el whichkeys 12 months ago
borja 184b932b78 test 2 years ago
borja ad8ec54d10 a ver si ahora 2 years ago
borja 82cafd0c8f tab y shift tab 2 years ago
borja 7a19758eb6 test 2 years ago
borja c7a256fdab cambio leve 2 years ago
borja 599d0524f7 añade tab 2 years ago
borja 4c8b17569e cambia el patter de toggle todo para que no pille todos los espacios del principio y así mantenga el indentado cuando hace los cambios 2 years ago
borja 1fa6f9048c devuelve al fin de línea cuando se crea todo vacío 2 years ago
borja 5ef2af6f6d nuevas pattern 2 years ago
borja ee6ddbdf4a test find 2 years ago
borja 981a084909 test 2 years ago
borja 28d6af114c ahora apaña el remove todo 2 years ago
borja 99e9d3790e a ver si así sí 2 years ago
borja f829721373 me habia dejado una cosa 2 years ago
borja bcd0ca26aa arregla bug 2 years ago
borja 98808b7c0e ni idea 2 years ago
borja 4eb596e405 a ver si ahora respeta los espacios 2 years ago
borja ac03e408f8 prueba con find 2 years ago
borja abde05a54f test 2 years ago
borja eb05f300a1 test 2 years ago
borja ee123faeed arregla 2 years ago
borja 0137f9a286 añade todo contando con la indentación 2 years ago
borja a05a096b73 no añade espacio extra al añadir todo si ya hay un espacio 2 years ago
borja e75c9d3a82 cambio quitar todo 2 years ago
borja 8bc9e689b4 a ver como va esto 2 years ago
borja a4c2acf107 cambio por igual a false 2 years ago
borja 649edc6234 cambia add_todo para hacerlo con pattern recognition 2 years ago
borja 71e37876e9 mejores patterns para titulos 2 years ago
borja 92aff65210 cambia los patterns 2 years ago
brobert 349b0d6832 Merge pull request 'cambia el reconocimiento por patrones que deberían aceptar los espacios iniciales' (#1) from spaces into main
Reviewed-on: #1
2 years ago

2
.gitignore vendored

@ -0,0 +1,2 @@
.aider*
debug.log

@ -0,0 +1,106 @@
# Todoer.nvim - Enhanced TODO Management for Neovim
A Neovim plugin that provides enhanced TODO list management with smart handling of checkboxes, indentation, and list items in markdown and other text formats.
## Features
✅ **Current Functionality:**
- Smart TODO item creation with `<leader>ti`, `<leader>ta`, `<leader>to`
- Toggle checkboxes with `<leader>tt`
- Remove TODO markup with `<leader>td`
- Smart Enter key handling in insert mode:
- Creates new TODO items with proper indentation
- Handles empty TODO items by outdenting or terminating lists
- Tab/Shift-Tab indentation for TODO items
- Supports multiple list markers: `-`, `*`, `+`
- Works with markdown, text, and norg files by default
## Known Issues
🐛 **Current Bugs:**
- Tab indentation handling still uses feedkeys and needs refactoring
- Shift-Tab behavior may not be consistent with spaces vs tabs
- Enter key (<CR>) handling has several issues:
- Doesn't properly handle empty lines after TODO items
- Cursor positioning can be incorrect in some cases
- Outdenting behavior is inconsistent
- Edge cases with mixed indentation (spaces + tabs) not fully handled
- Cursor positioning could be improved in several scenarios
- Debug output is currently only enabled for Tab/Shift-Tab but not other operations
## Roadmap
📌 **Planned Improvements:**
- [ ] Refactor tab indentation to use proper buffer operations
- [ ] Fix Enter key handling for all cases
- [ ] Add consistent debug output for all operations
- [ ] Improve cursor positioning logic
- [ ] Handle empty lines and edge cases better
- [ ] Add support for numbered lists
- [ ] Add support for nested TODO items with proper indentation
- [ ] Add visual selection operations for multiple TODOs
- [ ] Add commands for archiving completed items
- [ ] Add support for custom TODO markers
- [ ] Add support for custom checkbox states (e.g., `[ ]`, `[x]`, `[-]`)
## Installation
Using [lazy.nvim](https://github.com/folke/lazy.nvim):
```lua
{
'your-username/todoer.nvim',
config = function()
require('todoer').setup({
-- Optional: override default filetypes
filetypes = { 'markdown', 'text', 'norg' }
})
end
}
```
## Debugging Recommendations
To help diagnose issues, you can:
1. Add `debug_line()` calls to key functions like `press_enter()`
2. Create a debug mode that can be toggled via:
```lua
local debug_mode = false
```
3. Make debug output more structured with timestamps and operation types
4. Log cursor positions before/after operations
5. Add validation of line states after modifications
Example debug output format:
```
[DEBUG] [TIMESTAMP] [OPERATION]
Line: 42
Before: {indent=" ", marker="-", is_todo=true}
After: {indent=" ", marker="-", is_todo=true}
Cursor: {lnum=42, col=6} -> {lnum=43, col=4}
```
## Configuration
Default configuration:
```lua
{
filetypes = { "markdown", "text", "norg" } -- Filetypes to activate the plugin for
}
```
## Keybindings
Normal Mode:
- `<leader>ti` - Convert line to TODO (cursor after `] `)
- `<leader>ta` - Convert line to TODO (cursor at end)
- `<leader>to` - Insert new TODO line below
- `<leader>tt` - Toggle checkbox state
- `<leader>td` - Remove TODO markup
Insert Mode:
- `<CR>` - Smart enter behavior for TODO items
- `<Tab>` - Indent TODO item
- `<S-Tab>` - Outdent TODO item

@ -0,0 +1,4 @@
# TODO
- [ ] Fix press_enter when line is indented
- [ ] When line is a todo, tab indents

@ -0,0 +1,411 @@
-- Create the module table
local M = {}
-- Default configuration
local defaults = {
filetypes = { "markdown", "text", "norg" }, -- Filetypes to activate the plugin for
}
-- Helper: Parses line details for a given line number (1-based)
-- Returns table: { line = str, indent = str, marker = str|nil, content = str, is_todo = bool, prefix_len = number } or nil
local function get_line_details(lnum)
-- Use nvim_buf_get_lines which is 0-indexed for ranges
local lines = vim.api.nvim_buf_get_lines(0, lnum - 1, lnum, false)
if not lines or #lines == 0 then return nil end -- Handle potential errors getting line
local line = lines[1]
-- Define patterns
-- Pattern to capture the full TODO prefix, including trailing space(s)
-- Captures: 1: Full prefix, 2: Indent, 3: Marker, 4: Checkbox state
local todo_prefix_pattern = "^(%s*([%-%*%+])%s+%[([ x])%]%s*)"
-- Pattern to capture a regular list prefix
-- Captures: 1: Full prefix, 2: Indent, 3: Marker
local list_prefix_pattern = "^(%s*([%-%*%+])%s+)"
local indent = ""
local marker = nil
local content = ""
local is_todo = false
local prefix_len = 0
-- Try matching the TODO prefix first
local todo_prefix, todo_indent, todo_marker, _ = string.match(line, todo_prefix_pattern)
if todo_prefix then
-- It's a TODO line
is_todo = true
indent = todo_indent
marker = todo_marker
prefix_len = #todo_prefix
content = string.sub(line, prefix_len + 1) -- Content is everything after the matched prefix
else
-- Not a TODO line, try matching a regular list prefix
local list_prefix, list_indent, list_marker = string.match(line, list_prefix_pattern)
if list_prefix then
-- It's a regular list line
is_todo = false
indent = list_indent
marker = list_marker
prefix_len = #list_prefix
content = string.sub(line, prefix_len + 1) -- Content is everything after the matched prefix
else
-- Not a list line either, treat as plain text
is_todo = false
indent = string.match(line, "^%s*") or ""
marker = nil
prefix_len = #indent
content = string.sub(line, prefix_len + 1) -- Use sub, trim might be too aggressive
-- content = vim.trim(line) -- Old way
end
end
return {
line = line,
indent = indent,
marker = marker, -- '-', '*', '+', or nil
content = content,
is_todo = is_todo,
prefix_len = prefix_len, -- Store the calculated prefix length
}
end
-- Helper: Creates proper indent string based on buffer settings
local function get_indent_string()
local sw = vim.bo.shiftwidth
local et = vim.bo.expandtab
return et and string.rep(" ", sw) or "\t"
end
-- Debug helper to print line details
local function debug_line(msg, details)
print(string.format(
"[DEBUG] %s:\n indent: '%s' (len=%d)\n marker: '%s'\n content: '%s'\n is_todo: %s",
msg,
details.indent,
#details.indent,
details.marker or "nil",
details.content,
details.is_todo
))
end
-- Helper: Gets details for the current line including cursor position
local function get_current_line_details_with_cursor()
local cursor_pos = vim.api.nvim_win_get_cursor(0)
local lnum = cursor_pos[1] -- 1-based line number
local col = cursor_pos[2] -- 0-based byte column
return get_line_details(lnum), lnum, col
end
-- <leader>ti: Convert line to TODO, cursor after "] " (Normal mode)
local function add_todo_insert_mode()
local details, lnum = get_current_line_details_with_cursor() -- Use basic helper is fine
-- Don't convert if already a TODO or if getting details failed
if not details or details.is_todo then return end
local use_marker = details.marker or "-" -- Default to '-' if no list marker found
-- Use the raw content calculated by the improved get_line_details
local text_content = details.content
local new_line = details.indent .. use_marker .. " [ ] " .. text_content
-- Replace current line (lnum is 1-based, set_lines is 0-based)
vim.api.nvim_buf_set_lines(0, lnum - 1, lnum, false, { new_line })
-- Set cursor position: 1-based row, 0-based byte column
-- Position cursor right after the "] "
local cursor_col_bytes = #(details.indent .. use_marker .. " [ ] ") -- Use Lua # operator
vim.api.nvim_win_set_cursor(0, { lnum, cursor_col_bytes })
end
-- <leader>ta: Convert line to TODO, cursor at end of line (Normal mode)
local function add_todo_append_mode()
local details, lnum = get_current_line_details_with_cursor() -- Use basic helper is fine
if not details or details.is_todo then return end
local use_marker = details.marker or "-"
local text_content = details.content
local new_line = details.indent .. use_marker .. " [ ] " .. text_content
vim.api.nvim_buf_set_lines(0, lnum - 1, lnum, false, { new_line })
-- Set cursor position: 1-based row, 0-based byte column
-- Position cursor at the very end of the line content
local cursor_col_bytes = #new_line -- Use Lua # operator
vim.api.nvim_win_set_cursor(0, { lnum, cursor_col_bytes })
end
-- <leader>to: Insert new TODO line below, cursor after "] " (Normal mode)
local function add_todo_new_line_mode()
local details, lnum = get_current_line_details_with_cursor() -- Use basic helper is fine
if not details then return end -- Should not happen usually, but check anyway
-- Determine indent and marker based on current line, default to '-' if no marker
local new_indent = details.indent
local new_marker = details.marker or "-"
local new_line_content = new_indent .. new_marker .. " [ ] "
-- Insert after current line (lnum is 1-based, set_lines is 0-based for ranges)
vim.api.nvim_buf_set_lines(0, lnum, lnum, false, { new_line_content })
-- Set cursor position: 1-based row (lnum + 1), 0-based byte column
-- Position cursor at the end of the new line (after "] ")
local cursor_col_bytes = #new_line_content -- Use Lua # operator
vim.api.nvim_win_set_cursor(0, { lnum + 1, cursor_col_bytes })
end
-- <leader>td: Remove TODO markup from the current line (Normal mode)
local function remove_todo_markup()
local details, lnum, original_col = get_current_line_details_with_cursor()
if not details or not details.is_todo then return end -- Only act on TODO lines
-- Construct the new line without the TODO markup "[ ] " or "[x] "
-- Ensure marker exists, default to '-' if somehow nil (shouldn't happen if is_todo)
local use_marker = details.marker or "-"
local new_line = details.indent .. use_marker .. " " .. details.content
-- Calculate the position where the markup started
-- This is the length of the indent + marker + one space
local markup_start_col = #(details.indent .. use_marker .. " ")
-- The markup itself is 4 characters: '[', ' ' or 'x', ']', ' '
local markup_len = 4
-- Update the line content
vim.api.nvim_buf_set_lines(0, lnum - 1, lnum, false, { new_line })
-- Calculate the new cursor column
local new_col
if original_col < markup_start_col then
-- Cursor was before the markup, keep its position
new_col = original_col
elseif original_col >= markup_start_col and original_col < markup_start_col + markup_len then
-- Cursor was inside the markup, move it to the start of where the markup was
new_col = markup_start_col
else
-- Cursor was after the markup, shift it left by the length of the removed markup
new_col = original_col - markup_len
end
-- Ensure the column is not negative (shouldn't happen here, but good practice)
new_col = math.max(0, new_col)
-- Set the new cursor position
vim.api.nvim_win_set_cursor(0, { lnum, new_col })
end
-- Internal function to set up buffer-local keymaps
local function setup_buffer_keymaps()
-- Handles Enter key press in Insert mode
local function press_enter()
local details, lnum = get_current_line_details_with_cursor() -- Use basic helper is fine
if not details then
-- Getting details failed, do nothing and let Neovim handle Enter.
return
end
-- Check if the line is a TODO item and if it has content after the marker
-- Use string.match with %S to check for any non-whitespace character
local has_content = details.content and string.match(details.content, "%S")
if details.is_todo and has_content then
-- Case 1: Non-empty TODO line
-- Create a new TODO line below with same indent/marker
local new_marker = details.marker or "-" -- Should always have marker if is_todo, but safety check
local new_line_content = details.indent .. new_marker .. " [ ] "
-- Insert the new line below the current one
vim.api.nvim_buf_set_lines(0, lnum, lnum, false, { new_line_content })
-- Move cursor to the new line, after the "] "
local cursor_col_bytes = #new_line_content
vim.api.nvim_win_set_cursor(0, { lnum + 1, cursor_col_bytes })
-- Tell Neovim to ignore the original <CR> press
vim.api.nvim_input('<Ignore>')
return -- Action handled
elseif details.is_todo and not has_content then
-- Case 2: Empty TODO line (e.g., "- [ ]") - Implement Outdenting
local current_indent = details.indent
local current_indent_len = #current_indent
local sw = vim.bo.shiftwidth -- Get buffer's shiftwidth
local et = vim.bo.expandtab -- Get buffer's expandtab setting
if current_indent_len > 0 then
-- Line is indented, calculate new indentation
local new_indent = ""
if et then -- Using spaces
local target_indent_len = math.max(0, current_indent_len - sw)
new_indent = string.rep(" ", target_indent_len)
else -- Using tabs
-- Remove the first tab character found
new_indent = string.gsub(current_indent, "^\t", "", 1)
-- Safety check: if gsub didn't change anything (e.g., indent was spaces),
-- try removing spaces as a fallback, though this is less ideal with noexpandtab
if new_indent == current_indent and current_indent_len > 0 then
local target_indent_len = math.max(0, current_indent_len - sw)
new_indent = string.rep(" ", target_indent_len)
end
end
-- Replace the current line with the outdented version
local new_marker = details.marker or "-"
local new_line_content = new_indent .. new_marker .. " [ ] "
vim.api.nvim_buf_set_lines(0, lnum - 1, lnum, false, { new_line_content })
-- Move cursor after the "] " on the modified line
local cursor_col_bytes = #new_line_content
vim.api.nvim_win_set_cursor(0, { lnum, cursor_col_bytes })
-- Tell Neovim to ignore the original <CR> press
vim.api.nvim_input('<Ignore>')
return -- Action handled
else
-- Line is not indented, terminate the list
-- Replace the line with an empty string
vim.api.nvim_buf_set_lines(0, lnum - 1, lnum, false, { "" })
-- Now, manually insert a newline below using the API
vim.api.nvim_buf_set_lines(0, lnum, lnum, false, { "" })
-- Move cursor to the new empty line
vim.api.nvim_win_set_cursor(0, { lnum + 1, 0 })
-- Tell Neovim to ignore the original <CR> press
vim.api.nvim_input('<Ignore>')
return -- Action handled
end
else
-- Case 3: Not a TODO line
-- Do nothing. Neovim will automatically handle the Enter key press
-- because this function didn't modify the buffer or call nvim_input('<Ignore>').
return -- Explicitly return nothing to be clear
end
end
-- Handle tab indentation for TODO lines
local function press_tab()
local lnum = vim.api.nvim_win_get_cursor(0)[1]
local details = get_line_details(lnum)
print("\n[DEBUG TAB] Line "..lnum.." before:")
debug_line("Original", details)
if not details or not details.is_todo then
print("[DEBUG TAB] Not a TODO line, using default Tab")
return vim.api.nvim_replace_termcodes("<Tab>", true, false, true)
end
local indent_str = get_indent_string()
local new_line = details.indent .. indent_str ..
(details.marker or "-") .. " [ ] " .. details.content
print("[DEBUG TAB] New line will be:", new_line)
print("[DEBUG TAB] Indent string:", "'"..indent_str.."' (length="..#indent_str..")")
vim.api.nvim_set_current_line(new_line)
-- Calculate new cursor column (preserve relative position)
local cursor_col = vim.api.nvim_win_get_cursor(0)[2]
local new_col = cursor_col + #indent_str
vim.api.nvim_win_set_cursor(0, {vim.api.nvim_win_get_cursor(0)[1], new_col})
return "" -- Prevent default behavior
end
-- Handle shift-tab outdentation for TODO lines
local function press_shift_tab()
local lnum = vim.api.nvim_win_get_cursor(0)[1]
local details = get_line_details(lnum)
print("\n[DEBUG SHIFT-TAB] Line "..lnum.." before:")
debug_line("Original", details)
if not details or not details.is_todo or #details.indent == 0 then
print("[DEBUG SHIFT-TAB] Not a TODO line or at min indent, using default S-Tab")
return vim.api.nvim_replace_termcodes("<S-Tab>", true, false, true)
end
local sw = vim.bo.shiftwidth
local new_indent = details.indent:sub(1, -sw - 1)
local new_line = new_indent ..
(details.marker or "-") .. " [ ] " .. details.content
print("[DEBUG SHIFT-TAB] New indent:", "'"..new_indent.."' (length="..#new_indent..")")
print("[DEBUG SHIFT-TAB] New line will be:", new_line)
vim.api.nvim_set_current_line(new_line)
-- Calculate new cursor column (preserve relative position)
local cursor_col = vim.api.nvim_win_get_cursor(0)[2]
local new_col = math.max(0, cursor_col - sw)
vim.api.nvim_win_set_cursor(0, {vim.api.nvim_win_get_cursor(0)[1], new_col})
return "" -- Prevent default behavior
end
-- Toggles the checkbox [ ] <-> [x] for lines starting with -, *, +, or #
local function toggle_todo()
local line = vim.api.nvim_get_current_line()
-- Pattern captures:
-- 1: Prefix (indentation, marker '-', '*', '+', or '#', and whitespace)
-- 2: State (' ' or 'x')
-- 3: Rest of the line (after ']')
-- Adjusted pattern slightly to ensure it captures # correctly too if needed
local prefix, state, rest = string.match(line, "^([%s]*[%-#%*%+]%s*)%[([ x])%](.*)")
if prefix then -- Check if the pattern matched (i.e., it's a toggleable line)
-- Determine the new state
local new_state = (state == ' ') and 'x' or ' '
-- Reconstruct the line with the new state
local new_line = prefix .. "[" .. new_state .. "]" .. rest
-- Update the current line
vim.api.nvim_set_current_line(new_line)
end
-- If the pattern didn't match, do nothing.
end
-- Set up buffer-local keymaps
-- Use buffer = 0 to target the current buffer
vim.keymap.set("n", "<leader>t", function() end, { desc = "+TODOs", buffer = 0 }) -- Placeholder
-- Keep <CR> mapping without expr = true
vim.keymap.set("i", "<CR>", press_enter, { desc = "Todoer: Handle Enter", buffer = 0 })
-- Tab handling for TODO items
vim.keymap.set("i", "<TAB>", press_tab, { desc = "Todoer: Handle Tab", buffer = 0 })
vim.keymap.set("i", "<S-Tab>", press_shift_tab, { desc = "Todoer: Handle Shift-Tab", buffer = 0 })
vim.keymap.set("n", "<leader>tt", toggle_todo, { desc = "Todoer: Toggle TODO", buffer = 0 })
-- New mappings for adding TODOs
vim.keymap.set("n", "<leader>ti", add_todo_insert_mode, { desc = "Todoer: Add TODO (cursor after marker)", buffer = 0, silent = true })
vim.keymap.set("n", "<leader>ta", add_todo_append_mode, { desc = "Todoer: Add TODO (cursor at end)", buffer = 0, silent = true })
vim.keymap.set("n", "<leader>to", add_todo_new_line_mode, { desc = "Todoer: Add new TODO line below", buffer = 0, silent = true })
-- Mapping for removing TODO markup
vim.keymap.set("n", "<leader>td", remove_todo_markup, { desc = "Todoer: Remove TODO markup", buffer = 0, silent = true })
-- Optional: Notify that keymaps are set for this buffer
-- vim.notify("Todoer keymaps activated for this buffer", vim.log.levels.INFO)
end
-- Setup function: Called by the user in their config
function M.setup(opts)
-- 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
return M

@ -1,98 +1,8 @@
vim.keymap.set("n", "<leader>t", function() end, { desc = "+Todos" }) -- This file is intentionally left blank or can contain comments.
-- The plugin is now activated by calling require('todoer').setup()
-- add new todo line when previous is already a todo -- in the user's Neovim configuration (e.g., init.lua or via a plugin manager).
local function press_enter() -- Example user configuration (e.g., in init.lua or using lazy.nvim):
local current_line = vim.api.nvim_get_current_line() -- require('todoer').setup({
-- Check if the current line matches the pattern -- filetypes = { 'markdown', 'txt' } -- Optional: override default filetypes
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('"\\<esc>"'), "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
vim.keymap.set("i", "<CR>", press_enter, { desc = "On enter", noremap = true, expr = true })
-- function that checks if the current line starts with the string "- [ ]" or "- [x]" and toggles the x
local function toggle_todo()
-- create a variable called openpattern with a pattern that matches a string that starts with any amount of spaces or tabs followed by "- [ ]"
local openpattern = "^%s*%- %[[ x]%]"
-- create a variable called closepattern with a pattern that matches a string that starts with any amount of spaces or tabs followed by "- [x]"
local closedpattern = "^%s*%- %[[ x]%]"
-- create a variable called titleopenpattern with a pattern that matches a string that starts with "# [ ]"
local titleopenpattern = "^# [ ]"
-- create a variable called titleclosedpattern with a pattern that matches a string that starts with "# [x]"
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)
end
-- if string.sub(line, 1, 5) == "- [ ]" then
-- line = string.sub(line, 6, -1)
-- line = "- [x]" .. line
-- vim.api.nvim_set_current_line(line)
-- elseif string.sub(line, 1, 5) == "- [x]" then
-- line = string.sub(line, 6, -1)
-- line = "- [ ]" .. line
-- vim.api.nvim_set_current_line(line)
-- elseif string.sub(line, 1, 5) == "# [ ]" then
-- line = string.sub(line, 6, -1)
-- line = "# [x]" .. line
-- vim.api.nvim_set_current_line(line)
-- elseif string.sub(line, 1, 5) == "# [x]" then
-- line = string.sub(line, 6, -1)
-- line = "# [ ]" .. line
-- vim.api.nvim_set_current_line(line)
-- end
end
vim.keymap.set("n", "<leader>tt", toggle_todo, { desc = "Toggle todo" })
-- 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 line = vim.api.nvim_get_current_line()
if string.sub(line, 1, 5) ~= "- [ ] " then
line = "- [ ] " .. line
vim.api.nvim_set_current_line(line)
vim.api.nvim_feedkeys("A", "n", true)
end
end
vim.keymap.set("n", "<leader>ta", add_todo, { desc = "Add todo" })
-- 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 line = vim.api.nvim_get_current_line()
if string.sub(line, 1, 6) == "- [ ] " or string.sub(line, 1, 6) == "- [x] " then
line = string.sub(line, 7, -1)
vim.api.nvim_set_current_line(line)
end
end
vim.keymap.set("n", "<leader>td", remove_todo, { desc = "Remove todo" })

Loading…
Cancel
Save