Skip to content

Feat/terminal colors#123

Merged
Firstp1ck merged 14 commits intomainfrom
feat/terminal-colors
Feb 1, 2026
Merged

Feat/terminal colors#123
Firstp1ck merged 14 commits intomainfrom
feat/terminal-colors

Conversation

@Firstp1ck
Copy link
Owner

@Firstp1ck Firstp1ck commented Feb 1, 2026

Summary

  • Problem: When no theme is set (or user wants to match the terminal), Pacsea always wrote a default skeleton (Catppuccin Mocha) to theme.conf and used it. There was no way to use the terminal’s foreground/background colors so the UI could blend with the terminal palette.
  • Solution:
    • Add use_terminal_theme setting in settings.conf (default: false). When true, theme resolution tries to query the terminal via OSC 10/11 (foreground/background), parses the reply, builds Pacsea’s 16-color theme from fg/bg and derivation rules, and uses it. If the terminal does not support query or the query fails (e.g. non-TTY, timeout), resolution falls back to theme.conf or the default skeleton.
    • Add theme resolution order: prefer terminal theme when use_terminal_theme=true and terminal is supported; otherwise use file theme or skeleton.
    • Add OSC 10/11 query implementation with timeout and robust parsing (terminal_query.rs), terminal support detection (terminal_detect.rs), and resolution logic (resolve.rs).
    • Improve robustness of OSC query (handling reply format, ST terminator, non-TTY).
    • On Unix: query terminal colors via /dev/tty with nix poll so stdin is not used and crossterm is not raced.
    • Add WezTerm and wezterm-gui to supported terminals (unit test added).
    • On Windows: cancellable reader thread (WaitForSingleObject with short timeout + cancel flag) so join() returns quickly and does not hang if the OSC query never yields bytes; avoids freezing startup/theme reload.
    • On other non-Unix: bounded join so the caller does not block indefinitely if the reader is stuck on stdin.
    • In headless/test (PACSEA_TEST_HEADLESS=1): skip mouse capture disable/enable for clean output.
    • Remove dead load_theme_from_file from theme_loader; add rustdoc and error logging in ensure_theme_file_exists. ensure_theme_file_exists() always targets config_dir()/theme.conf for creation (never legacy pacsea.conf); reading continues to use resolve_theme_config_path() elsewhere.
    • Fix AUR cache handling for long filenames in updates feed.
    • Do not show a "Connection issue" modal for each failed official/AUR package-details fetch when scrolling; only log. Reduces modal spam when network is flaky or circuit breaker is open.
    • Build: add nix (Unix) dependency with poll and fs features; add windows-sys (Windows) for timeout-aware stdin wait in OSC reader.
  • Doc: Add dev/IMPROVEMENTS/TERMINAL_THEME_FALLBACK.md describing design, OSC sequences, and implementation choices.

Type of change

  • feat (new feature)
  • fix (bug fix)
  • docs (documentation only)
  • refactor (no functional change)
  • perf (performance)
  • test (add/update tests)
  • chore (build/infra/CI)
  • ui (visual/interaction changes)
  • breaking change (incompatible behavior)

Related issues

Closes #122

How to test

  1. Format, lint, check, and test:
cargo fmt --all
cargo clippy --all-targets --all-features -- -D warnings
cargo check
cargo test -- --test-threads=1
  1. Terminal theme on supported terminal (e.g. Alacritty, Kitty, WezTerm): set use_terminal_theme = true in settings.conf, run Pacsea; UI should match terminal fg/bg–derived colors. Change terminal theme and reload theme in Pacsea to see updates. On Unix, query uses /dev/tty (no stdin).
  2. Unsupported / non-TTY: run with use_terminal_theme = true in a pipe or unsupported terminal; should fall back to theme.conf or default skeleton without hanging.
  3. AUR updates: run update flow on a system with AUR packages; long cache filenames should not cause failures.
RUST_LOG=pacsea=debug cargo run -- --dry-run

Checklist

Code Quality:

  • Code compiles locally (cargo check)
  • cargo fmt --all ran without changes
  • cargo clippy --all-targets --all-features -- -D warnings is clean
  • cargo test -- --test-threads=1 passes
  • Complexity checks pass for new code (cargo test complexity -- --nocapture)
  • All new functions/methods have rustdoc comments (What, Inputs, Output, Details)
  • No unwrap() or expect() in non-test code

Testing:

  • Added or updated tests where it makes sense
  • For bug fixes: created failing tests first, then fixed the issue
  • Tests are meaningful and cover the functionality

Documentation:

  • Updated README if behavior, options, or keybinds changed (keep high-level, reference wiki)
  • Updated relevant wiki pages if needed:
  • Updated config examples in config/ directory if config keys changed (settings.conf: use_terminal_theme)
  • For UI changes: included screenshots and updated Images/ if applicable

Compatibility:

  • Changes respect --dry-run flag
  • Code degrades gracefully if pacman/paru/yay are unavailable
  • No breaking changes (or clearly documented if intentional): new setting is opt-in, default false

Other:

  • Not a packaging change for AUR (otherwise propose in pacsea-bin or pacsea-git repos)

Notes for reviewers

  • Theme resolution (src/theme/resolve.rs): Order is (1) if use_terminal_theme and terminal supported → query OSC, use terminal theme; (2) else use theme from file or skeleton. Fallback on query failure avoids hanging in pipes/CI/unsupported terminals.
  • OSC query (src/theme/terminal_query.rs): Uses blocking read with timeout; parses rgb:rrrr/gggg/bbbb and optional rgba; handles both \033\\ and BEL as ST. Non-TTY or no reply → returns error so resolution can fall back.
  • Terminal detection (src/theme/terminal_detect.rs): Heuristic (e.g. COLORTERM, TERM) to decide if we try OSC query; WezTerm/wezterm-gui added; not all terminals that set these support query (some only support set), so we still rely on query success/failure.
  • Unix query (src/theme/terminal_query.rs): Colors are read from /dev/tty via nix poll so stdin is untouched and there is no race with crossterm.
  • Windows: Reader uses WaitForSingleObject on stdin handle with short timeout and a cancel flag; main sets cancel on recv timeout then join() returns quickly (no hang when OSC query never yields bytes). Other non-Unix: bounded join so the caller does not block indefinitely.
  • Headless tests: When PACSEA_TEST_HEADLESS=1, mouse capture disable/enable is skipped for clean test output.
  • AUR updates (src/sources/feeds/updates.rs): Long filename fix is a small, separate change in the same branch; included in this PR.
  • Package details errors (src/app/runtime/event_loop.rs): When official or AUR package details fail to fetch (e.g. SSL/network or circuit breaker), the error is logged but no modal is shown, so scrolling through packages does not spam "Connection issue" dialogs.

Breaking changes

None. New setting use_terminal_theme defaults to false; existing configs unchanged.

Additional context

  • Design and OSC details: dev/IMPROVEMENTS/TERMINAL_THEME_FALLBACK.md
  • Terminals that support OSC 10/11 query (e.g. xterm, Alacritty, Kitty, WezTerm) will use terminal theme when use_terminal_theme = true; others fall back to file/skeleton.

…tting

- feat: add use_terminal_theme setting (settings.conf, Settings type) to opt into terminal colors.
- feat: add theme resolution (resolve.rs) to choose theme.conf vs terminal theme by setting and file presence.
- feat: add terminal_detect.rs to detect supported terminals (alacritty, kitty, konsole, ghostty, xterm, gnome-terminal, xfce-terminal, tilix, mate-terminal).
- feat: add terminal_query.rs to query foreground/background via OSC 10/11 and derive 16-color theme.
- change: reload settings before theme in config reload so theme resolution sees updated use_terminal_theme.
- change: theme store and loader use unified resolution; fallback to terminal theme when theme.conf missing/invalid and terminal supported.
- change: parse_settings and settings_ensure handle use_terminal_theme; skeletons updated for new flow.
- chore: add TERMINAL_THEME_FALLBACK.md to IMPROVEMENTS documenting design and OSC requirements.
…ache long filename fix

- feat: use TERM env before COLORTERM for terminal detection; skip COLORTERM when only "truecolor" or "24bit".
- feat: resolve theme before terminal setup so OSC color query runs before mouse capture.
- feat: disable mouse capture during OSC query, drain events before/after, retry once on failure.
- feat: increase OSC query timeout to 250ms; only toggle raw mode when not already enabled.
- fix: AUR cache path uses hash when key length exceeds 200 to avoid "File name too long" (os error 36).
- test: add tests for AUR cache path (long list uses short filename, determinism).
- docs: update TERMINAL_THEME_FALLBACK detection priority (TERM, then COLORTERM, then parent process).
@Firstp1ck Firstp1ck self-assigned this Feb 1, 2026
@Firstp1ck Firstp1ck marked this pull request as ready for review February 1, 2026 13:37
Copilot AI review requested due to automatic review settings February 1, 2026 13:37
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds an opt-in “use terminal theme” feature that queries terminal foreground/background via OSC 10/11 and derives Pacsea’s theme from those colors, with a unified resolution/fallback chain; also fixes AUR JSON cache filename length issues.

Changes:

  • Introduce terminal theme support (OSC 10/11 query, terminal detection, fg/bg → full palette derivation).
  • Centralize theme selection logic in a new resolver and update theme store/reload flow to use it.
  • Prevent AUR cache failures by hashing long cache keys into short deterministic filenames.

Reviewed changes

Copilot reviewed 17 out of 17 changed files in this pull request and generated 7 comments.

Show a summary per file
File Description
src/theme/types.rs Adds use_terminal_theme setting with default false.
src/theme/settings/parse_settings.rs Parses use_terminal_theme (and alias terminal_theme).
src/theme/config/skeletons.rs Updates settings skeleton to document/emit use_terminal_theme.
src/theme/config/settings_ensure.rs Ensures use_terminal_theme is persisted/read in settings management.
src/theme/terminal_detect.rs Adds supported-terminal detection for attempting OSC theme queries.
src/theme/terminal_query.rs Implements OSC 10/11 query + parsing + theme derivation from fg/bg.
src/theme/resolve.rs Adds unified theme resolution order (terminal/file/default fallback).
src/theme/store.rs Switches theme store initialization/reload to use unified resolver.
src/theme/mod.rs Wires new theme modules into the crate.
src/theme/config/theme_loader.rs Adds #[allow(dead_code)] to unused load_theme_from_file.
src/theme/config.rs Stops re-exporting load_theme_from_file (keeps diagnostics loader).
src/events/global.rs Reloads settings before reloading theme so resolver sees updated flag.
src/app/runtime/mod.rs Forces theme resolution before terminal setup to avoid input conflicts.
src/sources/feeds/updates.rs Hashes long AUR cache keys to avoid NAME_MAX filename limits + tests.
dev/IMPROVEMENTS/TERMINAL_THEME_FALLBACK.md Adds design/implementation documentation for terminal theme fallback.
config/settings.conf Documents use_terminal_theme in example config.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

- feat: query terminal colors on Unix via /dev/tty with nix poll (no stdin, no race with crossterm).
- feat: add WezTerm and wezterm-gui to supported terminals; add unit test.
- fix: on Windows, always join reader thread on timeout to avoid detached thread draining stdin.
- fix: in headless/test (PACSEA_TEST_HEADLESS=1), skip mouse capture disable/enable for clean output.
- refactor: remove dead load_theme_from_file from theme_loader; add rustdoc and error logging in ensure_theme_file_exists.
- build: add nix (Unix) dependency with poll and fs features.
- fix: skip Alert modal for official/AUR package-details-unavailable errors; only log.
- fix: show modal only for other network errors so UX stays clear.
- docs: update PR to document package-details error handling in event_loop.
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 23 out of 24 changed files in this pull request and generated 8 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Firstp1ck and others added 6 commits February 1, 2026 21:27
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
- fix: Windows OSC reader uses WaitForSingleObject + cancel flag so join() returns quickly when query never yields; avoids startup/theme-reload freeze.
- fix: other non-Unix use bounded join so caller does not block indefinitely if reader is stuck on stdin.
- refactor: ensure_theme_file_exists() always creates config_dir()/theme.conf; reading still uses resolve_theme_config_path() elsewhere.
- build: add windows-sys (Windows) for timeout-aware stdin wait in OSC reader.
- docs: update PR with Windows/non-Unix reader behavior and theme path details.
- fix: drain terminal event queue multiple times with short delays after OSC query.
- fix: avoid OSC response bytes (e.g. rgb:...) entering search field on Ctrl+R theme reload.
- refactor: extract drain logic into drain_stray_events() with configurable iterations/delay.
@Firstp1ck Firstp1ck merged commit 11e75eb into main Feb 1, 2026
5 checks passed
@Firstp1ck Firstp1ck deleted the feat/terminal-colors branch February 1, 2026 21:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[FEATURE] Terminal Colors

2 participants