lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


On 21.09.2012 17:21, Rena wrote:
On Sep 21, 2012 11:12 AM, "Matthew Wild" <mwild1@gmail.com
<mailto:mwild1@gmail.com>> wrote:
 >
 > On 21 September 2012 15:34, Rena <hyperhacker@gmail.com
<mailto:hyperhacker@gmail.com>> wrote:
 > > (Yep, this question again. :p)
 > >
 > > I'm coding in a rather limited Linux-like environment: I have a
text editor,
 > > a terminal emulator, a Lua 5.1 interpreter, and not much else. I
don't have
 > > a C compiler.
 > >
 > > My problem is I want to read keys from stdin as soon as they're
pressed,
 > > without having to press enter. The only ways I know to do this
involve C
 > > function calls. Is there perhaps an ANSI escape code or some other
crazy
 > > trick I can use? Can I call some program with os.execute to change
terminal
 > > settings?
 >
 > Try this small function:
 >
 >     function getchar(n)
 >         local stty_ret = os.execute("stty raw 2>/dev/null");
 >         local ok, char;
 >         if stty_ret == 0 then
 >             ok, char = pcall(io.read, n or 1);
 >             os.execute("stty sane");
 >         else
 >             ok, char = pcall(io.read, "*l");
 >             if ok then
 >                 char = char:sub(1, n or 1);
 >             end
 >         end
 >         if ok then
 >             return char;
 >         end
 >     end
 >
 > An improvement would be to save the current stty settings, and then
 > restore them (instead of 'stty sane'). I don't know how "portable"
 > this is though.
 >
 > Hope this helps,
 > Matthew
 >
 > PS. The code is taken from Prosody, which is MIT licensed.
 >

Thanks, I thought stty could be useful there, but I hadn't noticed the
raw option.

I think the raw option is overkill here, as it it disables special characters like Ctrl-C. Here is what I use:

--------------------------

-- Wrapper around stty, returns current state

stty = function(...)
    local ok, p = pcall(io.popen, "stty -g")

    if not ok then return nil end

    local state = p:read()
    p:close()

    if state then P.system("stty", ...) end
    return state
end
--------------------------


Call
	oldstate = stty("-echo", "cbreak")

at the beginning, and at the end restore the old state by

	stty(oldstate)

Omit the -echo option if you don't want to handle the echoing yourself. Don't forget to restore the old state, otherwise you'll end up with a strange behaving terminal!

Regards,
Bernd

--
Bernd Eggink
http://sudrala.de