콘텐츠로 이동

TTY

원시 입력 이벤트, 스타일이 적용된 출력, 레이아웃 유틸리티를 위한 터미널 UI 모듈입니다.

이 모듈은 터미널 컨텍스트 내에서만 작동합니다. 일반 함수에서 사용할 수 없으며 — Terminal Host에서 실행되는 프로세스에서만 사용할 수 있습니다.
local tty = require("tty")

원시 입력 리더를 시작하고, 이벤트를 구독하고, 루프에서 처리합니다:

local tty = require("tty")
local io = require("io")
local function handler()
tty.start()
local events = tty.events()
while true do
local ev = events:receive()
if not ev then break end
if ev.type == "key" then
if ev.key == "q" or (ev.ctrl and ev.key == "c") then
break
end
io.print("Key: " .. ev.key)
elseif ev.type == "resize" then
io.print("Size: " .. ev.width .. "x" .. ev.height)
end
end
tty.stop()
end

원시 터미널 입력 모드를 활성화합니다. 터미널이 원시 모드로 전환되고 이벤트 발행을 시작합니다.

local ok, err = tty.start()

반환: boolean, error

원시 입력을 비활성화하고 터미널을 일반 모드로 복원합니다.

local ok, err = tty.stop()

반환: boolean, error

터미널 이벤트를 구독하고 채널을 반환합니다. 이벤트는 type 필드가 있는 테이블로 전달됩니다.

local events = tty.events()

반환: EventChannel, error

현재 터미널 크기를 조회합니다.

local width, height, err = tty.screen_size()

반환: number, number, error

마우스 이벤트 추적을 활성화하거나 비활성화합니다.

local ok, err = tty.mouse(true)
파라미터타입설명
enableboolean활성화는 true, 비활성화는 false

반환: boolean, error

이벤트는 어떤 다른 필드가 있는지 결정하는 type 필드가 있는 테이블입니다.

{
type = "key",
key = "a", -- 인쇄 가능한 문자 또는 키 이름
key_type = "runes", -- 인쇄 가능한 경우 "runes", 또는 특수 키 이름
action = "press", -- "press" 또는 "release"
alt = false,
ctrl = false,
shift = false
}

tty.mouse(true)가 필요합니다.

{
type = "mouse",
action = "press", -- "press", "release", "motion", "wheel"
button = "left", -- 버튼 이름
x = 10,
y = 5,
alt = false,
ctrl = false,
shift = false
}
{type = "resize", width = 120, height = 40}

tty.start() 후 초기 크기와 함께 한 번 발행됩니다.

{type = "start", width = 120, height = 40}
{type = "focus", focused = true}
{type = "paste", text = "pasted content"}

키 이벤트와 매칭되는 재사용 가능한 키 바인딩을 생성합니다:

local quit = tty.bind({
keys = {"q", "ctrl+c"},
help = {key = "q/ctrl+c", desc = "quit"}
})
-- 이벤트 루프에서
if quit:matches(ev) then
break
end
필드타입설명
keysstring[]매칭할 키 패턴 (예: "a", "ctrl+c", "enter")
helptable선택. 도움말 텍스트용 {key = "...", desc = "..."}

반환: KeyBinding

메서드반환설명
matches(event)boolean키 이벤트가 이 바인딩과 일치하는지 테스트
set_enabled(bool)self바인딩 활성화 또는 비활성화
is_enabled()boolean바인딩이 활성화되었는지 확인
help()table{key, desc} 도움말 정보 반환

lipgloss 기반 스타일링을 사용하여 스타일이 적용된 텍스트 출력을 생성합니다. 모든 스타일 메서드는 새 스타일을 반환합니다(불변).

local tty = require("tty")
local io = require("io")
local title = tty.style()
:bold()
:foreground("#FF0000")
:padding(0, 1)
local box = tty.style()
:border(tty.borders.ROUNDED)
:border_foreground("#00FF00")
:width(40)
:padding(1, 2)
io.print(box:render(title:render("Hello"), "World"))

새 빈 스타일을 생성합니다.

반환: Style

모든 메서드는 새 Style을 반환하며 체이닝할 수 있습니다.

메서드파라미터설명
foreground(color)string텍스트 색상 (16진수 "#FF0000", ANSI "9", 또는 이름)
background(color)string배경 색상
bold(enable?)boolean굵은 텍스트 (기본값: true)
italic(enable?)boolean기울임꼴 텍스트
underline(enable?)boolean밑줄 텍스트
strikethrough(enable?)boolean취소선 텍스트
faint(enable?)boolean흐림 텍스트
blink(enable?)boolean깜빡이는 텍스트
reverse(enable?)boolean전경/배경 교체
메서드파라미터설명
width(n)number고정 너비
height(n)number고정 높이
max_width(n)number최대 너비
max_height(n)number최대 높이
padding(...)numbers패딩 (CSS 스타일: top, right, bottom, left)
margin(...)numbers마진 (CSS 스타일)
align(pos)number수평 정렬
align_vertical(pos)number수직 정렬
inline(enable?)boolean인라인 렌더링 모드
메서드파라미터설명
border(name, ...)string, booleans테두리 스타일, 선택적 측면별 토글
border_foreground(...)strings테두리 색상
border_background(...)strings테두리 배경 색상
메서드설명
render(...)이 스타일이 적용된 문자열 렌더링
copy()이 스타일의 복사본 생성
tty.borders.NORMAL
tty.borders.ROUNDED
tty.borders.THICK
tty.borders.DOUBLE
tty.borders.HIDDEN
tty.align.LEFT -- 0
tty.align.CENTER -- 0.5
tty.align.RIGHT -- 1

스타일이 적용된 텍스트의 레이아웃 및 측정 함수입니다. tty.text에서 사용할 수 있습니다.

local w = tty.text.width("hello") -- 인쇄 가능한 너비 (ANSI 인식)
local h = tty.text.height("a\nb\nc") -- 줄 수
local w, h = tty.text.size("hello\nworld") -- 둘 다
-- 위쪽으로 정렬하여 나란히 결합
local row = tty.text.join_horizontal(tty.text.position.TOP, left, right)
-- 가운데 정렬로 수직 스택
local col = tty.text.join_vertical(tty.text.position.CENTER, top, bottom)
local w = tty.text.max_width({"short", "a longer string"}) -- 가장 넓은
local h = tty.text.max_height({"one\ntwo", "single"}) -- 가장 높은

주어진 크기의 박스 내에 문자열을 배치합니다:

-- 80x24 박스의 가운데
local out = tty.text.place(80, 24, tty.text.position.CENTER, tty.text.position.CENTER, content)
-- 수평만
local out = tty.text.place_horizontal(80, tty.text.position.RIGHT, content)
-- 수직만
local out = tty.text.place_vertical(24, tty.text.position.BOTTOM, content)
tty.text.position.TOP -- 0
tty.text.position.LEFT -- 0
tty.text.position.CENTER -- 0.5
tty.text.position.BOTTOM -- 1
tty.text.position.RIGHT -- 1