Skip to content

Commit 4523cba

Browse files
fix bangen cli+tui errors
1 parent 94155d0 commit 4523cba

9 files changed

Lines changed: 300 additions & 10 deletions

File tree

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
# Changelog
22

3+
## [2.3.0]
4+
5+
### Fixed
6+
- CLI no longer errors with "no command called X" when passing text directly as a positional argument (e.g., `bangen "hello"`). The entry point now automatically routes bare text arguments to the `main` subcommand.
7+
- TUI rendering on Linux/macOS no longer produces shattered/jagged output. The `tty.setraw()` call was clearing the terminal's `OPOST` flag, which disabled `\n``\r\n` translation and broke Rich's layout rendering. Output processing is now restored immediately after entering raw mode. SIGWINCH is also handled to refresh the console on terminal resize.
8+
39
## [2.2.3]
410

511
### Added

bangen/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,5 @@
22

33
from __future__ import annotations
44

5-
__version__ = "2.2.3"
5+
__version__ = "2.3.0"
66
__author__ = "programmersd21"

bangen/app.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,15 @@
44

55

66
def main() -> None:
7+
import sys
8+
79
from bangen.cli.parser import app as cli_app
810
from bangen.cli.parser import has_cli_args
911

1012
if has_cli_args():
13+
args = sys.argv[1:]
14+
if args and not args[0].startswith("-") and args[0] != "main":
15+
sys.argv.insert(1, "main")
1116
cli_app()
1217
else:
1318
from bangen.presets.manager import PresetManager

bangen/cli/parser.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
import typer
99

10-
VERSION = "2.2.5"
10+
VERSION = "2.3.0"
1111

1212
app = typer.Typer(
1313
add_completion=False,

bangen/tui/app.py

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@ def run(self) -> TUIState:
9898
return self._state
9999

100100
def _run_unix(self) -> None:
101+
import signal
101102
import termios
102103
import tty
103104

@@ -107,8 +108,17 @@ def _run_unix(self) -> None:
107108
saved = termios_mod.tcgetattr(fd)
108109
try:
109110
tty_mod.setraw(fd)
111+
attrs = termios_mod.tcgetattr(fd)
112+
attrs[1] |= termios_mod.OPOST
113+
termios_mod.tcsetattr(fd, termios_mod.TCSANOW, attrs)
114+
115+
def _on_resize(*_: Any) -> None:
116+
self._console.size = self._console.size # force refresh
117+
118+
signal.signal(signal.SIGWINCH, _on_resize)
110119
self._event_loop(lambda: self._unix_key(fd))
111120
finally:
121+
signal.signal(signal.SIGWINCH, signal.SIG_DFL)
112122
termios_mod.tcsetattr(fd, termios_mod.TCSADRAIN, saved)
113123

114124
def _unix_key(self, fd: int) -> str | None:
@@ -132,16 +142,16 @@ def _unix_key(self, fd: int) -> str | None:
132142
return ch
133143

134144
def _run_windows(self) -> None:
135-
import msvcrt
145+
import msvcrt # type: ignore[import-untyped]
136146

137147
key_map = {b"H": "\x1b[A", b"P": "\x1b[B", b"K": "\x1b[D", b"M": "\x1b[C"}
138148

139149
def read() -> str | None:
140-
if not msvcrt.kbhit():
150+
if not msvcrt.kbhit(): # type: ignore[attr-defined]
141151
return None
142-
ch = msvcrt.getch()
152+
ch = msvcrt.getch() # type: ignore[attr-defined]
143153
if ch in (b"\x00", b"\xe0"):
144-
return key_map.get(msvcrt.getch(), "")
154+
return key_map.get(msvcrt.getch(), "") # type: ignore[attr-defined]
145155
try:
146156
return ch.decode("utf-8")
147157
except Exception:

bangen/tui/export_dialog.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
from copy import deepcopy
77
from pathlib import Path
88
from threading import Thread
9+
from typing import Any
910

1011
from rich import box
1112
from rich.align import Align
@@ -21,7 +22,7 @@
2122

2223

2324
class ExportDialog:
24-
def __init__(self, banner, engine):
25+
def __init__(self, banner: Any, engine: Any) -> None:
2526
self.banner = deepcopy(banner)
2627
self.engine = engine
2728
self.exporter = Exporter()
@@ -49,7 +50,7 @@ def __init__(self, banner, engine):
4950
self._worker_error: str | None = None
5051
self._worker_result: str | None = None
5152

52-
def render(self):
53+
def render(self) -> RenderableType:
5354
self.sync()
5455

5556
body = Table.grid(padding=(0, 1), expand=False)

bangen/tui/preset_dialog.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ def __init__(
5656
def sync(self) -> None:
5757
self._refresh_presets(initial=False)
5858

59-
def render(self):
59+
def render(self) -> RenderableType:
6060
self.sync()
6161

6262
body = Table.grid(padding=(0, 1), expand=False)

poetry.lock

Lines changed: 268 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
44

55
[project]
66
name = "bangen"
7-
version = "2.2.5"
7+
version = "2.3.0"
88
description = "ASCII banner rendering engine with a tiered effect library, live TUI, and transparent PNG/GIF export."
99
readme = "README.md"
1010
requires-python = ">=3.11"

0 commit comments

Comments
 (0)