gaoDean / autolist.nvim

Automatic list continuation and formatting for neovim, powered by lua
MIT License
242 stars 5 forks source link

Feature request: complete checked checkboxes with empty checkboxes #86

Open mawkler opened 7 months ago

mawkler commented 7 months ago

When creating a new line on a line with checked checkboxes the new line also gets a checked checkbox. To me, it would make more sense if a new checkbox line gets an empty check box. Since you just created the checkbox you've probably not completed the task in the list of checkboxes.

Here's an example where | is the cursor in insert-mode:

- [x] foo
- [x] bar|

Pressing <CR> currently yields this:

- [x] foo
- [x] bar
- [x] |

This is the behaviour that I think makes more sense:

- [x] foo
- [x] bar|

Pressing <CR>:

- [x] foo
- [x] bar
- [ ] |

What do you say?

benbrastmckie commented 7 months ago

I have also noticed this. I've tried to fix it, but don't have the Lua skills yet (in development).

Also related to this feature request, @kraxli provided this function here for toggling checkboxes, adding an empty checkbox if there is none.

function HandleCheckbox()
  local config = require("autolist.config")
  local auto = require("autolist.auto")

  local checkbox_pattern = " [ ]"

  local filetype_lists = config.lists[vim.bo.filetype]
  local line = vim.fn.getline(".")

  for index, list_pattern in ipairs(filetype_lists) do
    local list_item = line:match("^%s*" .. list_pattern .. "%s*") -- only bullet, no checkbox
    list_item = list_item:gsub("%s+", "")
    local is_list_item = list_item ~=
        nil -- only bullet, no checkbox
    local is_checkbox_item = line:match("^%s*" .. list_pattern .. "%s*" .. "%[.%]" .. "%s*") ~=
        nil -- bullet and checkbox

    if is_list_item == true and is_checkbox_item == false then
      vim.fn.setline(".", (line:gsub(list_item, list_item .. checkbox_pattern, 1)))
      local cursor_pos = vim.api.nvim_win_get_cursor(0)
      vim.api.nvim_win_set_cursor(0, { cursor_pos[1], cursor_pos[2] + checkbox_pattern:len() })
      goto continue
    else
      auto.toggle_checkbox()
      goto continue
    end
    -- ::continue_for_loop::
  end
  ::continue::
end

I commented out the continue_for_loop since it seemed to be unused. I am also unsure if the index (originally called i) ever gets used. I can't see that it does. Nevertheless, it works.

I would like to extend the function to cycle through the following:

- new item
- [ ] started
- [.] in progress 
- [:] almost finished 
- [x] complete

Instead of cycling in a loop in one direction, I think the best would be to have a function which moves towards completion (stopping there), and another function which moves backwards (stopping at the dash).

Any thoughts on how to do this would be greatly appreciated.