From 9f87eec204f02445a7605de31d50541dead6258b Mon Sep 17 00:00:00 2001 From: David Beniamine Date: Wed, 8 Jul 2015 09:27:59 +0200 Subject: [PATCH] More flexible file naming (Request #2) CHG: More flexible file naming files matching one of the following are todo files: YYYY-MM-[Tt]odo.txt YYYY-MM-DD[Tt]odo.txt [Tt]odo-YYYY-MM.txt [Tt]odo-YYYY-MM-DD.txt [Tt]odo.txt [Tt]oday.txt YYYY-MM-[Dd]one.txt YYYY-MM-DD[Dd]one.txt [Dd]one-YYYY-MM.txt [Dd]one-YYYY-MM-DD.txt [Dd]one.txt [Dd]one-[Tt]oday.txt Moreover, remove complete tasks (D) moves the task to the done.txt file corresponding to the current todo.txt, aka if you are editing 2015-07-07-todo.txt, the done file while be 2015-07-07-done.txt. This behaviour can be cancelled by fixing the done filename using g:TodoTxtForceDoneName FIX: Bug while completing empty file --- README.markdown | 36 +++++++++++++++++-- doc/todo.txt | 65 +++++++++++++++++++++++++++------- ftdetect/todo.vim | 11 +++++- ftplugin/todo.vim | 90 ++++++++++++++++++++++++++--------------------- 4 files changed, 144 insertions(+), 58 deletions(-) diff --git a/README.markdown b/README.markdown index 51a835d..b250ff6 100644 --- a/README.markdown +++ b/README.markdown @@ -3,9 +3,11 @@ ## What is this plugin ? This plugin is a fork of [freitass -todo.txt](https://github.com/freitass/todo.txt-vim). It add severals functionalities including a [hierarchical sort](#sort), a -[complete](#completion) function, some stuff to handle [due dates](#due-dates) -and others stuff see [new features](#new-features). +todo.txt](https://github.com/freitass/todo.txt-vim). It add severals +functionalities including a [hierarchical sort](#sort), a +[complete](#completion) function, some stuff to handle [due +dates](#due-dates), a more [flexible file naming](#flexible-file-naming), and +others stuff see [new features](#new-features). Freitass announced on october 30th 2014 that he is not going to merge his version. @@ -120,6 +122,34 @@ sorted by at the beginning of the file, the rest of the file is not modified. `DUE:` : (Insert mode) Insert `DUE:` followed by the current date +### Flexible File naming + +This plugin provides a Flexible file naming for todo.txt, all the following +names are recognized as todo: + + YYYY-MM-[Tt]odo.txt + YYYY-MM-DD[Tt]odo.txt + [Tt]odo-YYYY-MM.txt + [Tt]odo-YYYY-MM-DD.txt + [Tt]odo.txt + [Tt]oday.txt + +And obviously the same are recognize as done: + + YYYY-MM-[Dd]one.txt + YYYY-MM-DD[Dd]one.txt + [Dd]one-YYYY-MM.txt + [Dd]one-YYYY-MM-DD.txt + [Dd]one.txt + [Dd]one-[Tt]oday.txt + +Moreover, remove complete tasks `D` moves the task to the +done.txt file corresponding to the current todo.txt, aka if you are editing +2015-07-07-todo.txt, the done file while be 2015-07-07-done.txt. If you don't +like this behavior, you can set the default done.txt name: + + let g:TodoTxtForceDoneName='done.txt' + ### Others `x` is a toggle which allow you to unmark a task as done. diff --git a/doc/todo.txt b/doc/todo.txt index 15d62e2..8c86836 100644 --- a/doc/todo.txt +++ b/doc/todo.txt @@ -45,9 +45,9 @@ sorted by at the beginning of the file, the rest of the file is not modified. `X` : Mark all tasks as completed -`D` : Move completed tasks to done.txt +`D` : Move completed tasks to done file, see |todo-flexibleFileNaming| - is \ by default, so -s means you type \s +`` is \ by default, so ̀`-s` means you type \s =============================================================================== CONFIGURATION *todo-configuration* @@ -60,26 +60,35 @@ g:Todo_txt_second_level_sort_mode Defaults values are: -g:Todo_txt_first_level_sort_mode="i" -g:Todo_txt_second_level_sort_mode="i" - +> + g:Todo_txt_first_level_sort_mode="i" + g:Todo_txt_second_level_sort_mode="i" +< For more information on the available flags see help :sort We also provide a nice complete function for project and context, to use it add the following lines to your vimrc: - -" Use TodoComplete as the omni complete for todo files -au filetype todo setlocal omnifunc=TodoComplete +> + " Use TodoComplete as the omni complete for todo files + au filetype todo setlocal omnifunc=TodoComplete +< You can also start automatically the completion when entering '+' or '@' by adding the next lines to your vimrc: +> + " Auto complete projects + au filetype todo imap + + -" Auto complete projects -au filetype todo imap + + - -" Auto complete contexts -au filetype todo imap @ @ + " Auto complete contexts + au filetype todo imap @ @ +< +To force completed task to be moved to a file independently from the current +file name, add the following to your vimrc: +> + let g:TodoTxtForceDoneName='done.txt' +< +For more explanations, see |todo-flexibleFileNaming| =============================================================================== COMPLETION *todo-complete* @@ -92,3 +101,33 @@ buffers and for each of them, it will show their context and the name of the buffers in which they appears in the preview window. TodoCompelte does the same thing for context except that it gives in the preview the list of projects existing in each existing contexts. + +=============================================================================== +FLEXIBLE FILE NAMING *todo-flexibleFileNaming* + +This plugin provides a Flexible file naming for todo.txt, all the following +names are recognized as todo: +> + YYYY-MM-[Tt]odo.txt + YYYY-MM-DD[Tt]odo.txt + [Tt]odo-YYYY-MM.txt + [Tt]odo-YYYY-MM-DD.txt + [Tt]odo.txt + [Tt]oday.txt +< +And obviously the same are recognize as done: +> + YYYY-MM-[Dd]one.txt + YYYY-MM-DD[Dd]one.txt + [Dd]one-YYYY-MM.txt + [Dd]one-YYYY-MM-DD.txt + [Dd]one.txt + [Dd]one-[Tt]oday.txt +< +Moreover, remove complete tasks `D` moves the task to the +done.txt file corresponding to the current todo.txt, aka if you are editing +2015-07-07-todo.txt, the done file while be 2015-07-07-done.txt. If you don't +like this behavior, you can set the default done.txt name: +> + let g:TodoTxtForceDoneName='done.txt' +< diff --git a/ftdetect/todo.vim b/ftdetect/todo.vim index f3fdb87..81a83a7 100644 --- a/ftdetect/todo.vim +++ b/ftdetect/todo.vim @@ -6,5 +6,14 @@ " Version: 0.7 autocmd BufNewFile,BufRead [Tt]odo.txt set filetype=todo +autocmd BufNewFile,BufRead [Tt]odo-\d\\\{4\}-\d\\\{2\}-\d\\\{2\}.txt set filetype=todo +autocmd BufNewFile,BufRead [Tt]odo-\d\\\{4\}-\d\\\{2\}.txt set filetype=todo +autocmd BufNewFile,BufRead \d\\\{4\}-\d\\\{2\}-\d\\\{2\}-[Tt]odo.txt set filetype=todo +autocmd BufNewFile,BufRead \d\\\{4\}-\d\\\{2\}-[Tt]odo.txt set filetype=todo +autocmd BufNewFile,BufRead [Tt]oday.txt set filetype=todo autocmd BufNewFile,BufRead [Dd]one.txt set filetype=todo - +autocmd BufNewFile,BufRead [Dd]one-\d\\\{4\}-\d\\\{2\}-\d\\\{2\}.txt set filetype=todo +autocmd BufNewFile,BufRead [Dd]one-\d\\\{4\}-\d\\\{2\}.txt set filetype=todo +autocmd BufNewFile,BufRead \d\\\{4\}-\d\\\{2\}-\d\\\{2\}-[Dd]one.txt set filetype=todo +autocmd BufNewFile,BufRead \d\\\{4\}-\d\\\{2\}-[Dd]one.txt set filetype=todo +autocmd BufNewFile,BufRead [Dd]one-[Tt]oday.txt set filetype=todo diff --git a/ftplugin/todo.vim b/ftplugin/todo.vim index edf1dfb..05a9ff2 100644 --- a/ftplugin/todo.vim +++ b/ftplugin/todo.vim @@ -65,7 +65,13 @@ endfunction function! TodoTxtRemoveCompleted() " Check if we can write to done.txt before proceeding. let l:target_dir = expand('%:p:h') - let l:done_file = l:target_dir.'/done.txt' + if exists("g:TodoTxtForceDoneName") + let l:done=g:TodoTxtForceDoneName + else + let l:done=substitute(substitute(expand('%:t'),'todo','done',''),'Todo','Done','') + fi + let l:done_file = l:target_dir.'/'.l:done + echo "Writing to ".l:done_file if !filewritable(l:done_file) && !filewritable(l:target_dir) echoerr "Can't write to file 'done.txt'" return @@ -79,7 +85,7 @@ endfunction function! TodoTxtSort() " vim :sort is usually stable " we sort first on contexts, then on projects and then on priority - if expand('%')=~'done.txt' + if expand('%')=~'done.*.txt' silent! %s/\(x\s*\d\{4}\)-\(\d\{2}\)-\(\d\{2}\)/\1\2\3/g sort n /^x\s*/ silent! %s/\(x\s*\d\{4}\)\(\d\{2}\)/\1-\2-/g @@ -277,20 +283,20 @@ endfunction " Simple keyword completion on all buffers function! TodoKeywordComplete(base) - " Search for matchs - let res = [] - for bufnr in range(1,bufnr('$')) - let lines=getbufline(bufnr,1,"$") - for line in lines - if line =~ a:base - " init temporary item - let item={} - let item.word=substitute(line,'.*\('.a:base.'\S*\).*','\1',"") - call add(res,item) - endif - endfor + " Search for matchs + let res = [] + for bufnr in range(1,bufnr('$')) + let lines=getbufline(bufnr,1,"$") + for line in lines + if line =~ a:base + " init temporary item + let item={} + let item.word=substitute(line,'.*\('.a:base.'\S*\).*','\1',"") + call add(res,item) + endif endfor - return res + endfor + return res endfunction " Intelligent completion for projects and Contexts @@ -326,33 +332,35 @@ fun! TodoComplete(findstart, base) call sort(res) " Here all results are sorted in res, but we need to merge them let ret=[] - let curitem={} - let curitem.word=res[0].word - let curitem.related=[] - let curitem.buffers=[] - for it in res - if curitem.word==it.word - " Merge results - if index(curitem.related,it.related) <0 - call add(curitem.related,it.related) + if res != [] + let curitem={} + let curitem.word=res[0].word + let curitem.related=[] + let curitem.buffers=[] + for it in res + if curitem.word==it.word + " Merge results + if index(curitem.related,it.related) <0 + call add(curitem.related,it.related) + endif + if index(curitem.buffers,it.buffers) <0 + call add(curitem.buffers,it.buffers) + endif + else + " Create the definitive item + let resitem={} + let resitem.word=curitem.word + let resitem.info=opp=='+'?"Projects":"Contexts" + let resitem.info.=": ".join(curitem.related, ", ") + \."\nBuffers: ".join(curitem.buffers, ", ") + call add(ret,resitem) + " Init new item from it + let curitem.word=it.word + let curitem.related=[it.related] + let curitem.buffers=[it.buffers] endif - if index(curitem.buffers,it.buffers) <0 - call add(curitem.buffers,it.buffers) - endif - else - " Create the definitive item - let resitem={} - let resitem.word=curitem.word - let resitem.info=opp=='+'?"Projects":"Contexts" - let resitem.info.=": ".join(curitem.related, ", ") - \."\nBuffers: ".join(curitem.buffers, ", ") - call add(ret,resitem) - " Init new item from it - let curitem.word=it.word - let curitem.related=[it.related] - let curitem.buffers=[it.buffers] - endif - endfor + endfor + endif return ret endif endfun