Skip to content

Instantly share code, notes, and snippets.

@Be1zebub
Created July 18, 2024 21:56
Show Gist options
  • Save Be1zebub/3848ab1e3e4ac1a67f1bf4a46508ebed to your computer and use it in GitHub Desktop.
Save Be1zebub/3848ab1e3e4ac1a67f1bf4a46508ebed to your computer and use it in GitHub Desktop.
Функция для получения размера терминала. Я использую её для создания cli-ui
local ffi = require("ffi")
local terminalSize
if package.config:sub(1, 1) == "\\" then -- windows
local kernel32 = ffi.load("kernel32")
ffi.cdef([[
typedef struct _CONSOLE_SCREEN_BUFFER_INFO {
uint16_t dwSizeX;
uint16_t dwSizeY;
uint16_t dwCursorPositionX;
uint16_t dwCursorPositionY;
uint16_t wAttributes;
uint16_t srWindowLeft;
uint16_t srWindowTop;
uint16_t srWindowRight;
uint16_t srWindowBottom;
uint16_t dwMaximumWindowSizeX;
uint16_t dwMaximumWindowSizeY;
} CONSOLE_SCREEN_BUFFER_INFO;
bool GetConsoleScreenBufferInfo(void* hConsoleOutput, CONSOLE_SCREEN_BUFFER_INFO* lpConsoleScreenBufferInfo);
void* GetStdHandle(uint32_t nStdHandle);
]])
local STD_OUTPUT_HANDLE = -11
local hConsole = kernel32.GetStdHandle(STD_OUTPUT_HANDLE)
local csbi = ffi.new("CONSOLE_SCREEN_BUFFER_INFO")
function terminalSize()
if kernel32.GetConsoleScreenBufferInfo(hConsole, csbi) then
return csbi.dwSizeX, csbi.dwSizeY
end
return 80, 24 -- fallback
end
else -- linux
ffi.cdef([[
typedef struct {
unsigned short ws_row;
unsigned short ws_col;
unsigned short ws_xpixel;
unsigned short ws_ypixel;
} winsize;
int ioctl(int fd, unsigned long request, ...);
]])
local TIOCGWINSZ = 0x5413
function terminalSize()
local ws = ffi.new("winsize")
ffi.C.ioctl(0, TIOCGWINSZ, ws)
return ws.ws_col, ws.ws_row
end
end
local lib = setmetatable({
test = function()
local w, h = terminalSize()
print("terminal size: ".. w ..", ".. h)
local sleep = require("timer").sleep
local delay = 2 / h * 1000
local base = "progress [%s] ETA: null | %s/".. h
local max_wide = w - #base - 4 - 3
for y = 1, h do
local wide = math.floor(y / h * max_wide)
print(base:format(string.rep("=", wide) .. string.rep("-", max_wide - wide), y))
sleep(delay)
end
end
}, {__call = terminalSize})
-- lib.test()
return lib
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment