Add Possibility to fold on context or project

Closes #30

Folds now works the following way:

+ At initialisation, if all completed tasks are at the end, folds are
based on completed tasks only, else they are based on context
+ After a hierarchichal sort, folds are set by the first level between project and context
+ After a "normal" sort, folds are set only on completed tasks (as
before)

This work is greatly inspired from the snipped provided by @arecarn
This commit is contained in:
David Beniamine
2018-04-18 17:51:28 +02:00
parent d6256bcfe3
commit 7d70e30aae
2 changed files with 43 additions and 10 deletions

View File

@@ -150,6 +150,7 @@ endfunction
function! todo#Sort() function! todo#Sort()
" vim :sort is usually stable " vim :sort is usually stable
" we sort first on contexts, then on projects and then on priority " we sort first on contexts, then on projects and then on priority
let g:Todo_fold_char='x'
if expand('%')=~'[Dd]one.*.txt' if expand('%')=~'[Dd]one.*.txt'
" FIXME: Put some unit tests around this, and fix case sensitivity if ignorecase is set. " FIXME: Put some unit tests around this, and fix case sensitivity if ignorecase is set.
silent! %s/\(x\s*\d\{4}\)-\(\d\{2}\)-\(\d\{2}\)/\1\2\3/g silent! %s/\(x\s*\d\{4}\)-\(\d\{2}\)-\(\d\{2}\)/\1\2\3/g
@@ -268,6 +269,7 @@ function! todo#HierarchicalSort(symbol, symbolsub, dolastsort)
"Empty buffer do nothing "Empty buffer do nothing
return return
endif endif
let g:Todo_fold_char=a:symbol
"if the sort modes doesn't start by '!' it must start with a space "if the sort modes doesn't start by '!' it must start with a space
let l:sortmode=Todo_txt_InsertSpaceIfNeeded(g:Todo_txt_first_level_sort_mode) let l:sortmode=Todo_txt_InsertSpaceIfNeeded(g:Todo_txt_first_level_sort_mode)
let l:sortmodesub=Todo_txt_InsertSpaceIfNeeded(g:Todo_txt_second_level_sort_mode) let l:sortmodesub=Todo_txt_InsertSpaceIfNeeded(g:Todo_txt_second_level_sort_mode)

View File

@@ -106,26 +106,57 @@ setlocal foldmethod=expr
setlocal foldexpr=TodoFoldLevel(v:lnum) setlocal foldexpr=TodoFoldLevel(v:lnum)
setlocal foldtext=TodoFoldText() setlocal foldtext=TodoFoldText()
" Go to first completed task
let oldpos=getcurpos()
let g:Todo_fold_char='@'
let base_pos=search('^x\s', 'ce')
" Get next completed task
let first_incomplete = search('^\s*[^<x\s>]')
if (first_incomplete < base_pos)
" Check if all tasks from
let g:Todo_fold_char='x'
else
" TODO detect if sorted on prjects
let g:Todo_fold_char='@'
endif
call setpos('.', oldpos)
function! s:get_contextproject(line) abort "{{{2
return matchstr(getline(a:line), g:Todo_fold_char.'[^ ]\+')
endfunction "}}}3
" TodoFoldLevel(lnum) {{{2 " TodoFoldLevel(lnum) {{{2
function! TodoFoldLevel(lnum) function! TodoFoldLevel(lnum)
" The match function returns the index of the matching pattern or -1 if let this_context = s:get_contextproject(a:lnum)
" the pattern doesn't match. In this case, we always try to match a let next_context = s:get_contextproject(a:lnum - 1)
" completed task from the beginning of the line so that the matching
" function will always return -1 if the pattern doesn't match or 0 if the if g:Todo_fold_char == 'x'
" pattern matches. Incrementing by one the value returned by the matching " fold on cmpleted task
" function we will return 1 for the completed tasks (they will be at the
" first folding level) while for the other lines 0 will be returned,
" indicating that they do not fold.
return match(getline(a:lnum),'\C^x\s') + 1 return match(getline(a:lnum),'\C^x\s') + 1
endif
let fold_level = 0
if this_context ==# next_context
let fold_level = '1'
else
let fold_level = '>1'
endif
return fold_level
endfunction endfunction
" TodoFoldText() {{{2 " TodoFoldText() {{{2
function! TodoFoldText() function! TodoFoldText()
let this_context = s:get_contextproject(v:foldstart)
if g:Todo_fold_char == 'x'
let this_context = 'Completed tasks'
endif
" The text displayed at the fold is formatted as '+- N Completed tasks' " The text displayed at the fold is formatted as '+- N Completed tasks'
" where N is the number of lines folded. " where N is the number of lines folded.
return '+' . v:folddashes . ' ' return '+' . v:folddashes . ' '
\ . (v:foldend - v:foldstart + 1) \ . (v:foldend - v:foldstart + 1)
\ . ' Completed tasks ' \ .' '. this_context
endfunction endfunction
" Restore context {{{1 " Restore context {{{1