@@ -6,6 +6,9 @@ module Graphics.Vty.DisplayAttributes where
66import Graphics.Vty.Attributes
77
88import Data.Bits ((.&.))
9+import Data.ByteString (ByteString)
10+import Data.Text (Text)
11+import Data.Text.Encoding (encodeUtf8)
912
1013-- | Given the previously applied display attributes as a FixedAttr and
1114-- the current display attributes as an Attr produces a FixedAttr that
@@ -17,6 +20,7 @@ fixDisplayAttr fattr attr
1720 = FixedAttr (fixStyle (fixedStyle fattr) (attrStyle attr))
1821 (fixColor (fixedForeColor fattr) (attrForeColor attr))
1922 (fixColor (fixedBackColor fattr) (attrBackColor attr))
23+ (fixURL (fixedURL fattr) (attrURL attr))
2024 where
2125 fixStyle _s Default = defaultStyleMask
2226 fixStyle s KeepCurrent = s
@@ -24,6 +28,9 @@ fixDisplayAttr fattr attr
2428 fixColor _c Default = Nothing
2529 fixColor c KeepCurrent = c
2630 fixColor _c (SetTo c) = Just c
31+ fixURL c KeepCurrent = c
32+ fixURL _c (SetTo n) = Just n
33+ fixURL _c Default = Nothing
2734
2835-- | difference between two display attributes. Used in the calculation
2936-- of the operations required to go from one display attribute to the
@@ -36,16 +43,18 @@ data DisplayAttrDiff = DisplayAttrDiff
3643 { styleDiffs :: [StyleStateChange]
3744 , foreColorDiff :: DisplayColorDiff
3845 , backColorDiff :: DisplayColorDiff
46+ , urlDiff :: URLDiff
3947 }
4048 deriving (Show)
4149
4250instance Monoid DisplayAttrDiff where
43− mempty = DisplayAttrDiff [] NoColorChange NoColorChange
51+ mempty = DisplayAttrDiff [] NoColorChange NoColorChange NoLinkChange
4452 mappend d0 d1 =
4553 let ds = simplifyStyleDiffs (styleDiffs d0) (styleDiffs d1)
4654 fcd = simplifyColorDiffs (foreColorDiff d0) (foreColorDiff d1)
4755 bcd = simplifyColorDiffs (backColorDiff d0) (backColorDiff d1)
48− in DisplayAttrDiff ds fcd bcd
56+ ud = simplifyUrlDiffs (urlDiff d0) (urlDiff d1)
57+ in DisplayAttrDiff ds fcd bcd ud
4958
5059-- | Used in the computation of a final style attribute change.
5160simplifyStyleDiffs :: [StyleStateChange] -> [StyleStateChange] -> [StyleStateChange]
@@ -58,6 +67,12 @@ simplifyColorDiffs _cd ColorToDefault = ColorToDefault
5867simplifyColorDiffs cd NoColorChange = cd
5968simplifyColorDiffs _cd (SetColor !c) = SetColor c
6069
70+-- | Consider two URL changes, which are mostly going to be the latter
71+-- unless the latter specifies no change.
72+simplifyUrlDiffs :: URLDiff -> URLDiff -> URLDiff
73+simplifyUrlDiffs ud NoLinkChange = ud
74+simplifyUrlDiffs _ ud = ud
75+
6176-- | Difference between two display color attribute changes.
6277data DisplayColorDiff
6378 = ColorToDefault
@@ -82,6 +97,13 @@ data StyleStateChange
8297 | RemoveBold
8398 deriving (Show, Eq)
8499
100+-- Setting and unsetting hyperlinks
101+data URLDiff
102+ = LinkTo !ByteString
103+ | NoLinkChange
104+ | EndLink
105+ deriving (Show, Eq)
106+
85107-- | Determines the diff between two display&color attributes. This diff
86108-- determines the operations that actually get output to the terminal.
87109displayAttrDiffs :: FixedAttr -> FixedAttr -> DisplayAttrDiff
@@ -89,8 +111,14 @@ displayAttrDiffs attr attr' = DisplayAttrDiff
89111 { styleDiffs = diffStyles (fixedStyle attr) (fixedStyle attr')
90112 , foreColorDiff = diffColor (fixedForeColor attr) (fixedForeColor attr')
91113 , backColorDiff = diffColor (fixedBackColor attr) (fixedBackColor attr')
114+ , urlDiff = diffURL (fixedURL attr) (fixedURL attr')
92115 }
93116
117+diffURL :: Maybe Text -> Maybe Text -> URLDiff
118+diffURL Nothing Nothing = NoLinkChange
119+diffURL (Just _) Nothing = EndLink
120+diffURL _ (Just url) = LinkTo (encodeUtf8 url)
121+
94122diffColor :: Maybe Color -> Maybe Color -> DisplayColorDiff
95123diffColor Nothing (Just c') = SetColor c'
96124diffColor (Just c) (Just c')