module System.Terminal.MonadScreen where import System.Terminal.MonadPrinter data Size = Size { height :: {-# UNPACK #-} !Int , width :: {-# UNPACK #-} !Int } deriving (Eq, Ord, Show) data Position = Position { row :: {-# UNPACK #-} !Int , col :: {-# UNPACK #-} !Int } deriving (Eq, Ord, Show) data EraseMode = EraseBackward -- ^ Erase left of/above current cursor position. | EraseForward -- ^ Erase right of/below current cursor position. | EraseAll -- ^ Erase whole line/screen. deriving (Eq, Ord, Show) class (MonadPrinter m) => MonadScreen m where -- | Get the dimensions of the visible window. getWindowSize :: m Size -- | Move the cursor `n` lines up. Do not change column. moveCursorUp :: Int -> m () -- | Move the cursor `n` lines down. Do not change column. moveCursorDown :: Int -> m () -- | Move the cursor `n` columns to the right. Do not change line. moveCursorForward :: Int -> m () -- | Move the cursor `n` columns to the left. Do not change line. moveCursorBackward :: Int -> m () -- | Get the current cursor position as reported by the terminal. -- -- * @Position 0 0@ is the upper left of the window. -- * The cursor is always within window bounds. -- * This operation causes a round-trip to the terminal and -- shall be used sparely (e.g. on window size change). getCursorPosition :: m Position -- | Set the cursor position. -- -- * @Position 0 0@ is the upper left of the window. -- * The resulting cursor position is undefined when it is outside -- the window bounds. setCursorPosition :: Position -> m () -- | Set the cursor row. -- -- * @0@ is the topmost row. setCursorRow :: Int -> m () -- | Set the cursor column. -- -- * @0@ is the leftmost column. setCursorColumn :: Int -> m () -- | Save cursor position and attributes. saveCursor :: m () -- | Restore cursor position and attributes. -- -- * Restores the cursor as previously saved by `saveCursor`. -- * The cursor position is strictly relative to the visible -- window and does not take eventual scrolling into account. -- The advantage of this operation is that it does not require -- transmission of coordinates and attributes to the terminal -- and is therefor slightly more efficient than all other alternatives. -- * Only use this when auto-wrap is disabled, alternate screen -- buffer is enabled or you can otherwise guarantee that the -- window does not scroll between `saveCursor` and `restoreCursor`! restoreCursor :: m () -- | Insert whitespace at the cursor position and -- shift existing characters to the right. insertChars :: Int -> m () -- | Delete characters and shift existing characters from the right. deleteChars :: Int -> m () -- | Replace characters with whitespace. eraseChars :: Int -> m () -- | Insert lines and shift existing lines downwards. insertLines :: Int -> m () -- | Delete lines and shift up existing lines from below. deleteLines :: Int -> m () -- | Clears characters in the current line. eraseInLine :: EraseMode -> m () -- | Clears lines above/below the current line. eraseInDisplay :: EraseMode -> m () -- | Show the cursor. showCursor :: m () -- | Hide the cursor. hideCursor :: m () -- | Whether or not to automatically wrap on line ends. setAutoWrap :: Bool -> m () -- | Whether or not to use the alternate screen buffer. -- -- - The main screen buffer content is preserved and restored -- when leaving the alternate screen screen buffer. -- - The dimensions of the alternate screen buffer are -- exactly those of the screen. setAlternateScreenBuffer :: Bool -> m ()