readkey.lua - simple terminal control, like CPAN's Term::ReadKey
local K = require 'readkey' local P = require 'posix' local tty = io.open(P.ctermid(), 'a+') -- the controlling terminal K.ReadMode( 4, tty ) -- Turn off controls keys local key while true do key = K.ReadKey( -1, tty ) if key then break end do_something_else_meanwhile() -- no key yet... end print("You pressed key: "..key) K.ReadMode( 0, tty ) -- Reset tty mode before exiting
This Lua module is dedicated to providing simple control over terminal modes (cbreak, raw, cooked, etc.), and support for non-blocking reads, and some handy functions for working with terminals.
This module started as a re-expression in Lua of the Term::ReadKey Perl module by Kenneth Albanowski and Jonathan Stowe. The calling interface is similar, except that ReadLine() has quite different functionality, and SetTerminalSize() and GetSpeeds() are not implemented.
Takes an integer argument, which can be one of the following values:
0 Restore original settings 1 Change to cooked mode 2 Change to cooked mode with echo off (Good for passwords) 3 Change to cbreak mode 4 Change to raw mode 5 Change to ultra-raw mode (LF to CR/LF translation turned off)
Or, you may use the synonyms:
'restore', 'normal', 'noecho', 'cbreak', 'raw', 'ultra-raw'
These functions are automatically applied to io.stdin if no other filehandle is supplied. Mode 0 not only restores original settings, but it will cause the next ReadMode call to save a new set of default settings. Mode 5 is similar to mode 4, except no CR/LF translation is performed, and, if possible, parity will be disabled.
If you are executing another program that may be changing the terminal mode, you will either want to say
local tty = io.open(P.ctermid(), 'a+') K.ReadMode(1, tty) ... os.execute('someprogram') K.ReadMode(1, tty)
which resets the settings after the program has run, or:
somemode = 1 K.ReadMode(0) os.execute('someprogram') K.ReadMode(1)
which records any changes the program may have made, before resetting the mode.
Takes an integer argument, which can be one of the following values:
0 Perform a normal read using getc -1 Perform a non-blocked read >0 Perform a timed read
If mode is zero, ReadKey() will wait for input,
like a normal getc
(since version 1.2, if the filehandle has been
set to raw or ultra-raw, the underlying
read() call is restarted after any interrupt).
If mode is less than zero,
ReadKey will return nil immediately
unless a character is waiting in the buffer.
If mode is greater than zero, then ReadKey will use it
as a timeout value in seconds (fractional seconds are allowed),
and won't return nil until that time expires.
If the filehandle is not supplied, it will default to STDIN.
The syntax of this call is nothing like that of its Perl equivalent. It invokes the GNU Readline and History libraries, which display the prompt, allow Tab-Filename-Completion, and optionally save the line entered onto the end of the histfile, whose contents are available by the Up-Arrow. For example:
local str = K.ReadLine('Delete which file ? ', '~/.filemanager_history')
If the histfile parameter is nil, the Up and Down Arrows will not work, and no history-file will be created.
Returns four numbers:
the width and height of the terminal in characters,
and the width and height in pixels.
Since version 1.2, xwininfo -id $WINDOWID is used if possible, since it returns up-to-date information even after ReadLine() has been invoked.
If xwininfo is not available, various other means are tried, which all fail to respond to size-changes that occur after ReadLine() has been invoked; also the pixel sizes are returned as zero (they would need the ioctl command with the non-POSIX TIOCGWINSZ parameter).
Returns a table containing key/value pairs. Each key is the name of the control-character/signal, and its value is that character, as a single character, except for MIN and TIME, which are integers.
Each key will be an entry from the following list:
DISCARD EOF EOL EOL2 ERASE ERASEWORD INTERRUPT KILL MIN QUIT QUOTENEXT REPRINT START STOP SUSPEND TIME
The keys SWITCH and STATUS, which are supported by the Term::ReadKey CPAN module, are not present here because they are not specified by POSIX.
Thus, the following will give you the current interrupt character:
local keys = K.GetControlChars() interrupt_char = keys['INTERRUPT']
Takes a table containing key/value pairs. Each key should be the name of a legal control-character or signal, and its value should be either a single character, or a number in the range 0-255. SetControlChars may die with a runtime error if an invalid character name is passed or there is an error changing the settings. The list of valid names is the keys of GetControlChars()
This module is available as a LuaRock in http://luarocks.org/repositories/rocks/index.html#readkey so you should be able to install it with the command:
$ su Password: # luarocks install readkey
or:
# luarocks install http://www.pjb.com.au/comp/lua/readkey-1.2-0.rockspec
The Perl module is available from CPAN at http://search.cpan.org/perldoc?Term::ReadKey
20131022 1.2 xwininfo lets GetTerminalSize work even after ReadLine 20131021 K.ReadKey() restarts the P.read() after EINTR interrupt 20131005 1.1 GetTerminalSize returns numbers, ReadMode no longer sets ISTRIP 20130922 1.0 first working version
This Lua module is by Peter Billam, see http://www.pjb.com.au/comp/contact.html
http://search.cpan.org/perldoc?Term::ReadKey http://www.pjb.com.au/comp/lua/readkey.html http://luarocks.org/repositories/rocks/index.html#readkey http://www.pjb.com.au/comp/lua/terminfo.html http://luarocks.org/repositories/rocks/index.html#terminfo http://www.pjb.com.au/comp/lua/readline.html http://luarocks.org/repositories/rocks/index.html#readline http://luarocks.org/repositories/rocks/index.html#luaposix