Functions to remove all todo items that are done (#906)
Add function VimwikiRemoveDone that will delete lines with todo list items marked as done. Works on ranges as well as without range on the current list. Co-authored-by: Tinmarino <tinmarino@gmail.com>
This commit is contained in:
parent
61093f4f2a
commit
a9f21c6d4a
@ -155,6 +155,24 @@ function! s:line_has_marker(lnum) abort
|
|||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
|
|
||||||
|
" Remove a list item and it's children (recursive)
|
||||||
|
function! s:remove_including_children(item)
|
||||||
|
let num_removed_lines = 1
|
||||||
|
let child = s:get_first_child(a:item)
|
||||||
|
while child.type != 0
|
||||||
|
let num_removed_lines += s:remove_including_children(child)
|
||||||
|
let child = s:get_first_child(a:item)
|
||||||
|
endwhile
|
||||||
|
exec a:item.lnum.'delete _'
|
||||||
|
return num_removed_lines
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
|
||||||
|
function! s:is_done(item)
|
||||||
|
return a:item.type != 0 && a:item.cb !=# '' && s:get_rate(a:item) == 100
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
|
||||||
" ---------------------------------------------------------
|
" ---------------------------------------------------------
|
||||||
" get properties of a list item
|
" get properties of a list item
|
||||||
" ---------------------------------------------------------
|
" ---------------------------------------------------------
|
||||||
@ -1085,6 +1103,105 @@ function! vimwiki#lst#remove_cb_in_list() abort
|
|||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
|
|
||||||
|
" Iterate over given todo list and remove all task that are done
|
||||||
|
" If recursive is true, child items will be checked too
|
||||||
|
function! s:remove_done_in_list(item, recursive)
|
||||||
|
" Clause non-null item type
|
||||||
|
if a:item.type == 0
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
" Recurse self on list item
|
||||||
|
let first_item = s:get_first_item_in_list(a:item, 0)
|
||||||
|
let total_lines_removed = 0
|
||||||
|
let cur_item = first_item
|
||||||
|
while 1
|
||||||
|
let next_item = s:get_next_list_item(cur_item, 0)
|
||||||
|
if s:is_done(cur_item)
|
||||||
|
let lines_removed = s:remove_including_children(cur_item)
|
||||||
|
elseif a:recursive
|
||||||
|
let lines_removed = s:remove_done_in_list(s:get_first_child(cur_item), a:recursive)
|
||||||
|
else
|
||||||
|
let lines_removed = 0
|
||||||
|
endif
|
||||||
|
let total_lines_removed += lines_removed
|
||||||
|
|
||||||
|
if next_item.type == 0
|
||||||
|
break
|
||||||
|
else
|
||||||
|
let next_item.lnum -= lines_removed
|
||||||
|
let cur_item = next_item
|
||||||
|
endif
|
||||||
|
endwhile
|
||||||
|
|
||||||
|
" Update state of parent item (percentage of done)
|
||||||
|
call s:update_state(s:get_parent(first_item))
|
||||||
|
return total_lines_removed
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
|
||||||
|
" Iterate over the list that the cursor is positioned in
|
||||||
|
" and remove all lines of task that are done.
|
||||||
|
" If recursive is true, child items will be checked too
|
||||||
|
function! vimwiki#lst#remove_done_in_current_list(recursive)
|
||||||
|
let item = s:get_corresponding_item(line('.'))
|
||||||
|
call s:remove_done_in_list(item, a:recursive)
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
|
||||||
|
" Remove selected lines if they contain a task that is done
|
||||||
|
function! vimwiki#lst#remove_done_in_range(first_line, last_line)
|
||||||
|
let first_item = s:get_corresponding_item(a:first_line)
|
||||||
|
let last_item = s:get_corresponding_item(a:last_line)
|
||||||
|
|
||||||
|
" Clause non-null first and last type item
|
||||||
|
if first_item.type == 0 || last_item.type == 0
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
" For each line, delete done tasks
|
||||||
|
let parent_items_of_lines = []
|
||||||
|
let cur_ln = first_item.lnum
|
||||||
|
let end_ln = last_item.lnum
|
||||||
|
while cur_ln > 0 && cur_ln <= end_ln
|
||||||
|
let cur_item = s:get_item(cur_ln)
|
||||||
|
if s:is_done(cur_item)
|
||||||
|
let cur_parent_item = s:get_parent(cur_item)
|
||||||
|
if index(parent_items_of_lines, cur_parent_item) == -1
|
||||||
|
call insert(parent_items_of_lines, cur_parent_item)
|
||||||
|
endif
|
||||||
|
exe cur_ln.'delete _'
|
||||||
|
let cur_ln -= 1
|
||||||
|
let end_ln -= 1
|
||||||
|
endif
|
||||||
|
let cur_ln = s:get_next_line(cur_ln)
|
||||||
|
endwhile
|
||||||
|
|
||||||
|
" Update all parent state (percentage of done)
|
||||||
|
for parent_item in parent_items_of_lines
|
||||||
|
call s:update_state(parent_item)
|
||||||
|
endfor
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
|
||||||
|
" wrapper function to distinguish between function used with a range or not
|
||||||
|
" vim 8.0.1089 and newer and corresponding neovim versions allow to use <range> to distinguish if
|
||||||
|
" the function has been called with a range. For older versions we use remove_done_in_range if
|
||||||
|
" first and last line are identical, which means there was either no range or the range was within
|
||||||
|
" one line.
|
||||||
|
function! vimwiki#lst#remove_done(recursive, range, first_line, last_line)
|
||||||
|
if a:range ==# '<range>'
|
||||||
|
let range = a:first_line != a:last_line
|
||||||
|
else
|
||||||
|
let range = a:range > 0
|
||||||
|
endif
|
||||||
|
if range
|
||||||
|
call vimwiki#lst#remove_done_in_range(a:first_line, a:last_line)
|
||||||
|
else
|
||||||
|
call vimwiki#lst#remove_done_in_current_list(a:recursive)
|
||||||
|
endif
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
|
||||||
" ---------------------------------------------------------
|
" ---------------------------------------------------------
|
||||||
" change the level of list items
|
" change the level of list items
|
||||||
|
@ -799,6 +799,18 @@ Vimwiki file.
|
|||||||
*:VimwikiRenameFile*
|
*:VimwikiRenameFile*
|
||||||
Rename the wiki page you are in.
|
Rename the wiki page you are in.
|
||||||
|
|
||||||
|
*:VimwikiRemoveDone*
|
||||||
|
With range: Remove all lines that have a checked |vimwiki-todo-lists| checkbox
|
||||||
|
|
||||||
|
Otherwise:
|
||||||
|
Remove all lines in the current todo-list that have a checked box. This is
|
||||||
|
applied to the list in which the cursor is in, as well as all its sublists.
|
||||||
|
The status of parents is updated accordingly.
|
||||||
|
If you want to remove only items of the current nesting level, (re)define
|
||||||
|
a command that calls the same function with `0` as first argument: >
|
||||||
|
:command! -buffer -range VimwikiRemoveDone call
|
||||||
|
\ vimwiki#lst#remove_done(0, "<range>", <line1>, <line2>)
|
||||||
|
<
|
||||||
*:VimwikiNextTask*
|
*:VimwikiNextTask*
|
||||||
Jump to the next unfinished task in the current wiki page.
|
Jump to the next unfinished task in the current wiki page.
|
||||||
|
|
||||||
|
@ -297,6 +297,7 @@ command! -buffer VimwikiRemoveCBInList call vimwiki#lst#remove_cb_in_list()
|
|||||||
command! -buffer VimwikiRenumberList call vimwiki#lst#adjust_numbered_list()
|
command! -buffer VimwikiRenumberList call vimwiki#lst#adjust_numbered_list()
|
||||||
command! -buffer VimwikiRenumberAllLists call vimwiki#lst#adjust_whole_buffer()
|
command! -buffer VimwikiRenumberAllLists call vimwiki#lst#adjust_whole_buffer()
|
||||||
command! -buffer VimwikiListToggle call vimwiki#lst#toggle_list_item()
|
command! -buffer VimwikiListToggle call vimwiki#lst#toggle_list_item()
|
||||||
|
command! -buffer -range VimwikiRemoveDone call vimwiki#lst#remove_done(1, "<range>", <line1>, <line2>)
|
||||||
|
|
||||||
" table commands
|
" table commands
|
||||||
command! -buffer -nargs=* VimwikiTable call vimwiki#tbl#create(<f-args>)
|
command! -buffer -nargs=* VimwikiTable call vimwiki#tbl#create(<f-args>)
|
||||||
|
199
test/list_clean.vader
Normal file
199
test/list_clean.vader
Normal file
@ -0,0 +1,199 @@
|
|||||||
|
Include: vader_includes/vader_setup.vader
|
||||||
|
|
||||||
|
Given vimwiki (simple list):
|
||||||
|
* [X] Done 1
|
||||||
|
* [ ] Todo 1
|
||||||
|
* [X] Done 2
|
||||||
|
* [ ] Todo 2
|
||||||
|
|
||||||
|
Execute (Set syntax to default):
|
||||||
|
call SetSyntax('default')
|
||||||
|
|
||||||
|
Do (clean done, without recursion):
|
||||||
|
:call vimwiki#lst#remove_done_in_current_list(0)\<Enter>
|
||||||
|
|
||||||
|
Expect (two removed):
|
||||||
|
* [ ] Todo 1
|
||||||
|
* [ ] Todo 2
|
||||||
|
|
||||||
|
Given vimwiki (simple list):
|
||||||
|
* [X] Done 1
|
||||||
|
* [ ] Todo 1
|
||||||
|
* [X] Done 2
|
||||||
|
* [ ] Todo 2
|
||||||
|
|
||||||
|
Do (clean done with recursion, function):
|
||||||
|
:call vimwiki#lst#remove_done_in_current_list(1)\<Enter>
|
||||||
|
|
||||||
|
Expect (two removed):
|
||||||
|
* [ ] Todo 1
|
||||||
|
* [ ] Todo 2
|
||||||
|
|
||||||
|
Given vimwiki (simple list):
|
||||||
|
* [X] Done 1
|
||||||
|
* [ ] Todo 1
|
||||||
|
* [X] Done 2
|
||||||
|
* [ ] Todo 2
|
||||||
|
|
||||||
|
Do (clean done with recursion, command):
|
||||||
|
:VimwikiRemoveDone\<Enter>
|
||||||
|
|
||||||
|
Expect (two removed):
|
||||||
|
* [ ] Todo 1
|
||||||
|
* [ ] Todo 2
|
||||||
|
|
||||||
|
Given vimwiki (with sub items):
|
||||||
|
* [X] Done 1
|
||||||
|
* [X] Subdone 1
|
||||||
|
* [ ] Todo 1
|
||||||
|
* [o] Done 2
|
||||||
|
* [X] Subdone1
|
||||||
|
* [ ] Subtodo
|
||||||
|
* [ ] Todo 2
|
||||||
|
|
||||||
|
Do (clean done, without recursion):
|
||||||
|
:call vimwiki#lst#remove_done_in_current_list(0)\<Enter>
|
||||||
|
|
||||||
|
Expect (first removed):
|
||||||
|
* [ ] Todo 1
|
||||||
|
* [o] Done 2
|
||||||
|
* [X] Subdone1
|
||||||
|
* [ ] Subtodo
|
||||||
|
* [ ] Todo 2
|
||||||
|
|
||||||
|
Given vimwiki (with sub items):
|
||||||
|
* [ ] Todo 1
|
||||||
|
* [o] Done 2
|
||||||
|
* [X] Subdone1
|
||||||
|
* [ ] Subtodo
|
||||||
|
* [ ] Todo 2
|
||||||
|
|
||||||
|
Do (clean done, with recursion):
|
||||||
|
:call vimwiki#lst#remove_done_in_current_list(1)\<Enter>
|
||||||
|
|
||||||
|
Expect (all removed):
|
||||||
|
* [ ] Todo 1
|
||||||
|
* [ ] Done 2
|
||||||
|
* [ ] Subtodo
|
||||||
|
* [ ] Todo 2
|
||||||
|
|
||||||
|
Given vimwiki (nested list with space and code):
|
||||||
|
* [X] Done 1
|
||||||
|
* [ ] Todo 1
|
||||||
|
|
||||||
|
* [ ] Todo Post space
|
||||||
|
* [X] Done Post space
|
||||||
|
|
||||||
|
* [ ] Todo code
|
||||||
|
{{{code
|
||||||
|
* [X] print "hello, world"
|
||||||
|
}}}
|
||||||
|
|
||||||
|
* [ ] Post code Todo
|
||||||
|
* [X] Done Sub-child
|
||||||
|
* [X] Sub-sub-child
|
||||||
|
* Without cb
|
||||||
|
* [X] Post code Done
|
||||||
|
* [X] Done Sub-child
|
||||||
|
* [X] Sub-sub-child
|
||||||
|
* Without cb
|
||||||
|
|
||||||
|
Do (clean done, without recursion):
|
||||||
|
:call vimwiki#lst#remove_done_in_current_list(0)\<Enter>
|
||||||
|
|
||||||
|
Expect (removed):
|
||||||
|
* [ ] Todo 1
|
||||||
|
|
||||||
|
* [ ] Todo Post space
|
||||||
|
|
||||||
|
* [ ] Todo code
|
||||||
|
{{{code
|
||||||
|
* [X] print "hello, world"
|
||||||
|
}}}
|
||||||
|
|
||||||
|
* [ ] Post code Todo
|
||||||
|
* [X] Done Sub-child
|
||||||
|
* [X] Sub-sub-child
|
||||||
|
* Without cb
|
||||||
|
|
||||||
|
Given vimwiki (nested list with space and code):
|
||||||
|
* [X] Done 1
|
||||||
|
* [ ] Todo 1
|
||||||
|
|
||||||
|
* [ ] Todo Post space
|
||||||
|
* [X] Done Post space
|
||||||
|
|
||||||
|
* [ ] Todo code
|
||||||
|
{{{code
|
||||||
|
* [X] print "hello, world"
|
||||||
|
}}}
|
||||||
|
|
||||||
|
* [ ] Post code Todo
|
||||||
|
* [X] Done Sub-child
|
||||||
|
* [X] Sub-sub-child
|
||||||
|
* Without cb
|
||||||
|
* [X] Post code Done
|
||||||
|
* [X] Done Sub-child
|
||||||
|
* [X] Sub-sub-child
|
||||||
|
* Without cb
|
||||||
|
|
||||||
|
Do (clean done, with recursion):
|
||||||
|
:call vimwiki#lst#remove_done_in_current_list(1)\<Enter>
|
||||||
|
|
||||||
|
Expect (removed):
|
||||||
|
* [ ] Todo 1
|
||||||
|
|
||||||
|
* [ ] Todo Post space
|
||||||
|
|
||||||
|
* [ ] Todo code
|
||||||
|
{{{code
|
||||||
|
* [X] print "hello, world"
|
||||||
|
}}}
|
||||||
|
|
||||||
|
* [ ] Post code Todo
|
||||||
|
|
||||||
|
Given vimwiki (two lists):
|
||||||
|
* [X] Done 1
|
||||||
|
* [ ] Todo 1
|
||||||
|
|
||||||
|
Line in between.
|
||||||
|
|
||||||
|
* [ ] Todo Post space
|
||||||
|
* [X] Done Post space
|
||||||
|
|
||||||
|
Do (clean done, with recursion):
|
||||||
|
:call vimwiki#lst#remove_done_in_current_list(1)\<Enter>
|
||||||
|
|
||||||
|
Expect (only first is removed):
|
||||||
|
* [ ] Todo 1
|
||||||
|
|
||||||
|
Line in between.
|
||||||
|
|
||||||
|
* [ ] Todo Post space
|
||||||
|
* [X] Done Post space
|
||||||
|
|
||||||
|
Given vimwiki (list):
|
||||||
|
* [X] Done 1
|
||||||
|
* [ ] Todo 1
|
||||||
|
|
||||||
|
Line in between.
|
||||||
|
|
||||||
|
* [X] Done 2
|
||||||
|
* [X] Done 3
|
||||||
|
* [ ] Todo 2
|
||||||
|
* [X] Done 4
|
||||||
|
|
||||||
|
Do (clean done, with range):
|
||||||
|
:1,6VimwikiRemoveDone\<Enter>
|
||||||
|
|
||||||
|
Expect (only first is removed):
|
||||||
|
* [ ] Todo 1
|
||||||
|
|
||||||
|
Line in between.
|
||||||
|
|
||||||
|
* [X] Done 3
|
||||||
|
* [ ] Todo 2
|
||||||
|
* [X] Done 4
|
||||||
|
|
||||||
|
|
||||||
|
Include: vader_includes/vader_teardown.vader
|
Loading…
Reference in New Issue
Block a user