Add NAWS terminal size negotiation and dynamic dimensions
- Negotiate NAWS (option 31) on connect to receive terminal cols/rows - Expose term_cols/term_rows on Session (default 80×24) - Add term_cols/term_rows helpers to TUIRunner::Context - Make bar() default width dynamic via term_cols Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -6,7 +6,7 @@ module BBS
|
|||||||
class Session
|
class Session
|
||||||
include Telnet
|
include Telnet
|
||||||
|
|
||||||
attr_reader :session_id
|
attr_reader :session_id, :term_cols, :term_rows
|
||||||
|
|
||||||
def initialize(client)
|
def initialize(client)
|
||||||
@client = client
|
@client = client
|
||||||
|
|||||||
@@ -12,11 +12,15 @@ module BBS
|
|||||||
|
|
||||||
ECHO_OPT = 1
|
ECHO_OPT = 1
|
||||||
SGA_OPT = 3
|
SGA_OPT = 3
|
||||||
|
NAWS_OPT = 31
|
||||||
|
|
||||||
def negotiate
|
def negotiate
|
||||||
|
@term_cols = 80
|
||||||
|
@term_rows = 24
|
||||||
send_raw [IAC, WILL, SGA_OPT].pack('C*')
|
send_raw [IAC, WILL, SGA_OPT].pack('C*')
|
||||||
send_raw [IAC, WILL, ECHO_OPT].pack('C*')
|
send_raw [IAC, WILL, ECHO_OPT].pack('C*')
|
||||||
send_raw [IAC, DO, SGA_OPT].pack('C*')
|
send_raw [IAC, DO, SGA_OPT].pack('C*')
|
||||||
|
send_raw [IAC, DO, NAWS_OPT].pack('C*')
|
||||||
end
|
end
|
||||||
|
|
||||||
def readkey
|
def readkey
|
||||||
@@ -113,14 +117,24 @@ module BBS
|
|||||||
|
|
||||||
case cmd.ord
|
case cmd.ord
|
||||||
when SB
|
when SB
|
||||||
|
opt = @client.read(1)
|
||||||
|
buf = []
|
||||||
loop do
|
loop do
|
||||||
b = @client.read(1)
|
b = @client.read(1)
|
||||||
break if b.nil?
|
break if b.nil?
|
||||||
if b.ord == IAC
|
if b.ord == IAC
|
||||||
s = @client.read(1)
|
s = @client.read(1)
|
||||||
break if s.nil? || s.ord == SE
|
break if s.nil? || s.ord == SE
|
||||||
|
else
|
||||||
|
buf << b.ord
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
if opt&.ord == NAWS_OPT && buf.size >= 4
|
||||||
|
cols = (buf[0] << 8) | buf[1]
|
||||||
|
rows = (buf[2] << 8) | buf[3]
|
||||||
|
@term_cols = cols if cols > 0
|
||||||
|
@term_rows = rows if rows > 0
|
||||||
|
end
|
||||||
when WILL, WONT, DO, DONT
|
when WILL, WONT, DO, DONT
|
||||||
@client.read(1)
|
@client.read(1)
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -56,13 +56,17 @@ module BBS
|
|||||||
@buf << "\e[#{row};#{col}H"
|
@buf << "\e[#{row};#{col}H"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def term_cols = @session.term_cols || 80
|
||||||
|
def term_rows = @session.term_rows || 24
|
||||||
|
|
||||||
def text(content, x: nil, y: nil, style: nil)
|
def text(content, x: nil, y: nil, style: nil)
|
||||||
at(x, y) if x && y
|
at(x, y) if x && y
|
||||||
color = STYLES[style]
|
color = STYLES[style]
|
||||||
@buf << (color ? "#{color}#{content}\e[0m" : content.to_s)
|
@buf << (color ? "#{color}#{content}\e[0m" : content.to_s)
|
||||||
end
|
end
|
||||||
|
|
||||||
def bar(y:, content:, width: 80, style: :muted)
|
def bar(y:, content:, width: nil, style: :muted)
|
||||||
|
width ||= term_cols
|
||||||
text content.to_s.ljust(width), x: 1, y: y, style: style
|
text content.to_s.ljust(width), x: 1, y: y, style: style
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user