summaryrefslogtreecommitdiffstats
path: root/src/Much/TagUtils.hs
blob: d4e4d30a7fea8fa8aaff40e7a1478f20751e9336 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
{-# LANGUAGE LambdaCase #-}

module Much.TagUtils where

import qualified Data.Set as Set
import qualified Data.Text as T
import Data.Char
import Data.List.Split (wordsBy)
import Data.Tree
import Notmuch.Message
import Notmuch.SearchResult
import Much.TreeView.Types


type Tag = T.Text


data TagOp = AddTag Tag | DelTag Tag


parseTags :: String -> [Tag]
parseTags =
    mconcat . map (map T.pack . wordsBy isSpace . takeWhile (/='#')) . lines


diffTags :: [Tag] -> [Tag] -> [TagOp]
diffTags old new =
    let oldTags = Set.fromList old
        newTags = Set.fromList new
    in map DelTag (Set.toList $ oldTags `Set.difference` newTags) ++
       map AddTag (Set.toList $ newTags `Set.difference` oldTags)


patchRootLabelTags :: [TagOp] -> Tree TreeView -> Tree TreeView
patchRootLabelTags tagOps x =
    x { rootLabel = patchTags tagOps $ rootLabel x }


patchTreeTags :: [TagOp] -> Tree TreeView -> Tree TreeView
patchTreeTags tagOps =
    fmap (patchTags tagOps)


tagOpsToArgs :: [TagOp] -> [String]
tagOpsToArgs = map $ \case
    AddTag t -> '+' : T.unpack t
    DelTag t -> '-' : T.unpack t


patchTags :: [TagOp] -> TreeView -> TreeView
patchTags tagOps = \case
    TVSearchResult sr ->
        TVSearchResult sr { searchTags = foldr applyTagOp (searchTags sr) tagOps }
    TVMessage m ->
        TVMessage m { messageTags = foldr applyTagOp (messageTags m) tagOps }
    x -> x -- nop


applyTagOp :: TagOp -> [Tag] -> [Tag]
applyTagOp = \case
    AddTag t -> (t:)
    DelTag t -> filter (/=t)