Created
July 18, 2024 21:56
-
-
Save Be1zebub/3848ab1e3e4ac1a67f1bf4a46508ebed to your computer and use it in GitHub Desktop.
Функция для получения размера терминала. Я использую её для создания cli-ui
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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