summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcos <cos>2024-06-30 14:28:41 +0200
committercos <cos>2024-08-17 19:29:17 +0200
commit267be9e15c98a2f3f78b424e967ea2f63af92e25 (patch)
tree9af8aa84985c5cf95c103d8c3d0ad1da9688b2d5
parentcfe9568a006f4f25386140df658f43087a7cc979 (diff)
downloadtodo.txt-vim-267be9e15c98a2f3f78b424e967ea2f63af92e25.zip
Allow syntax inclusion, by going match → regiontopic/allow-embed_squashed4mr
Restructure syntax highlighting, using context aware `syntax region` rather `syntax match` statements requiring to match on line start anchors. This should be functionally identical when editing ordinary todo.txt files. The advantage is that this also allows reusing this syntax file within other file formats. Without this commit, attempting to embed todo.txt snippets in other file formats might result in only partial syntax highlighting. With TodoStart marking the start of each line, the grammar allows full syntax highlighting in case the snippet starts or ends on a non-line boundaries. Consider for example these four lines of prio/syntax.vim, for my purely personal `prio` file format: syntax include @Todo syntax/todo.vim hi! def link prioLabel Label sy region prioLabel start="^\s*TODO:" end="\s*" nextgroup=prioTodo sy region prioTodo contained start=/./ end=/$/ contains=@TodoStart This commit and the above configuration allows syntax highlighting of any todo.txt row prefixed by `TODO:` in those files. Making actionable items standing out from otherwise free-form natural language. Given the ease of configuration, one can imagine similarly embedding todo.txt directly in any text based file format. Thus improving many use cases where todo.txt files might be generated from other canonical sources.
-rw-r--r--syntax/todo.vim71
-rw-r--r--tests/todo.vader38
2 files changed, 59 insertions, 50 deletions
diff --git a/syntax/todo.vim b/syntax/todo.vim
index b4c120c..44dc87f 100644
--- a/syntax/todo.vim
+++ b/syntax/todo.vim
@@ -8,37 +8,46 @@ if exists("b:current_syntax")
finish
endif
-syntax match TodoDone '^[x]\s.\+$' contains=TodoKey,TodoDate,TodoProject,TodoContext
-syntax match TodoPriorityA '^(A) .\+$' contains=TodoKey,TodoDate,TodoProject,TodoContext,TodoDueToday,TodoOverDueDate,TodoThresholdDate
-syntax match TodoPriorityB '^(B) .\+$' contains=TodoKey,TodoDate,TodoProject,TodoContext,TodoDueToday,TodoOverDueDate,TodoThresholdDate
-syntax match TodoPriorityC '^(C) .\+$' contains=TodoKey,TodoDate,TodoProject,TodoContext,TodoDueToday,TodoOverDueDate,TodoThresholdDate
-syntax match TodoPriorityD '^(D) .\+$' contains=TodoKey,TodoDate,TodoProject,TodoContext,TodoDueToday,TodoOverDueDate,TodoThresholdDate
-syntax match TodoPriorityE '^(E) .\+$' contains=TodoKey,TodoDate,TodoProject,TodoContext,TodoDueToday,TodoOverDueDate,TodoThresholdDate
-syntax match TodoPriorityF '^(F) .\+$' contains=TodoKey,TodoDate,TodoProject,TodoContext,TodoDueToday,TodoOverDueDate,TodoThresholdDate
-syntax match TodoPriorityG '^(G) .\+$' contains=TodoKey,TodoDate,TodoProject,TodoContext,TodoDueToday,TodoOverDueDate,TodoThresholdDate
-syntax match TodoPriorityH '^(H) .\+$' contains=TodoKey,TodoDate,TodoProject,TodoContext,TodoDueToday,TodoOverDueDate,TodoThresholdDate
-syntax match TodoPriorityI '^(I) .\+$' contains=TodoKey,TodoDate,TodoProject,TodoContext,TodoDueToday,TodoOverDueDate,TodoThresholdDate
-syntax match TodoPriorityJ '^(J) .\+$' contains=TodoKey,TodoDate,TodoProject,TodoContext,TodoDueToday,TodoOverDueDate,TodoThresholdDate
-syntax match TodoPriorityK '^(K) .\+$' contains=TodoKey,TodoDate,TodoProject,TodoContext,TodoDueToday,TodoOverDueDate,TodoThresholdDate
-syntax match TodoPriorityL '^(L) .\+$' contains=TodoKey,TodoDate,TodoProject,TodoContext,TodoDueToday,TodoOverDueDate,TodoThresholdDate
-syntax match TodoPriorityM '^(M) .\+$' contains=TodoKey,TodoDate,TodoProject,TodoContext,TodoDueToday,TodoOverDueDate,TodoThresholdDate
-syntax match TodoPriorityN '^(N) .\+$' contains=TodoKey,TodoDate,TodoProject,TodoContext,TodoDueToday,TodoOverDueDate,TodoThresholdDate
-syntax match TodoPriorityO '^(O) .\+$' contains=TodoKey,TodoDate,TodoProject,TodoContext,TodoDueToday,TodoOverDueDate,TodoThresholdDate
-syntax match TodoPriorityP '^(P) .\+$' contains=TodoKey,TodoDate,TodoProject,TodoContext,TodoDueToday,TodoOverDueDate,TodoThresholdDate
-syntax match TodoPriorityQ '^(Q) .\+$' contains=TodoKey,TodoDate,TodoProject,TodoContext,TodoDueToday,TodoOverDueDate,TodoThresholdDate
-syntax match TodoPriorityR '^(R) .\+$' contains=TodoKey,TodoDate,TodoProject,TodoContext,TodoDueToday,TodoOverDueDate,TodoThresholdDate
-syntax match TodoPriorityS '^(S) .\+$' contains=TodoKey,TodoDate,TodoProject,TodoContext,TodoDueToday,TodoOverDueDate,TodoThresholdDate
-syntax match TodoPriorityT '^(T) .\+$' contains=TodoKey,TodoDate,TodoProject,TodoContext,TodoDueToday,TodoOverDueDate,TodoThresholdDate
-syntax match TodoPriorityU '^(U) .\+$' contains=TodoKey,TodoDate,TodoProject,TodoContext,TodoDueToday,TodoOverDueDate,TodoThresholdDate
-syntax match TodoPriorityV '^(V) .\+$' contains=TodoKey,TodoDate,TodoProject,TodoContext,TodoDueToday,TodoOverDueDate,TodoThresholdDate
-syntax match TodoPriorityW '^(W) .\+$' contains=TodoKey,TodoDate,TodoProject,TodoContext,TodoDueToday,TodoOverDueDate,TodoThresholdDate
-syntax match TodoPriorityX '^(X) .\+$' contains=TodoKey,TodoDate,TodoProject,TodoContext,TodoDueToday,TodoOverDueDate,TodoThresholdDate
-syntax match TodoPriorityY '^(Y) .\+$' contains=TodoKey,TodoDate,TodoProject,TodoContext,TodoDueToday,TodoOverDueDate,TodoThresholdDate
-syntax match TodoPriorityZ '^(Z) .\+$' contains=TodoKey,TodoDate,TodoProject,TodoContext,TodoDueToday,TodoOverDueDate,TodoThresholdDate
-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
-syntax match TodoContext '\(^\|\W\)@[^[:blank:]]\+' contains=NONE
+syntax cluster TodoStart contains=TodoTodo,TodoDone,TodoPriorityA,TodoPriorityB,TodoPriorityC,TodoPriorityD,TodoPriorityE,TodoPriorityF,TodoPriorityG,TodoPriorityH,TodoPriorityI,TodoPriorityJ,TodoPriorityK,TodoPriorityL,TodoPriorityM,TodoPriorityN,TodoPriorityO,TodoPriorityP,TodoPriorityQ,TodoPriorityR,TodoPriorityS,TodoPriorityT,TodoPriorityU,TodoPriorityV,TodoPriorityW,TodoPriorityX,TodoPriorityY,TodoPriorityZ,TodoProject,TodoContext
+syntax cluster TodoDoneArgs contains=TodoKey,TodoDate,TodoProject,TodoContext
+syntax cluster TodoFullArgs contains=@TodoDoneArgs,TodoDueToday,TodoOverDueDate,TodoThresholdDate
+
+hi def TodoCol0 guibg=black
+syntax region TodoCol0 start=/^/ end=/$/ nextgroup=@TodoStart
+
+syntax region TodoTodo contained start=// end=/$/ contains=@TodoFullArgs
+syntax region TodoDone contained start=/x / end=/$/ contains=@TodoDoneArgs
+syntax region TodoPriorityA contained start=/(A) / end=/$/ contains=@TodoFullArgs
+syntax region TodoPriorityB contained start=/(B) / end=/$/ contains=@TodoFullArgs
+syntax region TodoPriorityC contained start=/(C) / end=/$/ contains=@TodoFullArgs
+syntax region TodoPriorityD contained start=/(D) / end=/$/ contains=@TodoFullArgs
+syntax region TodoPriorityE contained start=/(E) / end=/$/ contains=@TodoFullArgs
+syntax region TodoPriorityF contained start=/(F) / end=/$/ contains=@TodoFullArgs
+syntax region TodoPriorityG contained start=/(G) / end=/$/ contains=@TodoFullArgs
+syntax region TodoPriorityH contained start=/(H) / end=/$/ contains=@TodoFullArgs
+syntax region TodoPriorityI contained start=/(I) / end=/$/ contains=@TodoFullArgs
+syntax region TodoPriorityJ contained start=/(J) / end=/$/ contains=@TodoFullArgs
+syntax region TodoPriorityK contained start=/(K) / end=/$/ contains=@TodoFullArgs
+syntax region TodoPriorityL contained start=/(L) / end=/$/ contains=@TodoFullArgs
+syntax region TodoPriorityM contained start=/(M) / end=/$/ contains=@TodoFullArgs
+syntax region TodoPriorityN contained start=/(N) / end=/$/ contains=@TodoFullArgs
+syntax region TodoPriorityO contained start=/(O) / end=/$/ contains=@TodoFullArgs
+syntax region TodoPriorityP contained start=/(P) / end=/$/ contains=@TodoFullArgs
+syntax region TodoPriorityQ contained start=/(Q) / end=/$/ contains=@TodoFullArgs
+syntax region TodoPriorityR contained start=/(R) / end=/$/ contains=@TodoFullArgs
+syntax region TodoPriorityS contained start=/(S) / end=/$/ contains=@TodoFullArgs
+syntax region TodoPriorityT contained start=/(T) / end=/$/ contains=@TodoFullArgs
+syntax region TodoPriorityU contained start=/(U) / end=/$/ contains=@TodoFullArgs
+syntax region TodoPriorityV contained start=/(V) / end=/$/ contains=@TodoFullArgs
+syntax region TodoPriorityW contained start=/(W) / end=/$/ contains=@TodoFullArgs
+syntax region TodoPriorityX contained start=/(X) / end=/$/ contains=@TodoFullArgs
+syntax region TodoPriorityY contained start=/(Y) / end=/$/ contains=@TodoFullArgs
+syntax region TodoPriorityZ contained start=/(Z) / end=/$/ contains=@TodoFullArgs
+
+syntax match TodoDate '\d\{2,4\}-\d\{2\}-\d\{2\}' contains=NONE
+syntax match TodoKey '\S*\S:\S\S*' contains=TodoDate
+syntax match TodoProject '\(^\|\s\)+[^[:blank:]]\+' contains=NONE
+syntax match TodoContext '\(^\|\s\)@[^[:blank:]]\+' contains=NONE
let s:todayDate=strftime('%Y\-%m\-%d')
execute 'syntax match TodoDueToday /\v\c<due:' . s:todayDate . '>/ contains=NONE'
diff --git a/tests/todo.vader b/tests/todo.vader
index 9da6918..12f7f77 100644
--- a/tests/todo.vader
+++ b/tests/todo.vader
@@ -33,7 +33,7 @@ Execute (Syntax for done task):
AssertEqual 'TodoProject', SyntaxAt( 3, 54)
AssertEqual 'TodoContext', SyntaxAt( 3, 63)
Execute (Syntax for active task):
- AssertEqual '', SyntaxAt( 4, 1)
+ AssertEqual 'TodoTodo', SyntaxAt( 4, 1)
AssertEqual 'TodoOverDueDate', SyntaxAt( 4, 13)
AssertEqual 'TodoKey', SyntaxAt( 4, 28)
AssertEqual 'TodoKey', SyntaxAt( 4, 72)
@@ -149,14 +149,14 @@ x 345678901234567890123456789012345678901234567890123456789012345678901234567890
x . 1 . 2 . 3 . 4 . 5 . 6 . 7 . 8 L22
Execute (Syntax for invalid or misleading tasks):
" Invalid done or priority
- AssertEqual '', SyntaxAt( 3, 1)
- AssertEqual '', SyntaxAt( 4, 1)
- AssertEqual '', SyntaxAt( 5, 1)
- AssertEqual '', SyntaxAt( 6, 1)
- AssertEqual '', SyntaxAt( 7, 1)
- AssertEqual '', SyntaxAt( 8, 1)
- AssertEqual '', SyntaxAt( 9, 1)
- AssertEqual '', SyntaxAt(10, 1)
+ AssertEqual 'TodoTodo', SyntaxAt( 3, 1)
+ AssertEqual 'TodoTodo', SyntaxAt( 4, 1)
+ AssertEqual 'TodoTodo', SyntaxAt( 5, 1)
+ AssertEqual 'TodoTodo', SyntaxAt( 6, 1)
+ AssertEqual 'TodoTodo', SyntaxAt( 7, 1)
+ AssertEqual 'TodoTodo', SyntaxAt( 8, 1)
+ AssertEqual 'TodoTodo', SyntaxAt( 9, 1)
+ AssertEqual 'TodoTodo', SyntaxAt(10, 1)
" Valid keys and dates at start of line
AssertEqual 'TodoKey', SyntaxAt(11, 1)
AssertEqual 'TodoDate', SyntaxAt(11, 5)
@@ -165,24 +165,24 @@ Execute (Syntax for invalid or misleading tasks):
" Invalid date formats.
" FIXME: Not all cases are tested, not sure how strict to be
" AssertEqual '', SyntaxAt(16, 15) " FIXME
- AssertEqual '', SyntaxAt(16, 24)
+ AssertEqual 'TodoTodo', SyntaxAt(16, 24)
" AssertEqual '', SyntaxAt(16, 33) " FIXME
- AssertEqual '', SyntaxAt(16, 42)
- AssertEqual '', SyntaxAt(16, 44)
- AssertEqual '', SyntaxAt(16, 55)
+ AssertEqual 'TodoTodo', SyntaxAt(16, 42)
+ AssertEqual 'TodoTodo', SyntaxAt(16, 44)
+ AssertEqual 'TodoTodo', SyntaxAt(16, 55)
" AssertEqual '', SyntaxAt(16, 64) " FIXME
- AssertEqual '', SyntaxAt(16, 78)
+ AssertEqual 'TodoTodo', SyntaxAt(16, 78)
" Contexts and projects on the start of a line (valid)
AssertEqual 'TodoContext', SyntaxAt(17, 1)
AssertEqual 'TodoProject', SyntaxAt(18, 1)
" Invalid keys, etc
- AssertEqual '', SyntaxAt(19, 5)
- AssertEqual '', SyntaxAt(19, 55)
- AssertEqual '', SyntaxAt(20, 1)
+ AssertEqual 'TodoTodo', SyntaxAt(19, 5)
+ AssertEqual 'TodoTodo', SyntaxAt(19, 55)
+ AssertEqual 'TodoTodo', SyntaxAt(20, 1)
AssertEqual 'TodoKey', SyntaxAt(20, 34)
AssertEqual 'TodoDate', SyntaxAt(20, 41)
- AssertEqual '', SyntaxAt(20, 55)
- AssertEqual '', SyntaxAt(20, 69)
+ AssertEqual 'TodoTodo', SyntaxAt(20, 55)
+ AssertEqual 'TodoTodo', SyntaxAt(20, 69)
Do (Insert a task due today):
OTask due-\<BS>:\<C-R>=strftime("%Y-%m-%d")\<CR> today\<C-O>
Then (Syntax for task due today):