aboutsummaryrefslogtreecommitdiff
path: root/system
diff options
context:
space:
mode:
Diffstat (limited to 'system')
-rw-r--r--system/init.lua53
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
269do 269do
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