diff options
author | cos <cos> | 2024-06-30 14:28:41 +0200 |
---|---|---|
committer | cos <cos> | 2024-08-17 19:29:17 +0200 |
commit | 267be9e15c98a2f3f78b424e967ea2f63af92e25 (patch) | |
tree | 9af8aa84985c5cf95c103d8c3d0ad1da9688b2d5 | |
parent | cfe9568a006f4f25386140df658f43087a7cc979 (diff) | |
download | todo.txt-vim-topic/allow-embed_squashed4mr.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.vim | 71 | ||||
-rw-r--r-- | tests/todo.vader | 38 |
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): |