Skip to content

Commit

Permalink
add tests for termbackup & termrestore
Browse files Browse the repository at this point in the history
  • Loading branch information
Tieske committed May 22, 2024
1 parent b1e250a commit 2746189
Show file tree
Hide file tree
Showing 2 changed files with 84 additions and 46 deletions.
38 changes: 35 additions & 3 deletions spec/04-term_spec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -392,13 +392,45 @@ describe("Terminal:", function()



pending("termbackup()", function()
describe("termbackup() & termrestore()", function()

end)
-- this is all Lua code, so testing one platform should be good enough
win_it("creates and restores a backup", function()
local backup = system.termbackup()

local old_cp = assert(system.getconsoleoutputcp())
finally(function()
system.setconsoleoutputcp(old_cp) -- ensure we restore the original one
end)

-- get the console page...
local new_cp
if old_cp ~= 65001 then
new_cp = 65001 -- set to UTF8
else
new_cp = 850 -- another common one
end

-- change the console page...
local success, err = system.setconsoleoutputcp(new_cp)
assert.is_nil(err)
assert.is_true(success)
-- ... and check it
local updated_cp = assert(system.getconsoleoutputcp())
assert.equals(new_cp, updated_cp)

-- restore the console page
system.termrestore(backup)
local restored_cp = assert(system.getconsoleoutputcp())
assert.equals(old_cp, restored_cp)
end)


pending("termrestore()", function()
it("termrestore() fails on bad input", function()
assert.has.error(function()
system.termrestore("invalid")
end, "arg #1 to termrestore, expected backup table, got string")
end)

end)

Expand Down
92 changes: 49 additions & 43 deletions system/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -4,61 +4,67 @@
local sys = require 'system.core'


do
local backup_mt = {}

--- Returns a backup of terminal setting for stdin/out/err.
-- Handles terminal/console flags, Windows codepage, and non-block flags on the streams.
-- Backs up terminal/console flags only if a stream is a tty.
-- @return table with backup of terminal settings
function sys.termbackup()
local backup = setmetatable({}, backup_mt)

if sys.isatty(io.stdin) then
backup.console_in = sys.getconsoleflags(io.stdin)
backup.term_in = sys.tcgetattr(io.stdin)
end
if sys.isatty(io.stdout) then
backup.console_out = sys.getconsoleflags(io.stdout)
backup.term_out = sys.tcgetattr(io.stdout)
end
if sys.isatty(io.stderr) then
backup.console_err = sys.getconsoleflags(io.stderr)
backup.term_err = sys.tcgetattr(io.stderr)
end

--- Returns a backup of terminal setting for stdin/out/err.
-- Handles terminal/console flags, Windows codepage, and non-block flags on the streams.
-- Backs up terminal/console flags only if a stream is a tty.
-- @return table with backup of terminal settings
function sys.termbackup()
local backup = {}

if sys.isatty(io.stdin) then
backup.console_in = sys.getconsoleflags(io.stdin)
backup.term_in = sys.tcgetattr(io.stdin)
end
if sys.isatty(io.stdout) then
backup.console_out = sys.getconsoleflags(io.stdout)
backup.term_out = sys.tcgetattr(io.stdout)
end
if sys.isatty(io.stderr) then
backup.console_err = sys.getconsoleflags(io.stderr)
backup.term_err = sys.tcgetattr(io.stderr)
end
backup.block_in = sys.getnonblock(io.stdin)
backup.block_out = sys.getnonblock(io.stdout)
backup.block_err = sys.getnonblock(io.stderr)

backup.block_in = sys.getnonblock(io.stdin)
backup.block_out = sys.getnonblock(io.stdout)
backup.block_err = sys.getnonblock(io.stderr)
backup.consoleoutcodepage = sys.getconsoleoutputcp()
backup.consolecp = sys.getconsolecp()

backup.consoleoutcodepage = sys.getconsoleoutputcp()
backup.consolecp = sys.getconsolecp()
return backup
end

return backup
end


--- Restores terminal settings from a backup
-- @tparam table backup the backup of terminal settings, see `termbackup`.
-- @treturn boolean true
function sys.termrestore(backup)
if getmetatable(backup) ~= backup_mt then
error("arg #1 to termrestore, expected backup table, got " .. type(backup), 2)
end

--- Restores terminal settings from a backup
-- @tparam table backup the backup of terminal settings, see `termbackup`.
-- @treturn boolean true
function sys.termrestore(backup)
if backup.console_in then sys.setconsoleflags(io.stdin, backup.console_in) end
if backup.term_in then sys.tcsetattr(io.stdin, sys.TCSANOW, backup.term_in) end
if backup.console_out then sys.setconsoleflags(io.stdout, backup.console_out) end
if backup.term_out then sys.tcsetattr(io.stdout, sys.TCSANOW, backup.term_out) end
if backup.console_err then sys.setconsoleflags(io.stderr, backup.console_err) end
if backup.term_err then sys.tcsetattr(io.stderr, sys.TCSANOW, backup.term_err) end
if backup.console_in then sys.setconsoleflags(io.stdin, backup.console_in) end
if backup.term_in then sys.tcsetattr(io.stdin, sys.TCSANOW, backup.term_in) end
if backup.console_out then sys.setconsoleflags(io.stdout, backup.console_out) end
if backup.term_out then sys.tcsetattr(io.stdout, sys.TCSANOW, backup.term_out) end
if backup.console_err then sys.setconsoleflags(io.stderr, backup.console_err) end
if backup.term_err then sys.tcsetattr(io.stderr, sys.TCSANOW, backup.term_err) end

if backup.block_in ~= nil then sys.setnonblock(io.stdin, backup.block_in) end
if backup.block_out ~= nil then sys.setnonblock(io.stdout, backup.block_out) end
if backup.block_err ~= nil then sys.setnonblock(io.stderr, backup.block_err) end
if backup.block_in ~= nil then sys.setnonblock(io.stdin, backup.block_in) end
if backup.block_out ~= nil then sys.setnonblock(io.stdout, backup.block_out) end
if backup.block_err ~= nil then sys.setnonblock(io.stderr, backup.block_err) end

if backup.consoleoutcodepage then sys.setconsoleoutputcp(backup.consoleoutcodepage) end
if backup.consolecp then sys.setconsolecp(backup.consolecp) end
return true
if backup.consoleoutcodepage then sys.setconsoleoutputcp(backup.consoleoutcodepage) end
if backup.consolecp then sys.setconsolecp(backup.consolecp) end
return true
end
end



do -- autotermrestore
local global_backup -- global backup for terminal settings

Expand Down

0 comments on commit 2746189

Please sign in to comment.