1-- Copyright 2009-2010 Corey O'Connor
2{-# LANGUAGE BangPatterns #-}
5module Graphics.Vty.DisplayAttributes where
7import Graphics.Vty.Attributes
9import Data.Bits ((.&.))
10import Data.ByteString (ByteString)
11#if !(MIN_VERSION_base(4,11,0))
12import Data.Semigroup (Semigroup(..))
14import Data.Text (Text)
15import Data.Text.Encoding (encodeUtf8)
17-- | Given the previously applied display attributes as a FixedAttr and
18-- the current display attributes as an Attr produces a FixedAttr that
19-- represents the current display attributes. This is done by using the
20-- previously applied display attributes to remove the "KeepCurrent"
22fixDisplayAttr :: FixedAttr -> Attr -> FixedAttr
23fixDisplayAttr fattr attr
24 = FixedAttr (fixStyle (fixedStyle fattr) (attrStyle attr))
25 (fixColor (fixedForeColor fattr) (attrForeColor attr))
26 (fixColor (fixedBackColor fattr) (attrBackColor attr))
27 (fixURL (fixedURL fattr) (attrURL attr))
29 fixStyle _s Default = defaultStyleMask
30 fixStyle s KeepCurrent = s
31 fixStyle _s (SetTo newStyle) = newStyle
32 fixColor _c Default = Nothing
33 fixColor c KeepCurrent = c
34 fixColor _c (SetTo c) = Just c
35 fixURL c KeepCurrent = c
36 fixURL _c (SetTo n) = Just n
37 fixURL _c Default = Nothing
39-- | difference between two display attributes. Used in the calculation
40-- of the operations required to go from one display attribute to the
43-- Previously, vty would reset display attributes to default then apply
44-- the new display attributes. This turned out to be very expensive: A
45-- *lot* more data would be sent to the terminal than required.
46data DisplayAttrDiff = DisplayAttrDiff
47 { styleDiffs :: [StyleStateChange]
48 , foreColorDiff :: DisplayColorDiff
49 , backColorDiff :: DisplayColorDiff
54instance Semigroup DisplayAttrDiff where
56 let ds = simplifyStyleDiffs (styleDiffs d0) (styleDiffs d1)
57 fcd = simplifyColorDiffs (foreColorDiff d0) (foreColorDiff d1)
58 bcd = simplifyColorDiffs (backColorDiff d0) (backColorDiff d1)
59 ud = simplifyUrlDiffs (urlDiff d0) (urlDiff d1)
60 in DisplayAttrDiff ds fcd bcd ud
62instance Monoid DisplayAttrDiff where
63 mempty = DisplayAttrDiff [] NoColorChange NoColorChange NoLinkChange
64#if !(MIN_VERSION_base(4,11,0))
68-- | Used in the computation of a final style attribute change.
69simplifyStyleDiffs :: [StyleStateChange] -> [StyleStateChange] -> [StyleStateChange]
70simplifyStyleDiffs cs0 cs1 = cs0 `mappend` cs1
72-- | Consider two display color attributes diffs. What display color
73-- attribute diff are these equivalent to?
74simplifyColorDiffs :: DisplayColorDiff -> DisplayColorDiff -> DisplayColorDiff
75simplifyColorDiffs _cd ColorToDefault = ColorToDefault
76simplifyColorDiffs cd NoColorChange = cd
77simplifyColorDiffs _cd (SetColor !c) = SetColor c
79-- | Consider two URL changes, which are mostly going to be the latter
80-- unless the latter specifies no change.
81simplifyUrlDiffs :: URLDiff -> URLDiff -> URLDiff
82simplifyUrlDiffs ud NoLinkChange = ud
83simplifyUrlDiffs _ ud = ud
85-- | Difference between two display color attribute changes.
92-- | Style attribute changes are transformed into a sequence of
93-- apply/removes of the individual attributes.
111-- Setting and unsetting hyperlinks
118-- | Determines the diff between two display&color attributes. This diff
119-- determines the operations that actually get output to the terminal.
120displayAttrDiffs :: FixedAttr -> FixedAttr -> DisplayAttrDiff
121displayAttrDiffs attr attr' = DisplayAttrDiff
122 { styleDiffs = diffStyles (fixedStyle attr) (fixedStyle attr')
123 , foreColorDiff = diffColor (fixedForeColor attr) (fixedForeColor attr')
124 , backColorDiff = diffColor (fixedBackColor attr) (fixedBackColor attr')
125 , urlDiff = diffURL (fixedURL attr) (fixedURL attr')
128diffURL :: Maybe Text -> Maybe Text -> URLDiff
129diffURL Nothing Nothing = NoLinkChange
130diffURL (Just _) Nothing = EndLink
131diffURL _ (Just url) = LinkTo (encodeUtf8 url)
133diffColor :: Maybe Color -> Maybe Color -> DisplayColorDiff
134diffColor Nothing (Just c') = SetColor c'
135diffColor (Just c) (Just c')
136 | c == c' = NoColorChange
137 | otherwise = SetColor c'
138diffColor Nothing Nothing = NoColorChange
139diffColor (Just _) Nothing = ColorToDefault
141diffStyles :: Style -> Style -> [StyleStateChange]
144 [ styleDiff standout ApplyStandout RemoveStandout
145 , styleDiff underline ApplyUnderline RemoveUnderline
146 , styleDiff italic ApplyItalic RemoveItalic
147 , styleDiff reverseVideo ApplyReverseVideo RemoveReverseVideo
148 , styleDiff blink ApplyBlink RemoveBlink
149 , styleDiff dim ApplyDim RemoveDim
150 , styleDiff bold ApplyBold RemoveBold
154 = case (0 == prev .&. s, 0 == cur .&. s) of
160 (True, False) -> [sm]
162 (False, True) -> [rm]
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list