From 8a3e38aa25b29575b7038cdab753cad0a126c698 Mon Sep 17 00:00:00 2001 From: Zsolt Tasnadi Date: Mon, 11 May 2026 21:05:44 +0200 Subject: [PATCH] Add NAWS terminal size negotiation and dynamic dimensions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 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 --- lib/bbs/session.rb | 2 +- lib/bbs/telnet.rb | 14 ++++++++++++++ lib/bbs/tui_runner.rb | 6 +++++- 3 files changed, 20 insertions(+), 2 deletions(-) diff --git a/lib/bbs/session.rb b/lib/bbs/session.rb index e19d374..57b2b19 100644 --- a/lib/bbs/session.rb +++ b/lib/bbs/session.rb @@ -6,7 +6,7 @@ module BBS class Session include Telnet - attr_reader :session_id + attr_reader :session_id, :term_cols, :term_rows def initialize(client) @client = client diff --git a/lib/bbs/telnet.rb b/lib/bbs/telnet.rb index bb6edf3..84eaf3a 100644 --- a/lib/bbs/telnet.rb +++ b/lib/bbs/telnet.rb @@ -12,11 +12,15 @@ module BBS ECHO_OPT = 1 SGA_OPT = 3 + NAWS_OPT = 31 def negotiate + @term_cols = 80 + @term_rows = 24 send_raw [IAC, WILL, SGA_OPT].pack('C*') send_raw [IAC, WILL, ECHO_OPT].pack('C*') send_raw [IAC, DO, SGA_OPT].pack('C*') + send_raw [IAC, DO, NAWS_OPT].pack('C*') end def readkey @@ -113,14 +117,24 @@ module BBS case cmd.ord when SB + opt = @client.read(1) + buf = [] loop do b = @client.read(1) break if b.nil? if b.ord == IAC s = @client.read(1) break if s.nil? || s.ord == SE + else + buf << b.ord 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 @client.read(1) end diff --git a/lib/bbs/tui_runner.rb b/lib/bbs/tui_runner.rb index 1a1c08c..de84a59 100644 --- a/lib/bbs/tui_runner.rb +++ b/lib/bbs/tui_runner.rb @@ -56,13 +56,17 @@ module BBS @buf << "\e[#{row};#{col}H" end + def term_cols = @session.term_cols || 80 + def term_rows = @session.term_rows || 24 + def text(content, x: nil, y: nil, style: nil) at(x, y) if x && y color = STYLES[style] @buf << (color ? "#{color}#{content}\e[0m" : content.to_s) 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 end