diff options
-rw-r--r-- | config.ld | 1 | ||||
-rw-r--r-- | examples/read.lua | 2 | ||||
-rw-r--r-- | src/environment.c | 6 | ||||
-rw-r--r-- | src/random.c | 7 | ||||
-rw-r--r-- | src/term.c | 5 | ||||
-rw-r--r-- | src/time.c | 6 | ||||
-rw-r--r-- | system/init.lua | 103 |
7 files changed, 75 insertions, 55 deletions
@@ -14,3 +14,4 @@ dir='docs' | |||
14 | sort=true | 14 | sort=true |
15 | sort_modules=true | 15 | sort_modules=true |
16 | all=false | 16 | all=false |
17 | merge=true | ||
diff --git a/examples/read.lua b/examples/read.lua index bd5cbff..4b57b54 100644 --- a/examples/read.lua +++ b/examples/read.lua | |||
@@ -37,7 +37,7 @@ while true do | |||
37 | if key == "A" then io.write(get_cursor_pos); io.flush() end | 37 | if key == "A" then io.write(get_cursor_pos); io.flush() end |
38 | 38 | ||
39 | -- check if we got a key or ANSI sequence | 39 | -- check if we got a key or ANSI sequence |
40 | if keytype == "key" then | 40 | if keytype == "char" then |
41 | -- just a key | 41 | -- just a key |
42 | local b = key:byte() | 42 | local b = key:byte() |
43 | if b < 32 then | 43 | if b < 32 then |
diff --git a/src/environment.c b/src/environment.c index 5f1c3da..ab5dd92 100644 --- a/src/environment.c +++ b/src/environment.c | |||
@@ -1,4 +1,8 @@ | |||
1 | /// @submodule system | 1 | /// @module system |
2 | |||
3 | /// Environment. | ||
4 | // @section environment | ||
5 | |||
2 | #include <lua.h> | 6 | #include <lua.h> |
3 | #include <lauxlib.h> | 7 | #include <lauxlib.h> |
4 | #include "compat.h" | 8 | #include "compat.h" |
diff --git a/src/random.c b/src/random.c index 90fb3f2..e55461a 100644 --- a/src/random.c +++ b/src/random.c | |||
@@ -1,4 +1,9 @@ | |||
1 | /// @submodule system | 1 | /// @module system |
2 | |||
3 | /// Random. | ||
4 | // @section random | ||
5 | |||
6 | |||
2 | #include <lua.h> | 7 | #include <lua.h> |
3 | #include <lauxlib.h> | 8 | #include <lauxlib.h> |
4 | #include "compat.h" | 9 | #include "compat.h" |
@@ -1,7 +1,10 @@ | |||
1 | /// @submodule system | 1 | /// @module system |
2 | 2 | ||
3 | /// Terminal. | ||
3 | // Unix: see https://blog.nelhage.com/2009/12/a-brief-introduction-to-termios-termios3-and-stty/ | 4 | // Unix: see https://blog.nelhage.com/2009/12/a-brief-introduction-to-termios-termios3-and-stty/ |
5 | // | ||
4 | // Windows: see https://learn.microsoft.com/en-us/windows/console/console-reference | 6 | // Windows: see https://learn.microsoft.com/en-us/windows/console/console-reference |
7 | // @section terminal | ||
5 | 8 | ||
6 | #include <lua.h> | 9 | #include <lua.h> |
7 | #include <lauxlib.h> | 10 | #include <lauxlib.h> |
@@ -1,4 +1,8 @@ | |||
1 | /// @submodule system | 1 | /// @module system |
2 | |||
3 | /// Time. | ||
4 | // @section time | ||
5 | |||
2 | #include <lua.h> | 6 | #include <lua.h> |
3 | #include <lauxlib.h> | 7 | #include <lauxlib.h> |
4 | 8 | ||
diff --git a/system/init.lua b/system/init.lua index 8049167..eee8bf6 100644 --- a/system/init.lua +++ b/system/init.lua | |||
@@ -1,7 +1,10 @@ | |||
1 | --- Lua System Library. | 1 | --- Lua System Library. |
2 | -- @module init | 2 | -- @module system |
3 | 3 | ||
4 | local sys = require 'system.core' | 4 | --- Terminal |
5 | -- @section terminal | ||
6 | |||
7 | local system = require 'system.core' | ||
5 | 8 | ||
6 | 9 | ||
7 | do | 10 | do |
@@ -11,28 +14,28 @@ do | |||
11 | -- Handles terminal/console flags, Windows codepage, and non-block flags on the streams. | 14 | -- Handles terminal/console flags, Windows codepage, and non-block flags on the streams. |
12 | -- Backs up terminal/console flags only if a stream is a tty. | 15 | -- Backs up terminal/console flags only if a stream is a tty. |
13 | -- @return table with backup of terminal settings | 16 | -- @return table with backup of terminal settings |
14 | function sys.termbackup() | 17 | function system.termbackup() |
15 | local backup = setmetatable({}, backup_mt) | 18 | local backup = setmetatable({}, backup_mt) |
16 | 19 | ||
17 | if sys.isatty(io.stdin) then | 20 | if system.isatty(io.stdin) then |
18 | backup.console_in = sys.getconsoleflags(io.stdin) | 21 | backup.console_in = system.getconsoleflags(io.stdin) |
19 | backup.term_in = sys.tcgetattr(io.stdin) | 22 | backup.term_in = system.tcgetattr(io.stdin) |
20 | end | 23 | end |
21 | if sys.isatty(io.stdout) then | 24 | if system.isatty(io.stdout) then |
22 | backup.console_out = sys.getconsoleflags(io.stdout) | 25 | backup.console_out = system.getconsoleflags(io.stdout) |
23 | backup.term_out = sys.tcgetattr(io.stdout) | 26 | backup.term_out = system.tcgetattr(io.stdout) |
24 | end | 27 | end |
25 | if sys.isatty(io.stderr) then | 28 | if system.isatty(io.stderr) then |
26 | backup.console_err = sys.getconsoleflags(io.stderr) | 29 | backup.console_err = system.getconsoleflags(io.stderr) |
27 | backup.term_err = sys.tcgetattr(io.stderr) | 30 | backup.term_err = system.tcgetattr(io.stderr) |
28 | end | 31 | end |
29 | 32 | ||
30 | backup.block_in = sys.getnonblock(io.stdin) | 33 | backup.block_in = system.getnonblock(io.stdin) |
31 | backup.block_out = sys.getnonblock(io.stdout) | 34 | backup.block_out = system.getnonblock(io.stdout) |
32 | backup.block_err = sys.getnonblock(io.stderr) | 35 | backup.block_err = system.getnonblock(io.stderr) |
33 | 36 | ||
34 | backup.consoleoutcodepage = sys.getconsoleoutputcp() | 37 | backup.consoleoutcodepage = system.getconsoleoutputcp() |
35 | backup.consolecp = sys.getconsolecp() | 38 | backup.consolecp = system.getconsolecp() |
36 | 39 | ||
37 | return backup | 40 | return backup |
38 | end | 41 | end |
@@ -42,24 +45,24 @@ do | |||
42 | --- Restores terminal settings from a backup | 45 | --- Restores terminal settings from a backup |
43 | -- @tparam table backup the backup of terminal settings, see `termbackup`. | 46 | -- @tparam table backup the backup of terminal settings, see `termbackup`. |
44 | -- @treturn boolean true | 47 | -- @treturn boolean true |
45 | function sys.termrestore(backup) | 48 | function system.termrestore(backup) |
46 | if getmetatable(backup) ~= backup_mt then | 49 | if getmetatable(backup) ~= backup_mt then |
47 | error("arg #1 to termrestore, expected backup table, got " .. type(backup), 2) | 50 | error("arg #1 to termrestore, expected backup table, got " .. type(backup), 2) |
48 | end | 51 | end |
49 | 52 | ||
50 | if backup.console_in then sys.setconsoleflags(io.stdin, backup.console_in) end | 53 | if backup.console_in then system.setconsoleflags(io.stdin, backup.console_in) end |
51 | if backup.term_in then sys.tcsetattr(io.stdin, sys.TCSANOW, backup.term_in) end | 54 | if backup.term_in then system.tcsetattr(io.stdin, system.TCSANOW, backup.term_in) end |
52 | if backup.console_out then sys.setconsoleflags(io.stdout, backup.console_out) end | 55 | if backup.console_out then system.setconsoleflags(io.stdout, backup.console_out) end |
53 | if backup.term_out then sys.tcsetattr(io.stdout, sys.TCSANOW, backup.term_out) end | 56 | if backup.term_out then system.tcsetattr(io.stdout, system.TCSANOW, backup.term_out) end |
54 | if backup.console_err then sys.setconsoleflags(io.stderr, backup.console_err) end | 57 | if backup.console_err then system.setconsoleflags(io.stderr, backup.console_err) end |
55 | if backup.term_err then sys.tcsetattr(io.stderr, sys.TCSANOW, backup.term_err) end | 58 | if backup.term_err then system.tcsetattr(io.stderr, system.TCSANOW, backup.term_err) end |
56 | 59 | ||
57 | if backup.block_in ~= nil then sys.setnonblock(io.stdin, backup.block_in) end | 60 | if backup.block_in ~= nil then system.setnonblock(io.stdin, backup.block_in) end |
58 | if backup.block_out ~= nil then sys.setnonblock(io.stdout, backup.block_out) end | 61 | if backup.block_out ~= nil then system.setnonblock(io.stdout, backup.block_out) end |
59 | if backup.block_err ~= nil then sys.setnonblock(io.stderr, backup.block_err) end | 62 | if backup.block_err ~= nil then system.setnonblock(io.stderr, backup.block_err) end |
60 | 63 | ||
61 | if backup.consoleoutcodepage then sys.setconsoleoutputcp(backup.consoleoutcodepage) end | 64 | if backup.consoleoutcodepage then system.setconsoleoutputcp(backup.consoleoutcodepage) end |
62 | if backup.consolecp then sys.setconsolecp(backup.consolecp) end | 65 | if backup.consolecp then system.setconsolecp(backup.consolecp) end |
63 | return true | 66 | return true |
64 | end | 67 | end |
65 | end | 68 | end |
@@ -107,13 +110,13 @@ do -- autotermrestore | |||
107 | -- @treturn[1] boolean true | 110 | -- @treturn[1] boolean true |
108 | -- @treturn[2] nil if the backup was already created | 111 | -- @treturn[2] nil if the backup was already created |
109 | -- @treturn[2] string error message | 112 | -- @treturn[2] string error message |
110 | function sys.autotermrestore() | 113 | function system.autotermrestore() |
111 | if global_backup then | 114 | if global_backup then |
112 | return nil, "global terminal backup was already set up" | 115 | return nil, "global terminal backup was already set up" |
113 | end | 116 | end |
114 | global_backup = sys.termbackup() | 117 | global_backup = system.termbackup() |
115 | add_gc_method(global_backup, function(self) | 118 | add_gc_method(global_backup, function(self) |
116 | sys.termrestore(self) end) | 119 | system.termrestore(self) end) |
117 | return true | 120 | return true |
118 | end | 121 | end |
119 | end | 122 | end |
@@ -129,15 +132,15 @@ do | |||
129 | -- Calls `termbackup` before calling the function and `termrestore` after. | 132 | -- Calls `termbackup` before calling the function and `termrestore` after. |
130 | -- @tparam function f function to wrap | 133 | -- @tparam function f function to wrap |
131 | -- @treturn function wrapped function | 134 | -- @treturn function wrapped function |
132 | function sys.termwrap(f) | 135 | function system.termwrap(f) |
133 | if type(f) ~= "function" then | 136 | if type(f) ~= "function" then |
134 | error("arg #1 to wrap, expected function, got " .. type(f), 2) | 137 | error("arg #1 to wrap, expected function, got " .. type(f), 2) |
135 | end | 138 | end |
136 | 139 | ||
137 | return function(...) | 140 | return function(...) |
138 | local bu = sys.termbackup() | 141 | local bu = system.termbackup() |
139 | local results = pack(f(...)) | 142 | local results = pack(f(...)) |
140 | sys.termrestore(bu) | 143 | system.termrestore(bu) |
141 | return unpack(results) | 144 | return unpack(results) |
142 | end | 145 | end |
143 | end | 146 | end |
@@ -152,7 +155,7 @@ end | |||
152 | -- system.listconsoleflags(io.stdin) | 155 | -- system.listconsoleflags(io.stdin) |
153 | -- system.listconsoleflags(io.stdout) | 156 | -- system.listconsoleflags(io.stdout) |
154 | -- system.listconsoleflags(io.stderr) | 157 | -- system.listconsoleflags(io.stderr) |
155 | function sys.listconsoleflags(fh) | 158 | function system.listconsoleflags(fh) |
156 | local flagtype | 159 | local flagtype |
157 | if fh == io.stdin then | 160 | if fh == io.stdin then |
158 | print "------ STDIN FLAGS WINDOWS ------" | 161 | print "------ STDIN FLAGS WINDOWS ------" |
@@ -165,7 +168,7 @@ function sys.listconsoleflags(fh) | |||
165 | flagtype = "COF_" | 168 | flagtype = "COF_" |
166 | end | 169 | end |
167 | 170 | ||
168 | local flags = assert(sys.getconsoleflags(fh)) | 171 | local flags = assert(system.getconsoleflags(fh)) |
169 | local out = {} | 172 | local out = {} |
170 | for k,v in pairs(sys) do | 173 | for k,v in pairs(sys) do |
171 | if type(k) == "string" and k:sub(1,4) == flagtype then | 174 | if type(k) == "string" and k:sub(1,4) == flagtype then |
@@ -191,7 +194,7 @@ end | |||
191 | -- system.listconsoleflags(io.stdin) | 194 | -- system.listconsoleflags(io.stdin) |
192 | -- system.listconsoleflags(io.stdout) | 195 | -- system.listconsoleflags(io.stdout) |
193 | -- system.listconsoleflags(io.stderr) | 196 | -- system.listconsoleflags(io.stderr) |
194 | function sys.listtermflags(fh) | 197 | function system.listtermflags(fh) |
195 | if fh == io.stdin then | 198 | if fh == io.stdin then |
196 | print "------ STDIN FLAGS POSIX ------" | 199 | print "------ STDIN FLAGS POSIX ------" |
197 | elseif fh == io.stdout then | 200 | elseif fh == io.stdout then |
@@ -200,7 +203,7 @@ function sys.listtermflags(fh) | |||
200 | print "------ STDERR FLAGS POSIX ------" | 203 | print "------ STDERR FLAGS POSIX ------" |
201 | end | 204 | end |
202 | 205 | ||
203 | local flags = assert(sys.tcgetattr(fh)) | 206 | local flags = assert(system.tcgetattr(fh)) |
204 | for _, flagtype in ipairs { "iflag", "oflag", "lflag" } do | 207 | for _, flagtype in ipairs { "iflag", "oflag", "lflag" } do |
205 | local prefix = flagtype:sub(1,1):upper() .. "_" -- I_, O_, or L_, the constant prefixes | 208 | local prefix = flagtype:sub(1,1):upper() .. "_" -- I_, O_, or L_, the constant prefixes |
206 | local out = {} | 209 | local out = {} |
@@ -234,18 +237,18 @@ do | |||
234 | -- @treturn[1] byte the byte value that was read. | 237 | -- @treturn[1] byte the byte value that was read. |
235 | -- @treturn[2] nil if no key was read | 238 | -- @treturn[2] nil if no key was read |
236 | -- @treturn[2] string error message; `"timeout"` if the timeout was reached. | 239 | -- @treturn[2] string error message; `"timeout"` if the timeout was reached. |
237 | function sys.readkey(timeout) | 240 | function system.readkey(timeout) |
238 | if type(timeout) ~= "number" then | 241 | if type(timeout) ~= "number" then |
239 | error("arg #1 to readkey, expected timeout in seconds, got " .. type(timeout), 2) | 242 | error("arg #1 to readkey, expected timeout in seconds, got " .. type(timeout), 2) |
240 | end | 243 | end |
241 | 244 | ||
242 | local interval = 0.0125 | 245 | local interval = 0.0125 |
243 | local key = sys._readkey() | 246 | local key = system._readkey() |
244 | while key == nil and timeout > 0 do | 247 | while key == nil and timeout > 0 do |
245 | sys.sleep(math.min(interval, timeout)) | 248 | system.sleep(math.min(interval, timeout)) |
246 | timeout = timeout - interval | 249 | timeout = timeout - interval |
247 | interval = math.min(0.2, interval * 2) | 250 | interval = math.min(0.2, interval * 2) |
248 | key = sys._readkey() | 251 | key = system._readkey() |
249 | end | 252 | end |
250 | 253 | ||
251 | if key then | 254 | if key then |
@@ -275,7 +278,7 @@ do | |||
275 | -- @treturn[2] nil in case of an error | 278 | -- @treturn[2] nil in case of an error |
276 | -- @treturn[2] string error message; `"timeout"` if the timeout was reached. | 279 | -- @treturn[2] string error message; `"timeout"` if the timeout was reached. |
277 | -- @treturn[2] string partial result in case of an error while reading a sequence, the sequence so far. | 280 | -- @treturn[2] string partial result in case of an error while reading a sequence, the sequence so far. |
278 | function sys.readansi(timeout) | 281 | function system.readansi(timeout) |
279 | if type(timeout) ~= "number" then | 282 | if type(timeout) ~= "number" then |
280 | error("arg #1 to readansi, expected timeout in seconds, got " .. type(timeout), 2) | 283 | error("arg #1 to readansi, expected timeout in seconds, got " .. type(timeout), 2) |
281 | end | 284 | end |
@@ -292,7 +295,7 @@ do | |||
292 | else | 295 | else |
293 | -- read a new key | 296 | -- read a new key |
294 | local err | 297 | local err |
295 | key, err = sys.readkey(timeout) | 298 | key, err = system.readkey(timeout) |
296 | if key == nil then -- timeout or error | 299 | if key == nil then -- timeout or error |
297 | return nil, err | 300 | return nil, err |
298 | end | 301 | end |
@@ -301,7 +304,7 @@ do | |||
301 | if key == 27 then | 304 | if key == 27 then |
302 | -- looks like an ansi escape sequence, immediately read next char | 305 | -- looks like an ansi escape sequence, immediately read next char |
303 | -- as an heuristic against manually typing escape sequences | 306 | -- as an heuristic against manually typing escape sequences |
304 | local key2 = sys.readkey(0) | 307 | local key2 = system.readkey(0) |
305 | if key2 ~= 91 and key2 ~= 79 then -- we expect either "[" or "O" for an ANSI sequence | 308 | if key2 ~= 91 and key2 ~= 79 then -- we expect either "[" or "O" for an ANSI sequence |
306 | -- not the expected [ or O character, so we return the key as is | 309 | -- not the expected [ or O character, so we return the key as is |
307 | -- and store the extra key read for the next call | 310 | -- and store the extra key read for the next call |
@@ -328,9 +331,9 @@ do | |||
328 | local err | 331 | local err |
329 | if utf8_length then | 332 | if utf8_length then |
330 | -- read remainder of UTF8 sequence | 333 | -- read remainder of UTF8 sequence |
331 | local timeout_end = sys.gettime() + timeout | 334 | local timeout_end = system.gettime() + timeout |
332 | while true do | 335 | while true do |
333 | key, err = sys.readkey(timeout_end - sys.gettime()) | 336 | key, err = system.readkey(timeout_end - system.gettime()) |
334 | if err then | 337 | if err then |
335 | break | 338 | break |
336 | end | 339 | end |
@@ -347,9 +350,9 @@ do | |||
347 | 350 | ||
348 | else | 351 | else |
349 | -- read remainder of ANSI sequence | 352 | -- read remainder of ANSI sequence |
350 | local timeout_end = sys.gettime() + timeout | 353 | local timeout_end = system.gettime() + timeout |
351 | while true do | 354 | while true do |
352 | key, err = sys.readkey(timeout_end - sys.gettime()) | 355 | key, err = system.readkey(timeout_end - system.gettime()) |
353 | if err then | 356 | if err then |
354 | break | 357 | break |
355 | end | 358 | end |