3#ifndef MIN_VERSION_base
4#defined MIN_VERSION_base(x,y,z) 1
7-- Copyright 2009-2010 Corey O'Connor
8module Graphics.Vty.Output.XTermColor ( reserveTerminal )
11import Graphics.Vty.Output.Interface
12import Graphics.Vty.Input.Mouse
13import qualified Graphics.Vty.Output.TerminfoBased as TerminfoBased
15import Blaze.ByteString.Builder (writeToByteString)
16import Blaze.ByteString.Builder.Word (writeWord8)
18import Control.Monad (void, when)
19import Control.Monad.Trans
22import System.Posix.IO (fdWrite)
23import System.Posix.Types (Fd)
24import System.Posix.Env (getEnv)
26#if !(MIN_VERSION_base(4,8,0))
27import Control.Applicative
28import Data.Foldable (foldMap)
31import Data.List (isInfixOf)
32import Data.Maybe (catMaybes)
33import Data.Monoid ((<>))
35-- | Initialize the display to UTF-8.
36reserveTerminal :: ( Applicative m, MonadIO m ) => String -> Fd -> m Output
37reserveTerminal variant outFd = liftIO $ do
38 let flushedPut = void . fdWrite outFd
39 -- If the terminal variant is xterm-color use xterm instead since, more often than not,
40 -- xterm-color is broken.
41 let variant' = if variant == "xterm-color" then "xterm" else variant
44 when (not utf8a) $ flushedPut setUtf8CharSet
45 t <- TerminfoBased.reserveTerminal variant' outFd
47 mouseModeStatus <- newIORef False
48 pasteModeStatus <- newIORef False
50 let xtermSetMode t' m newStatus = do
51 curStatus <- getModeStatus t' m
52 when (newStatus /= curStatus) $
56 True -> flushedPut requestMouseEvents
57 False -> flushedPut disableMouseEvents
58 writeIORef mouseModeStatus newStatus
59 BracketedPaste -> liftIO $ do
61 True -> flushedPut enableBracketedPastes
62 False -> flushedPut disableBracketedPastes
63 writeIORef pasteModeStatus newStatus
65 xtermGetMode Mouse = liftIO $ readIORef mouseModeStatus
66 xtermGetMode BracketedPaste = liftIO $ readIORef pasteModeStatus
69 { terminalID = terminalID t ++ " (xterm-color)"
70 , releaseTerminal = do
71 when (not utf8a) $ liftIO $ flushedPut setDefaultCharSet
72 setMode t' BracketedPaste False
73 setMode t' Mouse False
75 , mkDisplayContext = \tActual r -> do
76 dc <- mkDisplayContext t tActual r
77 return $ dc { inlineHack = xtermInlineHack t' }
78 , supportsMode = const True
79 , getModeStatus = xtermGetMode
80 , setMode = xtermSetMode t'
86 let vars = ["LC_ALL", "LANG", "LC_CTYPE"]
87 results <- catMaybes <$> mapM getEnv vars
88 let matches = filter ("UTF8" `isInfixOf`) results <>
89 filter ("UTF-8" `isInfixOf`) results
90 return $ not $ null matches
92-- | Enable bracketed paste mode:
93-- http://cirw.in/blog/bracketed-paste
94enableBracketedPastes :: String
95enableBracketedPastes = "\ESC[?2004h"
97-- | Disable bracketed paste mode:
98disableBracketedPastes :: String
99disableBracketedPastes = "\ESC[?2004l"
101-- | These sequences set xterm based terminals to UTF-8 output.
103-- \todo I don't know of a terminfo cap that is equivalent to this.
104setUtf8CharSet, setDefaultCharSet :: String
105setUtf8CharSet = "\ESC%G"
106setDefaultCharSet = "\ESC%@"
108-- | I think xterm is broken: Reseting the background color as the first bytes serialized on a
109-- new line does not effect the background color xterm uses to clear the line. Which is used
110-- *after* the next newline.
111xtermInlineHack :: Output -> IO ()
112xtermInlineHack t = do
113 let writeReset = foldMap (writeWord8.toEnum.fromEnum) "\ESC[K"
114 outputByteBuffer t $ writeToByteString writeReset
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