diff --git a/README.md b/README.md index ee2bf3b..1df7d1b 100644 --- a/README.md +++ b/README.md @@ -178,7 +178,7 @@ If you'd rather set them by hand, each category is controlled by a universal var | `__fish_config_op_autoexec` | Startup side-effects: Fisher bootstrap, theme apply, `paru`/`yay` wrapper generation, auto venv activation, WakaTime hook | | `__fish_config_op_overrides` | Vi mode, `exit`→`smart_exit`, `$PAGER`/`$MANPAGER`/`$CDPATH`, bang-bang history expansion, autopair, puffer, Starship prompt, theme colors | | `__fish_config_op_integrations` | Kitty/WezTerm window abbreviations, `done` notifications, `spwin`/`tab`/`split`, `hist`, `logs`, `upgrade`, WakaTime | -| `__fish_config_op_logging` | Scrollback capture on exit, `paru`/`yay` AUR log wrappers, Kitty watcher capture (sentinel-file coordinated) | +| `__fish_config_op_logging` | Scrollback capture on exit, tmux `pipe-pane` pane logging, `paru`/`yay` AUR log wrappers, Kitty watcher capture (sentinel-file coordinated) | | `__fish_config_op_greeting` | Per-session `fish_greeting` (suppresses distro greetings such as CachyOS fastfetch by overriding with an empty function); first-run welcome banner | | `__fish_config_opinionated` | Master switch — all six categories at once | diff --git a/conf.d/tmux-logging.fish b/conf.d/tmux-logging.fish new file mode 100644 index 0000000..044e8ab --- /dev/null +++ b/conf.d/tmux-logging.fish @@ -0,0 +1,19 @@ +# Copyright (C) 2026 Rootiest +# SPDX-License-Identifier: AGPL-3.0-or-later +# +# C5 — Logging & Capture: starts a pipe-pane log for the current tmux pane +# when fish launches inside a tmux session. Each fish shell gets its own +# timestamped log file in SCROLLBACK_HISTORY_DIR (default: ~/.terminal_history). +# Naming: tmux_-w-p_YYYY-MM-DD_HH-MM-SS.log + +__fish_config_op_enabled __fish_config_op_logging; or exit +status is-interactive; or exit +type -q tmux; or exit +set -q TMUX; or exit + +set -l log_dir (set -q SCROLLBACK_HISTORY_DIR; and echo $SCROLLBACK_HISTORY_DIR; or echo "$HOME/.terminal_history") +set -l pane_id (tmux display-message -p '#{session_name}-w#{window_index}-p#{pane_index}' 2>/dev/null) +set -l timestamp (date "+%Y-%m-%d_%H-%M-%S") + +mkdir -p $log_dir +tmux pipe-pane "cat >> $log_dir/tmux_${pane_id}_${timestamp}.log" 2>/dev/null diff --git a/docs/fish-config.md b/docs/fish-config.md index c936b00..766b0e9 100644 --- a/docs/fish-config.md +++ b/docs/fish-config.md @@ -1678,19 +1678,27 @@ silently failing. #### C5 — Logging and Capture -Three components capture shell output to disk. Disabling +Four components capture shell output to disk. Disabling __fish_config_op_logging skips all capture and removes the logging wrappers. Component What it captures ─────────────────────────────────────────────────────────────────────────── Scrollback capture Terminal session output saved to: ~/.terminal_history/scrollback_YYYY-MM-DD_HH-MM-SS.log + tmux pane capture Continuous pane stream via pipe-pane, saved to: + ~/.terminal_history/tmux_-w-p_YYYY-MM-DD_HH-MM-SS.log paru wrapper All paru/AUR output captured to: ~/.terminal_history/paru_YYYY-MM-DD_HH-MM-SS.log yay wrapper All yay/AUR output captured to: ~/.terminal_history/yay_YYYY-MM-DD_HH-MM-SS.log Kitty watcher watcher.py captures scrollback when Kitty closes +The tmux capture starts automatically when fish launches inside any tmux +pane ($TMUX is set). It uses tmux's native pipe-pane to stream all pane +output directly to disk without an intermediate process. Each fish shell +session gets its own log file; a new log is created on each shell start +(including exec fish and new splits). + Logging coordination via sentinel file C5 uses a sentinel file to synchronize state between the shell and @@ -1705,11 +1713,13 @@ Disabling __fish_config_op_logging: 3. Kitty's watcher.py reads the sentinel on each save attempt and skips capture — no Kitty restart required. 4. smart_exit stops saving scrollback logs. + 5. Stops tmux pipe-pane capture in every open fish shell inside tmux. Re-enabling __fish_config_op_logging: 1. Removes the sentinel in every open shell. 2. Regenerates paru/yay logging wrappers in ~/.local/bin/. 3. Kitty watcher resumes capture on the next session exit. + 4. Restarts tmux pipe-pane capture in every open fish shell inside tmux. Changes propagate to all running shells through an event handler that fires whenever __fish_config_op_logging changes — no shell restart needed. diff --git a/functions/__fish_config_sync_logging.fish b/functions/__fish_config_sync_logging.fish index c41c4af..70fff7f 100644 --- a/functions/__fish_config_sync_logging.fish +++ b/functions/__fish_config_sync_logging.fish @@ -6,8 +6,9 @@ # # DESCRIPTION # Synchronises C5 logging state: creates or removes the Kitty sentinel -# file ($XDG_CONFIG_HOME/fish/.logging_disabled) and generates or removes -# the paru/yay AUR-helper log wrappers based on the combined value of +# file ($XDG_CONFIG_HOME/fish/.logging_disabled), generates or removes the +# paru/yay AUR-helper log wrappers, and starts or stops tmux pipe-pane +# capture for the current pane — all based on the combined value of # __fish_config_opinionated (master) and __fish_config_op_logging (C5). # Called by --on-variable event handlers whenever either variable changes. # Safe to call at any time; wrapper removal only affects files bearing @@ -32,6 +33,15 @@ function __fish_config_sync_logging --description 'Sync C5 logging state: sentin # Logging enabled: remove sentinel and regenerate wrappers if binaries exist rm -f $sentinel + # Restart tmux pipe-pane for the current pane if inside tmux + if set -q TMUX + set -l log_dir (set -q SCROLLBACK_HISTORY_DIR; and echo $SCROLLBACK_HISTORY_DIR; or echo "$HOME/.terminal_history") + set -l pane_id (tmux display-message -p '#{session_name}-w#{window_index}-p#{pane_index}' 2>/dev/null) + set -l timestamp (date "+%Y-%m-%d_%H-%M-%S") + mkdir -p $log_dir + tmux pipe-pane "cat >> $log_dir/tmux_${pane_id}_${timestamp}.log" 2>/dev/null + end + if test -x /usr/bin/paru mkdir -p (dirname $paru_wrapper) printf '%s\n' \ @@ -95,5 +105,10 @@ function __fish_config_sync_logging --description 'Sync C5 logging state: sentin and grep -q "# yay-wrapper-version:" $yay_wrapper 2>/dev/null rm -f $yay_wrapper end + + # Stop tmux pipe-pane for the current pane if inside tmux + if set -q TMUX + tmux pipe-pane 2>/dev/null + end end end