1-- | Vty supports input and output to terminal devices. The input is provides as a sequence of
2-- 'Event's. The output is defined by a 'Picture'. Which is one or more layers of 'Image's.
6-- Good sources of documentation for terminal programming are:
8-- - <https://github.com/b4winckler/vim/blob/master/src/term.c>
9-- - <http://invisible-island.net/xterm/ctlseqs/ctlseqs.html>
10-- - <http://ulisse.elettra.trieste.it/services/doc/serial/config.html>
11-- - <http://www.leonerd.org.uk/hacks/hints/xterm-8bit.html>
12-- - <http://www.unixwiz.net/techtips/termios-vmin-vtime.html>
13-- - <<http://vt100.net/docs/vt100-ug/chapter3.html vt100 control sequences>
14module Graphics.Vty ( Vty(..)
17 , module Graphics.Vty.Output
18 , module Graphics.Vty.Picture
27import Graphics.Vty.Prelude
29import Graphics.Vty.Input
30import Graphics.Vty.Output
31import Graphics.Vty.Picture
35import qualified System.Console.Terminfo as Terminfo
37-- | The main object. At most one should be created.
38-- An alternative is to use unsafePerformIO to automatically create a singleton Vty instance when
41-- This does not assure any thread safety. In theory, as long as an update action is not executed
42-- when another update action is already then it's safe to call this on multiple threads.
44 { -- | Outputs the given Picture. Equivalent to output_picture applied to a display context
45 -- implicitly managed by Vty.
46 update :: Picture -> IO ()
47 -- | Get one Event object, blocking if necessary.
48 , next_event :: IO Event
49 -- | The terminal device interface. See `Interface`
51 -- The use of Vty typically follows this process:
55 -- 1. use the update equation of Vty to display a picture
61 -- todo: provide a similar abstraction to Graphics.Vty.Output for input. Use haskeline's
62 -- input backend for implementation.
64 -- todo: remove explicit `shutdown` requirement.
66 -- | Refresh the display. Normally the library takes care of refreshing. Nonetheless, some
67 -- other program might output to the terminal and mess the display. In that case the user
68 -- might want to force a refresh.
70 -- | Clean up after vty.
71 -- The above methods will throw an exception if executed after this is executed.
75-- | Set up the state object for using vty. At most one state object should be
78mkVty = mkVtyEscDelay defaultEscDelay
80-- | Set up the state object for using vty. At most one state object should be
81-- created at a time. The delay, in microseconds, specifies the period of time to wait for a key
82-- following reading ESC from the terminal before considering the ESC key press as a discrete event.
83-- \todo move input init into terminal interface
84mkVtyEscDelay :: Int -> IO Vty
85mkVtyEscDelay escDelay = do
86 term_info <- Terminfo.setupTermFromEnv
89 (kvar, endi) <- initTermInput escDelay term_info
90 intMkVty kvar ( endi >> release_display t >> release_terminal t ) t
92intMkVty :: IO Event -> IO () -> Output -> IO Vty
93intMkVty kvar fend t = do
94 last_pic_ref <- newIORef Nothing
95 last_update_ref <- newIORef Nothing
97 let inner_update in_pic = do
98 b@(w,h) <- display_bounds t
99 let cursor = pic_cursor in_pic
100 in_pic' = case cursor of
104 _ | x >= 0x80000000 -> 0
108 _ | y >= 0x80000000 -> 0
111 in in_pic { pic_cursor = Cursor x' y' }
113 mlast_update <- readIORef last_update_ref
114 update_data <- case mlast_update of
116 dc <- display_context t b
117 output_picture dc in_pic'
119 Just (last_bounds, last_context) -> do
122 dc <- display_context t b
123 output_picture dc in_pic'
126 output_picture last_context in_pic'
127 return (b, last_context)
128 writeIORef last_update_ref $ Just update_data
129 writeIORef last_pic_ref $ Just in_pic'
132 = writeIORef last_update_ref Nothing
133 >> readIORef last_pic_ref
134 >>= maybe ( return () ) ( \pic -> inner_update pic )
136 let gkey = do k <- kvar
138 (EvResize _ _) -> inner_refresh
140 >>= return . (\(w,h)-> EvResize w h)
143 return $ Vty { update = inner_update
146 , refresh = inner_refresh
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list