Fix sorting bugs with 'due:' at the start of the line, and properly handle completed tasks with lastdue and notoverdue post sort cursor preferences
This commit is contained in:
@@ -169,7 +169,7 @@ endfunction
|
|||||||
|
|
||||||
function! todo#SortDue()
|
function! todo#SortDue()
|
||||||
" Check how many lines have a due:date on them
|
" Check how many lines have a due:date on them
|
||||||
let l:tasksWithDueDate = 0
|
let l:tasksWithDueDate = 0
|
||||||
silent! %global/\v\c<due:\d{4}-\d{2}-\d{2}>/let l:tasksWithDueDate += 1
|
silent! %global/\v\c<due:\d{4}-\d{2}-\d{2}>/let l:tasksWithDueDate += 1
|
||||||
if l:tasksWithDueDate == 0
|
if l:tasksWithDueDate == 0
|
||||||
" No tasks with a due:date: No need to modify the buffer at all
|
" No tasks with a due:date: No need to modify the buffer at all
|
||||||
@@ -183,27 +183,47 @@ function! todo#SortDue()
|
|||||||
silent %global/\v\c<due:\d{8}>/throw "Text matching 'due:\\d\\{8\\}' exists in the buffer, this function cannot sort your buffer"
|
silent %global/\v\c<due:\d{8}>/throw "Text matching 'due:\\d\\{8\\}' exists in the buffer, this function cannot sort your buffer"
|
||||||
" Turn the due:date from due:yyyy-mm-dd to due:yyyymmdd so we can do a numeric sort
|
" Turn the due:date from due:yyyy-mm-dd to due:yyyymmdd so we can do a numeric sort
|
||||||
silent! %substitute/\v<(due:\d{4})\-(\d{2})\-(\d{2})>/\1\2\3/ei
|
silent! %substitute/\v<(due:\d{4})\-(\d{2})\-(\d{2})>/\1\2\3/ei
|
||||||
" Sort all the lines with due: by numeric yyyymmdd, they will end up in ascending order at the bottom of the buffer
|
" Sort all the lines with due: by numeric yyyymmdd, they will end up in ascending order at the bottom of the buffer
|
||||||
sort in /\v<due:\ze\d{8}>/
|
sort in /\v<due:\ze\d{8}>/
|
||||||
" Determine the line number of the first task with a due:date
|
" Determine the line number of the first task with a due:date
|
||||||
let l:firstLineWithDue = line("$") - l:tasksWithDueDate + 1
|
let l:firstLineWithDue = line("$") - l:tasksWithDueDate + 1
|
||||||
" Put the sorted lines at the beginning of the file
|
" Put the sorted lines at the beginning of the file
|
||||||
if l:firstLineWithDue > 1
|
if l:firstLineWithDue > 1
|
||||||
" ...but only if the whole file didn't get sorted.
|
" ...but only if the whole file didn't get sorted.
|
||||||
execute "silent " . l:firstLineWithDue . ",$move 0"
|
execute "silent " . l:firstLineWithDue . ",$move 0"
|
||||||
endif
|
endif
|
||||||
" Change the due:yyyymmdd back to due:yyyy-mm-dd.
|
" Change the due:yyyymmdd back to due:yyyy-mm-dd.
|
||||||
silent! %substitute/\v<(due:\d{4})(\d{2})(\d{2})>/\1-\2-\3/ei
|
silent! %substitute/\v<(due:\d{4})(\d{2})(\d{2})>/\1-\2-\3/ei
|
||||||
silent global/^x /move$
|
silent global/^x /move$
|
||||||
" Let's check a global for a user preference on the cursor position.
|
" Let's check a global for a user preference on the cursor position.
|
||||||
if exists("g:TodoTxtSortDueDateCursorPos")
|
if exists("g:TodoTxtSortDueDateCursorPos")
|
||||||
if g:TodoTxtSortDueDateCursorPos ==? "top"
|
if g:TodoTxtSortDueDateCursorPos ==? "top"
|
||||||
normal gg
|
normal gg
|
||||||
elseif g:TodoTxtSortDueDateCursorPos ==? "lastdue"
|
elseif g:TodoTxtSortDueDateCursorPos ==? "lastdue" || g:TodoTxtSortDueDateCursorPos ==? "notoverdue"
|
||||||
" Nothing to do
|
silent normal G
|
||||||
elseif g:TodoTxtSortDueDateCursorPos ==? "notoverdue"
|
" Sorry for the crazy RegExp. The next command should put cursor at at the top of the completed tasks,
|
||||||
|
" or the bottom of the buffer. This is done by searching backwards for any line not starting with
|
||||||
|
" "x " (x, space) which is important to distinguish from "xample task" for instance, which the more
|
||||||
|
" simple "^[^x]" would match. More info: ":help /\@!".
|
||||||
:silent! ?\v^(x )@!?+1
|
:silent! ?\v^(x )@!?+1
|
||||||
let l:overduePat = todo#GetDateRegexForPastDates()
|
let l:overduePat = todo#GetDateRegexForPastDates()
|
||||||
|
let l:lastwrapscan = &wrapscan
|
||||||
|
set nowrapscan
|
||||||
|
try
|
||||||
|
if g:TodoTxtSortDueDateCursorPos ==? "lastdue"
|
||||||
|
" This searches backwards for the last due task
|
||||||
|
:?\v\c<due:\d{4}\-\d{2}\-\d{2}>
|
||||||
|
elseif g:TodoTxtSortDueDateCursorPos ==? "notoverdue"
|
||||||
|
" This searches backwards for the last overdue task, and positions the cursor on the following line
|
||||||
|
execute ":?\\v\\c<due:" . l:overduePat . ">?+1"
|
||||||
|
endif
|
||||||
|
catch
|
||||||
|
" Might fail if there are no active (or overdue) due:date tasks. Requires nowrapscan
|
||||||
|
" This code path always means we want to be at the top of the buffer
|
||||||
|
normal gg
|
||||||
|
finally
|
||||||
|
let &wrapscan = l:lastwrapscan
|
||||||
|
endtry
|
||||||
elseif g:TodoTxtSortDueDateCursorPos ==? "notoverdue"
|
elseif g:TodoTxtSortDueDateCursorPos ==? "notoverdue"
|
||||||
elseif g:TodoTxtSortDueDateCursorPos ==? "bottom"
|
elseif g:TodoTxtSortDueDateCursorPos ==? "bottom"
|
||||||
silent normal G
|
silent normal G
|
||||||
|
|||||||
Reference in New Issue
Block a user