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
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> 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.
By default the terminal will wait for a newline before sending its input (see “canonical mode” in the termios manpage and libc manual). You can temporarily disable that and also disable echoing of the input by manipulating the terminal:
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:
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