From 9630301ca086af2dd3e0ab19f44f26c60fbd6b27 Mon Sep 17 00:00:00 2001 From: David Jensenius Date: Mon, 18 May 2026 22:22:34 -0400 Subject: [PATCH 1/7] Speed up fish prompt and mise activation Avoid duplicate mise fish activation and replace per-prompt mise environment updates with startup and directory-change hooks. Enable mise caching for env and remote version lookups, and make Starship jj custom modules avoid spawning fish for non-jj repositories. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- fish/conf.d/00-env.fish | 1 + fish/config.fish | 8 +++++++- mise/config.toml | 6 ++++++ starship.toml | 27 +++++++++++++++++++++++++-- 4 files changed, 39 insertions(+), 3 deletions(-) diff --git a/fish/conf.d/00-env.fish b/fish/conf.d/00-env.fish index b053d77..a169cdd 100644 --- a/fish/conf.d/00-env.fish +++ b/fish/conf.d/00-env.fish @@ -2,6 +2,7 @@ # Editor and tools set -gx EDITOR nvim +set -gx MISE_FISH_AUTO_ACTIVATE 0 # eza config set -gx EZA_CONFIG_DIR "$HOME/.config/eza" diff --git a/fish/config.fish b/fish/config.fish index 3872d27..bf4dc3d 100644 --- a/fish/config.fish +++ b/fish/config.fish @@ -2,7 +2,13 @@ # Initialize mise early so tools are available in all shells if command -q mise - mise activate fish | source + # Avoid mise's default prompt hook; update once on startup and again only after cd. + mise activate fish --no-hook-env | source + mise hook-env -s fish | source + + function __mise_cd_hook --on-variable PWD --description 'Update mise environment when changing directories' + mise hook-env -s fish | source + end end if status is-interactive diff --git a/mise/config.toml b/mise/config.toml index 893ad07..54be6dd 100644 --- a/mise/config.toml +++ b/mise/config.toml @@ -64,6 +64,7 @@ trusted_config_paths = [ verbose = false # set to true to see full installation output, see `MISE_VERBOSE` http_timeout = "30s" # set the timeout for http requests as duration string, see `MISE_HTTP_TIMEOUT` +fetch_remote_versions_cache = "1h" jobs = 4 # number of plugins or runtimes to install in parallel. The default is `4`. raw = false # set to true to directly pipe plugins to stdin/stdout/stderr yes = false # set to true to automatically answer yes to all prompts @@ -76,12 +77,17 @@ disable_default_registry = false # disable the default shorthands, see `MISE_DIS # disable_tools = ['node'] # disable specific tools, generally used to turn off core tools env_file = '.env' # load env vars from a dotenv file, see `MISE_ENV_FILE` +env_cache = true # cache computed env/PATH between shell hook runs +env_cache_ttl = "1h" experimental = true # enable experimental features # configure messages displayed when entering directories with config files status = { missing_tools = "if_other_versions_installed", show_env = false, show_tools = false } +[settings.github] +credential_command = "gh auth token" + # "_" is a special key for information you'd like to put into mise.toml that mise will never parse [_] foo = "bar" diff --git a/starship.toml b/starship.toml index 4f99989..f78f7e0 100644 --- a/starship.toml +++ b/starship.toml @@ -418,20 +418,43 @@ mantle = "#1e2030" crust = "#181926" [custom.jj_branch] -when = "jj workspace root --ignore-working-copy > /dev/null 2>&1" +shell = "sh" +when = ''' +dir="$PWD" +while [ "$dir" != "/" ]; do + [ -d "$dir/.jj" ] && exit 0 + dir="$(dirname "$dir")" +done +exit 1 +''' command = ''' jj log -r "(immutable_heads()..@):: & branches()" -T 'local_branches.join(\"\n\") ++ \"\n\"' --no-graph --ignore-working-copy | head -n 1 ''' style = 'yellow' [custom.jj_op] -when = "jj workspace root --ignore-working-copy > /dev/null 2>&1" +shell = "sh" +when = ''' +dir="$PWD" +while [ "$dir" != "/" ]; do + [ -d "$dir/.jj" ] && exit 0 + dir="$(dirname "$dir")" +done +exit 1 +''' command = 'jj op log -n 1 -T "id.short()" --no-graph --ignore-working-copy' symbol = 'op:' style = "bright-yellow" [custom.jj_git_notinsync] +shell = "sh" when = ''' +dir="$PWD" +while [ "$dir" != "/" ]; do + [ -d "$dir/.jj" ] && break + dir="$(dirname "$dir")" +done +[ "$dir" = "/" ] && exit 1 [ -n "${jj_git_head:=$(jj log -T commit_id --no-graph --ignore-working-copy -r HEAD@git)}" ] \ && [ -n "${git_head:=$(git rev-parse HEAD)}" ] \ && [ "$git_head" != "$jj_git_head" ] From 9c216b657407734ee2b4d3b3845b98f28b2eb2e8 Mon Sep 17 00:00:00 2001 From: David Jensenius Date: Mon, 18 May 2026 22:23:48 -0400 Subject: [PATCH 2/7] Update bat theme and copilot completions Use the current Catppuccin Mocha bat theme name and include none as a valid Copilot reasoning effort completion. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- bat/config | 2 +- fish/completions/copilot.fish | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/bat/config b/bat/config index 32ce965..9090233 100644 --- a/bat/config +++ b/bat/config @@ -4,7 +4,7 @@ # Specify desired highlighting theme (e.g. "TwoDark"). Run `bat --list-themes` # for a list of all available themes ---theme="Catppuccin-mocha" +--theme="Catppuccin Mocha" # Enable this to use italic text on the terminal. This is not supported on all # terminal emulators (like tmux, by default): diff --git a/fish/completions/copilot.fish b/fish/completions/copilot.fish index 37575d3..12f242b 100644 --- a/fish/completions/copilot.fish +++ b/fish/completions/copilot.fish @@ -14,7 +14,7 @@ complete -c copilot -l interactive -s i -r -d 'Start interactive mode and automa complete -c copilot -l prompt -s p -r -d 'Execute a prompt in non-interactive mode (exits after completion)' complete -c copilot -l silent -s s -f -d 'Output only the agent response (no stats), useful for scripting with -p' complete -c copilot -l model -r -d 'Set the AI model to use' -complete -c copilot -l effort -l reasoning-effort -r -d 'Set the reasoning effort level' -a 'low medium high xhigh' +complete -c copilot -l effort -l reasoning-effort -r -d 'Set the reasoning effort level' -a 'none low medium high xhigh' complete -c copilot -l enable-reasoning-summaries -f -d 'Request reasoning summaries for OpenAI models' complete -c copilot -l agent -r -d 'Specify a custom agent to use' complete -c copilot -l resume -r -d 'Resume from a previous session (optionally specify session ID, task ID, or name; name matching is exact, case-insensitive)' From aa4642abdf38c64a4fda7a40bf7456a20fe243c1 Mon Sep 17 00:00:00 2001 From: David Jensenius Date: Mon, 18 May 2026 22:31:17 -0400 Subject: [PATCH 3/7] Reduce tmux status line overhead Lower the status refresh rate, remove a per-window contextual-name shellout from Catppuccin window labels, and suppress noisy outdated-package status stderr. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- scripts/tmux-show-outdated.sh | 2 +- tmux/tmux.conf | 9 ++++----- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/scripts/tmux-show-outdated.sh b/scripts/tmux-show-outdated.sh index 791731f..1ab1916 100755 --- a/scripts/tmux-show-outdated.sh +++ b/scripts/tmux-show-outdated.sh @@ -3,7 +3,7 @@ PLUGIN_DIR="$HOME/.config/tmux/plugins/tmux-outdated-packages" SHOW_STATUS_SCRIPT="$PLUGIN_DIR/scripts/show-status.sh" if [ -x "$SHOW_STATUS_SCRIPT" ]; then - OUTPUT=$("$SHOW_STATUS_SCRIPT") + OUTPUT=$("$SHOW_STATUS_SCRIPT" 2>/dev/null) # Trim whitespace to check if empty TRIMMED=$(echo "$OUTPUT" | xargs) diff --git a/tmux/tmux.conf b/tmux/tmux.conf index deb8d81..7c5a87e 100644 --- a/tmux/tmux.conf +++ b/tmux/tmux.conf @@ -22,8 +22,8 @@ set -ga update-environment TERM_PROGRAM set -ga update-environment PATH set -s set-clipboard on -# Status line refresh interval (faster when background installations are running) -set -g status-interval 1 +# Keep status responsive without rerunning status helpers every second. +set -g status-interval 5 # ================== Theme ========================= set -g @catppuccin_window_status_style "rounded" @@ -35,9 +35,8 @@ set -g status-right "" set -ogq @catppuccin_window_flags "icon" # set -g @catppuccin_window_text " #{pane_current_command}" -set -g @catppuccin_window_text " #W #(/Users/djensenius/.config/tmux/plugins/tmux-contextual-window-name/bin/tmux-contextual-window-name name --pane #{q:pane_id} --command #{q:pane_current_command} --path #{q:pane_current_path} --title #{q:pane_title} --pane-pid #{q:pane_pid})" -set -g @catppuccin_window_current_text " #W #(/Users/djensenius/.config/tmux/plugins/tmux-contextual-window-name/bin/tmux-contextual-window-name name --pane #{q:pane_id} --command #{q:pane_current_command} --path #{q:pane_current_path} --title #{q:pane_title} --pane-pid #{q:pane_pid})" -# set -wg automatic-rename on +set -g @catppuccin_window_text " #W" +set -g @catppuccin_window_current_text " #W" set -g renumber-windows on set -g status-right "#{?client_prefix,#{E:@catppuccin_status_session},}" From 8d846132acee26737ef0e86f7e67d5f6069ac3ca Mon Sep 17 00:00:00 2001 From: David Jensenius Date: Mon, 18 May 2026 22:34:49 -0400 Subject: [PATCH 4/7] Restore contextual tmux window labels Keep the contextual window-name command in Catppuccin window labels and fix the hardcoded home path. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- tmux/tmux.conf | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tmux/tmux.conf b/tmux/tmux.conf index 7c5a87e..53ea998 100644 --- a/tmux/tmux.conf +++ b/tmux/tmux.conf @@ -35,8 +35,8 @@ set -g status-right "" set -ogq @catppuccin_window_flags "icon" # set -g @catppuccin_window_text " #{pane_current_command}" -set -g @catppuccin_window_text " #W" -set -g @catppuccin_window_current_text " #W" +set -g @catppuccin_window_text " #W #(/Users/david/.config/tmux/plugins/tmux-contextual-window-name/bin/tmux-contextual-window-name name --pane #{q:pane_id} --command #{q:pane_current_command} --path #{q:pane_current_path} --title #{q:pane_title} --pane-pid #{q:pane_pid})" +set -g @catppuccin_window_current_text " #W #(/Users/david/.config/tmux/plugins/tmux-contextual-window-name/bin/tmux-contextual-window-name name --pane #{q:pane_id} --command #{q:pane_current_command} --path #{q:pane_current_path} --title #{q:pane_title} --pane-pid #{q:pane_pid})" set -g renumber-windows on set -g status-right "#{?client_prefix,#{E:@catppuccin_status_session},}" From 12b41ce5a9bea40126d21515132ee72dcd8e00c7 Mon Sep 17 00:00:00 2001 From: David Jensenius Date: Mon, 18 May 2026 22:37:36 -0400 Subject: [PATCH 5/7] Add fast path for tmux window labels Use a lightweight shell wrapper for common contextual window labels and fall back to the Python helper for Copilot, Node, and complex cases. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- scripts/tmux-contextual-window-name-fast.sh | 107 ++++++++++++++++++++ tmux/tmux.conf | 4 +- 2 files changed, 109 insertions(+), 2 deletions(-) create mode 100755 scripts/tmux-contextual-window-name-fast.sh diff --git a/scripts/tmux-contextual-window-name-fast.sh b/scripts/tmux-contextual-window-name-fast.sh new file mode 100755 index 0000000..7e28fe8 --- /dev/null +++ b/scripts/tmux-contextual-window-name-fast.sh @@ -0,0 +1,107 @@ +#!/usr/bin/env sh +set -eu + +HELPER="$HOME/.config/tmux/plugins/tmux-contextual-window-name/bin/tmux-contextual-window-name" + +pane="" +command="" +path="" +title="" +pane_pid="" + +while [ "$#" -gt 0 ]; do + case "$1" in + --pane) + pane="${2:-}" + shift 2 + ;; + --command) + command="${2:-}" + shift 2 + ;; + --path) + path="${2:-}" + shift 2 + ;; + --title) + title="${2:-}" + shift 2 + ;; + --pane-pid) + pane_pid="${2:-}" + shift 2 + ;; + *) + shift + ;; + esac +done + +fallback() { + exec "$HELPER" name --pane "$pane" --command "$command" --path "$path" --title "$title" --pane-pid "$pane_pid" +} + +truncate() { + value="$1" + max="$2" + length=$(printf "%s" "$value" | wc -c | tr -d ' ') + if [ "$length" -le "$max" ]; then + printf "%s" "$value" + else + prefix_len=$((max - 1)) + printf "%s…" "$(printf "%s" "$value" | cut -c "1-$prefix_len")" + fi +} + +path_slug() { + target="${1:-}" + fallback_value="${2:-}" + + if [ -z "$target" ]; then + printf "%s" "$fallback_value" + return + fi + + if [ "$target" = "$HOME" ]; then + printf "~" + return + fi + + if [ -d "$target" ]; then + dir="$target" + else + dir=$(dirname "$target") + fi + + while [ "$dir" != "/" ] && [ -n "$dir" ]; do + if [ -d "$dir/.git" ] || [ -f "$dir/.git" ]; then + name=${dir%/} + printf "%s" "${name##*/}" + return + fi + dir=$(dirname "$dir") + done + + name=${target%/} + printf "%s" "${name##*/}" +} + +cmd=$(basename "${command:-}") + +case "$title" in + "🤖 "*|"Copilot: "|"Copilot: "*|"GitHub Copilot") + fallback + ;; +esac + +case "$cmd" in + node|nodejs|copilot) + fallback + ;; + nvim|fish) + truncate "$(path_slug "$path" "$cmd")" 24 + ;; + *) + truncate "${cmd:-$(path_slug "$path" "")}" 16 + ;; +esac diff --git a/tmux/tmux.conf b/tmux/tmux.conf index 53ea998..5b4891e 100644 --- a/tmux/tmux.conf +++ b/tmux/tmux.conf @@ -35,8 +35,8 @@ set -g status-right "" set -ogq @catppuccin_window_flags "icon" # set -g @catppuccin_window_text " #{pane_current_command}" -set -g @catppuccin_window_text " #W #(/Users/david/.config/tmux/plugins/tmux-contextual-window-name/bin/tmux-contextual-window-name name --pane #{q:pane_id} --command #{q:pane_current_command} --path #{q:pane_current_path} --title #{q:pane_title} --pane-pid #{q:pane_pid})" -set -g @catppuccin_window_current_text " #W #(/Users/david/.config/tmux/plugins/tmux-contextual-window-name/bin/tmux-contextual-window-name name --pane #{q:pane_id} --command #{q:pane_current_command} --path #{q:pane_current_path} --title #{q:pane_title} --pane-pid #{q:pane_pid})" +set -g @catppuccin_window_text " #W #($HOME/.config/tmux/../scripts/tmux-contextual-window-name-fast.sh --pane #{q:pane_id} --command #{q:pane_current_command} --path #{q:pane_current_path} --title #{q:pane_title} --pane-pid #{q:pane_pid})" +set -g @catppuccin_window_current_text " #W #($HOME/.config/tmux/../scripts/tmux-contextual-window-name-fast.sh --pane #{q:pane_id} --command #{q:pane_current_command} --path #{q:pane_current_path} --title #{q:pane_title} --pane-pid #{q:pane_pid})" set -g renumber-windows on set -g status-right "#{?client_prefix,#{E:@catppuccin_status_session},}" From 69fb038c2af3ab5b89e1bbf9c2f4f9530d0c19ff Mon Sep 17 00:00:00 2001 From: David Jensenius Date: Mon, 18 May 2026 22:51:01 -0400 Subject: [PATCH 6/7] Speed up personal tmux session launcher Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- fish/conf.d/21-aliases.fish | 1 - fish/functions/pt.fish | 27 +++++++++++++++++++++++++++ 2 files changed, 27 insertions(+), 1 deletion(-) create mode 100644 fish/functions/pt.fish diff --git a/fish/conf.d/21-aliases.fish b/fish/conf.d/21-aliases.fish index ab86d59..fa5fd44 100644 --- a/fish/conf.d/21-aliases.fish +++ b/fish/conf.d/21-aliases.fish @@ -1,5 +1,4 @@ # Aliases (functions under the hood) alias gt="tmuxinator start github" -alias pt="tmuxinator start personal" alias st="tmuxinator start server" alias fzg="rgf" diff --git a/fish/functions/pt.fish b/fish/functions/pt.fish new file mode 100644 index 0000000..799341d --- /dev/null +++ b/fish/functions/pt.fish @@ -0,0 +1,27 @@ +function pt --description "Start or attach the personal tmux session" + set -l session personal + + if tmux has-session -t "$session" 2>/dev/null + if set -q TMUX + tmux switch-client -t "$session" + else + tmux attach-session -t "$session" + end + return + end + + tmux new-session -d -s "$session" -n Monitor "fish -lc 'tmux set-window-option -t1 automatic-rename on; btm --battery; exec fish'" \; \ + split-window -t "$session:1" -v "fish -lc 'gping -c blue google.com -c red aka.ms -c green github.com; exec fish'" \; \ + split-window -t "$session:1" -v "fish -lc 'clear; exec fish'" \; \ + select-layout -t "$session:1" main-horizontal \; \ + new-window -t "$session:2" -n Code "fish -lc 'tmux set-window-option -t2 automatic-rename on; nvim; exec fish'" \; \ + select-window -t "$session:1" \; \ + select-pane -t "$session:1.0" + or return + + if set -q TMUX + tmux switch-client -t "$session" + else + tmux attach-session -t "$session" + end +end From fd32d1fff016ed0052c0a644ed8ee4f5b9a97067 Mon Sep 17 00:00:00 2001 From: David Jensenius Date: Mon, 18 May 2026 22:59:40 -0400 Subject: [PATCH 7/7] Load tmux plugins asynchronously Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- scripts/tmux-load-plugins.sh | 26 ++++++++++++++++++++++++++ tmux/tmux.conf | 14 +++----------- 2 files changed, 29 insertions(+), 11 deletions(-) create mode 100755 scripts/tmux-load-plugins.sh diff --git a/scripts/tmux-load-plugins.sh b/scripts/tmux-load-plugins.sh new file mode 100755 index 0000000..ec1f2e6 --- /dev/null +++ b/scripts/tmux-load-plugins.sh @@ -0,0 +1,26 @@ +#!/usr/bin/env sh +set -eu + +finish() { + status=$? + + if [ "$status" -eq 0 ]; then + tmux set-option -g @tmux_plugins_loading "0" 2>/dev/null || true + else + tmux set-option -g @tmux_plugins_loading "failed" 2>/dev/null || true + fi + + tmux refresh-client -S 2>/dev/null || true +} + +trap finish EXIT + +"$HOME/.config/tmux/plugins/tpm/tpm" + +tmux source-file "$HOME/.config/tmux/post-tpm.conf" +tmux set-option -g status-style "bg=terminal" +tmux set-option -g mouse on +tmux set-window-option -g mode-keys vi + +# Overrides that depend on Catppuccin plugin options must run after TPM. +tmux source-file "$HOME/.config/tmux/post-catppuccin.conf" diff --git a/tmux/tmux.conf b/tmux/tmux.conf index 5b4891e..cb90a0f 100644 --- a/tmux/tmux.conf +++ b/tmux/tmux.conf @@ -40,6 +40,8 @@ set -g @catppuccin_window_current_text " #W #($HOME/.config/tmux/../scripts/tmux set -g renumber-windows on set -g status-right "#{?client_prefix,#{E:@catppuccin_status_session},}" +set -g @tmux_plugins_loading "1" +set -ag status-right "#{?#{==:#{@tmux_plugins_loading},1},#[fg=yellow] loading plugins #[default],#{?#{==:#{@tmux_plugins_loading},failed},#[fg=red] plugin load failed #[default],}}" set -ag status-right "#(command -v tmux-background-install-indicator.sh >/dev/null 2>&1 && tmux-background-install-indicator.sh || echo '')" set -ag status-right "#{E:@catppuccin_status_outdated_packages}" set -ag status-right "#{?#($HOME/.config/tmux/plugins/tmux-speedtest/scripts/speedtest_status.sh),#{E:@catppuccin_status_ctp_speedtest},}" @@ -131,14 +133,4 @@ bind ` splitw "gotop -c monokai" bind m command-prompt "splitw 'exec man %%'" bind / command-prompt "splitw '%%'" -run '~/.config/tmux/plugins/tpm/tpm' -source-file ~/.config/tmux/post-tpm.conf - -set -g status-style "bg=terminal" -set -g mouse on -setw -g mode-keys vi - - - -# Override catppuccin status modules AFTER tpm loads them -source-file ~/.config/tmux/post-catppuccin.conf +run-shell -b '~/.config/tmux/../scripts/tmux-load-plugins.sh'