From 4e2e75a044b438b2f2b9af59a60134fd1c68f631 Mon Sep 17 00:00:00 2001 From: "s0wlz (Matthias Puchstein)" Date: Sun, 15 Feb 2026 00:54:45 +0100 Subject: [PATCH] simplified my pipewire conf --- ...un_onchange_pipewire-rnnoise-check.sh.tmpl | 31 --- dot_config/gtk-4.0/gtk.css | 129 +++++++++++ .../hypr/hyprland.d/70-keybinds.conf.tmpl | 13 +- dot_config/mimeapps.list | 8 +- .../pipewire.conf.d/20-voice-engine.conf | 72 +++++++ .../pipewire.conf.d/60-echo-cancel.conf.tmpl | 39 ---- .../pipewire.conf.d/99-input-denoising.conf | 45 ---- dot_config/private_htop/private_htoprc | 66 ++++++ dot_config/waybar/config.tmpl | 10 + dot_config/waybar/style.css.tmpl | 19 +- dot_config/zsh/apex-aeon.zsh | 204 ++++++++++++++---- dot_config/zsh/apex-neon.zsh | 204 ++++++++++++++---- dot_gemini/settings.json.tmpl | 10 - .../bin/executable_mic-toggle-processing | 90 ++++++++ dot_local/bin/executable_mic-toggle-usb | 31 +++ dot_local/bin/executable_mic-usb-status | 60 ++++++ .../game/csgo/cfg/autoexec.cfg | 2 +- pkglist/bluetooth.txt | 3 - pkglist/common.txt | 15 -- pkglist/desktop.txt | 5 - pkglist/dev.txt | 14 -- pkglist/entertainment.txt | 6 - pkglist/hyprland.txt | 45 ---- pkglist/laptop.txt | 4 - pkglist/pipewire.txt | 9 - pkglist/waybar.txt | 3 - 26 files changed, 823 insertions(+), 314 deletions(-) delete mode 100755 .chezmoiscripts/run_onchange_pipewire-rnnoise-check.sh.tmpl create mode 100644 dot_config/gtk-4.0/gtk.css create mode 100644 dot_config/pipewire/pipewire.conf.d/20-voice-engine.conf delete mode 100644 dot_config/pipewire/pipewire.conf.d/60-echo-cancel.conf.tmpl delete mode 100644 dot_config/pipewire/pipewire.conf.d/99-input-denoising.conf create mode 100644 dot_config/private_htop/private_htoprc delete mode 100644 dot_gemini/settings.json.tmpl create mode 100644 dot_local/bin/executable_mic-toggle-processing create mode 100644 dot_local/bin/executable_mic-toggle-usb create mode 100644 dot_local/bin/executable_mic-usb-status delete mode 100644 pkglist/bluetooth.txt delete mode 100644 pkglist/common.txt delete mode 100644 pkglist/desktop.txt delete mode 100644 pkglist/dev.txt delete mode 100644 pkglist/entertainment.txt delete mode 100644 pkglist/hyprland.txt delete mode 100644 pkglist/laptop.txt delete mode 100644 pkglist/pipewire.txt delete mode 100644 pkglist/waybar.txt diff --git a/.chezmoiscripts/run_onchange_pipewire-rnnoise-check.sh.tmpl b/.chezmoiscripts/run_onchange_pipewire-rnnoise-check.sh.tmpl deleted file mode 100755 index fe28642..0000000 --- a/.chezmoiscripts/run_onchange_pipewire-rnnoise-check.sh.tmpl +++ /dev/null @@ -1,31 +0,0 @@ -{{- if (index .chezmoi.config.data.tags "pipewire") -}} -#!/bin/sh -set -eu - -# Re-run whenever the denoising config changes. -# conf-sha: {{ (include "dot_config/pipewire/pipewire.conf.d/99-input-denoising.conf") | sha256sum }} - -if command -v pacman >/dev/null 2>&1; then - if pacman -Q noise-suppression-for-voice >/dev/null 2>&1; then - exit 0 - fi - - if [ -t 0 ]; then - printf 'noise-suppression-for-voice not installed. Install now? [y/N] ' >&2 - read -r ans - case "$ans" in - [yY]|[yY][eE][sS]) sudo pacman -S --needed noise-suppression-for-voice ;; - *) printf 'Skipping noise-suppression-for-voice install.\n' >&2 ;; - esac - else - printf 'noise-suppression-for-voice not installed. Install with: sudo pacman -S --needed noise-suppression-for-voice\n' >&2 - fi -else - if [ ! -f /usr/lib/ladspa/librnnoise_ladspa.so ]; then - printf 'rnnoise LADSPA plugin missing; install noise-suppression-for-voice for your distro.\n' >&2 - fi -fi -{{- else -}} -#!/bin/sh -exit 0 -{{- end -}} diff --git a/dot_config/gtk-4.0/gtk.css b/dot_config/gtk-4.0/gtk.css new file mode 100644 index 0000000..492891d --- /dev/null +++ b/dot_config/gtk-4.0/gtk.css @@ -0,0 +1,129 @@ +/* Apex Theme System — GTK4 / Libadwaita */ +/* Auto-generated from Apex DNA */ + + +/* Scheme: Apex Neon (dark) */ + +@media (prefers-color-scheme: dark) { + + :root { + /* Core Surfaces */ + @define-color window_bg_color #050505; + @define-color window_fg_color #ededed; + + @define-color view_bg_color #050505; + @define-color view_fg_color #ededed; + + @define-color headerbar_bg_color #141414; + @define-color headerbar_fg_color #ededed; + @define-color headerbar_border_color #262626; + @define-color headerbar_backdrop_color @window_bg_color; + @define-color headerbar_shade_color rgba(0, 0, 0, 0.07); + + @define-color popover_bg_color #141414; + @define-color popover_fg_color #ededed; + + @define-color card_bg_color #141414; + @define-color card_fg_color #ededed; + @define-color card_shade_color rgba(0, 0, 0, 0.07); + + @define-color dialog_bg_color #141414; + @define-color dialog_fg_color #ededed; + + /* Accents */ + @define-color accent_color #00eaff; + @define-color accent_bg_color #00eaff; + @define-color accent_fg_color #050505; + + @define-color destructive_color #ff0044; + @define-color destructive_bg_color #ff0044; + @define-color destructive_fg_color #050505; + + @define-color success_color #00ff99; + @define-color success_bg_color #00ff99; + @define-color success_fg_color #050505; + + @define-color warning_color #ffb700; + @define-color warning_bg_color #ffb700; + @define-color warning_fg_color #050505; + + @define-color error_color #ff8899; + @define-color error_bg_color #ff8899; + @define-color error_fg_color #050505; + + /* UI Elements */ + @define-color borders #262626; + @define-color sidebar_bg_color #141414; + @define-color sidebar_fg_color #ededed; + @define-color sidebar_backdrop_color @window_bg_color; + @define-color sidebar_shade_color rgba(0, 0, 0, 0.07); + + /* Custom Apex Palette */ + @define-color apex_razor #ff0044; + @define-color apex_void #050505; + @define-color apex_stealth #404040; + } +} + +/* Scheme: Apex Aeon (light) */ + +@media (prefers-color-scheme: light) { + + :root { + /* Core Surfaces */ + @define-color window_bg_color #f5f5f5; + @define-color window_fg_color #0a0a0a; + + @define-color view_bg_color #f5f5f5; + @define-color view_fg_color #0a0a0a; + + @define-color headerbar_bg_color #e8e8e8; + @define-color headerbar_fg_color #0a0a0a; + @define-color headerbar_border_color #737373; + @define-color headerbar_backdrop_color @window_bg_color; + @define-color headerbar_shade_color rgba(0, 0, 0, 0.07); + + @define-color popover_bg_color #e8e8e8; + @define-color popover_fg_color #0a0a0a; + + @define-color card_bg_color #e8e8e8; + @define-color card_fg_color #0a0a0a; + @define-color card_shade_color rgba(0, 0, 0, 0.07); + + @define-color dialog_bg_color #e8e8e8; + @define-color dialog_fg_color #0a0a0a; + + /* Accents */ + @define-color accent_color #007a88; + @define-color accent_bg_color #007a88; + @define-color accent_fg_color #f5f5f5; + + @define-color destructive_color #ff0044; + @define-color destructive_bg_color #ff0044; + @define-color destructive_fg_color #f5f5f5; + + @define-color success_color #00b377; + @define-color success_bg_color #00b377; + @define-color success_fg_color #f5f5f5; + + @define-color warning_color #d18f00; + @define-color warning_bg_color #d18f00; + @define-color warning_fg_color #f5f5f5; + + @define-color error_color #ff4d6d; + @define-color error_bg_color #ff4d6d; + @define-color error_fg_color #f5f5f5; + + /* UI Elements */ + @define-color borders #737373; + @define-color sidebar_bg_color #e8e8e8; + @define-color sidebar_fg_color #0a0a0a; + @define-color sidebar_backdrop_color @window_bg_color; + @define-color sidebar_shade_color rgba(0, 0, 0, 0.07); + + /* Custom Apex Palette */ + @define-color apex_razor #ff0044; + @define-color apex_void #f5f5f5; + @define-color apex_stealth #a0a0a0; + } +} diff --git a/dot_config/hypr/hyprland.d/70-keybinds.conf.tmpl b/dot_config/hypr/hyprland.d/70-keybinds.conf.tmpl index 86395fd..efa2f22 100644 --- a/dot_config/hypr/hyprland.d/70-keybinds.conf.tmpl +++ b/dot_config/hypr/hyprland.d/70-keybinds.conf.tmpl @@ -3,10 +3,10 @@ ############################################## # Set programs that you use -$terminal = uwsm app -- ghostty -$term_tmux = uwsm app -- ghostty -e tmux -$term_tmux_append = uwsm app -- ghostty -e tmux a -$editor = uwsm app -- ghostty -e nvim +$terminal = uwsm app -- kitty +$term_tmux = uwsm app -- kitty -e tmux +$term_tmux_append = uwsm app -- kitty -e tmux a +$editor = uwsm app -- kitty -e nvim $alteditor = uwsm app -- zeditor $filemanager = uwsm app -- nautilus @@ -56,6 +56,7 @@ bind = $mainMod, X, exec, $taskman bind = $mainMod, C, exec, $clipman bind = $mainMod, R, exec, $pwdmgr bind = $mainMod, F4, exec, $soundctl +bind = $mainMod, backslash, exec, mic-toggle-usb # Communication bind = $mainMod, A, exec, hypr-element-toggle @@ -123,6 +124,10 @@ bind = $mainMod, 8, workspace, 8 bind = $mainMod, 9, workspace, 9 bind = $mainMod, 0, workspace, 10 +# MOVE CURRENT WORKSPACE TO A MONITOR with mainMod + SHIFT + [,/.] +bind = $mainMod SHIFT, comma, movecurrentworkspacetomonitor, l +bind = $mainMod SHIFT, period, movecurrentworkspacetomonitor, r + # MOVE ACTIVE WINDOW TO A WORKSPACE with mainMod + SHIFT + [0-9] bind = $mainMod SHIFT, 1, movetoworkspace, 1 bind = $mainMod SHIFT, 2, movetoworkspace, 2 diff --git a/dot_config/mimeapps.list b/dot_config/mimeapps.list index 917a9a6..adcf085 100644 --- a/dot_config/mimeapps.list +++ b/dot_config/mimeapps.list @@ -13,8 +13,8 @@ application/x-extension-xht=firefox.desktop application/pdf=org.pwmt.zathura-pdf-mupdf.desktop x-scheme-handler/jetbrains=jetbrains-toolbox.desktop application/gml+xml=dev.zed.Zed.desktop -image/png=satty.desktop -image/jpeg=satty.desktop +image/png=gimp.desktop +image/jpeg=gimp.desktop [Added Associations] x-scheme-handler/http=firefox.desktop; @@ -29,5 +29,5 @@ application/x-extension-xhtml=firefox.desktop; application/x-extension-xht=firefox.desktop; application/pdf=org.pwmt.zathura-pdf-mupdf.desktop; application/gml+xml=dev.zed.Zed.desktop; -image/png=satty.desktop; -image/jpeg=satty.desktop; +image/png=satty.desktop;gimp.desktop; +image/jpeg=satty.desktop;gimp.desktop; diff --git a/dot_config/pipewire/pipewire.conf.d/20-voice-engine.conf b/dot_config/pipewire/pipewire.conf.d/20-voice-engine.conf new file mode 100644 index 0000000..fd2da49 --- /dev/null +++ b/dot_config/pipewire/pipewire.conf.d/20-voice-engine.conf @@ -0,0 +1,72 @@ +context.modules = [ + { name = libpipewire-module-echo-cancel + args = { + # Standard mode: Acts as a virtual sink/source pair + monitor.mode = false + library.name = aec/libspa-aec-webrtc + node.description = "Voice Engine (AEC)" + + # 1. The Virtual Sink (Reference) + # Route your Game/Desktop audio here so it gets cancelled from the mic. + # It will automatically pass through to your default speakers. + sink.props = { + node.name = "voice_engine_reference" + node.description = "Voice Engine Reference (Sink)" + } + + # 2. The Processed Source (Mic) + # This is the output of the echo canceller. We feed this into RNNoise below. + source.props = { + node.name = "voice_engine_aec_source" + node.description = "Voice Engine AEC Output" + } + + aec.args = { + # CRITICAL: Fixes robotic audio by handling clock drift between USB devices + webrtc.drift_compensation_enabled = true + + # We use RNNoise separately for better quality, so disable this + webrtc.noise_suppression = false + + webrtc.voice_detection = true + webrtc.extended_filter = true + } + } + }, + { name = libpipewire-module-filter-chain + args = { + node.description = "Voice Engine (Final)" + media.name = "Voice Engine (Final)" + + filter.graph = { + nodes = [ + { + type = ladspa + name = rnnoise + plugin = "/usr/lib/ladspa/librnnoise_ladspa.so" + label = noise_suppressor_mono + control = { + "VAD Threshold (%)" = 50.0 + "VAD Grace Period (ms)" = 200 + "Retroactive VAD Grace (ms)" = 20 + } + } + ] + } + + # Automatically grabs the output from the AEC module above + capture.props = { + node.name = "voice_engine_rnnoise_in" + node.passive = true + "target.object" = "voice_engine_aec_source" + } + + # This is the FINAL device you select in Discord/Zoom/etc. + playback.props = { + node.name = "voice_engine_final" + node.description = "Voice Engine (Final)" + media.class = "Audio/Source" + } + } + } +] \ No newline at end of file diff --git a/dot_config/pipewire/pipewire.conf.d/60-echo-cancel.conf.tmpl b/dot_config/pipewire/pipewire.conf.d/60-echo-cancel.conf.tmpl deleted file mode 100644 index f98846e..0000000 --- a/dot_config/pipewire/pipewire.conf.d/60-echo-cancel.conf.tmpl +++ /dev/null @@ -1,39 +0,0 @@ -context.modules = [ - { - name = libpipewire-module-echo-cancel - args = { - library.name = aec/libspa-aec-webrtc - monitor.mode = true - - capture.props = { - node.name = "EC Capture" - node.passive = true - "target.object" = "{{ .chezmoi.config.data.microphone }}" - } - - source.props = { - node.name = "source_ec" - node.description = "Echo-cancelled microphone" - node.autoconnect = false - audio.channels = 1 - audio.position = [ MONO ] - } - - sink.props = { - node.name = "sink_ec" - node.description = "Echo cancellation reference" - } - - playback.props = { - node.name = "EC Playback" - node.passive = true - } - - aec.args = { - webrtc.extended_filter = false - webrtc.gain_control = false - webrtc.voice_detection = true - } - } - } -] diff --git a/dot_config/pipewire/pipewire.conf.d/99-input-denoising.conf b/dot_config/pipewire/pipewire.conf.d/99-input-denoising.conf deleted file mode 100644 index 85936c4..0000000 --- a/dot_config/pipewire/pipewire.conf.d/99-input-denoising.conf +++ /dev/null @@ -1,45 +0,0 @@ -context.modules = [ - { - name = libpipewire-module-filter-chain - args = { - node.description = "Noise Canceling source" - media.name = "Noise Canceling source" - - audio.channels = 1 - audio.position = [ MONO ] - - filter.graph = { - nodes = [ - { - type = ladspa - name = rnnoise - plugin = /usr/lib/ladspa/librnnoise_ladspa.so - label = noise_suppressor_mono - control = { - "VAD Threshold (%)" = 80.0 - "VAD Grace Period (ms)" = 200 - "Retroactive VAD Grace (ms)" = 0 - } - } - ] - } - - capture.props = { - node.name = "capture.rnnoise_source" - node.passive = true - audio.channels = 1 - audio.position = [ MONO ] - audio.rate = 48000 - "target.object" = "source_ec" - } - - playback.props = { - node.name = "rnnoise_source" - media.class = "Audio/Source" - audio.channels = 1 - audio.position = [ MONO ] - audio.rate = 48000 - } - } - } -] diff --git a/dot_config/private_htop/private_htoprc b/dot_config/private_htop/private_htoprc new file mode 100644 index 0000000..6af467b --- /dev/null +++ b/dot_config/private_htop/private_htoprc @@ -0,0 +1,66 @@ +# Beware! This file is rewritten by htop when settings are changed in the interface. +# The parser is also very primitive, and not human-friendly. +htop_version=3.4.1-3.4.1 +config_reader_min_version=3 +fields=0 4 5 48 17 18 38 39 40 47 2 46 47 49 1 +hide_kernel_threads=1 +hide_userland_threads=0 +hide_running_in_container=0 +shadow_other_users=0 +show_thread_names=0 +show_program_path=1 +highlight_base_name=1 +highlight_deleted_exe=1 +shadow_distribution_path_prefix=0 +highlight_megabytes=1 +highlight_threads=1 +highlight_changes=0 +highlight_changes_delay_secs=5 +find_comm_in_cmdline=1 +strip_exe_from_cmdline=1 +show_merged_command=0 +header_margin=1 +screen_tabs=1 +detailed_cpu_time=0 +cpu_count_from_one=0 +show_cpu_usage=1 +show_cpu_frequency=1 +show_cpu_temperature=1 +degree_fahrenheit=0 +show_cached_memory=1 +update_process_names=0 +account_guest_in_cpu_meter=0 +color_scheme=5 +enable_mouse=1 +delay=15 +hide_function_bar=0 +header_layout=three_30_40_30 +column_meters_0=System DateTime Uptime DiskIO NetworkIO +column_meter_modes_0=2 2 2 2 2 +column_meters_1=AllCPUs4 MemorySwap GPU +column_meter_modes_1=1 1 1 +column_meters_2=Tasks LoadAverage FileDescriptors SystemdUser Systemd +column_meter_modes_2=2 2 2 2 2 +tree_view=1 +sort_key=40 +tree_sort_key=39 +sort_direction=-1 +tree_sort_direction=-1 +tree_view_always_by_pid=0 +all_branches_collapsed=0 +screen:Main=PID PGRP SESSION USER PRIORITY NICE M_VIRT M_RESIDENT M_SHARE PERCENT_MEM STATE PERCENT_CPU PERCENT_MEM TIME Command +.sort_key=M_SHARE +.tree_sort_key=M_RESIDENT +.tree_view_always_by_pid=0 +.tree_view=1 +.sort_direction=-1 +.tree_sort_direction=-1 +.all_branches_collapsed=0 +screen:I/O=PID USER IO_PRIORITY IO_RATE IO_READ_RATE IO_WRITE_RATE PERCENT_SWAP_DELAY PERCENT_IO_DELAY Command +.sort_key=IO_RATE +.tree_sort_key=PID +.tree_view_always_by_pid=0 +.tree_view=0 +.sort_direction=-1 +.tree_sort_direction=1 +.all_branches_collapsed=0 diff --git a/dot_config/waybar/config.tmpl b/dot_config/waybar/config.tmpl index 26d7f97..2d386c2 100644 --- a/dot_config/waybar/config.tmpl +++ b/dot_config/waybar/config.tmpl @@ -127,6 +127,15 @@ "icon-size": 16 }, + "custom/mic-usb": { + "exec": "mic-usb-status", + "return-type": "json", + "interval": 2, + "format": " {text}", + "tooltip": true, + "on-click": "mic-toggle-usb" + }, + "wireplumber#source": { "node-type": "Audio/Source", "format": " {volume}%", @@ -327,6 +336,7 @@ "group/volume": { "orientation": "vertical", "modules": [ + "custom/mic-usb", "wireplumber#source", "wireplumber#sink" ] diff --git a/dot_config/waybar/style.css.tmpl b/dot_config/waybar/style.css.tmpl index 9b0a705..749d06e 100644 --- a/dot_config/waybar/style.css.tmpl +++ b/dot_config/waybar/style.css.tmpl @@ -81,7 +81,8 @@ window#waybar { #custom-swaync, #custom-temps-cycle, #custom-hyprsunset, -#custom-alhp { +#custom-alhp, +#custom-mic-usb { background: @pill_bg; color: @foreground; border: 1px solid @border; @@ -107,7 +108,8 @@ window#waybar { #custom-swaync:hover, #custom-temps-cycle:hover, #custom-hyprsunset:hover, -#custom-alhp:hover { +#custom-alhp:hover, +#custom-mic-usb:hover { background: @pill_hover; border-color: @accent; } @@ -123,7 +125,8 @@ window#waybar { } #custom-alhp.stale, -#wireplumber.muted { +#wireplumber.muted, +#custom-mic-usb.mic-usb-muted { border-color: @warning; } @@ -154,8 +157,11 @@ window#waybar { border-color: @error; } -#wireplumber.muted { color: @dim; } +#wireplumber.muted, +#custom-mic-usb.mic-usb-muted { color: @dim; } #idle_inhibitor.deactivated { color: @dim; } +#custom-mic-usb.mic-usb-unknown, +#custom-mic-usb.mic-unavailable { border-color: @error; color: @error; } /* Group wrappers */ #group-temps, @@ -194,6 +200,11 @@ window#waybar { padding: 2px 3px; } #group-volume #wireplumber:hover { background: @pill_hover; border-color: @accent; } +#group-volume #custom-mic-usb { + margin: 1px 0; + padding: 2px 3px; +} +#group-volume #custom-mic-usb:hover { background: @pill_hover; border-color: @accent; } /* Tooltips */ tooltip, diff --git a/dot_config/zsh/apex-aeon.zsh b/dot_config/zsh/apex-aeon.zsh index 3963e5b..5b91d1a 100644 --- a/dot_config/zsh/apex-aeon.zsh +++ b/dot_config/zsh/apex-aeon.zsh @@ -82,10 +82,15 @@ typeset -g apex_in_git=0 typeset -g apex_git_branch="" typeset -g apex_git_dirty_wt=0 typeset -g apex_git_dirty_ix=0 +typeset -g apex_git_untracked=0 +typeset -g apex_git_conflict=0 typeset -g apex_git_op="" typeset -g apex_git_up_ok=0 typeset -g apex_git_ahead=0 typeset -g apex_git_behind=0 +typeset -g apex_git_stash=0 +typeset -g apex_git_root="" +typeset -g apex_git_dir="" # Radar previous snapshots (transition detection) typeset -g apex_prev_in_git=-1 @@ -123,6 +128,50 @@ apex__project_sig() { [[ -n "$s" ]] && print -r -- "$s" } +apex__escape_prompt() { + local s="$1" + s="${s//\\%/%%}" + print -r -- "$s" +} + +apex__now_float() { + if [[ -n "${EPOCHREALTIME:-}" ]]; then + print -r -- "$EPOCHREALTIME" + elif [[ -n "${EPOCHSECONDS:-}" ]]; then + print -r -- "${EPOCHSECONDS}.0" + else + print -r -- "0.0" + fi +} + +apex__find_git_root() { + local dir="$PWD" + local git_root="" + local git_dir="" + + while [[ -n "$dir" ]]; do + if [[ -d "$dir/.git" ]]; then + git_root="$dir" + git_dir="$dir/.git" + break + elif [[ -f "$dir/.git" ]]; then + local line + line="$(<"$dir/.git")" + if [[ "$line" == gitdir:* ]]; then + git_root="$dir" + git_dir="${line#gitdir: }" + [[ "$git_dir" != /* ]] && git_dir="$dir/$git_dir" + break + fi + fi + + [[ "$dir" == "/" ]] && break + dir="${dir:h}" + done + + [[ -n "$git_root" ]] && print -r -- "${git_root}|${git_dir}" +} + # ----------------------------------------------------------------------------- # 6) INTEL (sticky; updated each prompt) # ----------------------------------------------------------------------------- @@ -143,6 +192,8 @@ apex_update_intel() { apex_mode_sig="nix" elif [[ -n "$DIRENV_DIR" ]]; then apex_mode_sig="direnv" + elif [[ -f /run/.containerenv || -f /.dockerenv ]]; then + apex_mode_sig="ctr" else apex_mode_sig="" fi @@ -164,39 +215,101 @@ apex_git_update() { apex_git_branch="" apex_git_dirty_wt=0 apex_git_dirty_ix=0 + apex_git_untracked=0 + apex_git_conflict=0 apex_git_op="" apex_git_up_ok=0 apex_git_ahead=0 apex_git_behind=0 + apex_git_stash=0 - command git rev-parse --is-inside-work-tree &>/dev/null || return + local status_out + status_out="$(command git status --porcelain=2 --branch 2>/dev/null)" || { + apex_git_root="" + apex_git_dir="" + return + } apex_in_git=1 - apex_git_branch="$( - command git symbolic-ref --quiet --short HEAD 2>/dev/null \ - || command git rev-parse --short HEAD 2>/dev/null - )" + if (( apex_pwd_changed )) || [[ -z "$apex_git_root" ]]; then + local root_info + root_info="$(apex__find_git_root)" + if [[ -n "$root_info" ]]; then + apex_git_root="${root_info%%|*}" + apex_git_dir="${root_info#*|}" + else + apex_git_root="" + apex_git_dir="" + fi + fi - local gd; gd="$(command git rev-parse --git-dir 2>/dev/null)" || return - [[ -d "$gd/rebase-apply" || -d "$gd/rebase-merge" ]] && apex_git_op="rebase" - [[ -f "$gd/MERGE_HEAD" ]] && apex_git_op="merge" - [[ -f "$gd/CHERRY_PICK_HEAD" ]] && apex_git_op="cherry-pick" - [[ -f "$gd/BISECT_LOG" ]] && apex_git_op="bisect" + local branch_head="" branch_oid="" upstream="" + local xy="" ix="" wt="" + local line + while IFS= read -r line; do + case "$line" in + \#\ branch.head\ *) + branch_head="${line#\# branch.head }" + ;; + \#\ branch.oid\ *) + branch_oid="${line#\# branch.oid }" + ;; + \#\ branch.upstream\ *) + upstream="${line#\# branch.upstream }" + ;; + \#\ branch.ab\ *) + local ab a b + ab="${line#\# branch.ab }" + IFS=' ' read -r a b <<<"$ab" + a="${a#+}" + b="${b#-}" + apex_git_ahead="${a:-0}" + apex_git_behind="${b:-0}" + ;; + 1\ *|2\ *) + xy="${line[3,4]}" + ix="${xy[1]}" + wt="${xy[2]}" + [[ "$ix" != "." ]] && apex_git_dirty_ix=1 + [[ "$wt" != "." ]] && apex_git_dirty_wt=1 + ;; + u\ *) + apex_git_conflict=1 + apex_git_dirty_ix=1 + apex_git_dirty_wt=1 + ;; + \?\ *) + apex_git_untracked=1 + ;; + esac + done <<<"$status_out" - # Dirty markers - command git diff --quiet --ignore-submodules -- 2>/dev/null || apex_git_dirty_wt=1 - command git diff --cached --quiet --ignore-submodules -- 2>/dev/null || apex_git_dirty_ix=1 + if [[ -n "$branch_head" && "$branch_head" != "(detached)" && "$branch_head" != "HEAD" ]]; then + apex_git_branch="$branch_head" + elif [[ -n "$branch_oid" ]]; then + apex_git_branch="${branch_oid[1,7]}" + fi - # Upstream (earned ✓) - if command git rev-parse --abbrev-ref --symbolic-full-name @{u} &>/dev/null; then - local counts behind ahead - counts="$(command git rev-list --left-right --count @{u}...HEAD 2>/dev/null)" || return - local IFS=$' \t' - read -r behind ahead <<<"$counts" - apex_git_behind="${behind:-0}" - apex_git_ahead="${ahead:-0}" + if [[ -n "$apex_git_dir" ]]; then + [[ -d "$apex_git_dir/rebase-apply" || -d "$apex_git_dir/rebase-merge" ]] && apex_git_op="rebase" + [[ -f "$apex_git_dir/MERGE_HEAD" ]] && apex_git_op="merge" + [[ -f "$apex_git_dir/CHERRY_PICK_HEAD" ]] && apex_git_op="cherry-pick" + [[ -f "$apex_git_dir/BISECT_LOG" ]] && apex_git_op="bisect" - if (( apex_git_dirty_wt == 0 && apex_git_dirty_ix == 0 )) && [[ -z "$apex_git_op" ]]; then + if [[ -f "$apex_git_dir/logs/refs/stash" ]]; then + local -a stash_lines + stash_lines=(${(f)"$(<"$apex_git_dir/logs/refs/stash")"}) + apex_git_stash=$#stash_lines + elif [[ -f "$apex_git_dir/refs/stash" ]]; then + apex_git_stash=1 + fi + fi + + (( apex_git_conflict )) && apex_git_op="conflict" + + if [[ -n "$upstream" && "$upstream" != "(gone)" ]]; then + if (( apex_git_dirty_wt == 0 && apex_git_dirty_ix == 0 && apex_git_untracked == 0 && apex_git_conflict == 0 && apex_git_stash == 0 )) \ + && [[ -z "$apex_git_op" ]]; then [[ "$apex_git_behind" == "0" && "$apex_git_ahead" == "0" ]] && apex_git_up_ok=1 fi fi @@ -248,19 +361,23 @@ apex_intel_r() { apex_vcs_r() { (( APEX[SHOW_VCS] )) || return 0 (( apex_in_git )) || return 0 + local branch; branch="$(apex__escape_prompt "$apex_git_branch")" if [[ -n "$apex_git_op" ]]; then - print -n "%F{${C[ALERT]}}${I[GIT]} ${apex_git_branch} ${apex_git_op}%f" + print -n "%F{${C[ALERT]}}${I[GIT]} ${branch} ${apex_git_op}%f" return 0 fi - print -n "%F{${C[CYAN]}}${I[GIT]} ${apex_git_branch}%f" + print -n "%F{${C[CYAN]}}${I[GIT]} ${branch}%f" local mark="" (( apex_git_dirty_ix )) && mark+="+" (( apex_git_dirty_wt )) && mark+="!" + (( apex_git_untracked )) && mark+="?" [[ -n "$mark" ]] && print -n "%F{${C[GOLD]}} ${mark}%f" + (( apex_git_stash > 0 )) && print -n "%F{${C[MUTED]}} s${apex_git_stash}%f" + (( apex_git_up_ok )) && print -n "%F{${C[OK]}} ✓%f" if (( APEX[GIT_AHEAD_BEHIND] )); then @@ -270,15 +387,23 @@ apex_vcs_r() { } apex_friction_r() { - if (( APEX[SHOW_RO] )) && [[ ! -w . ]]; then - print -n "%F{${C[GOLD]}}${I[ROOT]} ro%f" - return 0 + if (( APEX[SHOW_RO] )); then + local ro=0 + [[ ! -w . ]] && ro=1 + if (( apex_in_git )) && [[ -n "$apex_git_root" && ! -w "$apex_git_root" ]]; then + ro=1 + fi + if (( ro )); then + print -n "%F{${C[GOLD]}}${I[ROOT]} ro%f" + return 0 + fi fi if (( APEX[SHOW_JOBS] )); then - local jc - jc=$(jobs -p 2>/dev/null | wc -l | tr -d ' ') - if [[ -n "$jc" && "$jc" != "0" ]]; then + local -a job_pids + job_pids=(${(f)"$(jobs -p 2>/dev/null)"}) + local jc=$#job_pids + if (( jc > 0 )); then print -n "%F{${C[MUTED]}}${I[JOBS]} ${jc}%f" return 0 fi @@ -313,6 +438,7 @@ apex_radar_aar() { (( show )) || return 0 local short; short="$(apex__short_cmd "$cmd")" + short="$(apex__escape_prompt "$short")" local dur_color="${C[MUTED]}" (( ms >= ${APEX[SLOW_HARD_MS]} )) && dur_color="${C[GOLD]}" @@ -388,10 +514,11 @@ apex_radar_context_burst() { # Git first if (( apex_in_git )); then + local branch; branch="$(apex__escape_prompt "$apex_git_branch")" if [[ -n "$apex_git_op" ]]; then - out+="%F{${C[ALERT]}}${I[GIT]} ${apex_git_branch} ${apex_git_op}%f" + out+="%F{${C[ALERT]}}${I[GIT]} ${branch} ${apex_git_op}%f" else - out+="%F{${C[CYAN]}}${I[GIT]} ${apex_git_branch}%f" + out+="%F{${C[CYAN]}}${I[GIT]} ${branch}%f" fi fi @@ -417,7 +544,7 @@ apex_radar_context_burst() { # ----------------------------------------------------------------------------- apex_preexec_hook() { apex_has_run_cmd=1 - apex_cmd_start=${EPOCHREALTIME:-$EPOCHSECONDS} + apex_cmd_start="$(apex__now_float)" apex_last_cmd="$1" } @@ -436,9 +563,14 @@ apex_precmd_hook() { (( apex_has_run_cmd )) && ran=1 if (( ran )); then - local now=${EPOCHREALTIME:-$EPOCHSECONDS} - local -i ms - ms=$(( (now - apex_cmd_start) * 1000 )) + local now; now="$(apex__now_float)" + local -i ms=0 + local -F delta=0.0 + if [[ -n "$now" ]]; then + delta=$(( now - apex_cmd_start )) + (( delta < 0 )) && delta=0 + ms=$(( delta * 1000 )) + fi # Show time if: slow OR ops OR failed. local dur="" diff --git a/dot_config/zsh/apex-neon.zsh b/dot_config/zsh/apex-neon.zsh index dd4dd15..b7c4234 100644 --- a/dot_config/zsh/apex-neon.zsh +++ b/dot_config/zsh/apex-neon.zsh @@ -82,10 +82,15 @@ typeset -g apex_in_git=0 typeset -g apex_git_branch="" typeset -g apex_git_dirty_wt=0 typeset -g apex_git_dirty_ix=0 +typeset -g apex_git_untracked=0 +typeset -g apex_git_conflict=0 typeset -g apex_git_op="" typeset -g apex_git_up_ok=0 typeset -g apex_git_ahead=0 typeset -g apex_git_behind=0 +typeset -g apex_git_stash=0 +typeset -g apex_git_root="" +typeset -g apex_git_dir="" # Radar previous snapshots (transition detection) typeset -g apex_prev_in_git=-1 @@ -123,6 +128,50 @@ apex__project_sig() { [[ -n "$s" ]] && print -r -- "$s" } +apex__escape_prompt() { + local s="$1" + s="${s//\\%/%%}" + print -r -- "$s" +} + +apex__now_float() { + if [[ -n "${EPOCHREALTIME:-}" ]]; then + print -r -- "$EPOCHREALTIME" + elif [[ -n "${EPOCHSECONDS:-}" ]]; then + print -r -- "${EPOCHSECONDS}.0" + else + print -r -- "0.0" + fi +} + +apex__find_git_root() { + local dir="$PWD" + local git_root="" + local git_dir="" + + while [[ -n "$dir" ]]; do + if [[ -d "$dir/.git" ]]; then + git_root="$dir" + git_dir="$dir/.git" + break + elif [[ -f "$dir/.git" ]]; then + local line + line="$(<"$dir/.git")" + if [[ "$line" == gitdir:* ]]; then + git_root="$dir" + git_dir="${line#gitdir: }" + [[ "$git_dir" != /* ]] && git_dir="$dir/$git_dir" + break + fi + fi + + [[ "$dir" == "/" ]] && break + dir="${dir:h}" + done + + [[ -n "$git_root" ]] && print -r -- "${git_root}|${git_dir}" +} + # ----------------------------------------------------------------------------- # 6) INTEL (sticky; updated each prompt) # ----------------------------------------------------------------------------- @@ -143,6 +192,8 @@ apex_update_intel() { apex_mode_sig="nix" elif [[ -n "$DIRENV_DIR" ]]; then apex_mode_sig="direnv" + elif [[ -f /run/.containerenv || -f /.dockerenv ]]; then + apex_mode_sig="ctr" else apex_mode_sig="" fi @@ -164,39 +215,101 @@ apex_git_update() { apex_git_branch="" apex_git_dirty_wt=0 apex_git_dirty_ix=0 + apex_git_untracked=0 + apex_git_conflict=0 apex_git_op="" apex_git_up_ok=0 apex_git_ahead=0 apex_git_behind=0 + apex_git_stash=0 - command git rev-parse --is-inside-work-tree &>/dev/null || return + local status_out + status_out="$(command git status --porcelain=2 --branch 2>/dev/null)" || { + apex_git_root="" + apex_git_dir="" + return + } apex_in_git=1 - apex_git_branch="$( - command git symbolic-ref --quiet --short HEAD 2>/dev/null \ - || command git rev-parse --short HEAD 2>/dev/null - )" + if (( apex_pwd_changed )) || [[ -z "$apex_git_root" ]]; then + local root_info + root_info="$(apex__find_git_root)" + if [[ -n "$root_info" ]]; then + apex_git_root="${root_info%%|*}" + apex_git_dir="${root_info#*|}" + else + apex_git_root="" + apex_git_dir="" + fi + fi - local gd; gd="$(command git rev-parse --git-dir 2>/dev/null)" || return - [[ -d "$gd/rebase-apply" || -d "$gd/rebase-merge" ]] && apex_git_op="rebase" - [[ -f "$gd/MERGE_HEAD" ]] && apex_git_op="merge" - [[ -f "$gd/CHERRY_PICK_HEAD" ]] && apex_git_op="cherry-pick" - [[ -f "$gd/BISECT_LOG" ]] && apex_git_op="bisect" + local branch_head="" branch_oid="" upstream="" + local xy="" ix="" wt="" + local line + while IFS= read -r line; do + case "$line" in + \#\ branch.head\ *) + branch_head="${line#\# branch.head }" + ;; + \#\ branch.oid\ *) + branch_oid="${line#\# branch.oid }" + ;; + \#\ branch.upstream\ *) + upstream="${line#\# branch.upstream }" + ;; + \#\ branch.ab\ *) + local ab a b + ab="${line#\# branch.ab }" + IFS=' ' read -r a b <<<"$ab" + a="${a#+}" + b="${b#-}" + apex_git_ahead="${a:-0}" + apex_git_behind="${b:-0}" + ;; + 1\ *|2\ *) + xy="${line[3,4]}" + ix="${xy[1]}" + wt="${xy[2]}" + [[ "$ix" != "." ]] && apex_git_dirty_ix=1 + [[ "$wt" != "." ]] && apex_git_dirty_wt=1 + ;; + u\ *) + apex_git_conflict=1 + apex_git_dirty_ix=1 + apex_git_dirty_wt=1 + ;; + \?\ *) + apex_git_untracked=1 + ;; + esac + done <<<"$status_out" - # Dirty markers - command git diff --quiet --ignore-submodules -- 2>/dev/null || apex_git_dirty_wt=1 - command git diff --cached --quiet --ignore-submodules -- 2>/dev/null || apex_git_dirty_ix=1 + if [[ -n "$branch_head" && "$branch_head" != "(detached)" && "$branch_head" != "HEAD" ]]; then + apex_git_branch="$branch_head" + elif [[ -n "$branch_oid" ]]; then + apex_git_branch="${branch_oid[1,7]}" + fi - # Upstream (earned ✓) - if command git rev-parse --abbrev-ref --symbolic-full-name @{u} &>/dev/null; then - local counts behind ahead - counts="$(command git rev-list --left-right --count @{u}...HEAD 2>/dev/null)" || return - local IFS=$' \t' - read -r behind ahead <<<"$counts" - apex_git_behind="${behind:-0}" - apex_git_ahead="${ahead:-0}" + if [[ -n "$apex_git_dir" ]]; then + [[ -d "$apex_git_dir/rebase-apply" || -d "$apex_git_dir/rebase-merge" ]] && apex_git_op="rebase" + [[ -f "$apex_git_dir/MERGE_HEAD" ]] && apex_git_op="merge" + [[ -f "$apex_git_dir/CHERRY_PICK_HEAD" ]] && apex_git_op="cherry-pick" + [[ -f "$apex_git_dir/BISECT_LOG" ]] && apex_git_op="bisect" - if (( apex_git_dirty_wt == 0 && apex_git_dirty_ix == 0 )) && [[ -z "$apex_git_op" ]]; then + if [[ -f "$apex_git_dir/logs/refs/stash" ]]; then + local -a stash_lines + stash_lines=(${(f)"$(<"$apex_git_dir/logs/refs/stash")"}) + apex_git_stash=$#stash_lines + elif [[ -f "$apex_git_dir/refs/stash" ]]; then + apex_git_stash=1 + fi + fi + + (( apex_git_conflict )) && apex_git_op="conflict" + + if [[ -n "$upstream" && "$upstream" != "(gone)" ]]; then + if (( apex_git_dirty_wt == 0 && apex_git_dirty_ix == 0 && apex_git_untracked == 0 && apex_git_conflict == 0 && apex_git_stash == 0 )) \ + && [[ -z "$apex_git_op" ]]; then [[ "$apex_git_behind" == "0" && "$apex_git_ahead" == "0" ]] && apex_git_up_ok=1 fi fi @@ -248,19 +361,23 @@ apex_intel_r() { apex_vcs_r() { (( APEX[SHOW_VCS] )) || return 0 (( apex_in_git )) || return 0 + local branch; branch="$(apex__escape_prompt "$apex_git_branch")" if [[ -n "$apex_git_op" ]]; then - print -n "%F{${C[ALERT]}}${I[GIT]} ${apex_git_branch} ${apex_git_op}%f" + print -n "%F{${C[ALERT]}}${I[GIT]} ${branch} ${apex_git_op}%f" return 0 fi - print -n "%F{${C[CYAN]}}${I[GIT]} ${apex_git_branch}%f" + print -n "%F{${C[CYAN]}}${I[GIT]} ${branch}%f" local mark="" (( apex_git_dirty_ix )) && mark+="+" (( apex_git_dirty_wt )) && mark+="!" + (( apex_git_untracked )) && mark+="?" [[ -n "$mark" ]] && print -n "%F{${C[GOLD]}} ${mark}%f" + (( apex_git_stash > 0 )) && print -n "%F{${C[MUTED]}} s${apex_git_stash}%f" + (( apex_git_up_ok )) && print -n "%F{${C[OK]}} ✓%f" if (( APEX[GIT_AHEAD_BEHIND] )); then @@ -270,15 +387,23 @@ apex_vcs_r() { } apex_friction_r() { - if (( APEX[SHOW_RO] )) && [[ ! -w . ]]; then - print -n "%F{${C[GOLD]}}${I[ROOT]} ro%f" - return 0 + if (( APEX[SHOW_RO] )); then + local ro=0 + [[ ! -w . ]] && ro=1 + if (( apex_in_git )) && [[ -n "$apex_git_root" && ! -w "$apex_git_root" ]]; then + ro=1 + fi + if (( ro )); then + print -n "%F{${C[GOLD]}}${I[ROOT]} ro%f" + return 0 + fi fi if (( APEX[SHOW_JOBS] )); then - local jc - jc=$(jobs -p 2>/dev/null | wc -l | tr -d ' ') - if [[ -n "$jc" && "$jc" != "0" ]]; then + local -a job_pids + job_pids=(${(f)"$(jobs -p 2>/dev/null)"}) + local jc=$#job_pids + if (( jc > 0 )); then print -n "%F{${C[MUTED]}}${I[JOBS]} ${jc}%f" return 0 fi @@ -313,6 +438,7 @@ apex_radar_aar() { (( show )) || return 0 local short; short="$(apex__short_cmd "$cmd")" + short="$(apex__escape_prompt "$short")" local dur_color="${C[MUTED]}" (( ms >= ${APEX[SLOW_HARD_MS]} )) && dur_color="${C[GOLD]}" @@ -388,10 +514,11 @@ apex_radar_context_burst() { # Git first if (( apex_in_git )); then + local branch; branch="$(apex__escape_prompt "$apex_git_branch")" if [[ -n "$apex_git_op" ]]; then - out+="%F{${C[ALERT]}}${I[GIT]} ${apex_git_branch} ${apex_git_op}%f" + out+="%F{${C[ALERT]}}${I[GIT]} ${branch} ${apex_git_op}%f" else - out+="%F{${C[CYAN]}}${I[GIT]} ${apex_git_branch}%f" + out+="%F{${C[CYAN]}}${I[GIT]} ${branch}%f" fi fi @@ -417,7 +544,7 @@ apex_radar_context_burst() { # ----------------------------------------------------------------------------- apex_preexec_hook() { apex_has_run_cmd=1 - apex_cmd_start=${EPOCHREALTIME:-$EPOCHSECONDS} + apex_cmd_start="$(apex__now_float)" apex_last_cmd="$1" } @@ -436,9 +563,14 @@ apex_precmd_hook() { (( apex_has_run_cmd )) && ran=1 if (( ran )); then - local now=${EPOCHREALTIME:-$EPOCHSECONDS} - local -i ms - ms=$(( (now - apex_cmd_start) * 1000 )) + local now; now="$(apex__now_float)" + local -i ms=0 + local -F delta=0.0 + if [[ -n "$now" ]]; then + delta=$(( now - apex_cmd_start )) + (( delta < 0 )) && delta=0 + ms=$(( delta * 1000 )) + fi # Show time if: slow OR ops OR failed. local dur="" diff --git a/dot_gemini/settings.json.tmpl b/dot_gemini/settings.json.tmpl deleted file mode 100644 index 6db005c..0000000 --- a/dot_gemini/settings.json.tmpl +++ /dev/null @@ -1,10 +0,0 @@ -{ - "security": { - "auth": { - "selectedType": "oauth-personal" - } - }, - "ui": { - "theme": "{{ .chezmoi.homeDir }}/.gemini/themes/{{ .chezmoi.config.data.theme }}.json" - } -} diff --git a/dot_local/bin/executable_mic-toggle-processing b/dot_local/bin/executable_mic-toggle-processing new file mode 100644 index 0000000..d99395c --- /dev/null +++ b/dot_local/bin/executable_mic-toggle-processing @@ -0,0 +1,90 @@ +#!/bin/sh +set -eu + +processed_name="processed_mic_output" +raw_name="raw_mic_output" +action="${1:-toggle}" + +case "$action" in + --status|-s) + action="status" + ;; + --help|-h) + printf 'Usage: %s [--status]\n' "$0" + exit 0 + ;; + toggle|"") + action="toggle" + ;; + *) + printf 'Unknown option: %s\n' "$action" >&2 + exit 2 + ;; +esac + +if ! command -v pw-cli >/dev/null 2>&1; then + printf 'pw-cli not found in PATH.\n' >&2 + exit 1 +fi + +if ! command -v wpctl >/dev/null 2>&1; then + printf 'wpctl not found in PATH.\n' >&2 + exit 1 +fi + +get_node_id() { + pw-cli info "$1" 2>/dev/null | awk -F' = ' ' + /object.id/ { + gsub(/"/, "", $2) + print $2 + exit + } + ' +} + +processed_id="$(get_node_id "$processed_name")" +raw_id="$(get_node_id "$raw_name")" + +if [ -z "${processed_id:-}" ] || [ -z "${raw_id:-}" ]; then + printf 'Unable to resolve "%s" or "%s".\n' "$processed_name" "$raw_name" >&2 + exit 1 +fi + +default_id="$( + wpctl status 2>/dev/null | awk ' + $1 == "Sources:" || $2 == "Sources:" { in_sources = 1; next } + in_sources && ($1 == "Sinks:" || $2 == "Sinks:") { exit } + in_sources && match($0, /\\* ([0-9]+)\\./, m) { print m[1]; exit } + ' +)" + +if [ "$action" = "status" ]; then + if [ -z "${default_id:-}" ]; then + printf 'unknown\n' + exit 1 + fi + + if [ "$default_id" = "$processed_id" ]; then + printf 'processed\n' + exit 0 + fi + + if [ "$default_id" = "$raw_id" ]; then + printf 'raw\n' + exit 0 + fi + + printf 'other:%s\n' "$default_id" + exit 0 +fi + +if [ -z "${default_id:-}" ]; then + wpctl set-default "$processed_id" + exit 0 +fi + +if [ "$default_id" = "$processed_id" ]; then + wpctl set-default "$raw_id" +else + wpctl set-default "$processed_id" +fi diff --git a/dot_local/bin/executable_mic-toggle-usb b/dot_local/bin/executable_mic-toggle-usb new file mode 100644 index 0000000..9ad32af --- /dev/null +++ b/dot_local/bin/executable_mic-toggle-usb @@ -0,0 +1,31 @@ +#!/bin/sh +set -eu + +node_name="input_usb_condenser_to_mixer" + +if ! command -v pw-cli >/dev/null 2>&1; then + printf 'pw-cli not found in PATH.\n' >&2 + exit 1 +fi + +if ! command -v wpctl >/dev/null 2>&1; then + printf 'wpctl not found in PATH.\n' >&2 + exit 1 +fi + +node_id=$( + pw-cli info "$node_name" 2>/dev/null | awk -F' = ' ' + /object.id/ { + gsub(/"/, "", $2) + print $2 + exit + } + ' +) + +if [ -z "${node_id:-}" ]; then + printf 'Unable to resolve node "%s".\n' "$node_name" >&2 + exit 1 +fi + +wpctl set-mute "$node_id" toggle diff --git a/dot_local/bin/executable_mic-usb-status b/dot_local/bin/executable_mic-usb-status new file mode 100644 index 0000000..35b9b80 --- /dev/null +++ b/dot_local/bin/executable_mic-usb-status @@ -0,0 +1,60 @@ +#!/bin/sh +set -eu + +node_name="input_usb_condenser_to_mixer" + +json_escape() { + printf '%s' "$1" | sed 's/\\/\\\\/g; s/"/\\"/g' +} + +if ! command -v pw-cli >/dev/null 2>&1; then + printf '{"text":"USB","tooltip":"pw-cli not found","class":"mic-unavailable"}\n' + exit 0 +fi + +if ! pw-cli info "$node_name" >/dev/null 2>&1; then + printf '{"text":"USB","tooltip":"%s missing","class":"mic-unavailable"}\n' \ + "$(json_escape "$node_name")" + exit 0 +fi + +if ! command -v wpctl >/dev/null 2>&1; then + printf '{"text":"USB","tooltip":"wpctl not found","class":"mic-unavailable"}\n' + exit 0 +fi + +node_id=$( + pw-cli info "$node_name" 2>/dev/null | awk -F' = ' ' + /object.id/ { + gsub(/"/, "", $2) + print $2 + exit + } + ' +) + +if [ -z "${node_id:-}" ]; then + printf '{"text":"USB","tooltip":"%s missing","class":"mic-unavailable"}\n' \ + "$(json_escape "$node_name")" + exit 0 +fi + +status=$(wpctl get-volume "$node_id" 2>/dev/null || true) + +class="mic-usb-unknown" +tooltip="USB Condenser state unknown" + +case "$status" in + *MUTED*|*muted*) + class="mic-usb-muted" + tooltip="USB Condenser muted" + ;; + Volume:*) + class="mic-usb-live" + tooltip="USB Condenser live" + ;; +esac + +printf '{"text":"USB","tooltip":"%s","class":"%s"}\n' \ + "$(json_escape "$tooltip")" \ + "$(json_escape "$class")" diff --git a/dot_local/share/Steam/steamapps/common/Counter-Strike Global Offensive/game/csgo/cfg/autoexec.cfg b/dot_local/share/Steam/steamapps/common/Counter-Strike Global Offensive/game/csgo/cfg/autoexec.cfg index afdb024..ef349cc 100644 --- a/dot_local/share/Steam/steamapps/common/Counter-Strike Global Offensive/game/csgo/cfg/autoexec.cfg +++ b/dot_local/share/Steam/steamapps/common/Counter-Strike Global Offensive/game/csgo/cfg/autoexec.cfg @@ -49,7 +49,7 @@ cl_crosshair_sniper_width 1 cl_crosshair_friendly_warning 1 // Mouse -sensitivity "0.355" +sensitivity "0.425" zoom_sensitivity_ratio "1.0" // Radar diff --git a/pkglist/bluetooth.txt b/pkglist/bluetooth.txt deleted file mode 100644 index ccaf988..0000000 --- a/pkglist/bluetooth.txt +++ /dev/null @@ -1,3 +0,0 @@ -bluez -bluez-utils -blueman diff --git a/pkglist/common.txt b/pkglist/common.txt deleted file mode 100644 index ddf2ac5..0000000 --- a/pkglist/common.txt +++ /dev/null @@ -1,15 +0,0 @@ -bat -btop -chezmoi -curl -eza -fd -fzf -git -jq -neovim -otf-geist-mono-nerd -ripgrep -tmux -zoxide -zsh diff --git a/pkglist/desktop.txt b/pkglist/desktop.txt deleted file mode 100644 index 37445b0..0000000 --- a/pkglist/desktop.txt +++ /dev/null @@ -1,5 +0,0 @@ -gamemode -mangohud -mumble -steam -vesktop-bin diff --git a/pkglist/dev.txt b/pkglist/dev.txt deleted file mode 100644 index 96adcd0..0000000 --- a/pkglist/dev.txt +++ /dev/null @@ -1,14 +0,0 @@ -jetbrains-toolbox -ollama -pandoc-cli -texlive-basic -texlive-bibtexextra -texlive-bin -texlive-fontsrecommended -texlive-latex -texlive-latexextra -texlive-luatex -texlive-xetex -uv -zathura -zathura-pdf-mupdf diff --git a/pkglist/entertainment.txt b/pkglist/entertainment.txt deleted file mode 100644 index f3b48bd..0000000 --- a/pkglist/entertainment.txt +++ /dev/null @@ -1,6 +0,0 @@ -jellyfin-mpv-shim -mpv -mpv-shim-default-shaders -spicetify-cli -spicetify-marketplace-bin -spotify-launcher diff --git a/pkglist/hyprland.txt b/pkglist/hyprland.txt deleted file mode 100644 index 864c8d1..0000000 --- a/pkglist/hyprland.txt +++ /dev/null @@ -1,45 +0,0 @@ -alacritty -chromium -cliphist -element-desktop -firefox -fuzzel -ghostty -ghostty-shell-integration -ghostty-terminfo -grim -grimblast-git -hyprcursor -hypridle -hyprland -hyprlock -hyprpaper -hyprpolkitagent -hyprsunset -keepassxc -kitty -kitty-shell-integration -kitty-terminfo -nautilus -nextcloud-client -owlry -owlry-meta-full -playerctl -pwvucontrol -python -python-toml -satty -sherlock-launcher-bin -slurp -swww -swaync -swayosd -uwsm -wezterm -wf-recorder -wl-clip-persist -wl-clipboard -xdg-desktop-portal -xdg-desktop-portal-gtk -xdg-desktop-portal-hyprland -zed diff --git a/pkglist/laptop.txt b/pkglist/laptop.txt deleted file mode 100644 index 9a24357..0000000 --- a/pkglist/laptop.txt +++ /dev/null @@ -1,4 +0,0 @@ -brightnessctl -network-manager-applet -power-profiles-daemon -upower diff --git a/pkglist/pipewire.txt b/pkglist/pipewire.txt deleted file mode 100644 index 909797e..0000000 --- a/pkglist/pipewire.txt +++ /dev/null @@ -1,9 +0,0 @@ -pipewire -pipewire-alsa -pipewire-audio -pipewire-jack -pipewire-pulse -pipewire-session-manager -rnnoise -local/noise-suppression-for-voice -wireplumber diff --git a/pkglist/waybar.txt b/pkglist/waybar.txt deleted file mode 100644 index 894f475..0000000 --- a/pkglist/waybar.txt +++ /dev/null @@ -1,3 +0,0 @@ -alhp-utils -libnotify -waybar