diff options
Diffstat (limited to 'system')
-rw-r--r-- | system/init.lua | 53 |
1 files changed, 34 insertions, 19 deletions
diff --git a/system/init.lua b/system/init.lua index 28fe65c..e0e5f21 100644 --- a/system/init.lua +++ b/system/init.lua | |||
@@ -267,7 +267,6 @@ end | |||
267 | 267 | ||
268 | 268 | ||
269 | do | 269 | do |
270 | local left_over_key | ||
271 | local sequence -- table to store the sequence in progress | 270 | local sequence -- table to store the sequence in progress |
272 | local utf8_length -- length of utf8 sequence currently being processed | 271 | local utf8_length -- length of utf8 sequence currently being processed |
273 | local unpack = unpack or table.unpack | 272 | local unpack = unpack or table.unpack |
@@ -285,6 +284,8 @@ do | |||
285 | -- @treturn[2] nil in case of an error | 284 | -- @treturn[2] nil in case of an error |
286 | -- @treturn[2] string error message; `"timeout"` if the timeout was reached. | 285 | -- @treturn[2] string error message; `"timeout"` if the timeout was reached. |
287 | -- @treturn[2] string partial result in case of an error while reading a sequence, the sequence so far. | 286 | -- @treturn[2] string partial result in case of an error while reading a sequence, the sequence so far. |
287 | -- The function retains its own internal buffer, so on the next call the incomplete buffer is used to | ||
288 | -- complete the sequence. | ||
288 | function system.readansi(timeout, fsleep) | 289 | function system.readansi(timeout, fsleep) |
289 | if type(timeout) ~= "number" then | 290 | if type(timeout) ~= "number" then |
290 | error("arg #1 to readansi, expected timeout in seconds, got " .. type(timeout), 2) | 291 | error("arg #1 to readansi, expected timeout in seconds, got " .. type(timeout), 2) |
@@ -295,33 +296,47 @@ do | |||
295 | 296 | ||
296 | if not sequence then | 297 | if not sequence then |
297 | -- no sequence in progress, read a key | 298 | -- no sequence in progress, read a key |
298 | 299 | local err | |
299 | if left_over_key then | 300 | key, err = system.readkey(timeout, fsleep) |
300 | -- we still have a cached key from the last call | 301 | if key == nil then -- timeout or error |
301 | key = left_over_key | 302 | return nil, err |
302 | left_over_key = nil | ||
303 | else | ||
304 | -- read a new key | ||
305 | local err | ||
306 | key, err = system.readkey(timeout, fsleep) | ||
307 | if key == nil then -- timeout or error | ||
308 | return nil, err | ||
309 | end | ||
310 | end | 303 | end |
311 | 304 | ||
312 | if key == 27 then | 305 | if key == 27 then |
313 | -- looks like an ansi escape sequence, immediately read next char | 306 | -- looks like an ansi escape sequence, immediately read next char |
314 | -- as an heuristic against manually typing escape sequences | 307 | -- as an heuristic against manually typing escape sequences |
315 | local key2 = system.readkey(0, fsleep) | 308 | local key2 = system.readkey(0, fsleep) |
316 | if key2 ~= 91 and key2 ~= 79 then -- we expect either "[" or "O" for an ANSI sequence | 309 | if key2 == nil then |
317 | -- not the expected [ or O character, so we return the key as is | 310 | -- no key available, return the escape key, on its own |
318 | -- and store the extra key read for the next call | 311 | sequence = nil |
319 | left_over_key = key2 | ||
320 | return string.char(key), "char" | 312 | return string.char(key), "char" |
313 | |||
314 | elseif key2 == 91 then | ||
315 | -- "[" means it is for sure an ANSI sequence | ||
316 | sequence = { key, key2 } | ||
317 | |||
318 | elseif key2 == 79 then | ||
319 | -- "O" means it is either an ANSI sequence or just an <alt>+O key stroke | ||
320 | -- check if there is yet another byte available | ||
321 | local key3 = system.readkey(0, fsleep) | ||
322 | if key3 == nil then | ||
323 | -- no key available, return the <alt>O key stroke, report as ANSI | ||
324 | sequence = nil | ||
325 | return string.char(key, key2), "ansi" | ||
326 | end | ||
327 | -- it's an ANSI sequence, marked with <ESC>O | ||
328 | if (key3 >= 65 and key3 <= 90) or (key3 >= 97 and key3 <= 126) then | ||
329 | -- end of sequence, return the full sequence | ||
330 | return string.char(key, key2, key3), "ansi" | ||
331 | end | ||
332 | sequence = { key, key2, key3 } | ||
333 | |||
334 | else | ||
335 | -- not an ANSI sequence, but an <alt>+<key2> key stroke, so report as ANSI | ||
336 | sequence = nil | ||
337 | return string.char(key, key2), "ansi" | ||
321 | end | 338 | end |
322 | 339 | ||
323 | -- escape sequence detected | ||
324 | sequence = { key, key2 } | ||
325 | else | 340 | else |
326 | -- check UTF8 length | 341 | -- check UTF8 length |
327 | utf8_length = key < 128 and 1 or key < 224 and 2 or key < 240 and 3 or key < 248 and 4 | 342 | utf8_length = key < 128 and 1 or key < 224 and 2 or key < 240 and 3 or key < 248 and 4 |