aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThijs Schreijer <thijs@thijsschreijer.nl>2024-05-22 21:37:27 +0200
committerThijs Schreijer <thijs@thijsschreijer.nl>2024-05-22 21:37:27 +0200
commit2746189f0a504d5929f8aa69edcc116dbbeff105 (patch)
tree2176dde5a3b2a439eef175921c61fc1ec4b1be22
parentb1e250a00406f5268a773f7923bb14708567ce9f (diff)
downloadluasystem-2746189f0a504d5929f8aa69edcc116dbbeff105.tar.gz
luasystem-2746189f0a504d5929f8aa69edcc116dbbeff105.tar.bz2
luasystem-2746189f0a504d5929f8aa69edcc116dbbeff105.zip
add tests for termbackup & termrestore
-rw-r--r--spec/04-term_spec.lua38
-rw-r--r--system/init.lua92
2 files changed, 84 insertions, 46 deletions
diff --git a/spec/04-term_spec.lua b/spec/04-term_spec.lua
index ba58fde..eb975b5 100644
--- a/spec/04-term_spec.lua
+++ b/spec/04-term_spec.lua
@@ -392,13 +392,45 @@ describe("Terminal:", function()
392 392
393 393
394 394
395 pending("termbackup()", function() 395 describe("termbackup() & termrestore()", function()
396 396
397 end) 397 -- this is all Lua code, so testing one platform should be good enough
398 win_it("creates and restores a backup", function()
399 local backup = system.termbackup()
400
401 local old_cp = assert(system.getconsoleoutputcp())
402 finally(function()
403 system.setconsoleoutputcp(old_cp) -- ensure we restore the original one
404 end)
405
406 -- get the console page...
407 local new_cp
408 if old_cp ~= 65001 then
409 new_cp = 65001 -- set to UTF8
410 else
411 new_cp = 850 -- another common one
412 end
398 413
414 -- change the console page...
415 local success, err = system.setconsoleoutputcp(new_cp)
416 assert.is_nil(err)
417 assert.is_true(success)
418 -- ... and check it
419 local updated_cp = assert(system.getconsoleoutputcp())
420 assert.equals(new_cp, updated_cp)
421
422 -- restore the console page
423 system.termrestore(backup)
424 local restored_cp = assert(system.getconsoleoutputcp())
425 assert.equals(old_cp, restored_cp)
426 end)
399 427
400 428
401 pending("termrestore()", function() 429 it("termrestore() fails on bad input", function()
430 assert.has.error(function()
431 system.termrestore("invalid")
432 end, "arg #1 to termrestore, expected backup table, got string")
433 end)
402 434
403 end) 435 end)
404 436
diff --git a/system/init.lua b/system/init.lua
index c232cd2..b9a4f6f 100644
--- a/system/init.lua
+++ b/system/init.lua
@@ -4,61 +4,67 @@
4local sys = require 'system.core' 4local sys = require 'system.core'
5 5
6 6
7do
8 local backup_mt = {}
9
10 --- Returns a backup of terminal setting for stdin/out/err.
11 -- 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.
13 -- @return table with backup of terminal settings
14 function sys.termbackup()
15 local backup = setmetatable({}, backup_mt)
16
17 if sys.isatty(io.stdin) then
18 backup.console_in = sys.getconsoleflags(io.stdin)
19 backup.term_in = sys.tcgetattr(io.stdin)
20 end
21 if sys.isatty(io.stdout) then
22 backup.console_out = sys.getconsoleflags(io.stdout)
23 backup.term_out = sys.tcgetattr(io.stdout)
24 end
25 if sys.isatty(io.stderr) then
26 backup.console_err = sys.getconsoleflags(io.stderr)
27 backup.term_err = sys.tcgetattr(io.stderr)
28 end
7 29
8--- Returns a backup of terminal setting for stdin/out/err. 30 backup.block_in = sys.getnonblock(io.stdin)
9-- Handles terminal/console flags, Windows codepage, and non-block flags on the streams. 31 backup.block_out = sys.getnonblock(io.stdout)
10-- Backs up terminal/console flags only if a stream is a tty. 32 backup.block_err = sys.getnonblock(io.stderr)
11-- @return table with backup of terminal settings
12function sys.termbackup()
13 local backup = {}
14
15 if sys.isatty(io.stdin) then
16 backup.console_in = sys.getconsoleflags(io.stdin)
17 backup.term_in = sys.tcgetattr(io.stdin)
18 end
19 if sys.isatty(io.stdout) then
20 backup.console_out = sys.getconsoleflags(io.stdout)
21 backup.term_out = sys.tcgetattr(io.stdout)
22 end
23 if sys.isatty(io.stderr) then
24 backup.console_err = sys.getconsoleflags(io.stderr)
25 backup.term_err = sys.tcgetattr(io.stderr)
26 end
27 33
28 backup.block_in = sys.getnonblock(io.stdin) 34 backup.consoleoutcodepage = sys.getconsoleoutputcp()
29 backup.block_out = sys.getnonblock(io.stdout) 35 backup.consolecp = sys.getconsolecp()
30 backup.block_err = sys.getnonblock(io.stderr)
31 36
32 backup.consoleoutcodepage = sys.getconsoleoutputcp() 37 return backup
33 backup.consolecp = sys.getconsolecp() 38 end
34 39
35 return backup
36end
37 40
38 41
42 --- Restores terminal settings from a backup
43 -- @tparam table backup the backup of terminal settings, see `termbackup`.
44 -- @treturn boolean true
45 function sys.termrestore(backup)
46 if getmetatable(backup) ~= backup_mt then
47 error("arg #1 to termrestore, expected backup table, got " .. type(backup), 2)
48 end
39 49
40--- Restores terminal settings from a backup 50 if backup.console_in then sys.setconsoleflags(io.stdin, backup.console_in) end
41-- @tparam table backup the backup of terminal settings, see `termbackup`. 51 if backup.term_in then sys.tcsetattr(io.stdin, sys.TCSANOW, backup.term_in) end
42-- @treturn boolean true 52 if backup.console_out then sys.setconsoleflags(io.stdout, backup.console_out) end
43function sys.termrestore(backup) 53 if backup.term_out then sys.tcsetattr(io.stdout, sys.TCSANOW, backup.term_out) end
44 if backup.console_in then sys.setconsoleflags(io.stdin, backup.console_in) end 54 if backup.console_err then sys.setconsoleflags(io.stderr, backup.console_err) end
45 if backup.term_in then sys.tcsetattr(io.stdin, sys.TCSANOW, backup.term_in) end 55 if backup.term_err then sys.tcsetattr(io.stderr, sys.TCSANOW, backup.term_err) end
46 if backup.console_out then sys.setconsoleflags(io.stdout, backup.console_out) end
47 if backup.term_out then sys.tcsetattr(io.stdout, sys.TCSANOW, backup.term_out) end
48 if backup.console_err then sys.setconsoleflags(io.stderr, backup.console_err) end
49 if backup.term_err then sys.tcsetattr(io.stderr, sys.TCSANOW, backup.term_err) end
50 56
51 if backup.block_in ~= nil then sys.setnonblock(io.stdin, backup.block_in) end 57 if backup.block_in ~= nil then sys.setnonblock(io.stdin, backup.block_in) end
52 if backup.block_out ~= nil then sys.setnonblock(io.stdout, backup.block_out) end 58 if backup.block_out ~= nil then sys.setnonblock(io.stdout, backup.block_out) end
53 if backup.block_err ~= nil then sys.setnonblock(io.stderr, backup.block_err) end 59 if backup.block_err ~= nil then sys.setnonblock(io.stderr, backup.block_err) end
54 60
55 if backup.consoleoutcodepage then sys.setconsoleoutputcp(backup.consoleoutcodepage) end 61 if backup.consoleoutcodepage then sys.setconsoleoutputcp(backup.consoleoutcodepage) end
56 if backup.consolecp then sys.setconsolecp(backup.consolecp) end 62 if backup.consolecp then sys.setconsolecp(backup.consolecp) end
57 return true 63 return true
64 end
58end 65end
59 66
60 67
61
62do -- autotermrestore 68do -- autotermrestore
63 local global_backup -- global backup for terminal settings 69 local global_backup -- global backup for terminal settings
64 70