# Intercept stdin to capture output from ANSI code

**URL:** <https://discourse.julialang.org/t/intercept-stdin-to-capture-output-from-ansi-code/100330>\
**Category:** General Usage\
**Tags:** terminal\
**Created:** [June 14, 2023, 1:24pm UTC](https://discourse.julialang.org/t/intercept-stdin-to-capture-output-from-ansi-code/100330 "2023-06-14T13:24:02Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![TheLateKronos](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/thelatekronos/32/12824_2.png) [@TheLateKronos](https://discourse.julialang.org/u/TheLateKronos)\
**Post date:** [June 14, 2023, 1:24pm UTC](https://discourse.julialang.org/t/intercept-stdin-to-capture-output-from-ansi-code/100330/1 "2023-06-14T13:24:02Z")

</div>

I am informed by this post: [linux - How can I get position of cursor in terminal? - Stack Overflow](https://stackoverflow.com/questions/8343250/how-can-i-get-position-of-cursor-in-terminal)

When I run `print("\x1b[6n")`, the current cursor position is written into `stdin`. However, the start is an escape sequence, and does not get captured. Furthermore, I want the output in a variable in a string, not as written text in the terminal.

I tried running stuff like

```julia
Base.redirect_stdin(()->print("\x1b[6n"), stdout)

```

, but I was unable to get the desired behaviour. The closest I could get was by running

```julia
julia> print("\x1b[6n"); readline()
^[[24;1R # this is written from running the print command
"\e[24;1R" # Pressing enter captures the input, and returnes this string

```

Is there a way to avoid this final step, of having to press enter? I am looking to use this in REPL.Terminals, where I want to implement `getX`, `getY` and `pos` for unix terminals, and I therefore need this to be non-interactive.

---

<div class="post-metadata">

**Author:** ![sijo](https://avatars.discourse-cdn.com/v4/letter/s/da6949/32.png) [@sijo](https://discourse.julialang.org/u/sijo)\
**Post date:** [June 14, 2023, 3:36pm UTC](https://discourse.julialang.org/t/intercept-stdin-to-capture-output-from-ansi-code/100330/2 "2023-06-14T15:36:29Z")

</div>

By default the terminal will wait for a newline before sending its input (see “canonical mode” in the [termios manpage](https://man7.org/linux/man-pages/man3/termios.3.html) and [libc manual](https://www.gnu.org/software/libc/manual/html_node/Canonical-or-Not.html)). You can temporarily disable that and also disable echoing of the input by manipulating the terminal:

```julia
using REPL

function withrawterm(f)
    t = REPL.TerminalMenus.terminal
    REPL.Terminals.raw!(t, true)
    f()
    REPL.Terminals.raw!(t, false)
    return nothing
end

julia> withrawterm() do
           print("\x1b[6n")
           x = readavailable(stdin)
           println("Read: $x.")
       end
Read: UInt8[0x1b, 0x5b, 0x35, 0x32, 0x3b, 0x31, 0x52].

```

Maybe you can use `REPL.Terminals.raw!` for your purpose? Although it looks like currently it’s implemented through an external call to `stty`. Maybe it would be better to call directly into the C library, something like this:

```julia
using TERMIOS

function withrawterm(f)
    T = TERMIOS
    s = T.termios()
    T.tcgetattr(stdin, s)
    sraw = deepcopy(s)
    T.cfmakeraw(sraw)
    T.tcsetattr(stdin, T.TCSANOW, sraw)
    f()
    T.tcsetattr(stdin, T.TCSANOW, s)
end

```

(See [here](https://kdheepak.com/TERMIOS.jl/stable/usage/#TERMIOS.cfmakeraw-Tuple%7BTERMIOS.termios%7D) for the flags changed by `cfmakeraw`.)
