Merge pull request 'feat(logging): add C5 — Logging & Capture opinionated guard' (#39) from feat/logging-toggle-c5 into main
Reviewed-on: #39
This commit was merged in pull request #39.
This commit is contained in:
@@ -62,6 +62,11 @@
|
||||
opinionated_catalog.md
|
||||
docs/superpowers
|
||||
|
||||
# ──────────────────── Runtime State Files ───────────────────
|
||||
# Sentinel file written/removed at runtime to coordinate logging state
|
||||
# across the fish config and the Kitty Python watcher. Never committed.
|
||||
.logging_disabled
|
||||
|
||||
# ──────────────── Fisher-Managed Plugin Files ───────────────
|
||||
# Fisher writes these into the repo directory on install/update.
|
||||
# They are owned by Fisher — do not commit them.
|
||||
|
||||
@@ -166,7 +166,7 @@ end
|
||||
|
||||
## Minimal Mode
|
||||
|
||||
Everything opinionated in this config — command shadows, startup side-effects, key and environment overrides, and terminal integrations — is active by default but can be switched off with universal variables. Four category toggles and one master switch are available:
|
||||
Everything opinionated in this config — command shadows, startup side-effects, key and environment overrides, terminal integrations, and logging — is active by default but can be switched off with universal variables. Five category toggles and one master switch are available:
|
||||
|
||||
| Variable | Disables |
|
||||
|---|---|
|
||||
@@ -174,7 +174,8 @@ Everything opinionated in this config — command shadows, startup side-effects,
|
||||
| `__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_opinionated` | Master switch — all four categories at once |
|
||||
| `__fish_config_op_logging` | Scrollback capture on exit, `paru`/`yay` AUR log wrappers, Kitty watcher capture (sentinel-file coordinated) |
|
||||
| `__fish_config_opinionated` | Master switch — all five categories at once |
|
||||
|
||||
Set any of them to a falsy value (`0`, `false`, `no`, `off`, `n`) to disable; erase the variable to re-enable:
|
||||
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
# Copyright (C) 2026 Rootiest
|
||||
# SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
#
|
||||
# C5 — Logging & Capture: registers --on-variable event handlers at shell
|
||||
# startup so that changes to __fish_config_op_logging or the master
|
||||
# __fish_config_opinionated take effect immediately in every running shell.
|
||||
# Also calls __fish_config_sync_logging once to reconcile sentinel-file and
|
||||
# wrapper state with any variable values that were pre-set before this shell
|
||||
# started.
|
||||
#
|
||||
# These functions must be defined in conf.d (not functions/) because fish
|
||||
# only autoloads from functions/ on explicit call — event handlers that live
|
||||
# solely in functions/ are never registered and their --on-variable triggers
|
||||
# never fire.
|
||||
|
||||
function __fish_config_logging_changed --on-variable __fish_config_op_logging \
|
||||
--description 'C5 event handler: sync logging state when __fish_config_op_logging changes'
|
||||
__fish_config_sync_logging
|
||||
end
|
||||
|
||||
function __fish_config_opinionated_changed --on-variable __fish_config_opinionated \
|
||||
--description 'C5 event handler: sync logging state when master opinionated switch changes'
|
||||
__fish_config_sync_logging
|
||||
end
|
||||
|
||||
# Sync once at startup so pre-set variable values take effect without a re-set
|
||||
__fish_config_sync_logging
|
||||
@@ -6,9 +6,18 @@
|
||||
# timestamped log file and prunes old logs, mirroring smart_exit behavior.
|
||||
|
||||
# Auto-generating a wrapper in ~/.local/bin is opinionated (C2 auto-exec).
|
||||
# Task #4's __fish_config_enable_logging will additionally gate this wrapper.
|
||||
# Wrapper generation is also gated by C5 (Logging & Capture).
|
||||
__fish_config_op_enabled __fish_config_op_autoexec; or return
|
||||
|
||||
# C5 — Logging & Capture: remove generated wrapper and skip when logging is off
|
||||
if not __fish_config_op_enabled __fish_config_op_logging
|
||||
if test -f "$HOME/.local/bin/paru"
|
||||
and grep -q "# paru-wrapper-version:" "$HOME/.local/bin/paru" 2>/dev/null
|
||||
rm -f "$HOME/.local/bin/paru"
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
set -l _paru_real /usr/bin/paru
|
||||
set -l _paru_wrapper "$HOME/.local/bin/paru"
|
||||
set -l _paru_wrapper_version 1
|
||||
|
||||
+10
-1
@@ -6,9 +6,18 @@
|
||||
# timestamped log file and prunes old logs, mirroring smart_exit behavior.
|
||||
|
||||
# Auto-generating a wrapper in ~/.local/bin is opinionated (C2 auto-exec).
|
||||
# Task #4's __fish_config_enable_logging will additionally gate this wrapper.
|
||||
# Wrapper generation is also gated by C5 (Logging & Capture).
|
||||
__fish_config_op_enabled __fish_config_op_autoexec; or return
|
||||
|
||||
# C5 — Logging & Capture: remove generated wrapper and skip when logging is off
|
||||
if not __fish_config_op_enabled __fish_config_op_logging
|
||||
if test -f "$HOME/.local/bin/yay"
|
||||
and grep -q "# yay-wrapper-version:" "$HOME/.local/bin/yay" 2>/dev/null
|
||||
rm -f "$HOME/.local/bin/yay"
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
set -l _yay_real /usr/bin/yay
|
||||
set -l _yay_wrapper "$HOME/.local/bin/yay"
|
||||
set -l _yay_wrapper_version 1
|
||||
|
||||
+7
-2
@@ -1382,7 +1382,7 @@ fish_variables.
|
||||
## Opinionated Components (Minimal Mode)
|
||||
|
||||
Every opinionated piece of this config is active by default but can be
|
||||
switched off through four category opt-out variables, each evaluated via
|
||||
switched off through five category opt-out variables, each evaluated via
|
||||
__fish_variable_check. Set a variable to any falsy value (0, false, no,
|
||||
off, n) to disable its category; erase it or set a truthy value (1, true,
|
||||
yes, on, y) to re-enable. Unset means enabled.
|
||||
@@ -1410,13 +1410,18 @@ yes, on, y) to re-enable. Unset means enabled.
|
||||
WezTerm window abbreviations, done
|
||||
notifications, spwin/tab/split,
|
||||
hist, logs, upgrade, WakaTime
|
||||
__fish_config_op_logging Logging & capture: scrollback
|
||||
capture on exit, paru/yay AUR log
|
||||
wrappers, Kitty watcher capture;
|
||||
sentinel file coordinates
|
||||
cross-process state
|
||||
|
||||
Examples:
|
||||
|
||||
# Disable command shadows only (rm becomes plain rm again):
|
||||
set -U __fish_config_op_aliases off
|
||||
|
||||
# Full minimal mode — disable all four categories at once:
|
||||
# Full minimal mode — disable all five categories at once:
|
||||
set -U __fish_config_opinionated 0
|
||||
|
||||
# Re-enable everything:
|
||||
|
||||
@@ -0,0 +1,99 @@
|
||||
# Copyright (C) 2026 Rootiest
|
||||
# SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
# SYNOPSIS
|
||||
# __fish_config_sync_logging
|
||||
#
|
||||
# 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
|
||||
# __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
|
||||
# the generated version-marker comment.
|
||||
#
|
||||
# RETURNS
|
||||
# 0 Always
|
||||
#
|
||||
# EXAMPLE
|
||||
# __fish_config_sync_logging
|
||||
function __fish_config_sync_logging --description 'Sync C5 logging state: sentinel file and paru/yay wrappers'
|
||||
set -l config_home $XDG_CONFIG_HOME
|
||||
if test -z "$config_home"
|
||||
set config_home "$HOME/.config"
|
||||
end
|
||||
set -l sentinel "$config_home/fish/.logging_disabled"
|
||||
set -l paru_wrapper "$HOME/.local/bin/paru"
|
||||
set -l yay_wrapper "$HOME/.local/bin/yay"
|
||||
set -l wrapper_version 1
|
||||
|
||||
if __fish_config_op_enabled __fish_config_op_logging
|
||||
# Logging enabled: remove sentinel and regenerate wrappers if binaries exist
|
||||
rm -f $sentinel
|
||||
|
||||
if test -x /usr/bin/paru
|
||||
mkdir -p (dirname $paru_wrapper)
|
||||
printf '%s\n' \
|
||||
'#!/usr/bin/env bash' \
|
||||
"# paru-wrapper-version: $wrapper_version" \
|
||||
'# Auto-generated by conf.d/paru-wrapper.fish — do not edit by hand.' \
|
||||
'# Tees paru output to a timestamped log file and prunes old ones.' \
|
||||
'set -o pipefail' \
|
||||
'' \
|
||||
'log_dir="${SCROLLBACK_HISTORY_DIR:-$HOME/.terminal_history}"' \
|
||||
'mkdir -p "$log_dir"' \
|
||||
'log_file="$log_dir/paru_$(date +%Y-%m-%d_%H-%M-%S).log"' \
|
||||
'' \
|
||||
'/usr/bin/paru "$@" 2>&1 | tee "$log_file"' \
|
||||
'' \
|
||||
'max_files="${SCROLLBACK_HISTORY_MAX_FILES:-100}"' \
|
||||
'mapfile -t logs < <(ls -1t "$log_dir"/paru_*.log 2>/dev/null)' \
|
||||
'excess=$(( ${#logs[@]} - max_files ))' \
|
||||
'for (( i = ${#logs[@]} - 1; i >= ${#logs[@]} - excess && i >= 0; i-- )); do' \
|
||||
' rm -f "${logs[$i]}"' \
|
||||
'done' \
|
||||
>$paru_wrapper
|
||||
chmod +x $paru_wrapper
|
||||
end
|
||||
|
||||
if test -x /usr/bin/yay
|
||||
mkdir -p (dirname $yay_wrapper)
|
||||
printf '%s\n' \
|
||||
'#!/usr/bin/env bash' \
|
||||
"# yay-wrapper-version: $wrapper_version" \
|
||||
'# Auto-generated by conf.d/yay-wrapper.fish — do not edit by hand.' \
|
||||
'# Tees yay output to a timestamped log file and prunes old ones.' \
|
||||
'set -o pipefail' \
|
||||
'' \
|
||||
'log_dir="${SCROLLBACK_HISTORY_DIR:-$HOME/.terminal_history}"' \
|
||||
'mkdir -p "$log_dir"' \
|
||||
'log_file="$log_dir/yay_$(date +%Y-%m-%d_%H-%M-%S).log"' \
|
||||
'' \
|
||||
'/usr/bin/yay "$@" 2>&1 | tee "$log_file"' \
|
||||
'' \
|
||||
'max_files="${SCROLLBACK_HISTORY_MAX_FILES:-100}"' \
|
||||
'mapfile -t logs < <(ls -1t "$log_dir"/yay_*.log 2>/dev/null)' \
|
||||
'excess=$(( ${#logs[@]} - max_files ))' \
|
||||
'for (( i = ${#logs[@]} - 1; i >= ${#logs[@]} - excess && i >= 0; i-- )); do' \
|
||||
' rm -f "${logs[$i]}"' \
|
||||
'done' \
|
||||
>$yay_wrapper
|
||||
chmod +x $yay_wrapper
|
||||
end
|
||||
else
|
||||
# Logging disabled: create sentinel and remove any generated wrappers
|
||||
mkdir -p (dirname $sentinel)
|
||||
touch $sentinel
|
||||
|
||||
if test -f $paru_wrapper
|
||||
and grep -q "# paru-wrapper-version:" $paru_wrapper 2>/dev/null
|
||||
rm -f $paru_wrapper
|
||||
end
|
||||
|
||||
if test -f $yay_wrapper
|
||||
and grep -q "# yay-wrapper-version:" $yay_wrapper 2>/dev/null
|
||||
rm -f $yay_wrapper
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -48,6 +48,16 @@ function smart_exit --description 'Capture colorized scrollback before exiting,
|
||||
return 0
|
||||
end
|
||||
|
||||
# C5 — Logging & Capture: skip all capture when logging is disabled.
|
||||
# When disabled, tell Kitty the window is handled so its watcher doesn't
|
||||
# capture either — belt-and-suspenders alongside the sentinel file.
|
||||
if not __fish_config_op_enabled __fish_config_op_logging
|
||||
if test -n "$KITTY_WINDOW_ID"
|
||||
kitty @ set-user-vars "logged_by_shell=true" 2>/dev/null
|
||||
end
|
||||
builtin exit
|
||||
end
|
||||
|
||||
set -l snapshot_dir (set -q SCROLLBACK_HISTORY_DIR; and echo $SCROLLBACK_HISTORY_DIR; or echo "$HOME/.terminal_history")
|
||||
set -l max_files (set -q SCROLLBACK_HISTORY_MAX_FILES; and echo $SCROLLBACK_HISTORY_MAX_FILES; or echo 100)
|
||||
|
||||
@@ -61,8 +71,8 @@ function smart_exit --description 'Capture colorized scrollback before exiting,
|
||||
set -l active_tui (ps -o comm= --ppid $fish_pid 2>/dev/null)
|
||||
|
||||
if test -n "$KITTY_WINDOW_ID"
|
||||
# LIVE BUFFER CHECK: Check the active token variable $_
|
||||
# If the user typed exit, $_ will match "exit". If flags were passed,
|
||||
# LIVE BUFFER CHECK: Check the active token variable $_
|
||||
# If the user typed exit, $_ will match "exit". If flags were passed,
|
||||
# we check if it contains the phrase "exit" to match 'exit -n' or 'exit --help'.
|
||||
if string match -qr exit "$_"
|
||||
if not string match -qr '^(nvim|vim|vi|nano|emacs|tmux)$' "$active_tui"
|
||||
|
||||
Reference in New Issue
Block a user