From f5c4016fa6beb5955a0254f02cee8a2be6f2e02b Mon Sep 17 00:00:00 2001 From: Rootiest Date: Tue, 8 Sep 2026 01:22:10 -0400 Subject: [PATCH 1/2] perf(conf.d): stop re-running expensive setup on tricks.fish's second source MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit tricks.fish is sourced twice per shell on CachyOS: once by the conf.d autoload, once forced by config.fish to re-win over the distro's own tricks.fish (measured 4.55ms for the second pass, see startup-latency-JOB-BRIEF-FINDINGS.md §1). The bang-bang functions, aliases, and history override further down need to re-run on both passes since those are what re-assert over the distro config, but the PATH/MANPAGER setup does not. Gates fish_add_path and the type -q bat probe behind a once-per-session global, guarding only that block. Everything else in the file, and the coupling with config.fish's own cachyos-tricks guard, is unchanged. --- conf.d/tricks.fish | 36 ++++++++++++++++++++++++------------ 1 file changed, 24 insertions(+), 12 deletions(-) diff --git a/conf.d/tricks.fish b/conf.d/tricks.fish index a3a5474..6c82fb1 100644 --- a/conf.d/tricks.fish +++ b/conf.d/tricks.fish @@ -18,20 +18,32 @@ if test -f ~/.fish_profile source ~/.fish_profile end -# Append unique directories to $PATH (fish_add_path handles duplicates automatically) -fish_add_path ~/.local/bin -fish_add_path ~/Applications/depot_tools +# This file is sourced twice per shell on CachyOS (once by the conf.d +# autoload, once forced by config.fish to re-win over the distro's own +# tricks.fish). The PATH/MANPAGER setup below doesn't need to repeat on +# the second pass -- only the functions/aliases further down do, since +# those are what re-assert over the distro config. Gate the expensive +# calls (fish_add_path, type -q bat) behind a once-per-session guard. +# ponytail: per-session guard, not per-value; if this file grows more +# expensive one-time setup, extend the same guard rather than adding more. +if not set -q __fish_config_tricks_env_applied + set -g __fish_config_tricks_env_applied 1 -# Expose user-local man pages -if not contains ~/.local/share/man $MANPATH - set -gx MANPATH ~/.local/share/man $MANPATH -end + # Append unique directories to $PATH (fish_add_path handles duplicates automatically) + fish_add_path ~/.local/bin + fish_add_path ~/Applications/depot_tools -# Format man pages using bat (only if bat is installed) -# Overriding $MANPAGER is opinionated (C3 overrides) -if type -q bat; and __fish_config_op_enabled (status basename) tricks-manpager - set -gx MANROFFOPT -c - set -gx MANPAGER "sh -c 'col -bx | bat -l man -p'" + # Expose user-local man pages + if not contains ~/.local/share/man $MANPATH + set -gx MANPATH ~/.local/share/man $MANPATH + end + + # Format man pages using bat (only if bat is installed) + # Overriding $MANPAGER is opinionated (C3 overrides) + if type -q bat; and __fish_config_op_enabled (status basename) tricks-manpager + set -gx MANROFFOPT -c + set -gx MANPAGER "sh -c 'col -bx | bat -l man -p'" + end end # Set settings for https://github.com/franciscolourenco/done -- 2.54.0 From 23bf649c5f9daf302ed0370d8955f1f0931fc28e Mon Sep 17 00:00:00 2001 From: Rootiest Date: Tue, 8 Sep 2026 01:22:22 -0400 Subject: [PATCH 2/2] fix(functions): dedupe conflicting paru/yay wrapper generators MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit __fish_config_sync_logging carried its own inferior copy of the paru/yay wrapper generator (tee-based, no PTY, no progress-bar rendering, hard-coded /usr/bin/paru|yay) alongside the canonical version-6 generators in conf.d/paru-wrapper.fish and conf.d/yay-wrapper.fish. Both wrote the same file with different version markers and the same misattributed provenance comment, so whichever ran last won and a subsequent C5 toggle would flip it back. See startup-latency-JOB-BRIEF-FINDINGS.md §2. __fish_config_sync_logging now delegates entirely to the canonical generators instead of carrying a copy: they already resolve the real binary via __fish_real_command (never /usr/bin-assumed) and independently gate on their own C2/C5 keys, covering both the enabled-regenerate and disabled-remove cases. One behavior change falls out of delegating rather than special-casing around it: a wrapper is no longer generated when C2 (paru-autoexec / yay-autoexec) is disabled, even if C5 logging is on. The removed sync-logging copy never checked C2, so it could reinstall a wrapper the user had explicitly turned auto-exec off for. Adds functions/_fish_source_scoped.fish: a small helper that runs source inside its own function-call boundary. source itself runs in the caller's scope, so a bare return inside a sourced conf.d guard (both files have several) would otherwise unwind whatever function called source directly -- verified with a minimal repro before relying on it. Routing through this helper contains the return to just that call, so calling paru's generator and then yay's actually reaches the second call. Manually verified end-to-end in an isolated HOME/XDG sandbox with a stubbed paru/yay: enable generates both v6 wrappers, disable removes both and drops the sentinel, re-enable regenerates them and clears the sentinel. --- functions/__fish_config_sync_logging.fish | 84 +++++------------------ functions/_fish_source_scoped.fish | 26 +++++++ 2 files changed, 45 insertions(+), 65 deletions(-) create mode 100644 functions/_fish_source_scoped.fish diff --git a/functions/__fish_config_sync_logging.fish b/functions/__fish_config_sync_logging.fish index 2d61e86..493a383 100644 --- a/functions/__fish_config_sync_logging.fish +++ b/functions/__fish_config_sync_logging.fish @@ -28,84 +28,38 @@ function __fish_config_sync_logging --description 'Sync C5 logging state: sentin 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 (status current-function) - # Logging enabled: remove sentinel and regenerate wrappers if binaries exist + # Logging enabled: remove sentinel rm -f $sentinel # Restart tmux pipe-pane for the current pane if inside tmux _tmux_pipe_log - - 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 + # Logging disabled: create sentinel 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 - # Stop tmux pipe-pane for the current pane if inside tmux if set -q TMUX tmux pipe-pane 2>/dev/null end end + + # Delegate paru/yay wrapper (re)generation and removal to the canonical + # generators. They resolve the real binary via __fish_real_command + # (never /usr/bin-assumed) and independently gate on their own C2/C5 + # keys, so sourcing them here covers both the enabled-regenerate and + # disabled-remove cases without duplicating that logic. Previously this + # function carried its own inferior copy (tee instead of a PTY, no + # progress-bar rendering, hard-coded /usr/bin/paru|yay), which fought + # the canonical generator for the wrapper file on every version-marker + # mismatch. See startup-latency-JOB-BRIEF-FINDINGS.md §2. + # + # Routed through _fish_source_scoped: both files `return` early on + # several guard checks, and a sourced `return` exits the *calling* + # function, which would otherwise abort this function and skip + # whichever of paru/yay hadn't run yet. + _fish_source_scoped "$__fish_config_dir/conf.d/paru-wrapper.fish" + _fish_source_scoped "$__fish_config_dir/conf.d/yay-wrapper.fish" end diff --git a/functions/_fish_source_scoped.fish b/functions/_fish_source_scoped.fish new file mode 100644 index 0000000..41446a8 --- /dev/null +++ b/functions/_fish_source_scoped.fish @@ -0,0 +1,26 @@ +# Copyright (C) 2026 Rootiest +# SPDX-License-Identifier: AGPL-3.0-or-later + +# SYNOPSIS +# _fish_source_scoped +# +# DESCRIPTION +# Sources inside its own function-call boundary. `source` runs +# in the caller's own scope, so a bare `return` in a sourced file -- +# used by several conf.d guards as an early exit -- would otherwise +# unwind whatever function called `source` directly, not just the +# sourced file. Calling through this helper contains it to here. +# +# ARGUMENTS +# file Path to the fish script to source +# +# EXIT STATUS +# 0 File does not exist (nothing to do) +# Exit status of the sourced file otherwise +# +# EXAMPLE +# _fish_source_scoped $__fish_config_dir/conf.d/paru-wrapper.fish +function _fish_source_scoped --argument-names file + test -f $file; or return 0 + source $file +end -- 2.54.0