|  |  | @ -19,7 +19,8 @@ local function get_line_details(lnum) | 
			
		
	
		
		
			
				
					
					|  |  |  |   -- Returns: indent, marker, space_after_marker |  |  |  |   -- Returns: indent, marker, space_after_marker | 
			
		
	
		
		
			
				
					
					|  |  |  |   local marker_pattern = "^(%s*)([%-%*%+])(%s+)" |  |  |  |   local marker_pattern = "^(%s*)([%-%*%+])(%s+)" | 
			
		
	
		
		
			
				
					
					|  |  |  |   -- Pattern captures marker, checkbox '[ ]' or '[x]', and optional space after checkbox |  |  |  |   -- Pattern captures marker, checkbox '[ ]' or '[x]', and optional space after checkbox | 
			
		
	
		
		
			
				
					
					|  |  |  |   local todo_pattern = "^%s*[%-%*%+]%s+%[([ x])%]%s*" |  |  |  |   -- Matches lines like: "- [ ] task", "* [x] task", "+ [ ] task" | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |   local todo_pattern = "^(%s*[%-%*%+]%s+)%[([ x])%]%s*" -- Capture prefix before checkbox | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |   local _, marker_match, _ = string.match(line, marker_pattern) |  |  |  |   local _, marker_match, _ = string.match(line, marker_pattern) | 
			
		
	
		
		
			
				
					
					|  |  |  |   local is_todo = (string.match(line, todo_pattern) ~= nil) |  |  |  |   local is_todo = (string.match(line, todo_pattern) ~= nil) | 
			
		
	
	
		
		
			
				
					|  |  | @ -110,34 +111,65 @@ end | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | -- Internal function to set up buffer-local keymaps |  |  |  | -- Internal function to set up buffer-local keymaps | 
			
		
	
		
		
			
				
					
					|  |  |  | local function setup_buffer_keymaps() |  |  |  | local function setup_buffer_keymaps() | 
			
		
	
		
		
			
				
					
					|  |  |  | 	-- add new todo line when previous is already a todo (Will be refactored in Step 3) |  |  |  | 	-- Handles Enter key press in Insert mode | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  | 	local function press_enter() |  |  |  | 	local function press_enter() | 
			
		
	
		
		
			
				
					
					|  |  |  | 		local current_line = vim.api.nvim_get_current_line() |  |  |  |         local details, lnum = get_current_line_details() | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 		-- Check if the current line matches the pattern (Only checks '-' marker currently) |  |  |  |         if not details then | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 		local pattern = "^%s*%- %[[ x]%]%s*$" -- Simplified pattern to check if it's an empty-ish TODO line |  |  |  |             -- Fallback if getting details fails for some reason | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |         local content_pattern = "^%s*%- %[[ x]%]%s+(.+)" -- Pattern to check if there's content |  |  |  |             return vim.api.nvim_replace_termcodes("<CR>", true, false, true) | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |         end | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 		if string.match(current_line, content_pattern) then -- If it's a TODO with content |  |  |  | 
 | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |             local indent = string.match(current_line, "^%s*") or "" |  |  |  |         -- Check if the line is a TODO item and if it has content after the marker | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 			vim.api.nvim_feedkeys(vim.api.nvim_replace_termcodes("<CR>"..indent.."- [ ] ", true, false, true), "n", false) |  |  |  |         local has_content = details.content and not vim.trim(details.content):empty() | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 		elseif string.match(current_line, pattern) then -- If it's an empty TODO line |  |  |  | 
 | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 			-- Current behavior: clear line and insert newline (will change in Step 3) |  |  |  |         if details.is_todo and has_content then | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 			vim.api.nvim_feedkeys(vim.api.nvim_replace_termcodes("<Esc>S<CR>", true, false, true), "n", false) |  |  |  |             -- Case 1: Non-empty TODO line | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 		else -- Not a TODO line |  |  |  |             -- Create a new TODO line below with same indent/marker | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 			vim.api.nvim_feedkeys(vim.api.nvim_replace_termcodes("<CR>", true, false, true), "n", false) |  |  |  |             local new_marker = details.marker or "-" -- Should always have marker if is_todo, but safety check | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 		end |  |  |  |             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 }) | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             -- Action handled, return empty string because mapping is expr=true | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             return "" | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         elseif details.is_todo and not has_content then | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             -- Case 2: Empty TODO line (e.g., "- [ ]") | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             -- TODO: Implement Step 3 logic (outdenting) here later. | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             -- For now, keep the old (potentially problematic) feedkeys behavior | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             -- or simply clear the line and let Neovim handle Enter. | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             -- Let's try clearing the line and returning <CR> for now. | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             vim.api.nvim_buf_set_lines(0, lnum - 1, lnum, false, { details.indent }) -- Replace with just indent | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             return vim.api.nvim_replace_termcodes("<CR>", true, false, true) -- Let Neovim handle newline | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             -- Old feedkeys behavior (kept for reference, but commented out): | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             -- vim.api.nvim_feedkeys(vim.api.nvim_replace_termcodes("<Esc>S<CR>", true, false, true), "n", false) | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             -- return "" -- Feedkeys handles it | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         else | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             -- Case 3: Not a TODO line | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             -- Let Neovim handle the Enter key press normally | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             return vim.api.nvim_replace_termcodes("<CR>", true, false, true) | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         end | 
			
		
	
		
		
			
				
					
					|  |  |  | 	end |  |  |  | 	end | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | 	-- indent line if tab is pressed when line is a todo (Will be refactored in Step 4) |  |  |  | 	-- indent line if tab is pressed when line is a todo (Will be refactored in Step 4) | 
			
		
	
		
		
			
				
					
					|  |  |  | 	local function press_tab() |  |  |  | 	local function press_tab() | 
			
		
	
		
		
			
				
					
					|  |  |  | 		local current_line = vim.api.nvim_get_current_line() |  |  |  | 		local current_line = vim.api.nvim_get_current_line() | 
			
		
	
		
		
			
				
					
					|  |  |  | 		-- Check if current line matches the patterns (Only checks '-' marker currently) |  |  |  | 		-- Check if current line matches the patterns (Only checks '-' marker currently) | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         -- TODO: Update pattern to match *, + as well | 
			
		
	
		
		
			
				
					
					|  |  |  | 		local pattern = "^%s*%- %[[ x]%]" |  |  |  | 		local pattern = "^%s*%- %[[ x]%]" | 
			
		
	
		
		
			
				
					
					|  |  |  | 		if string.match(current_line, pattern) then |  |  |  | 		if string.match(current_line, pattern) then | 
			
		
	
		
		
			
				
					
					|  |  |  | 			-- print("tab pressed, allegedly") -- Removed print |  |  |  | 			-- print("tab pressed, allegedly") -- Removed print | 
			
		
	
		
		
			
				
					
					|  |  |  | 			vim.api.nvim_feedkeys(vim.api.nvim_replace_termcodes("<C-t>", true, false, true), "i", false) |  |  |  | 			vim.api.nvim_feedkeys(vim.api.nvim_replace_termcodes("<C-t>", true, false, true), "i", false) | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             return "" -- Action handled by feedkeys | 
			
		
	
		
		
			
				
					
					|  |  |  | 		else |  |  |  | 		else | 
			
		
	
		
		
			
				
					
					|  |  |  |             -- Return <Tab> to allow default behavior if expr=true is set on mapping |  |  |  |             -- Return <Tab> to allow default behavior | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |             return vim.api.nvim_replace_termcodes("<Tab>", true, false, true) |  |  |  |             return vim.api.nvim_replace_termcodes("<Tab>", true, false, true) | 
			
		
	
		
		
			
				
					
					|  |  |  |         end |  |  |  |         end | 
			
		
	
		
		
			
				
					
					|  |  |  | 	end |  |  |  | 	end | 
			
		
	
	
		
		
			
				
					|  |  | @ -146,12 +178,14 @@ local function setup_buffer_keymaps() | 
			
		
	
		
		
			
				
					
					|  |  |  | 	local function press_shift_tab() |  |  |  | 	local function press_shift_tab() | 
			
		
	
		
		
			
				
					
					|  |  |  | 		local current_line = vim.api.nvim_get_current_line() |  |  |  | 		local current_line = vim.api.nvim_get_current_line() | 
			
		
	
		
		
			
				
					
					|  |  |  | 		-- Check if current line matches the patterns (Only checks '-' marker currently) |  |  |  | 		-- Check if current line matches the patterns (Only checks '-' marker currently) | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         -- TODO: Update pattern to match *, + as well | 
			
		
	
		
		
			
				
					
					|  |  |  | 		local pattern = "^%s*%- %[[ x]%]" |  |  |  | 		local pattern = "^%s*%- %[[ x]%]" | 
			
		
	
		
		
			
				
					
					|  |  |  | 		if string.match(current_line, pattern) then |  |  |  | 		if string.match(current_line, pattern) then | 
			
		
	
		
		
			
				
					
					|  |  |  | 			-- print("shift tab pressed, allegedly") -- Removed print |  |  |  | 			-- print("shift tab pressed, allegedly") -- Removed print | 
			
		
	
		
		
			
				
					
					|  |  |  | 			vim.api.nvim_feedkeys(vim.api.nvim_replace_termcodes("<C-d>", true, false, true), "i", false) |  |  |  | 			vim.api.nvim_feedkeys(vim.api.nvim_replace_termcodes("<C-d>", true, false, true), "i", false) | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             return "" -- Action handled by feedkeys | 
			
		
	
		
		
			
				
					
					|  |  |  | 		else |  |  |  | 		else | 
			
		
	
		
		
			
				
					
					|  |  |  |             -- Return <S-Tab> to allow default behavior if expr=true is set on mapping |  |  |  |             -- Return <S-Tab> to allow default behavior | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |             return vim.api.nvim_replace_termcodes("<S-Tab>", true, false, true) |  |  |  |             return vim.api.nvim_replace_termcodes("<S-Tab>", true, false, true) | 
			
		
	
		
		
			
				
					
					|  |  |  |         end |  |  |  |         end | 
			
		
	
		
		
			
				
					
					|  |  |  | 	end |  |  |  | 	end | 
			
		
	
	
		
		
			
				
					|  |  | 
 |