Open benbrastmckie opened 1 year ago
Sorry for the very late reply, ive been busy lately.
Have you tried org mode? I am proposing to use a sort of org-mode way of doing lists.
There will be a function purely for cycling the list types
There will be a mapping that when pressed on top of a checkbox, completes it. (normally bound to enter in emacs)
When pressing enter on a list, the new created bullet will inherit the last line's properties (checkbox or no checkbox)
There will not be a function for removing checkboxes. this is easily doable in vim, and when creating a new bullet, not using checkboxes is as easy as deleting it. Then with the above changes, the next new bullet will not have checkboxes, as it inherits the no checkbox property.
Suppose that I have a list like:
- [x] something done - [ ] something undone - some other point - something further - etc.
Now say that I am hovering on the "some other point" line and run the
invert_entry
function with the mappings provided. Currently autolist turns it into an numbered list to all lines at that indentation. Intuitively what I would expect (and want) is that it would add the empty box on just the current line so that it looks like- [x]
.I should say that I like how autolist toggles through just
- [ ]
and- [x]
withinvert_entry
instead of also including-
with no box in the cycle. However, wheninvert_entry
is run on-
with no box, it would be great it if added a checked box so that it looks like- [x]
. If one wanted to remove a box altogether (empty or otherwise), that would have to be handled by a separate function which removes the box (empty or otherwise). In practice, I mostly don't remove boxes once they are added, so this further function is not super important for me.It would also be helpful to have a function which toggles between unnumbered dashes like
-
and a numbered list. For instance, consider the list (A) below:- [x] something done - [ ] something undone - something with no box
Were I to run the imagined toggle numbering function, I think the most natural result would be (B):
1. [x] something done 2. [ ] something undone 3. something with no box
Toggling number again would then return the (A) list. To summarise, here is the feature set I'm imagining:
* toggle checkmark (adding a box if none is present) * remove box (whether checked or not) * toggle numbering
Hope that all makes sense, and thanks again for a great plugin!
Not exactly what you are looking for, but I added a small enhancement to add a checkbox if there is non present in a list:
function handle_checkbox()
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 i, 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
end
::continue::
end
May be it is useful for you as well.
Amazing! That's super convenient. Works great!
I've been using the handle_checkbox()
function you included and noticed that it does not behave nicely if we have a list like:
The behaviour that would make sense to me if I were on the first node is to return:
Is this something difficult to fix, or would a minor tweak to what you provided fix it. Thanks again for your help!
I have used it only with -
or *
. But hopefully the following does the job for different list types (it is not the nicest code, sorry):
function M.handle_checkbox()
local config = require("autolist.config")
local auto = require("autolist.auto")
local checkbox_pattern = " [ ]"
local filetype_list = config.lists[vim.bo.filetype]
local line = vim.fn.getline(".")
for i, list_pattern in ipairs(filetype_list) do
local list_item = line:match("^%s*" .. list_pattern .. "%s*") -- only bullet, no checkbox
if list_item == nil then goto continue_for_loop end
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
list_item = list_item:gsub('%)', '%%)')
vim.fn.setline(".", (line:gsub(list_item, list_item .. checkbox_pattern, 1)))
local cursor_pos = vim.api.nvim_win_get_cursor(0)
if cursor_pos[2] > 0 then
vim.api.nvim_win_set_cursor(0, {cursor_pos[1], cursor_pos[2] + checkbox_pattern:len()})
end
goto continue
else
auto.toggle_checkbox()
goto continue
end
::continue_for_loop::
end
::continue::
end
I've been using the
handle_checkbox()
function you included and noticed that it does not behave nicely if we have a list like:1. some 2. thing
The behaviour that would make sense to me if I were on the first node is to return:
1. [x] some 2. thing
Is this something difficult to fix, or would a minor tweak to what you provided fix it. Thanks again for your help!
not sure if you had the chance to test the updated code above
not sure if you had the chance to test the updated code above
Thanks @kraxli I tried again and got your updated code working. I then modified it to this monstrosity (I am very much a beginner at Lua):
function HandleCheckbox()
local config = require("autolist.config")
local auto = require("autolist.auto")
local emptybox_pattern = " [ ]"
local progbox_pattern = " [.]"
local closebox_pattern = " [:]"
local donebox_pattern = " [x]"
local filetype_list = config.lists[vim.bo.filetype]
local line = vim.fn.getline(".")
for i, list_pattern in ipairs(filetype_list) do
local list_item = line:match("^%s*" .. list_pattern .. "%s*")
-- only bullet, no checkbox
if list_item == nil then goto continue_for_loop end
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
local is_emptybox_item = line:match("^%s*" .. list_pattern .. "%s*" .. "%[%s%]" .. "%s*") ~= nil
-- bullet and emptybox
local is_progbox_item = line:match("^%s*" .. list_pattern .. "%s*" .. "%[%.%]" .. "%s*") ~= nil
-- bullet and progbox
local is_closebox_item = line:match("^%s*" .. list_pattern .. "%s*" .. "%[%:%]" .. "%s*") ~= nil
-- bullet and closebox
local is_donebox_item = line:match("^%s*" .. list_pattern .. "%s*" .. "%[x%]" .. "%s*") ~= nil
-- bullet and closebox
if is_list_item == true and is_checkbox_item == false then
list_item = list_item:gsub('%)', '%%)')
vim.fn.setline(".", (line:gsub(list_item, list_item .. emptybox_pattern, 1)))
local cursor_pos = vim.api.nvim_win_get_cursor(0)
if cursor_pos[2] > 0 then
vim.api.nvim_win_set_cursor(0, { cursor_pos[1], cursor_pos[2] + emptybox_pattern:len() })
end
goto continue
elseif is_list_item == true and is_emptybox_item == true then
list_item = list_item:gsub('%)', '%%)')
vim.fn.setline(".", (line:gsub(" %[%s%]", progbox_pattern, 1)))
goto continue
elseif is_list_item == true and is_progbox_item == true then
list_item = list_item:gsub('%)', '%%)')
vim.fn.setline(".", (line:gsub(" %[%.%]", closebox_pattern, 1)))
goto continue
elseif is_list_item == true and is_closebox_item == true then
list_item = list_item:gsub('%)', '%%)')
vim.fn.setline(".", (line:gsub(" %[%:%]", donebox_pattern, 1)))
goto continue
elseif is_list_item == true and is_donebox_item == true then
list_item = list_item:gsub('%)', '%%)')
vim.fn.setline(".", (line:gsub(" %[x%]", "", 1)))
local cursor_pos = vim.api.nvim_win_get_cursor(0)
-- vim.cmd("norm! 0 | f]")
if cursor_pos[2] > donebox_pattern:len() then
vim.api.nvim_win_set_cursor(0, { cursor_pos[1], cursor_pos[2] - donebox_pattern:len() })
end
goto continue
else
auto.toggle_checkbox()
goto continue
end
::continue_for_loop::
end
::continue::
end
It works, cycling checkboxes through the following:
- item
- [ ] undone
- [.] started
- [:] close
- [x] done
- item
And round and round. I noticed that my linter says, "Unused local 'i'" at the beginning of the for-loop. There is also some funny business about where the cursor gets moved to if it is too close to the start of a line. In any case, I'd love any help improving this if someone knows how.
Suppose that I have a list like:
Now say that I am hovering on the "some other point" line and run the
invert_entry
function with the mappings provided. Currently autolist turns it into an numbered list to all lines at that indentation. Intuitively what I would expect (and want) is that it would add the empty box on just the current line so that it looks like- [x]
.I should say that I like how autolist toggles through just
- [ ]
and- [x]
withinvert_entry
instead of also including-
with no box in the cycle. However, wheninvert_entry
is run on-
with no box, it would be great it if added a checked box so that it looks like- [x]
. If one wanted to remove a box altogether (empty or otherwise), that would have to be handled by a separate function which removes the box (empty or otherwise). In practice, I mostly don't remove boxes once they are added, so this further function is not super important for me.It would also be helpful to have a function which toggles between unnumbered dashes like
-
and a numbered list. For instance, consider the list (A) below:Were I to run the imagined toggle numbering function, I think the most natural result would be (B):
Toggling number again would then return the (A) list. To summarise, here is the feature set I'm imagining:
Hope that all makes sense, and thanks again for a great plugin!