@@ -59,9 +59,12 @@ PropertyStringMatch.__index = PropertyStringMatch
5959local PropertyNumberMatch = {}
6060PropertyNumberMatch .__index = PropertyNumberMatch
6161
62+ --- @class OrgTodoMatchAndItem
63+ --- @field operator string
64+ --- @field value string
65+
6266--- @class OrgTodoMatch
63- --- @field anyOf string[]
64- --- @field noneOf string[]
67+ --- @field orItems OrgTodoMatchAndItem[][]
6568local TodoMatch = {}
6669TodoMatch .__index = TodoMatch
6770
541544--- @private
542545--- @return OrgTodoMatch
543546function TodoMatch :_new ()
544- --- @type OrgTodoMatch
545547 local todo_match = {
546- anyOf = {},
547- noneOf = {},
548+ orItems = {},
548549 }
549550
550551 setmetatable (todo_match , TodoMatch )
@@ -567,65 +568,68 @@ function TodoMatch:parse(input)
567568
568569 -- Parse a whitelist of keywords
569570 --- @type string[] ?
570- local anyOf
571- anyOf , input = parse_delimited_sequence (input , function (i )
572- return parse_pattern (i , ' %w+' )
573- end , ' %|' )
574- if anyOf and # anyOf > 0 then
575- -- Successfully parsed the whitelist, return it
576- local todo_match = TodoMatch :_new ()
577- todo_match .anyOf = anyOf
578- return todo_match , input
579- end
571+ local orItems
572+ orItems , input = parse_delimited_sequence (input , function (i )
573+ --- @type string ?
574+ local operator
575+ operator , i = parse_pattern (i , ' [%+%-]?' )
576+
577+ if operator == ' ' then
578+ operator = ' +'
579+ end
580580
581- -- Parse a blacklist of keywords
582- --- @type string ?
583- local negation
584- negation , input = parse_pattern (input , ' -' )
585- if negation then
586- local negative_items
587- negative_items , input = parse_delimited_sequence (input , function (i )
588- return parse_pattern (i , ' %w+' )
589- end , ' %-' )
590-
591- if negative_items then
592- if # negation > 0 then
593- local todo_match = TodoMatch :_new ()
594- todo_match .noneOf = negative_items
595- return todo_match , input
596- else
597- return nil , original_input
581+ local andItems = {}
582+
583+ while operator do
584+ --- @type string ?
585+ local value
586+ value , i = parse_pattern (i , ' %w+' )
587+ if not value then
588+ break
598589 end
590+ table.insert (andItems , {
591+ operator = operator ,
592+ value = value ,
593+ })
594+
595+ operator , i = parse_pattern (i , ' [%+%-]' )
599596 end
597+
598+ return andItems , i
599+ end , ' %|' )
600+
601+ if not orItems or # orItems == 0 then
602+ return nil , original_input
600603 end
601604
602- return nil , original_input
605+ local todo_match = TodoMatch :_new ()
606+ todo_match .orItems = orItems
607+ return todo_match , input
603608end
604609
605610--- @param item OrgSearchable
606611--- @return boolean
607612function TodoMatch :match (item )
608613 local item_todo = item .todo
609614
610- if # self .anyOf > 0 then
611- for _ , todo_value in ipairs (self .anyOf ) do
612- if item_todo == todo_value then
613- return true
615+ for _ , orItem in ipairs (self .orItems ) do
616+ local validItems = true
617+ for _ , andItem in ipairs (orItem ) do
618+ if andItem .operator == ' -' and item_todo == andItem .value then
619+ validItems = false
620+ break
621+ elseif andItem .operator == ' +' and item_todo ~= andItem .value then
622+ validItems = false
623+ break
614624 end
615625 end
616626
617- return false
618- elseif # self .noneOf > 0 then
619- for _ , todo_value in ipairs (self .noneOf ) do
620- if item_todo == todo_value then
621- return false
622- end
627+ if validItems then
628+ return true
623629 end
624-
625- return true
626- else
627- return true
628630 end
631+
632+ return false
629633end
630634
631635return Search
0 commit comments