1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70
|
local sys = require "system"
print [[
This example shows how to do a non-blocking read from the cli.
]]
-- setup Windows console to handle ANSI processing
local of_in = sys.getconsoleflags(io.stdin)
local of_out = sys.getconsoleflags(io.stdout)
sys.setconsoleflags(io.stdout, sys.getconsoleflags(io.stdout) + sys.COF_VIRTUAL_TERMINAL_PROCESSING)
sys.setconsoleflags(io.stdin, sys.getconsoleflags(io.stdin) + sys.CIF_VIRTUAL_TERMINAL_INPUT)
-- setup Posix terminal to use non-blocking mode, and disable line-mode
local of_attr = sys.tcgetattr(io.stdin)
local of_block = sys.getnonblock(io.stdin)
sys.setnonblock(io.stdin, true)
sys.tcsetattr(io.stdin, sys.TCSANOW, {
lflag = of_attr.lflag - sys.L_ICANON - sys.L_ECHO, -- disable canonical mode and echo
})
-- cursor sequences
local get_cursor_pos = "\27[6n"
print("Press a key, or 'A' to get cursor position, 'ESC' to exit")
while true do
local key, keytype
-- wait for a key
while not key do
key, keytype = sys.readansi(math.huge)
end
if key == "A" then io.write(get_cursor_pos); io.flush() end
-- check if we got a key or ANSI sequence
if keytype == "char" then
-- just a key
local b = key:byte()
if b < 32 then
key = "." -- replace control characters with a simple "." to not mess up the screen
end
print("you pressed: " .. key .. " (" .. b .. ")")
if b == 27 then
print("Escape pressed, exiting")
break
end
elseif keytype == "ansi" then
-- we got an ANSI sequence
local seq = { key:byte(1, #key) }
print("ANSI sequence received: " .. key:sub(2,-1), "(bytes: " .. table.concat(seq, ", ")..")")
else
print("unknown key type received: " .. tostring(keytype))
end
end
-- Clean up afterwards
sys.setnonblock(io.stdin, false)
sys.setconsoleflags(io.stdout, of_out)
sys.setconsoleflags(io.stdin, of_in)
sys.tcsetattr(io.stdin, sys.TCSANOW, of_attr)
sys.setnonblock(io.stdin, of_block)
|