vty 3.0.4 → 3.1.0
raw patch · 5 files changed
+58/−17 lines, 5 files
Files
- Graphics/Vty.hs +16/−2
- Graphics/Vty/Cursor.hs +32/−8
- Graphics/Vty/LLInput.hs +7/−5
- test/Test.hs +2/−1
- vty.cabal +1/−1
Graphics/Vty.hs view
@@ -1,5 +1,10 @@ {-# OPTIONS_GHC -fffi #-} {-# CFILES gwinsz.c #-}++-- Good sources of documentation for terminal programming are:+-- vt100 control sequences: http://vt100.net/docs/vt100-ug/chapter3.html#S3.3.3+-- Xterm control sequences: http://invisible-island.net/xterm/ctlseqs/ctlseqs.html+ module Graphics.Vty (Vty(..), beep, mkVty, module Graphics.Vty.Types, Key(..), Modifier(..), Button(..), Event(..)) where import Control.Concurrent@@ -24,6 +29,10 @@ getEvent :: IO Event, -- |Get the size of the display. getSize :: IO (Int,Int),+ -- |Refresh the display. Normally the library takes care of refreshing. + -- Nonetheless, some other program might output to the terminal and mess the display.+ -- In that case the user might want to force a refresh.+ refresh :: IO (), -- |Clean up after vty. shutdown :: IO () } @@ -44,6 +53,7 @@ rec = Vty { update = update' , getEvent = gkey , getSize = ulift getwinsize+ , refresh = refr , shutdown = fend } update' (Pic nc (T.Image wr w h)) = modifyMVar_ rstate $ \(ts0, fbw, fbh, oldptr) -> do@@ -61,10 +71,14 @@ free shd return (ts4, w, h, fb) + -- just refresh+ refr = modifyMVar_ rstate $ \(ts0,_,_,p) ->+ fmap (\(_,ts1) -> (ts1,(-1),(-1),p)) (getwinsize ts0)++ -- refresh and return a state event inval = modifyMVar rstate $ \(ts0,_,_,p) -> fmap (\((x,y),ts1) -> ((ts1,(-1),(-1),p),EvResize x y)) (getwinsize ts0) gkey = do k <- kvar- case k of (EvKey (KASCII 'l') [MCtrl]) -> inval- (EvResize _ _) -> inval+ case k of (EvResize _ _) -> inval _ -> return k
Graphics/Vty/Cursor.hs view
@@ -17,7 +17,7 @@ import Graphics.Vty.Types -- | An object representing the current state of the terminal.-data TermState = TS !Int !Int !Attr+data TermState = TS {_tsRow :: !Int, _tsColumn :: !Int, _tsAttr :: !Attr} -- | Set up the terminal for output, and create an object representing the -- initial state. Also returns a function for shutting down the terminal access.@@ -125,17 +125,41 @@ getwinsize ts = do (a,b) <- (`divMod` 65536) `fmap` c_get_window_size return ((fromIntegral b, fromIntegral a), ts) -cvis, civis, reset :: [Char] -reset = "\ESCc\ESC%G\ESC[1;1H\ESC[2J"+csi, cvis, civis, reset :: String++csi = "\ESC["++reset = "\ESCc" ++ -- full reset+ utf8CharSet ++ + setCursorPosition 1 1 +++ "\ESC[2J" -- erase all++setCursorPosition :: Int -> Int -> String+setCursorPosition row column = csi ++ show row ++ ";" ++ show column ++ "H"+ -- | Make the terminal beep. beep :: IO () beep = putStr "\BEL" + -- | Show the cursor-cvis = "\ESC[?25h" -civis = "\ESC[?25l"+cvis = csi ++ "?25h" ++-- | Hide the cursor+civis = csi ++ "?25l"++defaultCharSet, utf8CharSet :: String+defaultCharSet = "\ESC%@"+utf8CharSet = "\ESC%G"++-- | Restore the terminal to a good state for the shell.+-- Parameter is the line where the cursor should appear. endterm :: Int -> [Char]-endterm sy = "\ESC[" ++ show sy ++ ";1H\ESC[0;39;49m" ++- "\ESC%@\CR" ++ -- select default charset (\ESC%G would select UTF8)+endterm sy = setCursorPosition sy 1 +++ "\ESC[0;39;49m" ++ -- graphic rendition+ defaultCharSet ++ + "\CR" ++ cvis ++- "\ESC[K"+ "\ESC[K" -- erase line++
Graphics/Vty/LLInput.hs view
@@ -124,11 +124,13 @@ [ let k c s = ("\ESC["++c,(s,[])) in [ k "G" KNP5, k "P" KPause, k "A" KUp, k "B" KDown, k "C" KRight, k "D" KLeft ], -- Support for arrows- let k c s = [("\ESC[1;"++show mc++c,(s,m)) | (m,mc) <- - [([MShift],2::Int), ([MCtrl],5), ([MMeta],3), - ([MShift, MCtrl],6), ([MShift, MMeta],4)]]- in concat [ k "A" KUp, k "B" KDown, k "C" KRight, k "D" KLeft ],-+ [("\ESC[" ++ charCnt ++ show mc++c,(s,m)) + | charCnt <- ["1;", ""], -- we can have a count or not+ (m,mc) <- [([MShift],2::Int), ([MCtrl],5), ([MMeta],3), + ([MShift, MCtrl],6), ([MShift, MMeta],4)], -- modifiers and their codes+ (c,s) <- [("A", KUp), ("B", KDown), ("C", KRight), ("D", KLeft)] -- directions and their codes+ ],+ let k n s = ("\ESC["++show n++"~",(s,[])) in zipWith k [2::Int,3,5,6] [KIns,KDel,KPageUp,KPageDown], -- Support for simple characters.
test/Test.hs view
@@ -12,7 +12,8 @@ play vt x y sx sy btl = do update vt (render x y sx sy btl) k <- getEvent vt- case k of EvKey KLeft [] | x /= 0 -> play vt (x-1) y sx sy btl+ case k of EvKey (KASCII 'r') [MCtrl] -> refresh vt >> play vt x y sx sy btl+ EvKey KLeft [] | x /= 0 -> play vt (x-1) y sx sy btl EvKey KRight [] | x /= (sx-1) -> play vt (x+1) y sx sy btl EvKey KUp [] | y /= 0 -> play vt x (y-1) sx sy btl EvKey KDown [] | y /= (sy-2) -> play vt x (y+1) sx sy btl
vty.cabal view
@@ -1,5 +1,5 @@ Name: vty-Version: 3.0.4+Version: 3.1.0 License: BSD3 License-file: LICENSE Author: Stefan O'Rear