Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support alternative terminal screens #147

Closed
chshersh opened this issue Nov 16, 2022 · 9 comments
Closed

Support alternative terminal screens #147

chshersh opened this issue Nov 16, 2022 · 9 comments

Comments

@chshersh
Copy link

Most common terminal simulators support alternative terminal screens:

However, I haven't found any functions in ansi-terminal to support this. Here is a simple Haskell script that uses this feature:

#!/usr/bin/env cabal
{- cabal:
build-depends:
  , base ^>= 4.16
-}

{-# LANGUAGE NumericUnderscores #-}
{-# LANGUAGE ScopedTypeVariables #-}

module Main where

import Control.Concurrent
import Data.Foldable

main :: IO ()
main = do
    putStrLn "\ESC[?1049h\ESC[H"

    for_ [1 .. 5] $ \(i :: Int) -> do
        putStrLn $ "Going back in: " <> show i
        threadDelay 1_000_000

    putStrLn "\ESC[?1049l"

Would it be possible to introduce functions like enterAlternativeScreen and leaveAlternativeScreen in ansi-terminal?

@mpilgrem
Copy link
Collaborator

As ansi-terminal aims to be cross-platform, it tends to support things that might be classified as the 'common ground' on the most popular terminals for Linux, macOS and Windows. That does not rule out other features, but it does mean that, if they are added, the Haddock documentation should aim to help users understand the limitations.

The website you refer to above covers Linux and Windows supports these codes (https://learn.microsoft.com/en-us/windows/console/console-virtual-terminal-sequences#alternate-screen-buffer). Do you know if the native terminal on macOS (Terminal) supports them?

@Bodigrim
Copy link
Contributor

Bodigrim commented Nov 16, 2022

These are known as smcup (switch to the alternative buffer) and rmcup (switch back) capabilities. On UNIX systems escape codes for a local terminal can be queried from terminfo database: from ghci

> import System.Console.Terminfo
> t <- setupTermFromEnv
> getCapability t (tiGetOutput1 "smcup") :: Maybe String
Just "\ESC7\ESC[?47h"
> getCapability t (tiGetOutput1 "rmcup") :: Maybe String
Just "\ESC[2J\ESC[?47l\ESC8"

or alternatively from bash:

~$ echo "$(tput smcup)" | cat -e
^[7^[[?47h$
~$ echo "$(tput rmcup)" | cat -e
^[[2J^[[?47l^[8$

@Bodigrim
Copy link
Contributor

I'm not sure which code is more portable, 47 or 1049. infocmp says

$ infocmp xterm-color | grep mcup
	ri=\EM, rmacs=^O, rmcup=\E[2J\E[?47l\E8, rmir=\E[4l,
	smcup=\E7\E[?47h, smir=\E[4h, smkx=\E[?1h\E=, smso=\E[7m,
$ infocmp xterm | grep mcup
	rin=\E[%p1%dT, rmacs=\E(B, rmam=\E[?7l, rmcup=\E[?1049l,
	sgr0=\E(B\E[m, smacs=\E(0, smam=\E[?7h, smcup=\E[?1049h,

@mpilgrem
Copy link
Collaborator

mpilgrem commented Nov 16, 2022

As Windows' documentation suggests it implements 1 0 4 9, and not 4 7, I would likely implement the former. I am also hoping that when Microsoft decided to look to XTerm, it made sensible choices... EDIT: the XTerm documentation describes 1 0 4 9 as 'newer'.

@Bodigrim
Copy link
Contributor

Do you know if the native terminal on macOS (Terminal) supports them?

I can confirm that code 1049 works with Terminal.app and iTerm.app on macOS.

@mpilgrem
Copy link
Collaborator

On naming, XTerm (the origin of these codes, I think) describes the functions as use Alternative Screen Buffer and use Normal Screen Buffer. ansi-terminal does not shy away from long function names. How about useAlternativeScreenBuffer and useNormalScreenBuffer?

@mpilgrem
Copy link
Collaborator

@chshersh, @Bodigrim, I'm happy for these to be implemented and happy to implement them - but may not get to that before the coming weekend.

@chshersh
Copy link
Author

I don't have capacity to work on this issue at the moment but I'm interested in having this feature in the library so if this issue is not resolved in the future, I'll try to work on it at some point.

I personally okay with long names for the functions 👌🏻 In my vision, the name useNormalScreenBuffer implies that the function is idempotent and it's okay to call it multiple times without worrying about entering an invalid state in the system. I'm not sure if this is true here but it might be so in that case the name is fine 🙂

@mpilgrem
Copy link
Collaborator

I've made a pull request that adds this. I was mistaken, in that XTerm actually calls it use Alternate Screen Buffer - so useAlternateScreenBuffer. Be aware that useNormalScreenBuffer always restores the saved cursor position. So, if you use it, move the cursor, and use it again, the cursor will be back where it was when you first used it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants