From f3c5e7b8922d27f750b451ae9e0938a49b76700d Mon Sep 17 00:00:00 2001 From: David Beniamine Date: Sat, 14 May 2016 12:03:55 +0200 Subject: [PATCH] Included Guilherme Victal works on overduedate See https://github.com/freitass/todo.txt-vim/pull/45 --- .gitignore | 1 + .gitmodules | 0 README.markdown | 9 ++ autoload/todo.vim | 1 - autoload/todo/txt.vim | 123 ++++++++++++++++++ ftdetect/todo.vim | 2 +- ftplugin/todo.vim | 8 +- syntax/python/dateregex/dateregex/__init__.py | 11 ++ syntax/python/dateregex/dateregex/after.py | 95 ++++++++++++++ syntax/python/dateregex/dateregex/before.py | 79 +++++++++++ syntax/python/todo.py | 31 +++++ syntax/todo.vim | 64 +++++---- test/tc_date.todo.txt | 28 ++++ test/tc_date.vim | 84 ++++++++++++ test/tc_mark_as_done.todo.txt | 5 + test/tc_mark_as_done.vim | 36 +++++ test/tc_priority.todo.txt | 7 + test/tc_priority.vim | 28 ++++ test/tc_sort_context.todo.txt | 5 + test/tc_sort_context.vim | 18 +++ test/tc_sort_date.todo.txt | 12 ++ test/tc_sort_date.vim | 31 +++++ test/tc_sort_project.todo.txt | 5 + test/tc_sort_project.vim | 18 +++ 24 files changed, 669 insertions(+), 32 deletions(-) create mode 100644 .gitmodules create mode 100644 autoload/todo/txt.vim create mode 100644 syntax/python/dateregex/dateregex/__init__.py create mode 100644 syntax/python/dateregex/dateregex/after.py create mode 100644 syntax/python/dateregex/dateregex/before.py create mode 100644 syntax/python/todo.py create mode 100644 test/tc_date.todo.txt create mode 100644 test/tc_date.vim create mode 100644 test/tc_mark_as_done.todo.txt create mode 100644 test/tc_mark_as_done.vim create mode 100644 test/tc_priority.todo.txt create mode 100644 test/tc_priority.vim create mode 100644 test/tc_sort_context.todo.txt create mode 100644 test/tc_sort_context.vim create mode 100644 test/tc_sort_date.todo.txt create mode 100644 test/tc_sort_date.vim create mode 100644 test/tc_sort_project.todo.txt create mode 100644 test/tc_sort_project.vim diff --git a/.gitignore b/.gitignore index 57e15c5..f6b54df 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ *.swp doc/tags +*.pyc diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..e69de29 diff --git a/README.markdown b/README.markdown index 9b062d4..5733e9b 100644 --- a/README.markdown +++ b/README.markdown @@ -28,6 +28,15 @@ ## Release notes +v0.7.4 includes the overduedate support from Guilherme Victal, it highlight +dates in overdue tasks as an Error (as suggested on issue +[#44][https://github.com/freitass/todo.txt-vim/issues/44]). It depends on a +Python library, however, and as such will only be able to work if your version +of Vim was compiled with the `+python` option (as most common versions do). + +If your Vim installation does **not** have Python support, this plugin **will work just fine** but this feature will be disabled. + + Since v0.7.3, `TodoComplete` is replaced by `todo#Complete`, you might need to update your vimrc (see [completion](#completion)). diff --git a/autoload/todo.vim b/autoload/todo.vim index 7c7e23e..dcc3103 100644 --- a/autoload/todo.vim +++ b/autoload/todo.vim @@ -3,7 +3,6 @@ " Author: David Beniamine " Licence: Vim licence " Website: http://github.com/dbeniamine/todo.txt.vim -" Version: 0.7.3 " vim: ts=4 sw=4 :help tw=78 cc=80 " These two variables are parameters for the successive calls the vim sort diff --git a/autoload/todo/txt.vim b/autoload/todo/txt.vim new file mode 100644 index 0000000..efd72df --- /dev/null +++ b/autoload/todo/txt.vim @@ -0,0 +1,123 @@ +" File: todo.txt.vim +" Description: Todo.txt filetype detection +" Author: Leandro Freitas +" License: Vim license +" Website: http://github.com/freitass/todo.txt-vim +" Version: 0.4 + +" Export Context Dictionary for unit testing {{{1 +function! s:get_SID() + return matchstr(expand(''), '\d\+_') +endfunction +let s:SID = s:get_SID() +delfunction s:get_SID + +function! todo#txt#__context__() + return { 'sid': s:SID, 'scope': s: } +endfunction + +" Functions {{{1 +function! s:remove_priority() + :s/^(\w)\s\+//ge +endfunction + +function! s:get_current_date() + return strftime('%Y-%m-%d') +endfunction + +function! todo#txt#prepend_date() + execute 'normal! I' . s:get_current_date() . ' ' +endfunction + +function! todo#txt#replace_date() + let current_line = getline('.') + if (current_line =~ '^\(([a-zA-Z]) \)\?\d\{2,4\}-\d\{2\}-\d\{2\} ') && + \ exists('g:todo_existing_date') && g:todo_existing_date == 'n' + return + endif + execute 's/^\(([a-zA-Z]) \)\?\(\d\{2,4\}-\d\{2\}-\d\{2\} \)\?/\1' . s:get_current_date() . ' /' +endfunction + +function! todo#txt#mark_as_done() + call s:remove_priority() + call todo#txt#prepend_date() + normal! Ix +endfunction + +function! todo#txt#mark_all_as_done() + :g!/^x /:call todo#txt#mark_as_done() +endfunction + +function! s:append_to_file(file, lines) + let l:lines = [] + + " Place existing tasks in done.txt at the beggining of the list. + if filereadable(a:file) + call extend(l:lines, readfile(a:file)) + endif + + " Append new completed tasks to the list. + call extend(l:lines, a:lines) + + " Write to file. + call writefile(l:lines, a:file) +endfunction + +function! todo#txt#remove_completed() + " Check if we can write to done.txt before proceeding. + + let l:target_dir = expand('%:p:h') + let l:todo_file = expand('%:p') + let l:done_file = substitute(substitute(l:todo_file, 'todo.txt$', 'done.txt', ''), 'Todo.txt$', 'Done.txt', '') + if !filewritable(l:done_file) && !filewritable(l:target_dir) + echoerr "Can't write to file 'done.txt'" + return + endif + + let l:completed = [] + :g/^x /call add(l:completed, getline(line(".")))|d + call s:append_to_file(l:done_file, l:completed) +endfunction + +function! todo#txt#sort_by_context() range + execute a:firstline . "," . a:lastline . "sort /\\(^\\| \\)\\zs@[^[:blank:]]\\+/ r" +endfunction + +function! todo#txt#sort_by_project() range + execute a:firstline . "," . a:lastline . "sort /\\(^\\| \\)\\zs+[^[:blank:]]\\+/ r" +endfunction + +function! todo#txt#sort_by_date() range + let l:date_regex = "\\d\\{2,4\\}-\\d\\{2\\}-\\d\\{2\\}" + execute a:firstline . "," . a:lastline . "sort /" . l:date_regex . "/ r" + execute a:firstline . "," . a:lastline . "g!/" . l:date_regex . "/m" . a:lastline +endfunction + +function! todo#txt#sort_by_due_date() range + let l:date_regex = "due:\\d\\{2,4\\}-\\d\\{2\\}-\\d\\{2\\}" + execute a:firstline . "," . a:lastline . "sort /" . l:date_regex . "/ r" + execute a:firstline . "," . a:lastline . "g!/" . l:date_regex . "/m" . a:lastline +endfunction + +" Increment and Decrement The Priority +:set nf=octal,hex,alpha + +function! todo#txt#prioritize_increase() + normal! 0f)h +endfunction + +function! todo#txt#prioritize_decrease() + normal! 0f)h +endfunction + +function! todo#txt#prioritize_add(priority) + " Need to figure out how to only do this if the first visible letter in a line is not ( + :call todo#txt#prioritize_add_action(a:priority) +endfunction + +function! todo#txt#prioritize_add_action(priority) + execute 's/^\(([a-zA-Z]) \)\?/(' . a:priority . ') /' +endfunction + +" Modeline {{{1 +" vim: ts=8 sw=4 sts=4 et foldenable foldmethod=marker foldcolumn=1 diff --git a/ftdetect/todo.vim b/ftdetect/todo.vim index c83b997..d775f25 100644 --- a/ftdetect/todo.vim +++ b/ftdetect/todo.vim @@ -3,7 +3,7 @@ " Author: David Beniamine , Leandro Freitas " License: Vim license " Website: http://github.com/dbeniamine/todo.txt-vim -" Version: 0.7.2 +" vim: ts=4 sw=4 :help tw=78 cc=80 autocmd BufNewFile,BufRead [Tt]odo.txt set filetype=todo autocmd BufNewFile,BufRead [Tt]odo-\d\\\{4\}-\d\\\{2\}-\d\\\{2\}.txt set filetype=todo diff --git a/ftplugin/todo.vim b/ftplugin/todo.vim index c76d0c4..73b5dec 100644 --- a/ftplugin/todo.vim +++ b/ftplugin/todo.vim @@ -3,13 +3,18 @@ " Author: David Beniamine , Leandro Freitas " License: Vim license " Website: http://github.com/dbeniamine/todo.txt-vim -" Version: 0.7.2 " vim: ts=4 sw=4 :help tw=78 cc=80 " Save context {{{1 let s:save_cpo = &cpo set cpo&vim +if exists("g:Todo_txt_loaded") + finish +else + let g:Todo_txt_loaded=0.7.4 +endif + " General options {{{1 " Some options lose their values when window changes. They will be set every " time this script is invocated, which is whenever a file of this type is @@ -96,4 +101,3 @@ endfunction " Restore context {{{1 let &cpo = s:save_cpo -" Modeline {{{1 diff --git a/syntax/python/dateregex/dateregex/__init__.py b/syntax/python/dateregex/dateregex/__init__.py new file mode 100644 index 0000000..cfbc141 --- /dev/null +++ b/syntax/python/dateregex/dateregex/__init__.py @@ -0,0 +1,11 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# File: __init__.py +# Author: Guilherme Victal +# Description: Dateregex library entry point +# License: Vim license +# Website: http://github.com/freitass/todo.txt-vim +# Version: 0.1 + +from after import regex_date_after +from before import regex_date_before diff --git a/syntax/python/dateregex/dateregex/after.py b/syntax/python/dateregex/dateregex/after.py new file mode 100644 index 0000000..8a13574 --- /dev/null +++ b/syntax/python/dateregex/dateregex/after.py @@ -0,0 +1,95 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# File: after.py +# Author: Guilherme Victal +# Description: Generates regexes after a certain date +# License: Vim license +# Website: http://github.com/freitass/todo.txt-vim +# Version: 0.1 + +from datetime import date, timedelta, MAXYEAR + + +def _year_regex_after(year): + if int(year) > MAXYEAR: + return None + + year_regex = r'(\d+\d{%s}' % len(year) + for idx, digit in enumerate(year): + if digit != '9': + regex = '|' + year[0:idx] + regex += '9' if digit == '8' else '[%s-9]' % str(int(digit) + 1) + if idx < len(year) - 1: + regex += '\d{%s}' % (len(year) - (idx + 1)) + year_regex += regex + + year_regex += ')' + return '-'.join((year_regex, r'\d{2}', r'\d{2}')) + + +def _month_regex_after(year, month): + if month == '12': + return None + + digit1, digit2 = month + if digit1 == '1': + month_regex = r'12' if month == '11' else r'1[12]' + else: + month_regex = r'1[0-2]' + if digit2 != '9': + if digit2 == '8': + month_regex = r'(' + month_regex + r'|09)' + else: + month_regex = r'(' + month_regex + r'|0[%s-9])' + month_regex = month_regex % str(int(digit2) + 1) + return '-'.join((year, month_regex, r'\d{2}')) + +def _day_regex_after(year, month, day): + last_month_day = str((date(int(year), (int(month) + 1) % 12, 1) + - date.resolution).day) + if day == last_month_day: + return None + day_regex = r'(' + digit1, digit2 = day + last_digit1, last_digit2 = last_month_day + if digit1 == last_digit1: + day_regex = last_month_day if int(digit2) == int(last_digit2) - 1 else last_digit1 + r'[%s-%s]' % (str(int(digit2) + 1), last_digit2) + else: + day_regex = r'(' + day_regex += last_digit1 if int(digit1) == int(last_digit1) - 1 else r'[%s-%s]' % (str(int(digit1) + 1), last_digit1) + day_regex +=r'\d' + if digit2 < '9': + day_regex += '|' + digit1 + day_regex += '9' if digit2 == '8' else r'[%s-9]' % str(int(digit2) + 1) + + day_regex += ')' + return '-'.join((year, month, day_regex)) + + +def regex_date_after(given_date): + year, month, day = given_date.isoformat().split('-') + + year_regex = _year_regex_after(year) + month_regex = _month_regex_after(year, month) + day_regex = _day_regex_after(year, month, day) + + date_regex = '(' + year_regex if year_regex else '(' + date_regex += ('|' + month_regex) if month_regex else '' + date_regex += ('|' + day_regex) if day_regex else '' + date_regex += ')' + return date_regex + + +def __main(): + import re + date_regex = regex_date_after(date(1999,12,31)) + print(date_regex) + pattern = re.compile(date_regex) + + + d = date.today() + date.resolution + assert pattern.match(date.strftime(d, '%Y-%m-%d')) is not None + print(date.strftime(d, '%Y-%m-%d') + ' is okay') + d += date.resolution + +if __name__ == '__main__': + __main() diff --git a/syntax/python/dateregex/dateregex/before.py b/syntax/python/dateregex/dateregex/before.py new file mode 100644 index 0000000..8a3402e --- /dev/null +++ b/syntax/python/dateregex/dateregex/before.py @@ -0,0 +1,79 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# File: before.py +# Author: Guilherme Victal +# Description: Generates regexes before a certain date +# License: Vim license +# Website: http://github.com/freitass/todo.txt-vim +# Version: 0.1 + +from datetime import date, timedelta, MINYEAR + +def _year_regex_before(year): + if int(year) <= MINYEAR: + return None + year_regex = r'(' + year_regex += r'\d{1,%s}' % str(len(year) - 1) if len(year) > 1 else '' + for idx, digit in enumerate(year): + if digit != '0': + regex = '|' + year[0:idx] + regex += '0' if digit == '1' else '[0-%s]' % str(int(digit) - 1) + if idx < len(year) - 1: + regex += '\d{%s}' % (len(year) - (idx + 1)) + year_regex += regex + + year_regex += ')' + return '-'.join((year_regex, r'\d{2}', r'\d{2}')) + +def _month_regex_before(year, month): + if month == '01': + return None + + digit1, digit2 = month + if digit1 == '0': + month_regex = '01' if month == '02' else r'0[1-%s]' % str(int(digit2) - 1) + elif month == '10': + month_regex = r'0\d' + elif month == '11': + month_regex = r'(0\d|10)' + else: + month_regex = r'(0\d|1[01])' + + return '-'.join((year, month_regex, r'\d{2}')) + +def _day_regex_before(year, month, day): + if day == '01': + return None + last_month_day = str((date(int(year), (int(month) + 1) % 12, 1) + - date.resolution).day) + last_digit1, last_digit2 = last_month_day + + digit1, digit2 = day + if digit1 == '0': + day_regex = '01' if day == '02' else r'0[1-%s]' % str(int(digit2) - 1) + else: + day_regex = r'(' + day_regex += '0' if digit1 == '1' else r'[0-%s]' % str(int(digit1) - 1) + day_regex += r'\d' + if digit2 != '0': + day_regex += '|' + day_regex += digit1 + day_regex += '0' if digit2 == '1' else r'[0-%s]' % str(int(digit2) - 1) + day_regex += ')' + + return '-'.join((year, month, day_regex)) + + + + +def regex_date_before(given_date): + year, month, day = given_date.isoformat().split('-') + + year_regex = _year_regex_before(year) + month_regex = _month_regex_before(year, month) + day_regex = _day_regex_before(year, month, day) + + date_regex = '(' + year_regex if year_regex else '(' + date_regex += ('|' + month_regex) if month_regex else '' + date_regex += ('|' + day_regex) if day_regex else '' + date_regex += ')' + return date_regex diff --git a/syntax/python/todo.py b/syntax/python/todo.py new file mode 100644 index 0000000..36d0d9d --- /dev/null +++ b/syntax/python/todo.py @@ -0,0 +1,31 @@ +#!/usr/bin/env python2 +# -*- coding: utf-8 -*- +# File: todo.py +# Description: Todo.txt overdue date syntax script +# License: Vim license +# Website: http://github.com/freitass/todo.txt-vim +# Version: 0.1 + +import vim +import os +import sys +from datetime import date + +dateregex_dir = os.path.join(vim.eval('s:script_dir'), 'dateregex') +if os.path.isdir(dateregex_dir): + sys.path.insert(0, dateregex_dir) + +def add_due_date_syntax_highlight(): + try: + from dateregex import regex_date_before + except ImportError: + print("dateregex module not found. Overdue dates won't be highlighted") + return + + regex = regex_date_before(date.today()) + regex = r'(^|<)due:%s(>|$)' % regex + + vim.command("syntax match OverDueDate '\\v%s'" % regex) + vim.command("highlight default link OverDueDate Error") + +add_due_date_syntax_highlight() diff --git a/syntax/todo.vim b/syntax/todo.vim index aec03a7..57c2c7c 100644 --- a/syntax/todo.vim +++ b/syntax/todo.vim @@ -3,39 +3,39 @@ " Author: David Beniamine ,Leandro Freitas " License: Vim license " Website: http://github.com/dbeniamine/todo.txt-vim -" Version: 0.7.2 +" vim: ts=4 sw=4 :help tw=78 cc=80 if exists("b:current_syntax") finish endif -syntax match TodoDone '^[xX]\s.\+$' contains=TodoKey,TodoDate,TodoProject,TodoContext -syntax match TodoPriorityA '^([aA])\s.\+$' contains=TodoKey,TodoDate,TodoProject,TodoContext -syntax match TodoPriorityB '^([bB])\s.\+$' contains=TodoKey,TodoDate,TodoProject,TodoContext -syntax match TodoPriorityC '^([cC])\s.\+$' contains=TodoKey,TodoDate,TodoProject,TodoContext -syntax match TodoPriorityD '^([dD])\s.\+$' contains=TodoKey,TodoDate,TodoProject,TodoContext -syntax match TodoPriorityE '^([eE])\s.\+$' contains=TodoKey,TodoDate,TodoProject,TodoContext -syntax match TodoPriorityF '^([fF])\s.\+$' contains=TodoKey,TodoDate,TodoProject,TodoContext -syntax match TodoPriorityG '^([gG])\s.\+$' contains=TodoKey,TodoDate,TodoProject,TodoContext -syntax match TodoPriorityH '^([hH])\s.\+$' contains=TodoKey,TodoDate,TodoProject,TodoContext -syntax match TodoPriorityI '^([iI])\s.\+$' contains=TodoKey,TodoDate,TodoProject,TodoContext -syntax match TodoPriorityJ '^([jJ])\s.\+$' contains=TodoKey,TodoDate,TodoProject,TodoContext -syntax match TodoPriorityK '^([kK])\s.\+$' contains=TodoKey,TodoDate,TodoProject,TodoContext -syntax match TodoPriorityL '^([lL])\s.\+$' contains=TodoKey,TodoDate,TodoProject,TodoContext -syntax match TodoPriorityM '^([mM])\s.\+$' contains=TodoKey,TodoDate,TodoProject,TodoContext -syntax match TodoPriorityN '^([nN])\s.\+$' contains=TodoKey,TodoDate,TodoProject,TodoContext -syntax match TodoPriorityO '^([oO])\s.\+$' contains=TodoKey,TodoDate,TodoProject,TodoContext -syntax match TodoPriorityP '^([pP])\s.\+$' contains=TodoKey,TodoDate,TodoProject,TodoContext -syntax match TodoPriorityQ '^([qQ])\s.\+$' contains=TodoKey,TodoDate,TodoProject,TodoContext -syntax match TodoPriorityR '^([rR])\s.\+$' contains=TodoKey,TodoDate,TodoProject,TodoContext -syntax match TodoPriorityS '^([sS])\s.\+$' contains=TodoKey,TodoDate,TodoProject,TodoContext -syntax match TodoPriorityT '^([tT])\s.\+$' contains=TodoKey,TodoDate,TodoProject,TodoContext -syntax match TodoPriorityU '^([uU])\s.\+$' contains=TodoKey,TodoDate,TodoProject,TodoContext -syntax match TodoPriorityV '^([vV])\s.\+$' contains=TodoKey,TodoDate,TodoProject,TodoContext -syntax match TodoPriorityW '^([wW])\s.\+$' contains=TodoKey,TodoDate,TodoProject,TodoContext -syntax match TodoPriorityX '^([xX])\s.\+$' contains=TodoKey,TodoDate,TodoProject,TodoContext -syntax match TodoPriorityY '^([yY])\s.\+$' contains=TodoKey,TodoDate,TodoProject,TodoContext -syntax match TodoPriorityZ '^([zZ])\s.\+$' contains=TodoKey,TodoDate,TodoProject,TodoContext +syntax match TodoDone '^[xX]\s.\+$' contains=TodoKey,TodoDate,TodoProject,TodoContext,OverDueDate +syntax match TodoPriorityA '^([aA])\s.\+$' contains=TodoKey,TodoDate,TodoProject,TodoContext,OverDueDate +syntax match TodoPriorityB '^([bB])\s.\+$' contains=TodoKey,TodoDate,TodoProject,TodoContext,OverDueDate +syntax match TodoPriorityC '^([cC])\s.\+$' contains=TodoKey,TodoDate,TodoProject,TodoContext,OverDueDate +syntax match TodoPriorityD '^([dD])\s.\+$' contains=TodoKey,TodoDate,TodoProject,TodoContext,OverDueDate +syntax match TodoPriorityE '^([eE])\s.\+$' contains=TodoKey,TodoDate,TodoProject,TodoContext,OverDueDate +syntax match TodoPriorityF '^([fF])\s.\+$' contains=TodoKey,TodoDate,TodoProject,TodoContext,OverDueDate +syntax match TodoPriorityG '^([gG])\s.\+$' contains=TodoKey,TodoDate,TodoProject,TodoContext,OverDueDate +syntax match TodoPriorityH '^([hH])\s.\+$' contains=TodoKey,TodoDate,TodoProject,TodoContext,OverDueDate +syntax match TodoPriorityI '^([iI])\s.\+$' contains=TodoKey,TodoDate,TodoProject,TodoContext,OverDueDate +syntax match TodoPriorityJ '^([jJ])\s.\+$' contains=TodoKey,TodoDate,TodoProject,TodoContext,OverDueDate +syntax match TodoPriorityK '^([kK])\s.\+$' contains=TodoKey,TodoDate,TodoProject,TodoContext,OverDueDate +syntax match TodoPriorityL '^([lL])\s.\+$' contains=TodoKey,TodoDate,TodoProject,TodoContext,OverDueDate +syntax match TodoPriorityM '^([mM])\s.\+$' contains=TodoKey,TodoDate,TodoProject,TodoContext,OverDueDate +syntax match TodoPriorityN '^([nN])\s.\+$' contains=TodoKey,TodoDate,TodoProject,TodoContext,OverDueDate +syntax match TodoPriorityO '^([oO])\s.\+$' contains=TodoKey,TodoDate,TodoProject,TodoContext,OverDueDate +syntax match TodoPriorityP '^([pP])\s.\+$' contains=TodoKey,TodoDate,TodoProject,TodoContext,OverDueDate +syntax match TodoPriorityQ '^([qQ])\s.\+$' contains=TodoKey,TodoDate,TodoProject,TodoContext,OverDueDate +syntax match TodoPriorityR '^([rR])\s.\+$' contains=TodoKey,TodoDate,TodoProject,TodoContext,OverDueDate +syntax match TodoPriorityS '^([sS])\s.\+$' contains=TodoKey,TodoDate,TodoProject,TodoContext,OverDueDate +syntax match TodoPriorityT '^([tT])\s.\+$' contains=TodoKey,TodoDate,TodoProject,TodoContext,OverDueDate +syntax match TodoPriorityU '^([uU])\s.\+$' contains=TodoKey,TodoDate,TodoProject,TodoContext,OverDueDate +syntax match TodoPriorityV '^([vV])\s.\+$' contains=TodoKey,TodoDate,TodoProject,TodoContext,OverDueDate +syntax match TodoPriorityW '^([wW])\s.\+$' contains=TodoKey,TodoDate,TodoProject,TodoContext,OverDueDate +syntax match TodoPriorityX '^([xX])\s.\+$' contains=TodoKey,TodoDate,TodoProject,TodoContext,OverDueDate +syntax match TodoPriorityY '^([yY])\s.\+$' contains=TodoKey,TodoDate,TodoProject,TodoContext,OverDueDate +syntax match TodoPriorityZ '^([zZ])\s.\+$' contains=TodoKey,TodoDate,TodoProject,TodoContext,OverDueDate syntax match TodoDate '\d\{2,4\}-\d\{2\}-\d\{2\}' contains=NONE syntax match TodoKey '\S*\S:\S\S*' contains=TodoDate syntax match TodoProject '\(^\|\W\)+[^[:blank:]]\+' contains=NONE @@ -51,4 +51,12 @@ highlight default link TodoDate PreProc highlight default link TodoProject Special highlight default link TodoContext Special +if has('python') + let b:curdir = expand(':p:h') + let s:script_dir = b:curdir . "/python/" + execute "pyfile " . s:script_dir. "todo.py" +else + echom "Your version of vim has no python support. Overdue dates won't be highlighted" +endif + let b:current_syntax = "todo" diff --git a/test/tc_date.todo.txt b/test/tc_date.todo.txt new file mode 100644 index 0000000..beb7d5e --- /dev/null +++ b/test/tc_date.todo.txt @@ -0,0 +1,28 @@ +# lorem_ipsum +example task +# end_lorem_ipsum + +# date_after_priority +(A) Call Mom +# end_date_after_priority + +# date_after_priority_visual +(A) Call Mom +(B) Call Dad +# end_date_after_priority_visual + +# existing_date_no_priority +2014-05-06 example task +# end_existing_date_no_priority + +# existing_date_after_priority +(A) 2014-05-06 Call Mom +# end_existing_date_after_priority + +# existing_date_do_nothing +2014-05-06 example task +# end_existing_date_do_nothing + +# non_existing_date_do_nothing +new todo line +# end_non_existing_date_do_nothing diff --git a/test/tc_date.vim b/test/tc_date.vim new file mode 100644 index 0000000..df8b0e0 --- /dev/null +++ b/test/tc_date.vim @@ -0,0 +1,84 @@ +let s:here = expand(':p:h') +let s:context = todo#txt#__context__() +let s:context['data'] = s:here . '/tc_date.todo.txt' +let s:tc = unittest#testcase#new('Date', s:context) + +let s:TODAY = strftime("%Y-%m-%d") + +function! s:tc.test_current_date() + call self.assert_equal(s:TODAY, self.call('s:get_current_date', [])) +endfunction + +let s:DATE_INSERTED = [ + \ s:TODAY . ' example task', + \ ] + +let s:DATE_INSERTED_AFTER_PRIORITY = [ + \ '(A) ' . s:TODAY . ' Call Mom', + \ ] + +let s:DATE_INSERTED_AFTER_PRIORITY_VISUAL = [ + \ '(A) ' . s:TODAY . ' Call Mom', + \ '(B) ' . s:TODAY . ' Call Dad', + \ ] + +let s:DATE_INSERTED_DO_NOTHING = [ + \ '2014-05-06 example task', + \ ] + +let s:NON_EXISTING_DATE_INSERTED_DO_NOTHING = [ + \ s:TODAY . ' new todo line', + \ ] + +function! s:tc.test_insert_date_normal_mode() + call self.data.goto('lorem_ipsum') + call todo#txt#replace_date() + call self.assert_equal(s:DATE_INSERTED, self.data.get('lorem_ipsum')) +endfunction + +function! s:tc.test_insert_date_insert_mode() + call self.data.goto('lorem_ipsum') + execute 'normal idate ' + call self.assert_equal(s:DATE_INSERTED, self.data.get('lorem_ipsum')) +endfunction + +function! s:tc.test_insert_date_visual_mode() + call self.data.visual_execute('call todo#txt#replace_date()', 'lorem_ipsum') + call self.assert_equal(s:DATE_INSERTED, self.data.get('lorem_ipsum')) +endfunction + +function! s:tc.test_insert_date_after_priority_normal_mode() + call self.data.execute('call todo#txt#replace_date()', 'date_after_priority') + call self.assert_equal(s:DATE_INSERTED_AFTER_PRIORITY, self.data.get('date_after_priority')) +endfunction + +function! s:tc.test_insert_date_after_priority_visual_mode() + call self.data.visual_execute('call todo#txt#replace_date()', 'date_after_priority_visual') + call self.assert_equal(s:DATE_INSERTED_AFTER_PRIORITY_VISUAL, self.data.get('date_after_priority_visual')) +endfunction + +function! s:tc.test_insert_with_existing_date() + call self.data.execute('call todo#txt#replace_date()', 'existing_date_no_priority') + call self.assert_equal(s:DATE_INSERTED, self.data.get('existing_date_no_priority')) +endfunction + +function! s:tc.test_insert_with_existing_date_and_priority() + call self.data.execute('call todo#txt#replace_date()', 'existing_date_after_priority') + call self.assert_equal(s:DATE_INSERTED_AFTER_PRIORITY, self.data.get('existing_date_after_priority')) +endfunction + +function! s:tc.test_insert_with_existing_date_and_priority() + let g:todo_existing_date = 'n' + call self.data.execute('call todo#txt#replace_date()', 'existing_date_do_nothing') + call self.assert_equal(s:DATE_INSERTED_DO_NOTHING, self.data.get('existing_date_do_nothing')) + unlet g:todo_existing_date +endfunction + +function! s:tc.test_insert_with_existing_date_and_priority() + let g:todo_existing_date = 'n' + call self.data.execute('call todo#txt#replace_date()', 'non_existing_date_do_nothing') + call self.assert_equal(s:NON_EXISTING_DATE_INSERTED_DO_NOTHING, self.data.get('non_existing_date_do_nothing')) + unlet g:todo_existing_date +endfunction + +unlet s:tc diff --git a/test/tc_mark_as_done.todo.txt b/test/tc_mark_as_done.todo.txt new file mode 100644 index 0000000..3cabcdd --- /dev/null +++ b/test/tc_mark_as_done.todo.txt @@ -0,0 +1,5 @@ +# lorem_ipsum +first task to be marked as done +second task to be marked as done +2015-05-20 third task to be marked as done +# end_lorem_ipsum diff --git a/test/tc_mark_as_done.vim b/test/tc_mark_as_done.vim new file mode 100644 index 0000000..f5a1e4b --- /dev/null +++ b/test/tc_mark_as_done.vim @@ -0,0 +1,36 @@ +let s:here = expand(':p:h') +let s:context = todo#txt#__context__() +let s:context['data'] = s:here . '/tc_mark_as_done.todo.txt' +let s:tc = unittest#testcase#new('Mark As Done', s:context) + +let s:TODAY = strftime("%Y-%m-%d") + +let s:FIRST_TASK_DONE = [ + \ 'x ' . s:TODAY . ' first task to be marked as done', + \ 'second task to be marked as done', + \ '2015-05-20 third task to be marked as done', + \ ] + +let s:ALL_TASKS_DONE = [ + \ 'x ' . s:TODAY . ' first task to be marked as done', + \ 'x ' . s:TODAY . ' second task to be marked as done', + \ 'x ' . s:TODAY . ' 2015-05-20 third task to be marked as done', + \ ] + +function! s:tc.test_mark_as_done() + call self.data.goto('lorem_ipsum') + call todo#txt#mark_as_done() + call self.assert_equal(s:FIRST_TASK_DONE, self.data.get('lorem_ipsum')) +endfunction + +function! s:tc.test_mark_range_as_done() + call self.data.execute('call todo#txt#mark_as_done()', 'lorem_ipsum') + call self.assert_equal(s:ALL_TASKS_DONE, self.data.get('lorem_ipsum')) +endfunction + +function! s:tc.test_mark_selection_as_done() + call self.data.visual_execute('call todo#txt#mark_as_done()', 'lorem_ipsum') + call self.assert_equal(s:ALL_TASKS_DONE, self.data.get('lorem_ipsum')) +endfunction + +unlet s:tc diff --git a/test/tc_priority.todo.txt b/test/tc_priority.todo.txt new file mode 100644 index 0000000..7cc2126 --- /dev/null +++ b/test/tc_priority.todo.txt @@ -0,0 +1,7 @@ +# insert_priority +example task +# end_insert_priority + +# replace_priority +(A) example task +# end_replace_priority diff --git a/test/tc_priority.vim b/test/tc_priority.vim new file mode 100644 index 0000000..7aa361d --- /dev/null +++ b/test/tc_priority.vim @@ -0,0 +1,28 @@ +let s:here = expand(':p:h') +let s:context = todo#txt#__context__() +let s:context['data'] = s:here . '/tc_priority.todo.txt' +let s:tc = unittest#testcase#new('Priority', s:context) + +let s:TODAY = strftime("%Y-%m-%d") + +let s:PRIORITY_INSERTED = [ + \ '(A) example task', + \ ] + +let s:PRIORITY_REPLACED = [ + \ '(C) example task', + \ ] + +function! s:tc.test_insert_priority() + call self.data.goto('insert_priority') + call todo#txt#prioritize_add('A') + call self.assert_equal(s:PRIORITY_INSERTED, self.data.get('insert_priority')) +endfunction + +function! s:tc.test_replace_priority() + call self.data.goto('replace_priority') + call todo#txt#prioritize_add('C') + call self.assert_equal(s:PRIORITY_REPLACED, self.data.get('replace_priority')) +endfunction + +unlet s:tc diff --git a/test/tc_sort_context.todo.txt b/test/tc_sort_context.todo.txt new file mode 100644 index 0000000..efa58f7 --- /dev/null +++ b/test/tc_sort_context.todo.txt @@ -0,0 +1,5 @@ +# lorem_ipsum +(B) Linear regression Rnet=Qh@Qle. @cons_emp_model +(B) Review key questions. @benchmarking +(A) simple model first @cons_emp_model +# end_lorem_ipsum diff --git a/test/tc_sort_context.vim b/test/tc_sort_context.vim new file mode 100644 index 0000000..53e518d --- /dev/null +++ b/test/tc_sort_context.vim @@ -0,0 +1,18 @@ +let s:here = expand(':p:h') +let s:tc = unittest#testcase#new('Sort Context', + \ { 'data': s:here . '/tc_sort_context.todo.txt' }) + +let s:LEADER = mapleader + +let s:SORTED_TASKS = [ + \ '(B) Review key questions. @benchmarking', + \ '(B) Linear regression Rnet=Qh@Qle. @cons_emp_model', + \ '(A) simple model first @cons_emp_model', + \ ] + +function! s:tc.test_sort_by_context() + call self.data.visual_execute('call todo#txt#sort_by_context()', 'lorem_ipsum') + call self.assert_equal(s:SORTED_TASKS, self.data.get('lorem_ipsum')) +endfunction + +unlet s:tc diff --git a/test/tc_sort_date.todo.txt b/test/tc_sort_date.todo.txt new file mode 100644 index 0000000..1144c24 --- /dev/null +++ b/test/tc_sort_date.todo.txt @@ -0,0 +1,12 @@ +# lorem_ipsum +(B) 2013-03-15 2015-03-17 +(B) 2012-04-16 2015-04-16 +(A) 2013-03-16 2013-03-10 +# end_lorem_ipsum +# task_with_no_date +2013-03-15 task with date +task with no date +2013-03-15 task with date +2013-03-15 task with date +task with no date +# end_task_with_no_date diff --git a/test/tc_sort_date.vim b/test/tc_sort_date.vim new file mode 100644 index 0000000..8041c0d --- /dev/null +++ b/test/tc_sort_date.vim @@ -0,0 +1,31 @@ +let s:here = expand(':p:h') +let s:tc = unittest#testcase#new('Sort Date', + \ { 'data': s:here . '/tc_sort_date.todo.txt' }) + +let s:LEADER = mapleader + +let s:SORTED_TASKS = [ + \ '(B) 2012-04-16 2015-04-16', + \ '(B) 2013-03-15 2015-03-17', + \ '(A) 2013-03-16 2013-03-10', + \ ] + +let s:SORTED_TASKS_WITH_NO_DATE = [ + \ '2013-03-15 task with date', + \ '2013-03-15 task with date', + \ '2013-03-15 task with date', + \ 'task with no date', + \ 'task with no date', + \ ] + +function! s:tc.test_sort_by_date() + call self.data.visual_execute('call todo#txt#sort_by_date()', 'lorem_ipsum') + call self.assert_equal(s:SORTED_TASKS, self.data.get('lorem_ipsum')) +endfunction + +function! s:tc.test_sort_by_date_with_tasks_without_date() + call self.data.visual_execute('call todo#txt#sort_by_date()', 'task_with_no_date') + call self.assert_equal(s:SORTED_TASKS_WITH_NO_DATE, self.data.get('task_with_no_date')) +endfunction + +unlet s:tc diff --git a/test/tc_sort_project.todo.txt b/test/tc_sort_project.todo.txt new file mode 100644 index 0000000..d40f0f0 --- /dev/null +++ b/test/tc_sort_project.todo.txt @@ -0,0 +1,5 @@ +# lorem_ipsum +(B) Linear regression Rnet=Qh+Qle. +cons_emp_model +(B) Review key questions. +benchmarking +(A) simple model first +cons_emp_model +# end_lorem_ipsum diff --git a/test/tc_sort_project.vim b/test/tc_sort_project.vim new file mode 100644 index 0000000..d4fd2c5 --- /dev/null +++ b/test/tc_sort_project.vim @@ -0,0 +1,18 @@ +let s:here = expand(':p:h') +let s:tc = unittest#testcase#new('Sort Project', + \ { 'data': s:here . '/tc_sort_project.todo.txt' }) + +let s:LEADER = mapleader + +let s:SORTED_TASKS = [ + \ '(B) Review key questions. +benchmarking', + \ '(B) Linear regression Rnet=Qh+Qle. +cons_emp_model', + \ '(A) simple model first +cons_emp_model', + \ ] + +function! s:tc.test_sort_by_project() + call self.data.visual_execute('call todo#txt#sort_by_project()', 'lorem_ipsum') + call self.assert_equal(s:SORTED_TASKS, self.data.get('lorem_ipsum')) +endfunction + +unlet s:tc