# Reading responses to ANSI escape codes

**URL:** <https://discourse.julialang.org/t/reading-responses-to-ansi-escape-codes/44572>\
**Category:** General Usage\
**Tags:** question, repl\
**Created:** [August 8, 2020, 3:23pm UTC](https://discourse.julialang.org/t/reading-responses-to-ansi-escape-codes/44572 "2020-08-08T15:23:24Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![simonschoelly](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/simonschoelly/32/21606_2.png) [@simonschoelly](https://discourse.julialang.org/u/simonschoelly)\
**Post date:** [August 8, 2020, 3:23pm UTC](https://discourse.julialang.org/t/reading-responses-to-ansi-escape-codes/44572/1 "2020-08-08T15:23:24Z")

</div>

When writing an ANSI escape code to the console like this:

```julia
julia> print(stdout, "\033[14t");

```

One gets an answer back that is also written to the console. In this case we get

```julia
^[[4;1012;1419t

```

which is the width and height of my console.  
Now I was wondering how I can use this to query for my console size, i.e how can I ensure that the answer is not directly written to the console but to some variable and how would I do such thing in a thread save way, so that other processes that might try to read from stdin do not interfere with my answer.

---

<div class="post-metadata">

**Author:** ![jagot](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jagot/32/12217_2.png) [@jagot](https://discourse.julialang.org/u/jagot)\
**Post date:** [August 8, 2020, 5:27pm UTC](https://discourse.julialang.org/t/reading-responses-to-ansi-escape-codes/44572/2 "2020-08-08T17:27:09Z")

</div>

Maybe you can use [`displaysize`](https://docs.julialang.org/en/v1/base/io-network/#Base.displaysize)?

---

<div class="post-metadata">

**Author:** ![simonschoelly](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/simonschoelly/32/21606_2.png) [@simonschoelly](https://discourse.julialang.org/u/simonschoelly)\
**Post date:** [August 8, 2020, 5:45pm UTC](https://discourse.julialang.org/t/reading-responses-to-ansi-escape-codes/44572/3 "2020-08-08T17:45:02Z")

</div>

Unfortunately that only gives me the number of rows/columns but I need the number of pixels. But I looked into the code for `displaysize` and it uses `ioctl` with `TIOCGWINSZ` internally (which is the second approach I am exploring right now). That call actually returns the number of pixels, but that information is then just thrown away.

---

<div class="post-metadata">

**Author:** ![jagot](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jagot/32/12217_2.png) [@jagot](https://discourse.julialang.org/u/jagot)\
**Post date:** [August 9, 2020, 8:31am UTC](https://discourse.julialang.org/t/reading-responses-to-ansi-escape-codes/44572/4 "2020-08-09T08:31:20Z")

</div>

Oh, then I misunderstood your question. Why do you want the pixel size of the terminal? I.e. what will you use the information for? Just out of curiosity, I don’t know of a way to retrieve that information.

---

<div class="post-metadata">

**Author:** ![simonschoelly](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/simonschoelly/32/21606_2.png) [@simonschoelly](https://discourse.julialang.org/u/simonschoelly)\
**Post date:** [August 9, 2020, 9:44am UTC](https://discourse.julialang.org/t/reading-responses-to-ansi-escape-codes/44572/5 "2020-08-09T09:44:51Z")

</div>

It s for a [package](https://github.com/simonschoelly/KittyTerminalImages.jl) of mine that allows one to display images in a terminal when using the [Kitty terminal emulator](https://sw.kovidgoyal.net/kitty/). So I thought It might be a good idea to have the ability to scale some output to the width of the terminal.

Also, there might be other information that I could get out using escape sequences, for example the name of the terminal emulator.

---

<div class="post-metadata">

**Author:** ![goerz](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/goerz/32/3269_2.png) [@goerz](https://discourse.julialang.org/u/goerz)\
**Post date:** [October 6, 2024, 1:44pm UTC](https://discourse.julialang.org/t/reading-responses-to-ansi-escape-codes/44572/6 "2024-10-06T13:44:59Z")

</div>

Bumping this… In 2024, are there any new recommendations for getting the response from ANSI escape codes?

---

<div class="post-metadata">

**Author:** ![Riley\_V](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/riley_v/32/212744_2.png) [@Riley\_V](https://discourse.julialang.org/u/Riley_V)\
**Post date:** [October 19, 2024, 10:50pm UTC](https://discourse.julialang.org/t/reading-responses-to-ansi-escape-codes/44572/7 "2024-10-19T22:50:31Z")

</div>

To read, the console needs to be in raw mode otherwise it buffers the response from the query. I was able to read the response using the following:

```julia
function query_terminal(s :: String, esc :: Char) :: String
    run(`stty raw`)
    print(s)
    out :: Vector{Char} = []
    while true
        push!(out, read(stdin, 1)[begin])
        (out[end] == esc) && break
    end
    run(`stty cooked`)
    String(out)
end

```

Probably not the most effective way to do this, but it works.

---

<div class="post-metadata">

**Author:** ![piechologist](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/piechologist/32/27662_2.png) [@piechologist](https://discourse.julialang.org/u/piechologist)\
**Post date:** [October 25, 2024, 6:32pm UTC](https://discourse.julialang.org/t/reading-responses-to-ansi-escape-codes/44572/8 "2024-10-25T18:32:10Z")

</div>

> [@Riley\_V](#):
>
> Probably not the most effective way to do this, but it works.

I use a similar approach to read my local system clipboard on remote machines:

```julia
using Base64: base64decode
using REPL: Terminals

function pbpaste()
    # Put term in raw mode:
    term = Terminals.TTYTerminal("xterm", stdin, stdout, stderr)
    Terminals.raw!(term, true)
    Base.start_reading(stdin)

    # Request the system clipboard with OSC52:
    print(stdout, "\e]52;c;?\a")

    # Decode the response:
    data = readuntil(stdin, "\e\\")
    startswith(data, "\e]52;c;") || return ""
    return String(base64decode(chopprefix(data, "\e]52;c;")))
end

```

The raw mode part is borrowed from [TerminalExtensions.jl](https://github.com/Keno/TerminalExtensions.jl/blob/master/src/TerminalExtensions.jl#L122). This is really fast (\< 1 ms). It uses undocumented functions, though.

The terminal exits the raw mode when the function returns. That’s handy if something goes wrong. I can hit ^C and the terminal goes back to a functional state.

There should be probably a timeout to make it more robust but as you said, _it works_.
