@@ -48,33 +48,21 @@ endfunction
4848function ! VimTodoListsSetItemDone (lineno)
4949 let l: line = getline (a: lineno )
5050 call setline (a: lineno , substitute (l: line , ' ^\(\s*\)\[ \]' , ' \1[X]' , ' ' ))
51-
52- let l: move_position = VimTodoListsFindTargetPositionDown (a: lineno )
53- if l: move_position != -1
54- call VimTodoListsMoveSubtree (a: lineno , l: move_position )
55- endif
56-
5751endfunction
5852
5953
6054" Sets the item not done
6155function ! VimTodoListsSetItemNotDone (lineno)
6256 let l: line = getline (a: lineno )
6357 call setline (a: lineno , substitute (l: line , ' ^\(\s*\)\[X\]' , ' \1[ ]' , ' ' ))
64-
65- let l: move_position = VimTodoListsFindTargetPositionUp (a: lineno )
66- if l: move_position != -1
67- call VimTodoListsMoveSubtree (a: lineno , l: move_position )
68- endif
69-
7058endfunction
7159
7260
7361" Checks that line is a todo list item
7462function ! VimTodoListsLineIsItem (line )
7563 if match (a: line , ' ^\s*\[[ X]\].*' ) != -1
7664 return 1
77- else
65+ endif
7866
7967 return 0
8068endfunction
@@ -84,8 +72,6 @@ endfunction
8472function ! VimTodoListsItemIsNotDone (line )
8573 if match (a: line , ' ^\s*\[ \].*' ) != -1
8674 return 1
87- else
88- return 0
8975 endif
9076
9177 return 0
@@ -96,8 +82,6 @@ endfunction
9682function ! VimTodoListsItemIsDone (line )
9783 if match (a: line , ' ^\s*\[X\].*' ) != -1
9884 return 1
99- else
100- return 0
10185 endif
10286
10387 return 0
@@ -129,9 +113,9 @@ endfunction
129113
130114
131115" Finds the insert position above the item
132- function ! VimTodoListsFindTargetPositionUp (line )
133- let l: range = range (a: line , 1 , -1 )
134- let l: candidate_line = VimTodoListsBrotherItemInRange (a: line , l: range )
116+ function ! VimTodoListsFindTargetPositionUp (lineno )
117+ let l: range = range (a: lineno , 1 , -1 )
118+ let l: candidate_line = VimTodoListsBrotherItemInRange (a: lineno , l: range )
135119 let l: target_line = -1
136120
137121 while l: candidate_line != -1
@@ -183,11 +167,15 @@ function! VimTodoListsMoveSubtree(lineno, position)
183167 " where it was before
184168 call cursor (l: cursor_pos [1 ], l: cursor_pos [4 ])
185169 else
186- if VimTodoListsItemIsNotDone (getline (a: position ))
187- execute ' normal! p'
188- else
170+ let l: indent = VimTodoListsCountLeadingSpaces (getline (a: lineno ))
171+
172+ if VimTodoListsItemIsDone (getline (a: position )) &&
173+ \ (VimTodoListsCountLeadingSpaces (getline (a: position )) == l: indent )
189174 execute ' normal! P'
175+ else
176+ execute ' normal! p'
190177 endif
178+
191179 " In case of moving item up the text became one longer by a subtree length
192180 call cursor (l: cursor_pos [1 ] + l: subtree_length , l: cursor_pos [4 ])
193181 endif
@@ -198,6 +186,26 @@ function! VimTodoListsMoveSubtree(lineno, position)
198186endfunction
199187
200188
189+ " Moves the subtree up
190+ function ! VimTodoListsMoveSubtreeUp (lineno)
191+ let l: move_position = VimTodoListsFindTargetPositionUp (a: lineno )
192+
193+ if l: move_position != -1
194+ call VimTodoListsMoveSubtree (a: lineno , l: move_position )
195+ endif
196+ endfunction
197+
198+
199+ " Moves the subtree down
200+ function ! VimTodoListsMoveSubtreeDown (lineno)
201+ let l: move_position = VimTodoListsFindTargetPositionDown (a: lineno )
202+
203+ if l: move_position != -1
204+ call VimTodoListsMoveSubtree (a: lineno , l: move_position )
205+ endif
206+ endfunction
207+
208+
201209" Counts the number of leading spaces
202210function ! VimTodoListsCountLeadingSpaces (line )
203211 return (strlen (a: line ) - strlen (substitute (a: line , ' ^\s*' , ' ' , ' ' )))
@@ -264,12 +272,14 @@ function! VimTodoListsUpdateParent(lineno)
264272 if VimTodoListsItemIsNotDone (getline (current_line)) == 1
265273 " Not all children are done
266274 call VimTodoListsSetItemNotDone (l: parent_lineno )
275+ call VimTodoListsMoveSubtreeUp (l: parent_lineno )
267276 call VimTodoListsUpdateParent (l: parent_lineno )
268277 return
269278 endif
270279 endfor
271280
272281 call VimTodoListsSetItemDone (l: parent_lineno )
282+ call VimTodoListsMoveSubtreeDown (l: parent_lineno )
273283 call VimTodoListsUpdateParent (l: parent_lineno )
274284endfunction
275285
@@ -278,20 +288,11 @@ endfunction
278288function ! VimTodoListsForEachChild (lineno, function )
279289 let l: last_child_lineno = VimTodoListsFindLastChild (a: lineno )
280290
281- " No children items
282- if l: last_child_lineno == a: lineno
283- call call (a: function , [a: lineno ])
284- return
285- endif
286-
287291 " Apply the function on children prior to the item.
288292 " This order is required for proper work of the items moving on toggle
289- for current_line in range (a: lineno + 1 , l: last_child_lineno )
293+ for current_line in range (a: lineno , l: last_child_lineno )
290294 call call (a: function , [current_line])
291295 endfor
292-
293- call call (a: function , [a: lineno ])
294-
295296endfunction
296297
297298
@@ -368,8 +369,10 @@ function! VimTodoListsToggleItem()
368369
369370 if VimTodoListsItemIsNotDone (l: line ) == 1
370371 call VimTodoListsForEachChild (line (' .' ), ' VimTodoListsSetItemDone' )
372+ call VimTodoListsMoveSubtreeDown (line (' .' ))
371373 elseif VimTodoListsItemIsDone (l: line ) == 1
372374 call VimTodoListsForEachChild (line (' .' ), ' VimTodoListsSetItemNotDone' )
375+ call VimTodoListsMoveSubtreeUp (line (' .' ))
373376 endif
374377
375378 " Restore the current position
0 commit comments