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
|
||||
|
||||
|
||||
" 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
|
||||
" ---------------------------------------------------------
|
||||
@ -1085,6 +1103,105 @@ function! vimwiki#lst#remove_cb_in_list() abort
|
||||
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
|
||||
|
@ -799,6 +799,18 @@ Vimwiki file.
|
||||
*:VimwikiRenameFile*
|
||||
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*
|
||||
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 VimwikiRenumberAllLists call vimwiki#lst#adjust_whole_buffer()
|
||||
command! -buffer VimwikiListToggle call vimwiki#lst#toggle_list_item()
|
||||
command! -buffer -range VimwikiRemoveDone call vimwiki#lst#remove_done(1, "<range>", <line1>, <line2>)
|
||||
|
||||
" table commands
|
||||
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