summaryrefslogtreecommitdiffstats
path: root/src/Much/State.hs
blob: 620a489eaf4a16bc9ac537aa53cbff50060d8785 (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
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE OverloadedStrings #-}
module Much.State where

import Blessings
import Data.Aeson
import Data.Default
import Data.Functor.Identity
import Data.Time
import GHC.Generics
import Much.TreeView (TreeView(TVSearch))
import Scanner
import System.Posix.Signals
import qualified Data.CaseInsensitive as CI
import qualified Data.Map as M
import qualified Data.Text as T
import qualified Data.Tree as Tree
import qualified Data.Tree.Zipper as Z
import qualified Much.API.Config
import qualified Notmuch.Message as Notmuch

data State = State
    { cursor :: Z.TreePos Z.Full TreeView
    , xoffset :: Int
    , yoffset :: Int
    , flashMessage :: Blessings String
    , screenWidth :: Int
    , screenHeight :: Int
    , headBuffer :: [Blessings String]
    , treeBuffer :: [Blessings String]
    , now :: UTCTime
    , signalHandlers :: [(Signal, IO ())]
    , query :: String
    , keymap :: String -> State -> IO State
    , mousemap :: Scan -> State -> IO State
    , tagSymbols :: M.Map T.Text T.Text
    , colorConfig :: ColorConfig Identity
    , apiConfig :: Much.API.Config.Config
    , attachmentOverwrite :: Bool
    , attachmentDirectory :: FilePath
    , attachmentFileName :: Notmuch.Message -> Notmuch.MessagePart -> FilePath
    }

instance Show (State -> IO ()) where
    show = const "λ"

data ColorConfig f = ColorConfig
    { alt :: f Pm
    , search :: f Pm
    , focus :: f Pm
    , quote :: f Pm
    , boring :: f Pm
    , prefix :: f Pm
    , date :: f Pm
    , tags :: f Pm
    , unreadSearch :: f Pm
    , unreadMessage :: f Pm
    , boringMessage :: f Pm
    , tagMap :: f (M.Map T.Text (f Pm))
    , unprintableFocus :: f Pm
    , unprintableNormal :: f Pm
    } deriving (Generic)

instance Applicative f => Default (ColorConfig f) where
  def = ColorConfig
    { tagMap = pure $ M.fromList
        [ ("killed", pure [38,5,088])
        , ("star", pure [38,5,226])
        , ("draft", pure [38,5,202])
        ]
    , alt = pure [38,5,182]
    , search = pure [38,5,162]
    , focus = pure [38,5,160]
    , unprintableFocus = pure [38,5,204]
    , unprintableNormal = pure [35]
    , quote = pure [38,5,242]
    , boring = pure [38,5,240]
    , prefix = pure [38,5,235]
    , date = pure [38,5,071]
    , tags = pure [38,5,036]
    , boringMessage = pure [38,5,023]
    , unreadMessage = pure [38,5,117]
    , unreadSearch = pure [38,5,250]
    }

instance FromJSON (ColorConfig Maybe)
instance Show (ColorConfig Maybe)

instance Default State where
  def = State
      { cursor = Z.fromTree (Tree.Node (TVSearch "<emptyState>") [])
      , xoffset = 0
      , yoffset = 0
      , flashMessage = "Welcome to much; quit with ^C"
      , screenWidth = 0
      , screenHeight = 0
      , headBuffer = []
      , treeBuffer = []
      , now = UTCTime (fromGregorian 1984 5 23) 49062
      , signalHandlers = []
      , query = "tag:inbox AND NOT tag:killed"
      , keymap = const return
      , mousemap = const return
      , colorConfig = def
      , tagSymbols = M.empty
      , apiConfig = def
      , attachmentOverwrite = False
      , attachmentDirectory = "/tmp"
      , attachmentFileName = \message part ->
          case Notmuch.partContentFilename part of
            Just partFileName -> T.unpack partFileName
            Nothing ->
              "much_"
              <> formatTime defaultTimeLocale "%s" (Notmuch.messageTime message)
              <> "_"
              <> show (Notmuch.partID part)
              <> extension (Notmuch.partContentType part)
      }

extension :: CI.CI T.Text -> String
extension "text/html" = ".html"
extension "text/plain" = ".txt"
extension _ = ""