packages feed

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 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