-- Copyright Corey O'Connor -- The standard Mac OS X terminals Terminal.app and iTerm both declare themselves to be -- "xterm-color" by default. However the terminfo database for xterm-color included with OS X is -- incomplete. -- -- This terminal implementation modifies the standard terminfo terminal as required for complete OS -- X support. {-# LANGUAGE MagicHash #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE TypeFamilies #-} module Graphics.Vty.Output.MacOSX ( reserveTerminal ) where import Graphics.Vty.Output.Interface import qualified Graphics.Vty.Output.TerminfoBased as TerminfoBased import Control.Applicative import Control.Monad (void) import Control.Monad.Trans import System.Posix.IO (fdWrite) import System.Posix.Types (Fd) -- | for Terminal.app the terminal identifier "xterm" is used. For iTerm.app the terminal identifier -- "xterm-256color" is used. -- -- This effects the terminfo lookup. reserveTerminal :: ( Applicative m, MonadIO m ) => String -> Fd -> m Output reserveTerminal v outFd = do let remapTerm "iTerm.app" = "xterm-256color" remapTerm _ = "xterm" flushedPut :: String -> IO () flushedPut = void . fdWrite outFd t <- TerminfoBased.reserveTerminal (remapTerm v) outFd return $ t { terminalID = terminalID t ++ " (Mac)" , reserveDisplay = terminalAppReserveDisplay flushedPut , releaseDisplay = terminalAppReleaseDisplay flushedPut } -- | Terminal.app requires the xterm-color smcup and rmcup caps. Not the generic xterm ones. -- Otherwise, Terminal.app expects the xterm caps. smcupStr, rmcupStr :: String smcupStr = "\ESC7\ESC[?47h" rmcupStr = "\ESC[2J\ESC[?47l\ESC8" -- | always smcup then clear the screen on terminal.app -- -- \todo really? terminalAppReserveDisplay :: MonadIO m => (String -> IO ()) -> m () terminalAppReserveDisplay flushedPut = liftIO $ do flushedPut smcupStr flushedPut clearScreenStr terminalAppReleaseDisplay :: MonadIO m => (String -> IO ()) -> m () terminalAppReleaseDisplay flushedPut = liftIO $ do flushedPut rmcupStr -- | iTerm needs a clear screen after smcup as well. -- -- \todo but we apply to all mac terminals? clearScreenStr :: String clearScreenStr = "\ESC[H\ESC[2J"