vty 4.7.0.20 → 4.7.1
raw patch · 13 files changed
+1093/−56 lines, 13 filesdep +string-qqdep ~QuickChecknew-component:exe:vty-interactive-terminal-test
Dependencies added: string-qq
Dependency ranges changed: QuickCheck
Files
- src/Codec/Binary/UTF8/Width.hs +0/−6
- src/Data/Terminfo/Eval.hs +1/−0
- src/Graphics/Vty/Attributes.hs +4/−5
- src/Graphics/Vty/DisplayAttributes.hs +18/−0
- src/Graphics/Vty/DisplayRegion.hs +1/−0
- src/Graphics/Vty/Picture.hs +3/−3
- src/Graphics/Vty/Span.hs +26/−8
- src/Graphics/Vty/Terminal/Generic.hs +8/−2
- src/Graphics/Vty/Terminal/MacOSX.hs +8/−3
- src/Graphics/Vty/Terminal/TerminfoBased.hs +13/−7
- src/Graphics/Vty/Terminal/XTermColor.hs +14/−6
- test/interactive_terminal_test.hs +953/−0
- vty.cabal +44/−16
src/Codec/Binary/UTF8/Width.hs view
@@ -11,16 +11,12 @@ import Foreign.Storable import Foreign.Ptr --- import Numeric ( showHex )- import System.IO.Unsafe wcwidth :: Char -> Int wcwidth c = unsafePerformIO (withCWString [c] $! \ws -> do wc <- peek ws- -- putStr $ "wcwidth(0x" ++ showHex (fromEnum wc) "" ++ ")" let !w = fromIntegral $! wcwidth' wc- -- putStrLn $ " -> " ++ show w return w ) {-# NOINLINE wcwidth #-}@@ -29,9 +25,7 @@ wcswidth :: String -> Int wcswidth str = unsafePerformIO (withCWStringLen str $! \(ws, ws_len) -> do- -- putStr $ "wcswidth(...)" let !w = fromIntegral $! wcswidth' ws (fromIntegral ws_len)- -- putStrLn $ " -> " ++ show w return w ) {-# NOINLINE wcswidth #-}
src/Data/Terminfo/Eval.hs view
@@ -28,6 +28,7 @@ import GHC.Prim import GHC.Word +-- | capability evaluator state data EvalState = EvalState { eval_stack :: ![ CapParam ] , eval_expression :: !CapExpression
src/Graphics/Vty/Attributes.hs view
@@ -1,12 +1,11 @@ {-# LANGUAGE StandaloneDeriving #-} {-# LANGUAGE GADTs #-} {-# LANGUAGE RankNTypes #-}--- Copyright 2009-2010 Corey O'Connor--- Display attributes+-- | Display attributes ----- For efficiency this can be, in the future, encoded into a single 32 bit word. The 32 bit word is--- first divided into 4 groups of 8 bits where:--- The first group codes what action should be taken with regards to the other groups.+-- For efficiency, this could be encoded into a single 32 bit word. The 32 bit word is first divided+-- into 4 groups of 8 bits where: The first group codes what action should be taken with regards to+-- the other groups. -- XXYYZZ__ -- XX - style action -- 00 => reset to default
src/Graphics/Vty/DisplayAttributes.hs view
@@ -25,6 +25,12 @@ fix_color c KeepCurrent = c fix_color _c (SetTo c) = Just c +-- | difference between two display attributes. Used in the calculation of the operations required+-- to go from one display attribute to the next.+--+-- Previously, vty would reset display attributes to default then apply the new display attributes.+-- This turned out to be very expensive: A *lot* more data would be sent to the terminal than+-- required. data DisplayAttrDiff = DisplayAttrDiff { style_diffs :: [ StyleStateChange ] , fore_color_diff :: DisplayColorDiff@@ -40,20 +46,30 @@ bcd = simplify_color_diffs ( back_color_diff d_0 ) ( back_color_diff d_1 ) in DisplayAttrDiff ds fcd bcd +-- | Used in the computation of a final style attribute change.+--+-- TODO(corey): not really a simplify but a monoid instance. simplify_style_diffs :: [ StyleStateChange ] -> [ StyleStateChange ] -> [ StyleStateChange ] simplify_style_diffs cs_0 cs_1 = cs_0 `mappend` cs_1 +-- | Consider two display color attributes diffs. What display color attribute diff are these+-- equivalent to?+--+-- TODO(corey): not really a simplify but a monoid instance. simplify_color_diffs :: DisplayColorDiff -> DisplayColorDiff -> DisplayColorDiff simplify_color_diffs _cd ColorToDefault = ColorToDefault simplify_color_diffs cd NoColorChange = cd simplify_color_diffs _cd ( SetColor !c ) = SetColor c +-- | Difference between two display color attribute changes. data DisplayColorDiff = ColorToDefault | NoColorChange | SetColor !Color deriving ( Show, Eq ) +-- | Style attribute changes are transformed into a sequence of apply/removes of the individual+-- attributes. data StyleStateChange = ApplyStandout | RemoveStandout@@ -69,6 +85,8 @@ | RemoveBold deriving ( Show, Eq ) +-- | Determines the diff between two display&color attributes. This diff determines the operations+-- that actually get output to the terminal. display_attr_diffs :: FixedAttr -> FixedAttr -> DisplayAttrDiff display_attr_diffs attr attr' = DisplayAttrDiff { style_diffs = diff_styles ( fixed_style attr ) ( fixed_style attr' )
src/Graphics/Vty/DisplayRegion.hs view
@@ -4,6 +4,7 @@ import Data.Word +-- | Region of the terminal that vty will output to. Units are columns not characters. data DisplayRegion = DisplayRegion { region_width :: !Word , region_height :: !Word
src/Graphics/Vty/Picture.hs view
@@ -28,7 +28,7 @@ import Data.Word --- |The type of images to be displayed using 'update'. +-- | The type of images to be displayed using 'update'. -- Can be constructed directly or using `pic_for_image`. Which provides an initial instance with -- reasonable defaults for pic_cursor and pic_background. data Picture = Picture@@ -66,10 +66,10 @@ -- be used for a background fill then use `current_attr` for the background attribute. This is the -- default background display attribute. ----- (tofix) The current attribute is always set to the default attributes at the start of updating the+-- \todo The current attribute is always set to the default attributes at the start of updating the -- screen to a picture. ----- (tofix) The background character *must* occupy a single column and no more. +-- \todo The background character *must* occupy a single column and no more. data Background = Background { background_char :: Char , background_attr :: Attr
src/Graphics/Vty/Span.hs view
@@ -16,7 +16,8 @@ import Codec.Binary.UTF8.String ( encode ) import Control.Monad ( forM_ )-import Control.Monad.ST.Strict+import Control.Monad.ST.Strict hiding ( unsafeIOToST )+import Control.Monad.ST.Unsafe ( unsafeIOToST ) import Data.Vector (Vector) import qualified Data.Vector as Vector hiding ( take, replicate )@@ -48,12 +49,15 @@ , display_ops :: RowOps } --- vector of span operation vectors. One per row of the screen.+-- | vector of span operation vectors. One per row of the screen. type RowOps = Vector SpanOps type MRowOps s = MVector s SpanOps --- vector of span operations. executed in succession+-- | vector of span operations. executed in succession. This represents the operations required to+-- render a row of the terminal. The operations in one row may effect subsequent rows.+-- EG: Setting the foreground color in one row will effect all subsequent rows until the foreground+-- color is changed. type SpanOps = Vector SpanOp type MSpanOps s = MVector s SpanOp@@ -66,19 +70,23 @@ show (AttributeChange attr) = show attr show (TextSpan ow cw _) = "TextSpan " ++ show ow ++ " " ++ show cw +-- | Number of columns the DisplayOps are defined for span_ops_columns :: DisplayOps -> Word span_ops_columns ops = region_width $ effected_region ops +-- | Number of rows the DisplayOps are defined for span_ops_rows :: DisplayOps -> Word span_ops_rows ops = region_height $ effected_region ops +-- | The number of columns a SpanOps effects. span_ops_effected_columns :: SpanOps -> Word span_ops_effected_columns in_ops = Vector.foldl' span_ops_effected_columns' 0 in_ops where span_ops_effected_columns' t (TextSpan w _ _ ) = t + w span_ops_effected_columns' t _ = t --- |+-- | This represents an operation on the terminal. Either an attribute change or the output of a+-- text string. -- -- todo: This type may need to be restructured to increase sharing in the bytestring -- @@ -91,12 +99,12 @@ | TextSpan !Word !Word (UTF8.UTF8 B.ByteString) deriving Eq --- used to determine the width of a span operation , if it has one. +-- | The width of a single SpanOp in columns span_op_has_width :: SpanOp -> Maybe (Word, Word) span_op_has_width (TextSpan ow cw _) = Just (cw, ow) span_op_has_width _ = Nothing --- returns the number of columns to the character at the given position in the span op+-- | returns the number of columns to the character at the given position in the span op columns_to_char_offset :: Word -> SpanOp -> Word columns_to_char_offset cx (TextSpan _ _ utf8_str) = let str = UTF8.toString utf8_str@@ -108,11 +116,14 @@ spans_for_pic :: Picture -> DisplayRegion -> DisplayOps spans_for_pic pic r = DisplayOps r $ Vector.create (build_spans pic r) +-- | Builds a vector of row operations that will output the given picture to the terminal.+--+-- Crops to the given display region. build_spans :: Picture -> DisplayRegion -> ST s (MRowOps s) build_spans pic region = do- -- m for mutable! ;-)+ -- First we create a mutable vector for each rows output operations. mrow_ops <- Vector.replicate (fromEnum $ region_height region) Vector.empty- -- XXX: I think building the span operations in display order would provide better performance.+ -- \todo I think building the span operations in display order would provide better performance. -- However, I got stuck trying to implement an algorithm that did this. This will be considered -- as a possible future optimization. --@@ -146,6 +157,7 @@ else return () return mrow_ops +-- | Add the operations required to build a given image to the current set of row operations. row_ops_for_image :: MRowOps s -> Image -> Background -> DisplayRegion -> (Word, Word) -> Int -> Word -> Int -> ST s (Word, Word) row_ops_for_image mrow_ops -- the image to output the ops to image -- the image to rasterize in column order to mrow_ops@@ -305,6 +317,11 @@ , used_char_count ) +-- | Add a background fill of the given column width to the row display operations.+--+-- This has a fast path for background characters that are a single column and a single byte.+-- Otherwise this has to compute the width of the background character and replicate a sequence of+-- bytes to fill in the required width. snoc_bg_fill :: MRowOps s -> Background -> Word -> Int -> ST s () snoc_bg_fill _row_ops _bg 0 _row = return ()@@ -328,6 +345,7 @@ $ zip [0 .. fromEnum (fill_length - 1)] (cycle c_bytes) snoc_op mrow_ops row $ TextSpan fill_length fill_length (UTF8.fromRep utf8_bs) +-- | snocs the operation to the operations for the given row. snoc_op :: MRowOps s -> Int -> SpanOp -> ST s () snoc_op !mrow_ops !row !op = do ops <- Vector.read mrow_ops row
src/Graphics/Vty/Terminal/Generic.hs view
@@ -28,6 +28,7 @@ import System.IO +-- | An handle to a terminal that hides the implementation. data TerminalHandle where TerminalHandle :: Terminal t => t -> IORef TerminalState -> TerminalHandle @@ -39,11 +40,12 @@ s_ref <- liftIO $ newIORef initial_terminal_state return $ TerminalHandle t s_ref +-- | The current terminal state. This may not exactly be known. data TerminalState = TerminalState- { -- | The current terminal display attributes or Nothing if they are not known.- known_fattr :: Maybe FixedAttr+ { known_fattr :: Maybe FixedAttr } +-- | Initially we know nothing about a terminal's state. initial_terminal_state :: TerminalState initial_terminal_state = TerminalState Nothing @@ -352,6 +354,8 @@ free start_ptr return () +-- | The cursor position is given in X,Y character offsets. Due to multi-column characters this+-- needs to be translated to column, row positions. data CursorOutputMap = CursorOutputMap { char_to_output_pos :: (Word, Word) -> (Word, Word) } @@ -386,6 +390,8 @@ cursor_row_ops in out_offset +-- | Not all terminals support all display attributes. This filters a display attribute to what the+-- given terminal can display. limit_attr_for_display :: DisplayTerminal d => d -> Attr -> Attr limit_attr_for_display d attr = attr { attr_fore_color = clamp_color $ attr_fore_color attr
src/Graphics/Vty/Terminal/MacOSX.hs view
@@ -22,12 +22,16 @@ import System.IO +-- | A Mac terminal is assumed to be an xterm based terminal. data Term = Term { super_term :: TerminalHandle , term_app :: String } --- for Terminal.app use "xterm". For iTerm.app use "xterm-256color"+-- | for Terminal.app the terminal identifier "xterm" is used. For iTerm.app the terminal identifier+-- "xterm-256color" is used.+--+-- This effects the terminfo lookup. terminal_instance :: ( Applicative m, MonadIO m ) => String -> m Term terminal_instance v = do let base_term "iTerm.app" = "xterm-256color"@@ -40,12 +44,13 @@ liftIO $ hPutStr stdout str liftIO $ hFlush stdout --- Terminal.app really does want the xterm-color smcup and rmcup caps. Not the generic xterm ones.+-- | Terminal.app requires the xterm-color smcup and rmcup caps. Not the generic xterm ones.+-- Otherwise, Terminal.app expects the xterm caps. smcup_str, rmcup_str :: String smcup_str = "\ESC7\ESC[?47h" rmcup_str = "\ESC[2J\ESC[?47l\ESC8" --- iTerm needs a clear screen after smcup as well?+-- | iTerm needs a clear screen after smcup as well. clear_screen_str :: String clear_screen_str = "\ESC[H\ESC[2J"
src/Graphics/Vty/Terminal/TerminfoBased.hs view
@@ -215,7 +215,7 @@ serialize_hide_cursor d out_ptr = liftIO $ serialize_cap_expression (civis $ term d) [] out_ptr - -- Instead of evaluating all the rules related to setting display attributes twice (once in+ -- | Instead of evaluating all the rules related to setting display attributes twice (once in -- required bytes and again in serialize) or some memoization scheme just return a size -- requirement as big the longest possible control string. -- @@ -224,14 +224,16 @@ -- \todo Not verified as safe and wastes memory. attr_required_bytes _d _prev_attr _req_attr _diffs = 512 - -- Portably setting the display attributes is a giant pain in the ass.+ -- | Portably setting the display attributes is a giant pain in the ass.+ -- -- If the terminal supports the sgr capability (which sets the on/off state of each style- -- directly ; and, for no good reason, resets the colors to the default) this always works:+ -- directly ; and, for no good reason, resets the colors to the default) this procedure is used: + -- -- 0. set the style attributes. This resets the fore and back color. -- 1, If a foreground color is to be set then set the foreground color -- 2. likewise with the background color -- - -- If the terminal does not support the sgr then + -- If the terminal does not support the sgr cap then: -- if there is a change from an applied color to the default (in either the fore or back color) -- then: -- 0. reset all display attributes (sgr0)@@ -242,7 +244,7 @@ -- Entering the required style modes could require a reset of the display attributes. If this is -- the case then the back and fore colors always need to be set if not default. --- -- All this (I think) is satisfied by the following logic:+ -- This equation implements the above logic. serialize_set_attr d prev_attr req_attr diffs out_ptr = do case (fore_color_diff diffs == ColorToDefault) || (back_color_diff diffs == ColorToDefault) of -- The only way to reset either color, portably, to the default is to use either the set@@ -321,11 +323,16 @@ serialize_default_attr d out_ptr = do liftIO $ serialize_cap_expression ( set_default_attr $ term d ) [] out_ptr +-- | The color table used by a terminal is a 16 color set followed by a 240 color set that might not+-- be supported by the terminal.+--+-- This takes a Color which clearly identifies which pallete to use and computes the index+-- into the full 256 color pallete. ansi_color_index :: Color -> Word ansi_color_index (ISOColor v) = toEnum $ fromEnum v ansi_color_index (Color240 v) = 16 + ( toEnum $ fromEnum v ) -{- The sequence of terminfo caps to apply a given style are determined according to these rules.+{- | The sequence of terminfo caps to apply a given style are determined according to these rules. - - 1. The assumption is that it's preferable to use the simpler enter/exit mode capabilities than - the full set display attribute state capability. @@ -340,7 +347,6 @@ - apply/remove. - -}- data DisplayAttrSeq = EnterExitSeq [CapExpression] | SetState DisplayAttrState
src/Graphics/Vty/Terminal/XTermColor.hs view
@@ -18,13 +18,16 @@ import System.IO +-- | An xterm color based terminal is some variant paired with a standard TerminfoBased terminal+-- interface.+--+-- For the most part, xterm terminals just use the TerminfoBased implementation. data XTermColor = XTermColor { xterm_variant :: String , super_term :: TerminalHandle } --- Initialize the display to UTF-8--- Regardless of what is output the text encoding is assumed to be UTF-8+-- | Initialize the display to UTF-8. terminal_instance :: ( Applicative m, MonadIO m ) => String -> m XTermColor terminal_instance variant = do -- If the terminal variant is xterm-color use xterm instead since, more often than not,@@ -34,12 +37,17 @@ t <- TerminfoBased.terminal_instance variant' >>= new_terminal_handle return $ XTermColor variant' t +-- | Output immediately followed by a flush.+--+-- \todo move out of this module. flushed_put :: MonadIO m => String -> m () flushed_put str = do liftIO $ hPutStr stdout str liftIO $ hFlush stdout --- Since I don't know of a terminfo string cap that produces these strings these are hardcoded.+-- | These sequences set xterm based terminals to UTF-8 output.+--+-- \todo I don't know of a terminfo cap that is equivalent to this. set_utf8_char_set, set_default_char_set :: String set_utf8_char_set = "\ESC%G" set_default_char_set = "\ESC%@"@@ -89,9 +97,9 @@ default_attr_required_bytes d = default_attr_required_bytes (super_display d) serialize_default_attr d = serialize_default_attr (super_display d) - -- I think xterm is broken: Reseting the background color as the first bytes serialized on a new- -- line does not effect the background color xterm uses to clear the line. Which is used *after*- -- the next newline.+ -- | I think xterm is broken: Reseting the background color as the first bytes serialized on a+ -- new line does not effect the background color xterm uses to clear the line. Which is used+ -- *after* the next newline. inline_hack d = do let t = case super_display d of DisplayHandle _ t_ _ -> t_
+ test/interactive_terminal_test.hs view
@@ -0,0 +1,953 @@+{-# LANGUAGE QuasiQuotes #-}+{-# LANGUAGE ScopedTypeVariables #-}+module Main where++import Graphics.Vty+import Graphics.Vty.Attributes+import Graphics.Vty.Inline+import Graphics.Vty.Picture+import Graphics.Vty.Terminal+import Graphics.Vty.DisplayRegion++import Control.Exception+import Control.Monad++import Data.List ( lookup )+import Data.Maybe ( isJust, fromJust )+import Data.Monoid+import Data.String.QQ+import Data.Word++import Foreign.Marshal.Array ++import qualified System.Environment as Env++import System.IO ( hFlush, hPutStr, hPutBuf, stdout )++main = do+ print_intro++output_file_path = "test_results.list"++print_intro = do+ putStr $ [s| +This is an interactive verification program for the terminal input and output+support of the VTY library. This will ask a series of questions about what you+see on screen. The goal is to verify that VTY's output and input support+performs as expected with your terminal.++This program produces a file named + |] ++ output_file_path ++ [s| +in the current directory that contains the results for each test assertion. This+can be emailed to coreyoconnor@gmail.com and used by the VTY authors to improve+support for your terminal. No personal information is contained in the report.++Each test follows, more or less, the following format:+ 0. A description of the test is printed which will include a detailed+ description of what VTY is going to try and what the expected results are.+ Press return to move on.+ 1. The program will produce some output or ask for you to press a key.+ 2. You will then be asked to confirm if the behavior matched the provided+ description. Just pressing enter implies the default response that+ everything was as expected. ++All the tests assume the following about the terminal display:+ 0. The terminal display will not be resized during a test and is at least 80 + characters in width. + 1. The terminal display is using a monospaced font for both single width and+ double width characters.+ 2. A double width character is displayed with exactly twice the width of a + single column character. This may require adjusting the font used by the+ terminal. At least, that is the case using xterm. + 3. Fonts are installed, and usable by the terminal, that define glyphs for+ a good range of the unicode characters. Each test involving unicode display+ describes the expected appearance of each glyph. ++Thanks for the help! :-D+To exit the test early enter "q" anytime at the following menu screen.++If any test failed then please post an issue to+ https://github.com/coreyoconnor/vty/issues+with the test_results.list file pasted into the issue. The issue summary can+mention the specific tests that failed or just say "interactive terminal test+failure".+|]+ wait_for_return+ results <- do_test_menu 1+ env_attributes <- mapM ( \env_name -> catch ( Env.getEnv env_name >>= return . (,) env_name ) + ( \ (_ :: SomeException) -> return (env_name, "") ) + ) + [ "TERM", "COLORTERM", "LANG", "TERM_PROGRAM", "XTERM_VERSION" ]+ t <- terminal_handle+ let results_txt = show env_attributes ++ "\n" + ++ terminal_ID t ++ "\n"+ ++ show results ++ "\n"+ release_terminal t+ writeFile output_file_path results_txt++wait_for_return = do+ putStr "\n(press return to continue)"+ hFlush stdout+ getLine++test_menu :: [(String, Test)]+test_menu = zip (map show [1..]) all_tests++do_test_menu :: Int -> IO [(String, Bool)]+do_test_menu next_ID + | next_ID > length all_tests = do+ putStrLn $ "Done! Please email the " ++ output_file_path ++ " file to coreyoconnor@gmail.com"+ return []+ | otherwise = do+ display_test_menu+ putStrLn $ "Press return to start with #" ++ show next_ID ++ "."+ putStrLn "Enter a test number to perform only that test."+ putStrLn "q (or control-C) to quit."+ putStr "> "+ hFlush stdout+ s <- getLine >>= return . filter (/= '\n')+ case s of+ "q" -> return mempty+ "" -> do + r <- run_test $ show next_ID + rs <- do_test_menu ( next_ID + 1 )+ return $ r : rs+ i | isJust ( lookup i test_menu ) -> do+ r <- run_test i + rs <- do_test_menu ( read i + 1 )+ return $ r : rs+ where+ display_test_menu + = mapM_ display_test_menu' test_menu+ display_test_menu' ( i, t ) + = putStrLn $ ( if i == show next_ID + then "> " + else " "+ ) ++ i ++ ". " ++ test_name t++run_test :: String -> IO (String, Bool)+run_test i = do+ let t = fromJust $ lookup i test_menu + print_summary t+ wait_for_return+ test_action t+ r <- confirm_results t+ return (test_ID t, r)++default_success_confirm_results = do+ putStr "\n"+ putStr "[Y/n] "+ hFlush stdout+ r <- getLine+ case r of+ "" -> return True+ "y" -> return True+ "Y" -> return True+ "n" -> return False++data Test = Test+ { test_name :: String+ , test_ID :: String+ , test_action :: IO ()+ , print_summary :: IO ()+ , confirm_results :: IO Bool+ }++all_tests + = [ reserve_output_test + , display_bounds_test_0+ , display_bounds_test_1+ , display_bounds_test_2+ , display_bounds_test_3+ , unicode_single_width_0+ , unicode_single_width_1+ , unicode_double_width_0+ , unicode_double_width_1+ , attributes_test_0+ , attributes_test_1+ , attributes_test_2+ , attributes_test_3+ , attributes_test_4+ , attributes_test_5+ , inline_test_0+ , inline_test_1+ , inline_test_2+ , cursor_hide_test_0+ ]++reserve_output_test = Test + { test_name = "Initialize and reserve terminal output then restore previous state."+ , test_ID = "reserve_output_test"+ , test_action = do+ t <- terminal_handle+ reserve_display t+ putStrLn "Line 1"+ putStrLn "Line 2"+ putStrLn "Line 3"+ putStrLn "Line 4 (press return)"+ hFlush stdout+ getLine+ release_display t+ release_terminal t+ return ()+ , print_summary = do+ putStr $ [s|+Once return is pressed:+ 0. The screen will be cleared. + 1. Four lines of text should be visible.+ 1. The cursor should be visible and at the start of the fifth line.++After return is pressed for the second time this test then:+ * The screen containing the test summary should be restored;+ * The cursor is visible.+|]+ , confirm_results = do+ putStr $ [s|+Did the test output match the description?+|]+ default_success_confirm_results+ }++display_bounds_test_0 = Test+ { test_name = "Verify display bounds are correct test 0: Using spaces."+ , test_ID = "display_bounds_test_0"+ , test_action = do+ t <- terminal_handle+ reserve_display t+ DisplayRegion w h <- display_bounds t+ let row_0 = replicate (fromEnum w) 'X' ++ "\n"+ row_h = replicate (fromEnum w - 1) 'X'+ row_n = "X" ++ replicate (fromEnum w - 2) ' ' ++ "X\n"+ image = row_0 ++ (concat $ replicate (fromEnum h - 2) row_n) ++ row_h+ putStr image+ hFlush stdout+ getLine+ release_display t+ release_terminal t+ return ()+ , print_summary = display_bounds_test_summary True+ , confirm_results = generic_output_match_confirm+ }++display_bounds_test_1 = Test+ { test_name = "Verify display bounds are correct test 0: Using cursor movement."+ , test_ID = "display_bounds_test_1"+ , test_action = do+ t <- terminal_handle+ reserve_display t+ DisplayRegion w h <- display_bounds t+ set_cursor_pos t 0 0+ let row_0 = replicate (fromEnum w) 'X' ++ "\n"+ putStr row_0+ forM_ [1 .. h - 2] $ \y -> do+ set_cursor_pos t 0 y+ putStr "X"+ hFlush stdout+ set_cursor_pos t (w - 1) y+ putStr "X"+ hFlush stdout+ set_cursor_pos t 0 (h - 1)+ let row_h = replicate (fromEnum w - 1) 'X'+ putStr row_h+ hFlush stdout+ getLine+ release_display t+ release_terminal t+ return ()+ , print_summary = display_bounds_test_summary True+ , confirm_results = generic_output_match_confirm+ }++display_bounds_test_2 = Test+ { test_name = "Verify display bounds are correct test 0: Using Image ops."+ , test_ID = "display_bounds_test_2"+ , test_action = do+ t <- terminal_handle+ reserve_display t+ bounds@(DisplayRegion w h) <- display_bounds t+ let first_row = horiz_cat $ replicate (fromEnum w) (char def_attr 'X')+ middle_rows = vert_cat $ replicate (fromEnum h - 2) middle_row+ middle_row = (char def_attr 'X') <|> background_fill (w - 2) 1 <|> (char def_attr 'X')+ end_row = first_row+ image = first_row <-> middle_rows <-> end_row+ pic = (pic_for_image image) { pic_cursor = Cursor (w - 1) (h - 1) }+ d <- display_context t bounds+ output_picture d pic+ getLine+ release_display t+ release_terminal t+ return ()+ , print_summary = display_bounds_test_summary True+ , confirm_results = generic_output_match_confirm+ }++display_bounds_test_3 = Test+ { test_name = "Verify display bounds are correct test 0: Hide cursor; Set cursor pos."+ , test_ID = "display_bounds_test_3"+ , test_action = do+ t <- terminal_handle+ reserve_display t+ DisplayRegion w h <- display_bounds t+ hide_cursor t+ set_cursor_pos t 0 0+ let row_0 = replicate (fromEnum w) 'X'+ putStrLn row_0+ forM_ [1 .. h - 2] $ \y -> do+ set_cursor_pos t 0 y+ putStr "X"+ hFlush stdout+ set_cursor_pos t (w - 1) y+ putStr "X"+ hFlush stdout+ set_cursor_pos t 0 (h - 1)+ let row_h = row_0+ putStr row_h+ hFlush stdout+ getLine+ show_cursor t+ release_display t+ release_terminal t+ return ()+ , print_summary = display_bounds_test_summary False+ , confirm_results = generic_output_match_confirm+ }++display_bounds_test_summary has_cursor = do+ putStr $ [s|+Once return is pressed:+ 0. The screen will be cleared.+|]+ if has_cursor+ then putStr " 1. The cursor will be visible."+ else putStr " 1. The cursor will NOT be visible."+ putStr [s|+ 2. The border of the display will be outlined in Xs. + So if - and | represented the edge of the terminal window:+ |-------------|+ |XXXXXXXXXXXXX|+ |X X||]++ if has_cursor+ then putStr $ [s|+ |XXXXXXXXXXXXC| |]+ else putStr $ [s|+ |XXXXXXXXXXXXX| |]++ putStr $ [s|+ |-------------|++ ( Where C is the final position of the cursor. There may be an X drawn+ under the cursor. )+ 3. The display will remain in this state until return is pressed again.++After return is pressed for the second time:+ 0. The screen containing the test summary should be restored.+ 1. The cursor should be visible.+|]++generic_output_match_confirm = do+ putStr $ [s|+Did the test output match the description?+|]+ default_success_confirm_results++-- Explicitely definethe bytes that encode each example text.+-- This avoids any issues with how the compiler represents string literals.+--+-- This document is UTF-8 encoded so the UTF-8 string is still included for+-- reference+--+-- It's assumed the compiler will at least not barf on UTF-8 encoded text in+-- comments ;-)+--+-- txt_0 = ↑↑↓↓←→←→BA++utf8_txt_0 :: [[Word8]]+utf8_txt_0 = [ [ 0xe2 , 0x86 , 0x91 ]+ , [ 0xe2 , 0x86 , 0x91 ]+ , [ 0xe2 , 0x86 , 0x93 ]+ , [ 0xe2 , 0x86 , 0x93 ]+ , [ 0xe2 , 0x86 , 0x90 ]+ , [ 0xe2 , 0x86 , 0x92 ]+ , [ 0xe2 , 0x86 , 0x90 ]+ , [ 0xe2 , 0x86 , 0x92 ]+ , [ 0x42 ]+ , [ 0x41 ]+ ]++iso_10646_txt_0 :: String+iso_10646_txt_0 = map toEnum+ [ 8593 + , 8593+ , 8595+ , 8595+ , 8592+ , 8594+ , 8592+ , 8594+ , 66+ , 65+ ]++unicode_single_width_0 = Test+ { test_name = "Verify terminal can display unicode single-width characters. (Direct UTF-8)"+ , test_ID = "unicode_single_width_0"+ , test_action = do+ t <- terminal_handle+ reserve_display t+ hide_cursor t+ withArrayLen (concat utf8_txt_0) (flip $ hPutBuf stdout)+ hPutStr stdout "\n"+ hPutStr stdout "0123456789\n"+ hFlush stdout+ getLine+ release_display t+ release_terminal t+ return ()+ , print_summary = unicode_single_width_summary+ , confirm_results = generic_output_match_confirm+ }++unicode_single_width_1 = Test+ { test_name = "Verify terminal can display unicode single-width characters. (Image ops)"+ , test_ID = "unicode_single_width_1"+ , test_action = do+ t <- terminal_handle+ reserve_display t+ let pic = pic_for_image image+ image = line_0 <-> line_1+ line_0 = iso_10646_string def_attr iso_10646_txt_0+ line_1 = string def_attr "0123456789"+ d <- display_bounds t >>= display_context t+ output_picture d pic+ getLine+ release_display t+ release_terminal t+ return ()+ , print_summary = unicode_single_width_summary+ , confirm_results = generic_output_match_confirm+ }++unicode_single_width_summary = putStr [s|+Once return is pressed:+ 0. The screen will be cleared.+ 1. The cursor will be hidden.+ 2. Two horizontal lines of text will be displayed:+ a. The first will be a sequence of glyphs in UTF-8 encoding. Each glyph+ will occupy one column of space. The order and appearance of the glyphs+ will be:+ | column | appearance |+ ==========================+ | 0 | up arrow |+ | 1 | up arrow |+ | 2 | down arrow |+ | 3 | down arrow |+ | 4 | left arrow |+ | 5 | right arrow |+ | 6 | left arrow |+ | 7 | right arrow |+ | 8 | B |+ | 9 | A |+ ( see: http://en.wikipedia.org/wiki/Arrow_(symbol) )+ b. The second will be: 0123456789. ++Verify: + * The far right extent of the glyphs on both lines are equal; + * The glyphs are as described.++After return is pressed for the second time:+ 0. The screen containing the test summary should be restored.+ 1. The cursor should be visible.+|]++-- The second example is a unicode string containing double-width glyphs+-- 你好吗+utf8_txt_1 :: [[Word8]]+utf8_txt_1 = [ [0xe4,0xbd,0xa0]+ , [0xe5,0xa5,0xbd]+ , [0xe5,0x90,0x97]+ ]++iso_10646_txt_1 :: String+iso_10646_txt_1 = map toEnum [20320,22909,21527]++unicode_double_width_0 = Test+ { test_name = "Verify terminal can display unicode double-width characters. (Direct UTF-8)"+ , test_ID = "unicode_double_width_0"+ , test_action = do+ t <- terminal_handle+ reserve_display t+ hide_cursor t+ withArrayLen (concat utf8_txt_1) (flip $ hPutBuf stdout)+ hPutStr stdout "\n"+ hPutStr stdout "012345\n"+ hFlush stdout+ getLine+ release_display t+ release_terminal t+ return ()+ , print_summary = unicode_double_width_summary+ , confirm_results = generic_output_match_confirm+ }++unicode_double_width_1 = Test+ { test_name = "Verify terminal can display unicode double-width characters. (Image ops)"+ , test_ID = "unicode_double_width_1"+ , test_action = do+ t <- terminal_handle+ reserve_display t+ let pic = pic_for_image image+ image = line_0 <-> line_1+ line_0 = iso_10646_string def_attr iso_10646_txt_1+ line_1 = string def_attr "012345"+ d <- display_bounds t >>= display_context t+ output_picture d pic+ getLine+ release_display t+ release_terminal t+ return ()+ , print_summary = unicode_double_width_summary+ , confirm_results = generic_output_match_confirm+ }++unicode_double_width_summary = putStr [s|+Once return is pressed:+ 0. The screen will be cleared.+ 1. The cursor will be hidden.+ 2. Two horizontal lines of text will be displayed:+ a. The first will be a sequence of glyphs in UTF-8 encoding. Each glyph+ will occupy two columns of space. The order and appearance of the glyphs+ will be:+ | column | appearance |+ ======================================+ | 0 | first half of ni3 |+ | 1 | second half of ni3 |+ | 2 | first half of hao3 |+ | 3 | second half of hao3 |+ | 4 | first half of ma |+ | 5 | second half of ma |+ b. The second will be: 012345. ++Verify: + * The far right extent of the glyphs on both lines are equal; + * The glyphs are as described.++After return is pressed for the second time:+ 0. The screen containing the test summary should be restored.+ 1. The cursor should be visible.+|]++all_colors = zip [ black, red, green, yellow, blue, magenta, cyan, white ]+ [ "black", "red", "green", "yellow", "blue", "magenta", "cyan", "white" ]++all_bright_colors + = zip [ bright_black, bright_red, bright_green, bright_yellow, bright_blue, bright_magenta, bright_cyan, bright_white ]+ [ "bright black", "bright red", "bright green", "bright yellow", "bright blue", "bright magenta", "bright cyan", "bright white" ]++attributes_test_0 = Test + { test_name = "Character attributes: foreground colors."+ , test_ID = "attributes_test_0"+ , test_action = do+ t <- terminal_handle+ reserve_display t+ let pic = pic_for_image image+ image = border <|> column_0 <|> border <|> column_1 <|> border+ column_0 = vert_cat $ map line_with_color all_colors+ border = vert_cat $ replicate (length all_colors) $ string def_attr " | "+ column_1 = vert_cat $ map (string def_attr . snd) all_colors+ line_with_color (c, c_name) = string (def_attr `with_fore_color` c) c_name+ d <- display_bounds t >>= display_context t+ output_picture d pic+ getLine+ release_display t+ release_terminal t+ return ()+ , print_summary = do+ putStr $ [s|+Once return is pressed:+ 0. The screen will be cleared.+ 1. The cursor will be hidden.+ 2. 9 lines of text in two columns will be drawn. The first column will be a+ name of a standard color (for an 8 color terminal) rendered in that color.+ For instance, one line will be the word "magenta" and that word should be+ rendered in the magenta color. The second column will be the name of a+ standard color rendered with the default attributes.++Verify: + * In the first column: The foreground color matches the named color.+ * The second column: All text is rendered with the default attributes.+ * The vertical bars used in each line to mark the border of a column are+ lined up.++After return is pressed for the second time:+ 0. The screen containing the test summary should be restored.+ 1. The cursor should be visible.+|]+ , confirm_results = do+ putStr $ [s|+Did the test output match the description?+|]+ default_success_confirm_results+ }++attributes_test_1 = Test + { test_name = "Character attributes: background colors."+ , test_ID = "attributes_test_1"+ , test_action = do+ t <- terminal_handle+ reserve_display t+ let pic = pic_for_image image+ image = border <|> column_0 <|> border <|> column_1 <|> border+ column_0 = vert_cat $ map line_with_color all_colors+ border = vert_cat $ replicate (length all_colors) $ string def_attr " | "+ column_1 = vert_cat $ map (string def_attr . snd) all_colors+ line_with_color (c, c_name) = string (def_attr `with_back_color` c) c_name+ d <- display_bounds t >>= display_context t+ output_picture d pic+ getLine+ release_display t+ release_terminal t+ return ()+ , print_summary = do+ putStr $ [s|+Once return is pressed:+ 0. The screen will be cleared.+ 1. The cursor will be hidden.+ 2. 9 lines of text in two columns will be drawn. The first column will+ contain be a name of a standard color for an 8 color terminal rendered with+ the default foreground color with a background the named color. For+ instance, one line will contain be the word "magenta" and the word should+ be rendered in the default foreground color over a magenta background. The+ second column will be the name of a standard color rendered with the default+ attributes.++Verify: + * The first column: The background color matches the named color.+ * The second column: All text is rendered with the default attributes.+ * The vertical bars used in each line to mark the border of a column are+ lined up.++Note: I haven't decided if, in this case, the background color should extend to+fills added for alignment. Right now the selected background color is only+applied to the background where the word is actually rendered. Since each word+is not of the same length VTY adds background fills to make the width of each+row effectively the same. These added fills are all currently rendered with the+default background pattern.++After return is pressed for the second time:+ 0. The screen containing the test summary should be restored.+ 1. The cursor should be visible.+|]+ , confirm_results = do+ putStr $ [s|+Did the test output match the description?+|]+ default_success_confirm_results+ }++attributes_test_2 = Test + { test_name = "Character attributes: Vivid foreground colors."+ , test_ID = "attributes_test_2"+ , test_action = do+ t <- terminal_handle+ reserve_display t+ let pic = pic_for_image image+ image = horiz_cat [border, column_0, border, column_1, border, column_2, border]+ border = vert_cat $ replicate (length all_colors) $ string def_attr " | "+ column_0 = vert_cat $ map line_with_color_0 all_colors+ column_1 = vert_cat $ map line_with_color_1 all_bright_colors+ column_2 = vert_cat $ map (string def_attr . snd) all_colors+ line_with_color_0 (c, c_name) = string (def_attr `with_fore_color` c) c_name+ line_with_color_1 (c, c_name) = string (def_attr `with_fore_color` c) c_name+ d <- display_bounds t >>= display_context t+ output_picture d pic+ getLine+ release_display t+ release_terminal t+ return ()+ , print_summary = do+ putStr $ [s|+Once return is pressed:+ 0. The screen will be cleared.+ 1. The cursor will be hidden.+ 2. 9 lines of text in three columns will be drawn:+ a. The first column will be a name of a standard color (for an 8 color+ terminal) rendered with that color as the foreground color. + b. The next column will be also be the name of a standard color rendered+ with that color as the foreground color but the shade used should be+ more vivid than the shade used in the first column. + c. The final column will be the name of a color rendered with the+ default attributes.++For instance, one line will be the word "magenta" and that word should be+rendered in the magenta color. ++I'm not actually sure exactly what "vivid" means in this context. For xterm the+vivid colors are brighter. ++Verify: + * The first column: The foreground color matches the named color.+ * The second column: The foreground color matches the named color but is+ more vivid than the color used in the first column. + * The third column: All text is rendered with the default attributes.+ * The vertical bars used in each line to mark the border of a column are+ lined up.++After return is pressed for the second time:+ 0. The screen containing the test summary should be restored.+ 1. The cursor should be visible.+|]+ , confirm_results = do+ putStr $ [s|+Did the test output match the description?+|]+ default_success_confirm_results+ }++attributes_test_3 = Test + { test_name = "Character attributes: Vivid background colors."+ , test_ID = "attributes_test_3"+ , test_action = do+ t <- terminal_handle+ reserve_display t+ let pic = pic_for_image image+ image = horiz_cat [border, column_0, border, column_1, border, column_2, border]+ border = vert_cat $ replicate (length all_colors) $ string def_attr " | "+ column_0 = vert_cat $ map line_with_color_0 all_colors+ column_1 = vert_cat $ map line_with_color_1 all_bright_colors+ column_2 = vert_cat $ map (string def_attr . snd) all_colors+ line_with_color_0 (c, c_name) = string (def_attr `with_back_color` c) c_name+ line_with_color_1 (c, c_name) = string (def_attr `with_back_color` c) c_name+ d <- display_bounds t >>= display_context t+ output_picture d pic+ getLine+ release_display t+ release_terminal t+ return ()+ , print_summary = do+ putStr $ [s|+Once return is pressed:+ 0. The screen will be cleared.+ 1. The cursor will be hidden.+ 2. 9 lines of text in three columns will be drawn:+ a. The first column will contain be a name of a standard color for an 8+ color terminal rendered with the default foreground color with a+ background the named color. + b. The first column will contain be a name of a standard color for an 8+ color terminal rendered with the default foreground color with the+ background a vivid version of the named color. + c. The third column will be the name of a standard color rendered with+ the default attributes.+ +For instance, one line will contain be the word "magenta" and the word should+be rendered in the default foreground color over a magenta background. ++I'm not actually sure exactly what "vivid" means in this context. For xterm the+vivid colors are brighter.++Verify: + * The first column: The background color matches the named color.+ * The second column: The background color matches the named color and is+ more vivid than the color used in the first column. + * The third column column: All text is rendered with the default attributes.+ * The vertical bars used in each line to mark the border of a column are+ lined up.++Note: I haven't decided if, in this case, the background color should extend to+fills added for alignment. Right now the selected background color is only+applied to the background where the word is actually rendered. Since each word+is not of the same length VTY adds background fills to make the width of each+row effectively the same. These added fills are all currently rendered with the+default background pattern.++After return is pressed for the second time:+ 0. The screen containing the test summary should be restored.+ 1. The cursor should be visible.+|]+ , confirm_results = do+ putStr $ [s|+Did the test output match the description?+|]+ default_success_confirm_results+ }++attr_combos = + [ ( "default", id )+ , ( "bold", flip with_style bold )+ , ( "blink", flip with_style blink )+ , ( "underline", flip with_style underline )+ , ( "bold + blink", flip with_style (bold + blink) )+ , ( "bold + underline", flip with_style (bold + underline) )+ , ( "underline + blink", flip with_style (underline + blink) )+ , ( "bold + blink + underline", flip with_style (bold + blink + underline) )+ ]++attributes_test_4 = Test + { test_name = "Character attributes: Bold; Blink; Underline."+ , test_ID = "attributes_test_4"+ , test_action = do+ t <- terminal_handle+ reserve_display t+ let pic = pic_for_image image+ image = horiz_cat [border, column_0, border, column_1, border]+ border = vert_cat $ replicate (length attr_combos) $ string def_attr " | "+ column_0 = vert_cat $ map line_with_attrs attr_combos+ column_1 = vert_cat $ map (string def_attr . fst) attr_combos+ line_with_attrs (desc, attr_f) = string (attr_f def_attr) desc+ d <- display_bounds t >>= display_context t+ output_picture d pic+ getLine+ release_display t+ release_terminal t+ return ()+ , print_summary = do+ putStr $ [s|+Once return is pressed:+ 0. The screen will be cleared.+ 1. The cursor will be hidden.+ 2. 8 rows of text in two columns. + The rows will contain the following text:+ default+ bold + blink+ underline+ bold + blink+ bold + underline+ underline + blink+ bold + blink + underline+ The first column will be rendered with the described attributes. The second+ column will be rendered with the default attributes.+ +Verify: + * The vertical bars used in each line to mark the border of a column are+ lined up.+ * The text in the first column is rendered as described.++After return is pressed for the second time:+ 0. The screen containing the test summary should be restored.+ 1. The cursor should be visible.+|]+ , confirm_results = do+ putStr $ [s|+Did the test output match the description?+|]+ default_success_confirm_results+ }++attributes_test_5 = Test + { test_name = "Character attributes: 240 color palette"+ , test_ID = "attributes_test_5"+ , test_action = do+ t <- terminal_handle+ reserve_display t+ let pic = pic_for_image image+ image = vert_cat $ map horiz_cat $ split_color_images color_images+ color_images = map (\i -> string (current_attr `with_back_color` Color240 i) " ") [0..239]+ split_color_images [] = []+ split_color_images is = (take 20 is ++ [string def_attr " "]) : (split_color_images (drop 20 is))+ d <- display_bounds t >>= display_context t+ output_picture d pic+ getLine+ release_display t+ release_terminal t+ return ()+ , print_summary = do+ putStr $ [s|+Once return is pressed:+ 0. The screen will be cleared.+ 1. The cursor will be hidden.+ 2. A 20 character wide and 12 row high block of color squares. This should look like a palette+ of some sort. I'm not exactly sure if all color terminals use the same palette. I doubt it...++Verify: ++After return is pressed for the second time:+ 0. The screen containing the test summary should be restored.+ 1. The cursor should be visible.+|]+ , confirm_results = do+ putStr $ [s|+Did the test output match the description?+|]+ default_success_confirm_results+ }++inline_test_0 = Test+ { test_name = "Verify styled output can be performed without clearing the screen."+ , test_ID = "inline_test_0"+ , test_action = do+ t <- terminal_handle+ putStrLn "line 1."+ put_attr_change t $ back_color red >> apply_style underline+ putStrLn "line 2."+ put_attr_change t $ default_all+ putStrLn "line 3."+ release_terminal t+ return ()+ , print_summary = putStr $ [s|+lines are in order.+The second line "line 2" should have a red background and the text underline.+The third line "line 3" should be drawn in the same style as the first line.+|]++ , confirm_results = generic_output_match_confirm+ }++inline_test_1 = Test+ { test_name = "Verify styled output can be performed without clearing the screen."+ , test_ID = "inline_test_1"+ , test_action = do+ t <- terminal_handle+ putStr "Not styled. "+ put_attr_change t $ back_color red >> apply_style underline+ putStr " Styled! "+ put_attr_change t $ default_all+ putStrLn "Not styled."+ release_terminal t+ return ()+ , print_summary = putStr $ [s|+|]++ , confirm_results = generic_output_match_confirm+ }++inline_test_2 = Test+ { test_name = "Verify styled output can be performed without clearing the screen."+ , test_ID = "inline_test_1"+ , test_action = do+ t <- terminal_handle+ putStr "Not styled. "+ put_attr_change t $ back_color red >> apply_style underline+ putStr " Styled! "+ put_attr_change t $ default_all+ putStr "Not styled.\n"+ release_terminal t+ return ()+ , print_summary = putStr $ [s|+|]+ , confirm_results = generic_output_match_confirm+ }++cursor_hide_test_0 :: Test+cursor_hide_test_0 = Test+ { test_name = "Verify the cursor is hid and re-shown. issue #7"+ , test_ID = "cursor_hide_test_0"+ , test_action = do+ vty <- mkVty+ show_cursor $ terminal vty+ set_cursor_pos (terminal vty) 5 5+ next_event vty+ hide_cursor $ terminal vty+ next_event vty+ shutdown vty+ return ()+ , print_summary = putStr $ [s|+ 1. verify the cursor is displayed.+ 2. press enter+ 3. verify the cursor is hid.+ 4. press enter.+ 5. the display should return to the state before the test.+|]+ , confirm_results = generic_output_match_confirm+ }+
vty.cabal view
@@ -1,5 +1,5 @@ name: vty-version: 4.7.0.20+version: 4.7.1 license: BSD3 license-file: LICENSE author: AUTHORS@@ -36,7 +36,6 @@ CHANGELOG, LICENSE - library default-language: Haskell2010 build-depends: base >= 4 && < 5,@@ -92,7 +91,7 @@ hs-source-dirs: src test test-module: VerifyAttributeOps build-depends: Cabal == 1.17.*,- QuickCheck == 2.4.*,+ QuickCheck >= 2.4, random == 1.0.*, base >= 4 && < 5, bytestring,@@ -143,7 +142,7 @@ include-dirs: cbits build-depends: Cabal == 1.17.*,- QuickCheck == 2.4.*,+ QuickCheck >= 2.4, random == 1.0.*, base >= 4 && < 5, bytestring,@@ -194,7 +193,7 @@ include-dirs: cbits build-depends: Cabal == 1.17.*,- QuickCheck == 2.4.*,+ QuickCheck >= 2.4, random == 1.0.*, base >= 4 && < 5, bytestring,@@ -222,7 +221,7 @@ Verify build-depends: Cabal == 1.17.*,- QuickCheck == 2.4.*,+ QuickCheck >= 2.4, random == 1.0.*, base >= 4 && < 5, bytestring,@@ -253,7 +252,7 @@ Verify build-depends: Cabal == 1.17.*,- QuickCheck == 2.4.*,+ QuickCheck >= 2.4, random == 1.0.*, base >= 4 && < 5, bytestring,@@ -296,7 +295,7 @@ include-dirs: cbits build-depends: Cabal == 1.17.*,- QuickCheck == 2.4.*,+ QuickCheck >= 2.4, random == 1.0.*, base >= 4 && < 5, bytestring,@@ -333,7 +332,7 @@ include-dirs: cbits build-depends: Cabal == 1.17.*,- QuickCheck == 2.4.*,+ QuickCheck >= 2.4, random == 1.0.*, base >= 4 && < 5, bytestring,@@ -380,7 +379,7 @@ include-dirs: cbits build-depends: Cabal == 1.17.*,- QuickCheck == 2.4.*,+ QuickCheck >= 2.4, random == 1.0.*, base >= 4 && < 5, bytestring,@@ -411,7 +410,7 @@ include-dirs: cbits build-depends: Cabal == 1.17.*,- QuickCheck == 2.4.*,+ QuickCheck >= 2.4, random == 1.0.*, base >= 4 && < 5, bytestring,@@ -441,7 +440,7 @@ include-dirs: cbits build-depends: Cabal == 1.17.*,- QuickCheck == 2.4.*,+ QuickCheck >= 2.4, random == 1.0.*, base >= 4 && < 5, bytestring,@@ -492,7 +491,7 @@ include-dirs: cbits build-depends: Cabal == 1.17.*,- QuickCheck == 2.4.*,+ QuickCheck >= 2.4, random == 1.0.*, base >= 4 && < 5, bytestring,@@ -543,7 +542,7 @@ include-dirs: cbits build-depends: Cabal == 1.17.*,- QuickCheck == 2.4.*,+ QuickCheck >= 2.4, random == 1.0.*, base >= 4 && < 5, bytestring,@@ -577,7 +576,7 @@ include-dirs: cbits build-depends: Cabal == 1.17.*,- QuickCheck == 2.4.*,+ QuickCheck >= 2.4, random == 1.0.*, base >= 4 && < 5, bytestring,@@ -592,6 +591,36 @@ utf8-string >= 0.3 && < 0.4, vector >= 0.7 +executable vty-interactive-terminal-test+ main-is: interactive_terminal_test.hs++ default-language: Haskell2010++ hs-source-dirs: src test++ c-sources: cbits/gwinsz.c+ cbits/set_term_timing.c+ cbits/mk_wcwidth.c++ include-dirs: cbits++ build-depends: Cabal == 1.17.*,+ QuickCheck >= 2.4,+ random == 1.0.*,+ base >= 4 && < 5,+ bytestring,+ containers,+ deepseq >= 1.1 && < 1.4,+ ghc-prim,+ mtl >= 1.1.1.0 && < 2.2,+ parallel >= 2.2 && < 3.3,+ parsec >= 2 && < 4,+ string-qq,+ terminfo >= 0.3 && < 0.4,+ unix,+ utf8-string >= 0.3 && < 0.4,+ vector >= 0.7+ -- Bench.hs -- Bench2.hs -- BenchRenderChar.hs@@ -606,7 +635,6 @@ -- Verify/Graphics/Vty/Image.hs -- Verify/Graphics/Vty/Picture.hs -- Verify/Graphics/Vty/Span.hs--- interactive_terminal_test.hs -- vty_inline_example.hs -- vty_issue_18.hs -- yi_issue_264.hs