Compare commits

...

4 Commits

7 changed files with 96 additions and 28 deletions

View File

@@ -5,9 +5,44 @@ Lightweight stdlib-only utilities to replace Rich dependency in preview scripts.
Provides RGB color formatting, table rendering, and markdown stripping.
"""
import os
import re
import shutil
import textwrap
import unicodedata
def get_terminal_width() -> int:
"""
Get terminal width, prioritizing FZF preview environment variables.
Returns:
Terminal width in columns
"""
fzf_cols = os.environ.get("FZF_PREVIEW_COLUMNS")
if fzf_cols:
return int(fzf_cols)
return shutil.get_terminal_size((80, 24)).columns
def display_width(text: str) -> int:
"""
Calculate the actual display width of text, accounting for wide characters.
Args:
text: Text to measure
Returns:
Display width in terminal columns
"""
width = 0
for char in text:
# East Asian Width property: 'F' (Fullwidth) and 'W' (Wide) take 2 columns
if unicodedata.east_asian_width(char) in ("F", "W"):
width += 2
else:
width += 1
return width
def rgb_color(r: int, g: int, b: int, text: str, bold: bool = False) -> str:
@@ -51,7 +86,7 @@ def print_rule(sep_color: str) -> None:
Args:
sep_color: Color as 'R,G,B' string
"""
width = shutil.get_terminal_size((80, 24)).columns
width = get_terminal_width()
r, g, b = parse_color(sep_color)
print(rgb_color(r, g, b, "" * width))
@@ -72,22 +107,35 @@ def print_table_row(
r, g, b = parse_color(header_color)
key_styled = rgb_color(r, g, b, key, bold=True)
# Ensure minimum width to avoid textwrap errors
safe_value_width = max(20, value_width)
# Get actual terminal width
term_width = get_terminal_width()
# Wrap value if it's too long
value_lines = textwrap.wrap(str(value), width=safe_value_width) if value else [""]
# Calculate display widths accounting for wide characters
key_display_width = display_width(key)
# Calculate actual value width based on terminal and key display width
actual_value_width = max(20, term_width - key_display_width - 2)
# Wrap value if it's too long (use character count, not display width for wrapping)
value_lines = textwrap.wrap(str(value), width=actual_value_width) if value else [""]
if not value_lines:
value_lines = [""]
# Print first line with right-aligned value
# Print first line with properly aligned value
first_line = value_lines[0]
print(f"{key_styled:<{key_width + 20}} {first_line:>{safe_value_width}}")
first_line_display_width = display_width(first_line)
# Use manual spacing to right-align based on display width
spacing = term_width - key_display_width - first_line_display_width - 2
if spacing > 0:
print(f"{key_styled} {' ' * spacing}{first_line}")
else:
print(f"{key_styled} {first_line}")
# Print remaining wrapped lines (left-aligned, indented)
for line in value_lines[1:]:
print(f"{' ' * (key_width + 2)}{line}")
print(f"{' ' * (key_display_width + 2)}{line}")
def strip_markdown(text: str) -> str:
@@ -149,6 +197,6 @@ def wrap_text(text: str, width: int | None = None) -> str:
Wrapped text
"""
if width is None:
width = shutil.get_terminal_size((80, 24)).columns
width = get_terminal_width()
return textwrap.fill(text, width=width)

View File

@@ -1,12 +1,17 @@
import sys
import shutil
from _ansi_utils import print_rule, print_table_row, strip_markdown, wrap_text
from _ansi_utils import (
print_rule,
print_table_row,
strip_markdown,
wrap_text,
get_terminal_width,
)
HEADER_COLOR = sys.argv[1]
SEPARATOR_COLOR = sys.argv[2]
# Get terminal dimensions
term_width = shutil.get_terminal_size((80, 24)).columns
term_width = get_terminal_width()
# Print title centered
print("{ANIME_TITLE}".center(term_width))

View File

@@ -1,12 +1,17 @@
import sys
import shutil
from _ansi_utils import print_rule, print_table_row, strip_markdown, wrap_text
from _ansi_utils import (
print_rule,
print_table_row,
strip_markdown,
wrap_text,
get_terminal_width,
)
HEADER_COLOR = sys.argv[1]
SEPARATOR_COLOR = sys.argv[2]
# Get terminal dimensions
term_width = shutil.get_terminal_size((80, 24)).columns
term_width = get_terminal_width()
# Print title centered
print("{CHARACTER_NAME}".center(term_width))

View File

@@ -1,12 +1,11 @@
import sys
import shutil
from _ansi_utils import print_rule, print_table_row
from _ansi_utils import print_rule, print_table_row, get_terminal_width
HEADER_COLOR = sys.argv[1]
SEPARATOR_COLOR = sys.argv[2]
# Get terminal dimensions
term_width = shutil.get_terminal_size((80, 24)).columns
term_width = get_terminal_width()
# Print title centered
print("{TITLE}".center(term_width))

View File

@@ -1,12 +1,17 @@
import sys
import shutil
from _ansi_utils import print_rule, print_table_row, strip_markdown, wrap_text
from _ansi_utils import (
print_rule,
print_table_row,
strip_markdown,
wrap_text,
get_terminal_width,
)
HEADER_COLOR = sys.argv[1]
SEPARATOR_COLOR = sys.argv[2]
# Get terminal dimensions
term_width = shutil.get_terminal_size((80, 24)).columns
term_width = get_terminal_width()
# Print title centered
print("{TITLE}".center(term_width))

View File

@@ -244,12 +244,13 @@ def fzf_image_preview(file_path: str):
def fzf_text_info_render():
"""Renders the text-based info via the cached python script."""
import shutil
# Get terminal dimensions from FZF environment or fallback
cols, lines = get_terminal_dimensions()
# Print simple separator line
width = shutil.get_terminal_size((80, 24)).columns
# Print simple separator line with proper width
r, g, b = map(int, SEPARATOR_COLOR.split(","))
print(f"\x1b[38;2;{r};{g};{b}m" + "" * width + "\x1b[0m")
separator = f"\x1b[38;2;{r};{g};{b}m" + ("" * cols) + "\x1b[0m"
print(separator, flush=True)
if PREVIEW_MODE == "text" or PREVIEW_MODE == "full":
preview_info_path = INFO_CACHE_DIR / f"{hash_id}.py"

View File

@@ -1,12 +1,17 @@
import sys
import shutil
from _ansi_utils import print_rule, print_table_row, strip_markdown, wrap_text
from _ansi_utils import (
print_rule,
print_table_row,
strip_markdown,
wrap_text,
get_terminal_width,
)
HEADER_COLOR = sys.argv[1]
SEPARATOR_COLOR = sys.argv[2]
# Get terminal dimensions
term_width = shutil.get_terminal_size((80, 24)).columns
term_width = get_terminal_width()
# Print title centered
print("{REVIEWER_NAME}".center(term_width))