on master help sign in
References to ISO-10464 (testing of gas cylinders) should actually be ISO-10646. (John Pybus)
dcc2951coreyoconnor
src/Codec/Binary/UTF8/Debug.hs+1−1
@@ -8,7 +8,7 @@ import Data.Word
8
8
9import Numeric
9import Numeric
10
10
11−-- Converts an array of ISO-10464 characters (Char type) to an array of Word8 bytes that is the
11+-- Converts an array of ISO-10646 characters (Char type) to an array of Word8 bytes that is the
12-- corresponding UTF8 byte sequence
12-- corresponding UTF8 byte sequence
13utf8_from_iso :: Integral i => [i] -> [Word8]
13utf8_from_iso :: Integral i => [i] -> [Word8]
14utf8_from_iso = encode . map toEnum
14utf8_from_iso = encode . map toEnum
src/Graphics/Vty.hs+4−2
@@ -37,12 +37,14 @@ import System.IO
37-- An alternative is to use unsafePerformIO to automatically create a singleton Vty instance when
37-- An alternative is to use unsafePerformIO to automatically create a singleton Vty instance when
38-- required.
38-- required.
39--
39--
40−-- This has the same thread safety as `output_picture`.
40+-- This does not assure any thread safety. In theory, as long as an update action is not executed
41+-- when another update action is already then it's safe to call this on multiple threads.
41--
42--
42-- todo: Once the Terminal interface encompasses input this interface will be deprecated.
43-- todo: Once the Terminal interface encompasses input this interface will be deprecated.
43-- Currently, just using the Terminal interface there is no support for input events.
44-- Currently, just using the Terminal interface there is no support for input events.
44data Vty = Vty
45data Vty = Vty
45− { -- | Outputs the given Picture. Equivalent to output_picture.
46+ { -- | Outputs the given Picture. Equivalent to output_picture applied to a display context
47+ -- implicitly managed by Vty.
46 update :: Picture -> IO ()
48 update :: Picture -> IO ()
47 -- | Get one Event object, blocking if necessary.
49 -- | Get one Event object, blocking if necessary.
48 , next_event :: IO Event
50 , next_event :: IO Event
src/Graphics/Vty/Attributes.hs+56−42
@@ -1,27 +1,5 @@
1-- Copyright 2009 Corey O'Connor
1-- Copyright 2009 Corey O'Connor
2-- Display attributes
2-- Display attributes
3−{-# LANGUAGE MagicHash #-}
4−module Graphics.Vty.Attributes
5− where
6−
7−import Data.Bits
8−
9−import Data.Word
10−
11−import Numeric
12−
13−-- | A display attribute defines the color and style of all the characters rendered after the
14−-- attribute is applied.
15−-- 6 possible style attributes:
16−-- standout
17−-- underline
18−-- reverse
19−-- blink
20−-- dim
21−-- bold/bright
22−-- ( invisible, protect, and altcharset are not supported)
23−-- At most 240 + 16 colors for the background and foreground. The 240 colors and 16 colors are
24−-- points in different palettes. Which is why it's not simply "at most 256 colors"
25--
3--
26-- For efficiency this can be, in the future, encoded into a single 32 bit word. The 32 bit word is
4-- For efficiency this can be, in the future, encoded into a single 32 bit word. The 32 bit word is
27-- first divided into 4 groups of 8 bits where:
5-- first divided into 4 groups of 8 bits where:
@@ -54,6 +32,19 @@ import Numeric
54-- Then the foreground color encoded into 8 bits.
32-- Then the foreground color encoded into 8 bits.
55-- Then the background color encoded into 8 bits.
33-- Then the background color encoded into 8 bits.
56--
34--
35+module Graphics.Vty.Attributes
36+ where
37+
38+import Data.Bits
39+
40+import Data.Word
41+
42+-- | A display attribute defines the Color and Style of all the characters rendered after the
43+-- attribute is applied.
44+--
45+-- At most 256 colors, picked from a 240 and 16 color palette, are possible for the background and
46+-- foreground. The 240 colors and 16 colors are points in different palettes. See Color for more
47+-- information.
57data Attr = Attr
48data Attr = Attr
58 { style :: !(MaybeDefault Style)
49 { style :: !(MaybeDefault Style)
59 , fore_color :: !(MaybeDefault Color)
50 , fore_color :: !(MaybeDefault Color)
@@ -62,32 +53,44 @@ data Attr = Attr
62
53
63-- | Specifies the display attributes such that the final style and color values do not depend on
54-- | Specifies the display attributes such that the final style and color values do not depend on
64-- the previously applied display attribute. The display attributes can still depend on the
55-- the previously applied display attribute. The display attributes can still depend on the
65−-- terminal's default attributes unfortunately.
56+-- terminal's default colors (unfortunately).
66data FixedAttr = FixedAttr
57data FixedAttr = FixedAttr
67 { fixed_style :: !Style
58 { fixed_style :: !Style
68 , fixed_fore_color :: !(Maybe Color)
59 , fixed_fore_color :: !(Maybe Color)
69 , fixed_back_color :: !(Maybe Color)
60 , fixed_back_color :: !(Maybe Color)
70 } deriving ( Eq, Show )
61 } deriving ( Eq, Show )
71
62
63+-- | The style and color attributes can either be the terminal defaults. Or be equivalent to the
64+-- previously applied style. Or be a specific value.
72data Eq v => MaybeDefault v = Default | KeepCurrent | SetTo !v
65data Eq v => MaybeDefault v = Default | KeepCurrent | SetTo !v
73 deriving ( Eq, Show )
66 deriving ( Eq, Show )
74
67
75-- | Abstract data type representing a color.
68-- | Abstract data type representing a color.
76--
69--
77-- Currently the foreground and background color are specified as points in either a:
70-- Currently the foreground and background color are specified as points in either a:
71+--
78-- * 16 color palette. Where the first 8 colors are equal to the 8 colors of the ISO 6429 (ANSI) 8
72-- * 16 color palette. Where the first 8 colors are equal to the 8 colors of the ISO 6429 (ANSI) 8
79-- color palette and the second 8 colors are bright/vivid versions of the first 8 colors.
73-- color palette and the second 8 colors are bright/vivid versions of the first 8 colors.
74+--
80-- * 240 color palette. This palette is a regular sampling of the full RGB colorspace.
75-- * 240 color palette. This palette is a regular sampling of the full RGB colorspace.
81--
76--
82-- The 8 ISO 6429 (ANSI) colors are as follows:
77-- The 8 ISO 6429 (ANSI) colors are as follows:
78+--
83−-- 0. black
79+-- 0. black
80+--
84−-- 1. red
81+-- 1. red
82+--
85−-- 2. green
83+-- 2. green
84+--
86−-- 3. yellow
85+-- 3. yellow
86+--
87−-- 4. blue
87+-- 4. blue
88+--
88−-- 5. magenta
89+-- 5. magenta
90+--
89−-- 6. cyan
91+-- 6. cyan
92+--
90−-- 7. white
93+-- 7. white
91--
94--
92-- The mapping from points in the 240 color palette to colors actually displayable by the terminal
95-- The mapping from points in the 240 color palette to colors actually displayable by the terminal
93-- depends on the number of colors the terminal claims to support. Which is usually determined by
96-- depends on the number of colors the terminal claims to support. Which is usually determined by
@@ -122,8 +125,6 @@ white = ISOColor 7
122
125
123-- | Bright/Vivid variants of the standard 8-color ANSI
126-- | Bright/Vivid variants of the standard 8-color ANSI
124bright_black, bright_red, bright_green, bright_yellow :: Color
127bright_black, bright_red, bright_green, bright_yellow :: Color
125−
126−-- | Bright/Vivid variants of the standard 8-color ANSI
127bright_blue, bright_magenta, bright_cyan, bright_white :: Color
128bright_blue, bright_magenta, bright_cyan, bright_white :: Color
128bright_black = ISOColor 8
129bright_black = ISOColor 8
129bright_red = ISOColor 9
130bright_red = ISOColor 9
@@ -134,16 +135,26 @@ bright_magenta= ISOColor 13
134bright_cyan = ISOColor 14
135bright_cyan = ISOColor 14
135bright_white = ISOColor 15
136bright_white = ISOColor 15
136
137
138+-- | Styles are represented as an 8 bit word. Each bit in the word is 1 if the style attribute
139+-- assigned to that bit should be applied and 0 if the style attribute should not be applied.
137type Style = Word8
140type Style = Word8
138
141
139−-- | 6 possible style attributes:
142+-- | The 6 possible style attributes:
143+--
140−-- standout
144+-- * standout
145+--
141−-- underline
146+-- * underline
147+--
142−-- reverse_video
148+-- * reverse_video
149+--
143−-- blink
150+-- * blink
151+--
144−-- dim
152+-- * dim
153+--
145−-- bold/bright
154+-- * bold/bright
155+--
146−-- ( invisible, protect, and altcharset are not supported)
156+-- ( The invisible, protect, and altcharset display attributes some terminals support are not
157+-- supported via VTY.)
147standout, underline, reverse_video, blink, dim, bold :: Style
158standout, underline, reverse_video, blink, dim, bold :: Style
148standout = 0x01
159standout = 0x01
149underline = 0x02
160underline = 0x02
@@ -162,8 +173,9 @@ style_mask attr
162 KeepCurrent -> 0
173 KeepCurrent -> 0
163 SetTo v -> v
174 SetTo v -> v
164
175
176+-- | true if the given Style value has the specified Style set.
165has_style :: Style -> Style -> Bool
177has_style :: Style -> Style -> Bool
166−has_style style bit_mask = ( style .&. bit_mask ) /= 0
178+has_style s bit_mask = ( s .&. bit_mask ) /= 0
167
179
168-- | Set the foreground color of an `Attr'.
180-- | Set the foreground color of an `Attr'.
169with_fore_color :: Attr -> Color -> Attr
181with_fore_color :: Attr -> Color -> Attr
@@ -184,7 +196,9 @@ def_attr = Attr Default Default Default
184
196
185-- | Keeps the style, background color and foreground color that was previously set. Used to
197-- | Keeps the style, background color and foreground color that was previously set. Used to
186-- override some part of the previous style.
198-- override some part of the previous style.
199+--
187-- EG: current_style `with_fore_color` bright_magenta
200-- EG: current_style `with_fore_color` bright_magenta
201+--
188-- Would be the currently applied style (be it underline, bold, etc) but with the foreground color
202-- Would be the currently applied style (be it underline, bold, etc) but with the foreground color
189-- set to bright_magenta.
203-- set to bright_magenta.
190current_attr :: Attr
204current_attr :: Attr
src/Graphics/Vty/Image.hs+50−39
@@ -2,23 +2,7 @@
2{-# LANGUAGE BangPatterns #-}
2{-# LANGUAGE BangPatterns #-}
3{-# LANGUAGE NamedFieldPuns #-}
3{-# LANGUAGE NamedFieldPuns #-}
4{-# LANGUAGE DisambiguateRecordFields #-}
4{-# LANGUAGE DisambiguateRecordFields #-}
5−{-# LANGUAGE MagicHash, UnboxedTuples #-}
6{-# OPTIONS_GHC -funbox-strict-fields #-}
5{-# OPTIONS_GHC -funbox-strict-fields #-}
7−{- A picutre in VTY defines
8− - * properties required to display the image. These are properties that effect the output image
9− - but are independent of position
10− - * A set of position-dependent text and attribute regions. The possible regions are
11− - * a point
12− - * a horizontal line of characters with a single attribute
13− - * a vertical line of a single character
14− - * a horizontal line of a single character.
15− - * a rectangle of a single character
16− -
17− -
18− -
19− - todo: Move to UTF-8 encoded bytestring streams?
20− -}
21−
22module Graphics.Vty.Image ( Image(..)
6module Graphics.Vty.Image ( Image(..)
23 , image_width
7 , image_width
24 , image_height
8 , image_height
@@ -31,7 +15,7 @@ module Graphics.Vty.Image ( Image(..)
31 , background_fill
15 , background_fill
32 , char
16 , char
33 , string
17 , string
34− , iso_10464_string
18+ , iso_10646_string
35 , utf8_string
19 , utf8_string
36 , utf8_bytestring
20 , utf8_bytestring
37 , char_fill
21 , char_fill
@@ -56,17 +40,34 @@ infixr 4 <->
56
40
57type StringSeq = Seq.Seq Char
41type StringSeq = Seq.Seq Char
58
42
43+-- | An image in VTY defines:
44+--
45+-- * properties required to display the image. These are properties that effect the output image
46+-- but are independent of position
47+--
48+-- * A set of position-dependent text and attribute regions. The possible regions are:
49+--
50+-- * a point. ( char )
51+--
52+-- * a horizontal line of characters with a single attribute. (string, utf8_string,
53+-- utf8_bytestring )
54+--
55+-- * a fill of a single character. (char_fill)
56+--
57+-- * a fill of the picture's background. (background_fill)
58+--
59+-- todo: increase the number of encoded bytestring formats supported.
59data Image =
60data Image =
60− -- | A horizontal text span is always >= 1 column and has a row height of 1.
61+ -- A horizontal text span is always >= 1 column and has a row height of 1.
61 HorizText
62 HorizText
62 { attr :: !Attr
63 { attr :: !Attr
63− -- | All character data is stored as Char sequences with the ISO-10646 encoding.
64+ -- All character data is stored as Char sequences with the ISO-10646 encoding.
64 , text :: StringSeq
65 , text :: StringSeq
65− -- | in columns
66+ -- in columns
66 , output_width :: !Word -- >= 0
67 , output_width :: !Word -- >= 0
67 , char_width :: !Word -- >= 1
68 , char_width :: !Word -- >= 1
68 }
69 }
69− -- | A horizontal join can be constructed between any two images. However a HorizJoin instance is
70+ -- A horizontal join can be constructed between any two images. However a HorizJoin instance is
70 -- required to be between two images of equal height. The horiz_join constructor adds blanks to
71 -- required to be between two images of equal height. The horiz_join constructor adds blanks to
71 -- the provided images that assure this is true for the HorizJoin value produced.
72 -- the provided images that assure this is true for the HorizJoin value produced.
72 | HorizJoin
73 | HorizJoin
@@ -75,7 +76,7 @@ data Image =
75 , output_width :: !Word -- >= 1
76 , output_width :: !Word -- >= 1
76 , output_height :: !Word -- >= 1
77 , output_height :: !Word -- >= 1
77 }
78 }
78− -- | A veritical join can be constructed between any two images. However a VertJoin instance is
79+ -- A veritical join can be constructed between any two images. However a VertJoin instance is
79 -- required to be between two images of equal width. The horiz_join constructor adds blanks to
80 -- required to be between two images of equal width. The horiz_join constructor adds blanks to
80 -- the provides images that assure this is true for the HorizJoin value produced.
81 -- the provides images that assure this is true for the HorizJoin value produced.
81 | VertJoin
82 | VertJoin
@@ -84,7 +85,7 @@ data Image =
84 , output_width :: !Word -- >= 1
85 , output_width :: !Word -- >= 1
85 , output_height :: !Word -- >= 1
86 , output_height :: !Word -- >= 1
86 }
87 }
87− -- | A background fill will be filled with the background pattern. The background pattern is
88+ -- A background fill will be filled with the background pattern. The background pattern is
88 -- defined as a property of the Picture this Image is used to form.
89 -- defined as a property of the Picture this Image is used to form.
89 | BGFill
90 | BGFill
90 { output_width :: !Word -- >= 1
91 { output_width :: !Word -- >= 1
@@ -173,14 +174,14 @@ vert_join i_0 i_1 w h
173 w h
174 w h
174vert_join _ _ _ _ = error "vert_join applied to undefined values."
175vert_join _ _ _ _ = error "vert_join applied to undefined values."
175
176
176−-- | An area of the picture's bacground (See `Background`) of w columns and h rows.
177+-- | An area of the picture's bacground (See Background) of w columns and h rows.
177background_fill :: Word -> Word -> Image
178background_fill :: Word -> Word -> Image
178background_fill w h
179background_fill w h
179 | w == 0 = IdImage
180 | w == 0 = IdImage
180 | h == 0 = IdImage
181 | h == 0 = IdImage
181 | otherwise = BGFill w h
182 | otherwise = BGFill w h
182
183
183−-- | Access the width of an Image.
184+-- | The width of an Image. This is the number display columns the image will occupy.
184image_width :: Image -> Word
185image_width :: Image -> Word
185image_width HorizText { output_width = w } = w
186image_width HorizText { output_width = w } = w
186image_width HorizJoin { output_width = w } = w
187image_width HorizJoin { output_width = w } = w
@@ -188,7 +189,7 @@ image_width VertJoin { output_width = w } = w
188image_width BGFill { output_width = w } = w
189image_width BGFill { output_width = w } = w
189image_width IdImage = 0
190image_width IdImage = 0
190
191
191−-- | Access the height of an Image.
192+-- | The height of an Image. This is the number of display rows the image will occupy.
192image_height :: Image -> Word
193image_height :: Image -> Word
193image_height HorizText {} = 1
194image_height HorizText {} = 1
194image_height HorizJoin { output_height = r } = r
195image_height HorizJoin { output_height = r } = r
@@ -197,10 +198,10 @@ image_height BGFill { output_height = r } = r
197image_height IdImage = 0
198image_height IdImage = 0
198
199
199-- | Combines two images side by side.
200-- | Combines two images side by side.
201+--
200−-- The result image will have a width equal to the sum of the two images width.
202+-- The result image will have a width equal to the sum of the two images width. And the height will
201−-- The height will equal the largest height of the two images
203+-- equal the largest height of the two images. The area not defined in one image due to a height
202−-- The area not defined in one image due to a height missmatch will be filled with the background
204+-- missmatch will be filled with the background pattern.
203−-- pattern.
204(<|>) :: Image -> Image -> Image
205(<|>) :: Image -> Image -> Image
205
206
206-- Two horizontal text spans with the same attributes can be merged.
207-- Two horizontal text spans with the same attributes can be merged.
@@ -257,24 +258,30 @@ vertcat :: [Image] -> Image
257vertcat = vert_cat
258vertcat = vert_cat
258
259
259-- | an image of a single character. This is a standard Haskell 31-bit character assumed to be in
260-- | an image of a single character. This is a standard Haskell 31-bit character assumed to be in
260−-- the ISO-10464 encoding.
261+-- the ISO-10646 encoding.
261char :: Attr -> Char -> Image
262char :: Attr -> Char -> Image
262char !a !c = HorizText a (Seq.singleton c) (safe_wcwidth c) 1
263char !a !c = HorizText a (Seq.singleton c) (safe_wcwidth c) 1
263
264
264−-- | A string of characters layed out on a single row. The string is assumed to be a sequence of
265+-- | A string of characters layed out on a single row with the same display attribute. The string is
266+-- assumed to be a sequence of ISO-10646 characters.
267+--
265−-- ISO-10464 characters. Note: depending on how the Haskell compiler represents string literals a
268+-- Note: depending on how the Haskell compiler represents string literals a string literal in a
266−-- string literal in a UTF-8 encoded source file, for example, may be represented as a ISO-10464
269+-- UTF-8 encoded source file, for example, may be represented as a ISO-10646 string.
267−-- string. That is, I think, the case with GHC 6.10.
270+-- That is, I think, the case with GHC 6.10. This means, for the most part, you don't need to worry
271+-- about the encoding format when outputting string literals. Just provide the string literal
272+-- directly to iso_10646_string or string.
273+--
268−iso_10464_string :: Attr -> String -> Image
274+iso_10646_string :: Attr -> String -> Image
269−iso_10464_string !a !str = horiz_text a (Seq.fromList str) (safe_wcswidth str)
275+iso_10646_string !a !str = horiz_text a (Seq.fromList str) (safe_wcswidth str)
270
276
271-- | Alias for iso_10646_string. Since the usual case is that a literal string like "foo" is
277-- | Alias for iso_10646_string. Since the usual case is that a literal string like "foo" is
272−-- represented internally as a list of ISO 10646 31 bit characters.
278+-- represented internally as a list of ISO 10646 31 bit characters.
279+--
273-- Note: Keep in mind that GHC will compile source encoded as UTF-8 but the literal strings, while
280-- Note: Keep in mind that GHC will compile source encoded as UTF-8 but the literal strings, while
274-- UTF-8 encoded in the source, will be transcoded to a ISO 10646 31 bit characters runtime
281-- UTF-8 encoded in the source, will be transcoded to a ISO 10646 31 bit characters runtime
275-- representation.
282-- representation.
276string :: Attr -> String -> Image
283string :: Attr -> String -> Image
277−string = iso_10464_string
284+string = iso_10646_string
278
285
279-- | A string of characters layed out on a single row. The string is assumed to be a sequence of
286-- | A string of characters layed out on a single row. The string is assumed to be a sequence of
280-- UTF-8 characters.
287-- UTF-8 characters.
@@ -295,6 +302,10 @@ safe_wcswidth str = case wcswidth str of
295utf8_bytestring :: Attr -> BS.ByteString -> Image
302utf8_bytestring :: Attr -> BS.ByteString -> Image
296utf8_bytestring !a !bs = string a (UTF8.toString $ UTF8.fromRep bs)
303utf8_bytestring !a !bs = string a (UTF8.toString $ UTF8.fromRep bs)
297
304
305+-- | creates a fill of the specified character. The dimensions are in number of characters wide and
306+-- number of rows high.
307+--
308+-- Unlike the Background fill character this character can have double column display width.
298char_fill :: Enum d => Attr -> Char -> d -> d -> Image
309char_fill :: Enum d => Attr -> Char -> d -> d -> Image
299char_fill !a !c w h =
310char_fill !a !c w h =
300 vert_cat $ replicate (fromEnum h) $ horiz_cat $ replicate (fromEnum w) $ char a c
311 vert_cat $ replicate (fromEnum h) $ horiz_cat $ replicate (fromEnum w) $ char a c
src/Graphics/Vty/Picture.hs+13−13
@@ -12,7 +12,7 @@ module Graphics.Vty.Picture ( module Graphics.Vty.Picture
12 , background_fill
12 , background_fill
13 , char
13 , char
14 , string
14 , string
15− , iso_10464_string
15+ , iso_10646_string
16 , utf8_string
16 , utf8_string
17 , utf8_bytestring
17 , utf8_bytestring
18 , char_fill
18 , char_fill
@@ -35,7 +35,7 @@ data Picture = Picture
35 , pic_background :: Background
35 , pic_background :: Background
36 }
36 }
37
37
38−-- | Create a picture instance from the given image. The picture will not have a displayed cursor
38+-- | Create a picture for display for the given image. The picture will not have a displayed cursor
39-- and the background display attribute will be `current_attr`.
39-- and the background display attribute will be `current_attr`.
40pic_for_image :: Image -> Picture
40pic_for_image :: Image -> Picture
41pic_for_image i = Picture
41pic_for_image i = Picture
@@ -46,25 +46,25 @@ pic_for_image i = Picture
46
46
47-- | A picture can be configured either to not show the cursor or show the cursor at the specified
47-- | A picture can be configured either to not show the cursor or show the cursor at the specified
48-- character position.
48-- character position.
49+--
49-- There is not a 1 to 1 map from character positions to a row and column on the screen due to
50-- There is not a 1 to 1 map from character positions to a row and column on the screen due to
50-- characters that take more than 1 column.
51-- characters that take more than 1 column.
52+--
51−-- todo?: The Cursor can be given a (character,row) offset outside of the visible bounds of the output
53+-- todo: The Cursor can be given a (character,row) offset outside of the visible bounds of the
52−-- region. In this case the cursor will not be shown.
54+-- output region. In this case the cursor will not be shown.
53data Cursor =
55data Cursor =
54 NoCursor
56 NoCursor
55 | Cursor Word Word
57 | Cursor Word Word
56
58
57−-- | Unspecified regions are filled with the picture's background pattern.
59+-- | Unspecified regions are filled with the picture's background pattern. The background pattern
58−-- The background pattern can specify a character and a display attribute. If the display attribute
60+-- can specify a character and a display attribute. If the display attribute used previously should
59−-- used previously should be used for a background fill then use `current_attr` for the background
61+-- be used for a background fill then use `current_attr` for the background attribute. This is the
60−-- attribute. This is the default background display attribute.
62+-- default background display attribute.
61--
63--
62−-- The current attribute is always set to the default attributes on the start of updating the screen
64+-- (tofix) The current attribute is always set to the default attributes at the start of updating the
63−-- to a picture.
65+-- screen to a picture.
64--
66--
65−-- todo: The background character *must* occupy a single column and no more.
67+-- (tofix) The background character *must* occupy a single column and no more.
66−-- The spans for a picture do not specify character data beyond the bounds of the region provided.
67−-- A text run may be cropped or padded to fit within the region.
68data Background = Background
68data Background = Background
69 { background_char :: Char
69 { background_char :: Char
70 , background_attr :: Attr
70 , background_attr :: Attr
src/Graphics/Vty/Terminal.hs+35−15
@@ -11,15 +11,6 @@
11-- for as many control codes as possible. H: This should derive functionality from the
11-- for as many control codes as possible. H: This should derive functionality from the
12-- TerminfoBased terminal.
12-- TerminfoBased terminal.
13--
13--
14−-- Selection of a terminal is done as follows:
15−-- If TERM == xterm
16−--
17−-- todo: Use XTermColor with the variant parameter
18−-- StandardXTerm if COLORTERM is not set
19−-- GnomeTerminal if COLORTERM is gnome-terminal
20−-- - Default attribute is different ?How?
21−-- - No blink support
22−-- otherwise TerminfoBased is used.
23--
14--
24{-# LANGUAGE ScopedTypeVariables #-}
15{-# LANGUAGE ScopedTypeVariables #-}
25{-# LANGUAGE GADTs #-}
16{-# LANGUAGE GADTs #-}
@@ -45,20 +36,47 @@ import Data.Word
45
36
46import System.Environment
37import System.Environment
47
38
39+-- | Returns a TerminalHandle (an abstract Terminal instance) for the current terminal.
40+--
41+-- The specific Terminal implementation used is hidden from the API user. All terminal
42+-- implementations are assumed to perform more, or less, the same. Currently all implementations use
43+-- terminfo for at least some terminal specific information. This is why platforms without terminfo
44+-- are not supported. However, as mentioned before, any specifics about it being based on terminfo
45+-- are hidden from the API user. If a terminal implementation is developed for a terminal for a
46+-- platform without terminfo support then Vty should work as expected on that terminal.
47+--
48+-- Selection of a terminal is done as follows:
49+--
50+-- * If TERM == xterm
51+-- then the terminal might be one of the Mac OS X .app terminals. Check if that might be
52+-- the case and use MacOSX if so.
53+-- otherwise use XTermColor.
54+--
55+-- * for any other TERM value TerminfoBased is used.
56+--
57+--
48−-- | The terminal has to be determined dynamically at runtime. To satisfy this requirement all
58+-- The terminal has to be determined dynamically at runtime. To satisfy this requirement all
49-- terminals instances are lifted into an abstract terminal handle via existential qualification.
59-- terminals instances are lifted into an abstract terminal handle via existential qualification.
50-- This implies that the only equations that can used are those in the terminal class.
60-- This implies that the only equations that can used are those in the terminal class.
61+--
62+-- To differentiate between Mac OS X terminals this uses the TERM_PROGRAM environment variable.
63+-- However, an xterm started by Terminal or iTerm *also* has TERM_PROGRAM defined since the
64+-- environment variable is not reset/cleared by xterm. However a Terminal.app or iTerm.app started
65+-- from an xterm under X11 on mac os x will likely be done via open. Since this does not propogate
66+-- environment variables (I think?) this assumes that XTERM_VERSION will never be set for a true
67+-- Terminal.app or iTerm.app session.
68+--
69+-- todo: add an implementation for windows that does not depend on terminfo. Should be installable
70+-- with only what is provided in the haskell platform.
71+--
72+-- todo: The Terminal interface does not provide any input support.
51terminal_handle :: IO TerminalHandle
73terminal_handle :: IO TerminalHandle
52terminal_handle = do
74terminal_handle = do
53 term_type <- getEnv "TERM"
75 term_type <- getEnv "TERM"
54 t <- if "xterm" `isPrefixOf` term_type
76 t <- if "xterm" `isPrefixOf` term_type
55 then do
77 then do
56− -- Mac OS X terminals define TERM_PROGRAM. Course, an xterm started by Terminal or iTerm
57− -- *also* has TERM_PROGRAM defined. However Terminal or iTerm will never have
58− -- XTERM_VERSION defined. whew
59 maybe_terminal_app <- get_env "TERM_PROGRAM"
78 maybe_terminal_app <- get_env "TERM_PROGRAM"
60 case maybe_terminal_app of
79 case maybe_terminal_app of
61− -- No TERM_PROGRAM then assume actual xterm
62 Nothing
80 Nothing
63 -> XTermColor.terminal_instance term_type >>= new_terminal_handle
81 -> XTermColor.terminal_instance term_type >>= new_terminal_handle
64 Just v | v == "Apple_Terminal" || v == "iTerm.app"
82 Just v | v == "Apple_Terminal" || v == "iTerm.app"
@@ -86,19 +104,21 @@ terminal_handle = do
86-- Characters can be a variable number of columns in width.
104-- Characters can be a variable number of columns in width.
87--
105--
88-- Currently, the only way to set the cursor position to a given character coordinate is to specify
106-- Currently, the only way to set the cursor position to a given character coordinate is to specify
89−-- the coordinate in the `Picture` instance provided to `output_picture`.
107+-- the coordinate in the Picture instance provided to output_picture or refresh.
90set_cursor_pos :: TerminalHandle -> Word -> Word -> IO ()
108set_cursor_pos :: TerminalHandle -> Word -> Word -> IO ()
91set_cursor_pos t x y = do
109set_cursor_pos t x y = do
92 bounds <- display_bounds t
110 bounds <- display_bounds t
93 d <- display_context t bounds
111 d <- display_context t bounds
94 marshall_to_terminal t (move_cursor_required_bytes d x y) (serialize_move_cursor d x y)
112 marshall_to_terminal t (move_cursor_required_bytes d x y) (serialize_move_cursor d x y)
95
113
114+-- | Hides the cursor
96hide_cursor :: TerminalHandle -> IO ()
115hide_cursor :: TerminalHandle -> IO ()
97hide_cursor t = do
116hide_cursor t = do
98 bounds <- display_bounds t
117 bounds <- display_bounds t
99 d <- display_context t bounds
118 d <- display_context t bounds
100 marshall_to_terminal t (hide_cursor_required_bytes d) (serialize_hide_cursor d)
119 marshall_to_terminal t (hide_cursor_required_bytes d) (serialize_hide_cursor d)
101
120
121+-- | Shows the cursor
102show_cursor :: TerminalHandle -> IO ()
122show_cursor :: TerminalHandle -> IO ()
103show_cursor t = do
123show_cursor t = do
104 bounds <- display_bounds t
124 bounds <- display_bounds t
test/Test.hs+1−1
@@ -39,4 +39,4 @@ current_pic x y sx sy btl = pic_for_image i
39 <-> char_fill pieceA ' ' sx (y - 1)
39 <-> char_fill pieceA ' ' sx (y - 1)
40 <-> char_fill pieceA ' ' x 1 <|> char pieceA '@' <|> char_fill pieceA ' ' (sx - x - 1) 1
40 <-> char_fill pieceA ' ' x 1 <|> char pieceA '@' <|> char_fill pieceA ' ' (sx - x - 1) 1
41 <-> char_fill pieceA ' ' sx (sy - y - 2)
41 <-> char_fill pieceA ' ' sx (sy - y - 2)
42− <-> iso_10464_string dumpA btl
42+ <-> iso_10646_string dumpA btl
test/interactive_terminal_test.hs+6−6
@@ -354,8 +354,8 @@ utf8_txt_0 = [ [ 0xe2 , 0x86 , 0x91 ]
354 , [ 0x41 ]
354 , [ 0x41 ]
355 ]
355 ]
356
356
357−iso_10464_txt_0 :: String
357+iso_10646_txt_0 :: String
358−iso_10464_txt_0 = map toEnum
358+iso_10646_txt_0 = map toEnum
359 [ 8593
359 [ 8593
360 , 8593
360 , 8593
361 , 8595
361 , 8595
@@ -394,7 +394,7 @@ unicode_single_width_1 = Test
394 reserve_display t
394 reserve_display t
395 let pic = pic_for_image image
395 let pic = pic_for_image image
396 image = line_0 <-> line_1
396 image = line_0 <-> line_1
397− line_0 = iso_10464_string def_attr iso_10464_txt_0
397+ line_0 = iso_10646_string def_attr iso_10646_txt_0
398 line_1 = string def_attr "0123456789"
398 line_1 = string def_attr "0123456789"
399 d <- display_bounds t >>= display_context t
399 d <- display_bounds t >>= display_context t
400 output_picture d pic
400 output_picture d pic
@@ -446,8 +446,8 @@ utf8_txt_1 = [ [0xe4,0xbd,0xa0]
446 , [0xe5,0x90,0x97]
446 , [0xe5,0x90,0x97]
447 ]
447 ]
448
448
449−iso_10464_txt_1 :: String
449+iso_10646_txt_1 :: String
450−iso_10464_txt_1 = map toEnum [20320,22909,21527]
450+iso_10646_txt_1 = map toEnum [20320,22909,21527]
451
451
452unicode_double_width_0 = Test
452unicode_double_width_0 = Test
453 { test_name = "Verify terminal can display unicode double-width characters. (Direct UTF-8)"
453 { test_name = "Verify terminal can display unicode double-width characters. (Direct UTF-8)"
@@ -475,7 +475,7 @@ unicode_double_width_1 = Test
475 reserve_display t
475 reserve_display t
476 let pic = pic_for_image image
476 let pic = pic_for_image image
477 image = line_0 <-> line_1
477 image = line_0 <-> line_1
478− line_0 = iso_10464_string def_attr iso_10464_txt_1
478+ line_0 = iso_10646_string def_attr iso_10464_txt_1
479 line_1 = string def_attr "012345"
479 line_1 = string def_attr "012345"
480 d <- display_bounds t >>= display_context t
480 d <- display_bounds t >>= display_context t
481 output_picture d pic
481 output_picture d pic