added a dedicated pager library
This commit is contained in:
+1
-1
@@ -77,7 +77,7 @@ def clear_ctx(stub, state):
|
|||||||
|
|
||||||
# main initialization
|
# main initialization
|
||||||
llm = LLMChat(config_file=CONFIG_FILE, message_limit=20)
|
llm = LLMChat(config_file=CONFIG_FILE, message_limit=20)
|
||||||
chat = DeckChat(start_state=llm, chat_prefix='> ', paginate=8)
|
chat = DeckChat(start_state=llm, chat_prefix='> ')
|
||||||
chat.command('default', send_msg)
|
chat.command('default', send_msg)
|
||||||
chat.command('clear', clear_ctx)
|
chat.command('clear', clear_ctx)
|
||||||
chat.command('system', set_sys_prompt)
|
chat.command('system', set_sys_prompt)
|
||||||
|
|||||||
+3
-15
@@ -4,9 +4,10 @@
|
|||||||
# Created by Luxferre in 2025, released into public domain
|
# Created by Luxferre in 2025, released into public domain
|
||||||
|
|
||||||
from deck.input import input
|
from deck.input import input
|
||||||
|
from deck.pager import print_paged
|
||||||
|
|
||||||
class DeckChat:
|
class DeckChat:
|
||||||
def __init__(self, start_state={}, chat_prefix='> ', command_prefix='/', paginate=0):
|
def __init__(self, start_state={}, chat_prefix='> ', command_prefix='/'):
|
||||||
"""Init the chat class"""
|
"""Init the chat class"""
|
||||||
self.command_prefix = command_prefix # prefix that commands start with
|
self.command_prefix = command_prefix # prefix that commands start with
|
||||||
self.chat_prefix = chat_prefix # prefix to write before input
|
self.chat_prefix = chat_prefix # prefix to write before input
|
||||||
@@ -14,7 +15,6 @@ class DeckChat:
|
|||||||
'default': lambda m,s: (m,s) # echo handler by default
|
'default': lambda m,s: (m,s) # echo handler by default
|
||||||
}
|
}
|
||||||
self.state = start_state # internal state object (impl-specific)
|
self.state = start_state # internal state object (impl-specific)
|
||||||
self.paginate_n = paginate # paginate the responses exceeding N>0 lines
|
|
||||||
|
|
||||||
def command(self, command, handler):
|
def command(self, command, handler):
|
||||||
"""
|
"""
|
||||||
@@ -43,15 +43,6 @@ class DeckChat:
|
|||||||
res = (cmd, arg)
|
res = (cmd, arg)
|
||||||
return res
|
return res
|
||||||
|
|
||||||
def _paginate_output(self, text):
|
|
||||||
"""Splits output for small terminals."""
|
|
||||||
lines = text.split('\n')
|
|
||||||
for i in range(0, len(lines), self.paginate_n):
|
|
||||||
chunk = lines[i:i + self.paginate_n]
|
|
||||||
for line in chunk: print(line)
|
|
||||||
if i + self.paginate_n < len(lines):
|
|
||||||
input("-- Press Enter --")
|
|
||||||
|
|
||||||
def start(self):
|
def start(self):
|
||||||
"""Start the chat loop"""
|
"""Start the chat loop"""
|
||||||
while True:
|
while True:
|
||||||
@@ -60,10 +51,7 @@ class DeckChat:
|
|||||||
if len(input_msg) == 0: continue
|
if len(input_msg) == 0: continue
|
||||||
cmd, msg = self._detect_command(input_msg)
|
cmd, msg = self._detect_command(input_msg)
|
||||||
output, self.state = self.command_handlers[cmd](msg, self.state)
|
output, self.state = self.command_handlers[cmd](msg, self.state)
|
||||||
if self.paginate_n > 0:
|
print_paged(output.strip())
|
||||||
self._paginate_output(output.strip())
|
|
||||||
else:
|
|
||||||
print(output)
|
|
||||||
if self.state is None:
|
if self.state is None:
|
||||||
break
|
break
|
||||||
except (KeyboardInterrupt, EOFError):
|
except (KeyboardInterrupt, EOFError):
|
||||||
|
|||||||
@@ -0,0 +1,44 @@
|
|||||||
|
# deck.pager: Simple text pagination library for T-Deck
|
||||||
|
# Usage: from deck.pager import print_paged
|
||||||
|
# Created by Luxferre in 2025, released into public domain
|
||||||
|
|
||||||
|
import os
|
||||||
|
from deck.input import input
|
||||||
|
|
||||||
|
# detect terminal size
|
||||||
|
TERM_ROWS = os.getenv('TERM_ROWS', 24)
|
||||||
|
TERM_COLS = os.getenv('TERM_COLS', 80)
|
||||||
|
try: # if running on CPython
|
||||||
|
TERM_COLS, TERM_ROWS = os.get_terminal_size()
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
|
# additional constants
|
||||||
|
REAL_TERM_ROWS = TERM_ROWS - 1 # for the "press Enter" message
|
||||||
|
CONT_MSG = '--- Press Enter ---'
|
||||||
|
|
||||||
|
def term_size():
|
||||||
|
"""Return the detected terminal size (rows, columns)"""
|
||||||
|
return (TERM_ROWS, TERM_COLS)
|
||||||
|
|
||||||
|
def reflow(text):
|
||||||
|
"""Split the text into lines not exceeding the terminal width"""
|
||||||
|
out = []
|
||||||
|
for line in text.split('\n'):
|
||||||
|
line = line.rstrip()
|
||||||
|
while len(line) > 0:
|
||||||
|
out.append(line[0:TERM_COLS])
|
||||||
|
line = line[TERM_COLS:]
|
||||||
|
return out
|
||||||
|
|
||||||
|
def print_paged(text):
|
||||||
|
"""Reflow and print the text in a paginated manner"""
|
||||||
|
lines = reflow(text)
|
||||||
|
ll = len(lines)
|
||||||
|
for i in range(0, ll, REAL_TERM_ROWS):
|
||||||
|
chunk = lines[i:i + REAL_TERM_ROWS]
|
||||||
|
for line in chunk: print(line)
|
||||||
|
if i + REAL_TERM_ROWS < ll:
|
||||||
|
input(CONT_MSG)
|
||||||
|
|
||||||
|
|
||||||
Reference in New Issue
Block a user