33{-# LANGUAGE DuplicateRecordFields #-}
44{-# LANGUAGE ImportQualifiedPost #-}
55{-# LANGUAGE LambdaCase #-}
6+ {-# LANGUAGE NamedFieldPuns #-}
67{-# LANGUAGE OverloadedStrings #-}
8+ {-# LANGUAGE PatternSynonyms #-}
79{-# LANGUAGE RecordWildCards #-}
810{-# LANGUAGE ScopedTypeVariables #-}
911{-# LANGUAGE TypeApplications #-}
12+ {-# LANGUAGE ViewPatterns #-}
1013
1114module FF.Options (
1215 ActionOptions (.. ),
@@ -23,6 +26,7 @@ module FF.Options (
2326 Search (.. ),
2427 Shuffle (.. ),
2528 Tags (.. ),
29+ TagsRequest (EmptyTagsRequest , .. ),
2630 Track (.. ),
2731 assignToMaybe ,
2832 parseOptions ,
@@ -136,9 +140,21 @@ assignToMaybe = \case
136140 Clear -> Nothing
137141 Set x -> Just x
138142
139- data Agenda = Agenda { limit :: Maybe Limit , tags :: Tags }
143+ data Agenda = Agenda { limit :: Maybe Limit , tags :: TagsRequest }
140144
141- data Tags = Tags { require , exclude :: Set Text } | NoTags
145+ data Tags = Tags { require , exclude :: Set Text }
146+ deriving (Eq )
147+
148+ data TagsRequest = TagsContain Tags | TagsAbsent
149+ deriving (Eq )
150+
151+ emptyTagsRequest :: TagsRequest
152+ emptyTagsRequest = TagsContain Tags {require = mempty , exclude = mempty }
153+
154+ pattern EmptyTagsRequest :: TagsRequest
155+ pattern EmptyTagsRequest <- ((emptyTagsRequest == ) -> True )
156+ where
157+ EmptyTagsRequest = emptyTagsRequest
142158
143159data Edit = Edit
144160 { ids :: NonEmpty NoteId
@@ -166,7 +182,7 @@ data Search = Search
166182 , inContacts :: Bool
167183 , status :: Status
168184 , limit :: Maybe Limit
169- , tags :: Tags
185+ , tags :: TagsRequest
170186 }
171187
172188parseOptions :: Maybe StorageFS. Handle -> IO Options
@@ -263,10 +279,14 @@ parser h = do
263279 briefOption =
264280 switch $ long " brief" <> short ' b' <> help " List only note titles and ids"
265281
266- agenda = Agenda <$> optional limitOption <*> filterTags
282+ agenda = Agenda <$> optional limitOption <*> filterByTags
283+
284+ filterByTags = filterByTagsAbsent <|> filterByTagsContain
267285
268- filterTags =
269- filterByNoTags <|> (Tags <$> filterRequireTags <*> filterExcludeTags)
286+ filterByTagsContain = do
287+ require <- filterRequireTags
288+ exclude <- filterExcludeTags
289+ pure $ TagsContain Tags {require, exclude}
270290
271291 track = Track <$> dryRunOption <*> optional repo <*> optional limitOption
272292
@@ -325,7 +345,7 @@ parser h = do
325345 <*> searchC
326346 <*> searchA
327347 <*> optional limitOption
328- <*> filterTags
348+ <*> filterByTags
329349
330350 searchT = switch $ long " tasks" <> short ' t' <> help " Search among tasks"
331351
@@ -350,8 +370,8 @@ parser h = do
350370 strOption $
351371 long " tag" <> metavar " TAG" <> help " Filter by tag"
352372
353- filterByNoTags =
354- flag' NoTags $
373+ filterByTagsAbsent =
374+ flag' TagsAbsent $
355375 long " no-tag"
356376 <> short ' n'
357377 <> help " Filter items that have no tags"
0 commit comments