1-- Copyright 2009-2010 Corey O'Connor
2module Graphics.Vty.Output.XTermColor
7import Graphics.Vty.Output.Interface
8import Graphics.Vty.Input.Mouse
9import qualified Graphics.Vty.Output.TerminfoBased as TerminfoBased
11import Blaze.ByteString.Builder (writeToByteString)
12import Blaze.ByteString.Builder.Word (writeWord8)
14import Control.Monad (void, when)
15import Control.Monad.Trans
18import System.Posix.IO (fdWrite)
19import System.Posix.Types (Fd)
20import System.Posix.Env (getEnv)
22import Data.List (isInfixOf)
23import Data.Maybe (catMaybes)
24import Data.Monoid ((<>))
26-- | Initialize the display to UTF-8.
27reserveTerminal :: ( Applicative m, MonadIO m ) => String -> Fd -> m Output
28reserveTerminal variant outFd = liftIO $ do
29 let flushedPut = void . fdWrite outFd
30 -- If the terminal variant is xterm-color use xterm instead since,
31 -- more often than not, xterm-color is broken.
32 let variant' = if variant == "xterm-color" then "xterm" else variant
35 when (not utf8a) $ flushedPut setUtf8CharSet
36 t <- TerminfoBased.reserveTerminal variant' outFd
38 mouseModeStatus <- newIORef False
39 pasteModeStatus <- newIORef False
41 let xtermSetMode t' m newStatus = do
42 curStatus <- getModeStatus t' m
43 when (newStatus /= curStatus) $
47 True -> flushedPut requestMouseEvents
48 False -> flushedPut disableMouseEvents
49 writeIORef mouseModeStatus newStatus
50 BracketedPaste -> liftIO $ do
52 True -> flushedPut enableBracketedPastes
53 False -> flushedPut disableBracketedPastes
54 writeIORef pasteModeStatus newStatus
56 xtermGetMode Mouse = liftIO $ readIORef mouseModeStatus
57 xtermGetMode BracketedPaste = liftIO $ readIORef pasteModeStatus
60 { terminalID = terminalID t ++ " (xterm-color)"
61 , releaseTerminal = do
62 when (not utf8a) $ liftIO $ flushedPut setDefaultCharSet
63 setMode t' BracketedPaste False
64 setMode t' Mouse False
66 , mkDisplayContext = \tActual r -> do
67 dc <- mkDisplayContext t tActual r
68 return $ dc { inlineHack = xtermInlineHack t' }
69 , supportsMode = const True
70 , getModeStatus = xtermGetMode
71 , setMode = xtermSetMode t'
77 let vars = ["LC_ALL", "LANG", "LC_CTYPE"]
78 results <- catMaybes <$> mapM getEnv vars
79 let matches = filter ("UTF8" `isInfixOf`) results <>
80 filter ("UTF-8" `isInfixOf`) results
81 return $ not $ null matches
83-- | Enable bracketed paste mode:
84-- http://cirw.in/blog/bracketed-paste
85enableBracketedPastes :: String
86enableBracketedPastes = "\ESC[?2004h"
88-- | Disable bracketed paste mode:
89disableBracketedPastes :: String
90disableBracketedPastes = "\ESC[?2004l"
92-- | These sequences set xterm based terminals to UTF-8 output.
94-- There is no known terminfo capability equivalent to this.
95setUtf8CharSet, setDefaultCharSet :: String
96setUtf8CharSet = "\ESC%G"
97setDefaultCharSet = "\ESC%@"
99-- | I think xterm is broken: Reseting the background color as the first
100-- bytes serialized on a new line does not effect the background color
101-- xterm uses to clear the line. Which is used *after* the next newline.
102xtermInlineHack :: Output -> IO ()
103xtermInlineHack t = do
104 let writeReset = foldMap (writeWord8.toEnum.fromEnum) "\ESC[K"
105 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