1-- | Generic Terminal interface.
3-- Defines the common interface supported by all terminals.
7-- 1. Graphics.Vty.Terminal: This instantiates an abtract interface to the terminal interface based
8-- on the TERM and COLORTERM environment variables.
10-- 2. Graphics.Vty.Terminal.Generic: Defines the generic interface all terminals need to implement.
12-- 3. Graphics.Vty.Terminal.TerminfoBased: Defines a terminal instance that uses terminfo for all
13-- control strings. No attempt is made to change the character set to UTF-8 for these terminals.
14-- I don't know a way to reliably determine if that is required or how to do so.
16-- 4. Graphics.Vty.Terminal.XTermColor: This module contains an interface suitable for xterm-like
17-- terminals. These are the terminals where TERM == xterm. This does use terminfo for as many
18-- control codes as possible.
20-- Copyright 2009-2010 Corey O'Connor
21{-# LANGUAGE ScopedTypeVariables #-}
22module Graphics.Vty.Terminal ( module Graphics.Vty.Terminal
32import Graphics.Vty.DisplayRegion
33import Graphics.Vty.Terminal.Generic
34import Graphics.Vty.Terminal.MacOSX as MacOSX
35import Graphics.Vty.Terminal.XTermColor as XTermColor
36import Graphics.Vty.Terminal.TerminfoBased as TerminfoBased
38import Control.Applicative
39import Control.Exception ( SomeException, try )
41import Control.Monad.Trans
43import Data.List ( isPrefixOf )
45import System.Environment
47-- | Returns a TerminalHandle (an abstract Terminal instance) for the current terminal.
49-- The specific Terminal implementation used is hidden from the API user. All terminal
50-- implementations are assumed to perform more, or less, the same. Currently all implementations use
51-- terminfo for at least some terminal specific information. This is why platforms without terminfo
52-- are not supported. However, as mentioned before, any specifics about it being based on terminfo
53-- are hidden from the API user. If a terminal implementation is developed for a terminal for a
54-- platform without terminfo support then Vty should work as expected on that terminal.
56-- Selection of a terminal is done as follows:
59-- then the terminal might be one of the Mac OS X .app terminals. Check if that might be
60-- the case and use MacOSX if so.
61-- otherwise use XTermColor.
63-- * for any other TERM value TerminfoBased is used.
66-- The terminal has to be determined dynamically at runtime. To satisfy this requirement all
67-- terminals instances are lifted into an abstract terminal handle via existential qualification.
68-- This implies that the only equations that can used are those in the terminal class.
70-- To differentiate between Mac OS X terminals this uses the TERM_PROGRAM environment variable.
71-- However, an xterm started by Terminal or iTerm *also* has TERM_PROGRAM defined since the
72-- environment variable is not reset/cleared by xterm. However a Terminal.app or iTerm.app started
73-- from an xterm under X11 on mac os x will likely be done via open. Since this does not propogate
74-- environment variables (I think?) this assumes that XTERM_VERSION will never be set for a true
75-- Terminal.app or iTerm.app session.
78-- The file descriptor used for output will a duplicate of the current stdout file descriptor.
80-- todo: add an implementation for windows that does not depend on terminfo. Should be installable
81-- with only what is provided in the haskell platform.
83-- todo: The Terminal interface does not provide any input support.
84terminal_handle :: ( Applicative m, MonadIO m ) => m TerminalHandle
86 term_type <- liftIO $ getEnv "TERM"
87 t <- if "xterm" `isPrefixOf` term_type
89 maybe_terminal_app <- get_env "TERM_PROGRAM"
90 case maybe_terminal_app of
92 -> XTermColor.terminal_instance term_type >>= new_terminal_handle
93 Just v | v == "Apple_Terminal" || v == "iTerm.app"
95 maybe_xterm <- get_env "XTERM_VERSION"
97 Nothing -> MacOSX.terminal_instance v >>= new_terminal_handle
98 Just _ -> XTermColor.terminal_instance term_type >>= new_terminal_handle
99 -- Assume any other terminal that sets TERM_PROGRAM to not be an OS X terminal.app
101 _ -> XTermColor.terminal_instance term_type >>= new_terminal_handle
102 -- Not an xterm-like terminal. try for generic terminfo.
103 else TerminfoBased.terminal_instance term_type >>= new_terminal_handle
107 mv <- liftIO $ try $ getEnv var
109 Left (_e :: SomeException) -> return $ Nothing
110 Right v -> return $ Just v
112-- | Sets the cursor position to the given output column and row.
114-- This is not necessarially the same as the character position with the same coordinates.
115-- Characters can be a variable number of columns in width.
117-- Currently, the only way to set the cursor position to a given character coordinate is to specify
118-- the coordinate in the Picture instance provided to output_picture or refresh.
119set_cursor_pos :: MonadIO m => TerminalHandle -> Int -> Int -> m ()
120set_cursor_pos t x y = do
121 bounds <- display_bounds t
122 when (x >= 0 && x < region_width bounds && y >= 0 && y < region_height bounds) $ do
123 d <- display_context t bounds
124 liftIO $ marshall_to_terminal t (move_cursor_required_bytes d x y) (serialize_move_cursor d x y)
127hide_cursor :: MonadIO m => TerminalHandle -> m ()
129 bounds <- display_bounds t
130 d <- display_context t bounds
131 liftIO $ marshall_to_terminal t (hide_cursor_required_bytes d) (serialize_hide_cursor d)
134show_cursor :: MonadIO m => TerminalHandle -> m ()
136 bounds <- display_bounds t
137 d <- display_context t bounds
138 liftIO $ marshall_to_terminal t (show_cursor_required_bytes d) (serialize_show_cursor d)
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