[Update] bulk update
This commit is contained in:
@@ -0,0 +1,28 @@
|
|||||||
|
# Shell formatting for this repo.
|
||||||
|
#
|
||||||
|
# Both `shfmt` and the Claude format hook (common/.config/claude/hooks/format.py, which only
|
||||||
|
# runs shfmt/fish_indent where an .editorconfig opts in) read this file, so the policy and the
|
||||||
|
# tool that enforces it live in one place. Neovim reads it natively too.
|
||||||
|
#
|
||||||
|
# The settings were picked to stay as close as possible to how these scripts were already
|
||||||
|
# written by hand: 2-space indent, `case` arms indented under `case`, and `&&`/`||` starting
|
||||||
|
# the wrapped line rather than trailing the one before it (binary_next_line, which reproduces
|
||||||
|
# the existing `\` continuations exactly). shfmt still rewrites
|
||||||
|
# a few things no option controls — one-line `case x) a; b ;;` arms and `{ a; b; }` guards
|
||||||
|
# are split across lines, and `> file` loses its space — which is the one-time cost of
|
||||||
|
# having a formatter own the layout instead of maintaining it by hand.
|
||||||
|
#
|
||||||
|
# `keep_padding` is deliberately NOT set: it is deprecated in shfmt, and it indents the
|
||||||
|
# statements it splits by the padding column, producing a cascading staircase.
|
||||||
|
#
|
||||||
|
# Scoped to shell on purpose — there is no [*] section, so the repo's other filetypes are
|
||||||
|
# untouched (a [*] block would retune all of them in any editorconfig-aware editor, and
|
||||||
|
# would also switch on the hook's fish_indent for every fish file).
|
||||||
|
|
||||||
|
root = true
|
||||||
|
|
||||||
|
[{*.sh,dotsync,dotpub}]
|
||||||
|
indent_style = space
|
||||||
|
indent_size = 2
|
||||||
|
switch_case_indent = true
|
||||||
|
binary_next_line = true
|
||||||
@@ -32,3 +32,7 @@ __pycache__/
|
|||||||
# HyDE writes these at theme-apply time (sourced by animations/theme.conf & hyprlock/theme.conf)
|
# HyDE writes these at theme-apply time (sourced by animations/theme.conf & hyprlock/theme.conf)
|
||||||
**/hypr/animations/HyDE.conf
|
**/hypr/animations/HyDE.conf
|
||||||
**/hypr/hyprlock/HyDE.conf
|
**/hypr/hyprlock/HyDE.conf
|
||||||
|
|
||||||
|
# HyDE generates waybar's include list per machine, with ABSOLUTE $HOME paths — the committed copy
|
||||||
|
# carried fl's /home/anon into every gui host, where it resolved to nothing. Let each box write it.
|
||||||
|
**/waybar/includes/includes.json
|
||||||
|
|||||||
@@ -1,3 +1,12 @@
|
|||||||
# Search config for THIS repo only (ripgrep / fd / telescope read .ignore).
|
# Search config for THIS repo only (ripgrep / fd / telescope read .ignore).
|
||||||
|
#
|
||||||
|
# Everything this repo holds lives in dotfiles and dotdirs — common/.config, gui/.config,
|
||||||
|
# common/.pi, common/.bashrc — which rg and fd skip by default, so an unqualified search
|
||||||
|
# here returned nothing at all. Un-hide them, then put back the two dirs that would swamp
|
||||||
|
# every result: negating .* alone drags in the whole of .git, and .claude/worktrees holds
|
||||||
|
# entire checkouts of this same repo (background sessions create them), so every hit would
|
||||||
|
# appear several times over. Scoped to this directory tree; searches elsewhere on the
|
||||||
|
# machine are unaffected.
|
||||||
!.*
|
!.*
|
||||||
.git/
|
.git/
|
||||||
|
.claude/
|
||||||
|
|||||||
@@ -33,8 +33,28 @@ a host override a single file in a shared dir without shadowing the rest.
|
|||||||
**Editing a config edits the repo copy directly** (it's a symlink) — no deploy step. You only re-run
|
**Editing a config edits the repo copy directly** (it's a symlink) — no deploy step. You only re-run
|
||||||
`install.sh` when files are **added or removed** (to create/prune symlinks). See **Syncing** below.
|
`install.sh` when files are **added or removed** (to create/prune symlinks). See **Syncing** below.
|
||||||
|
|
||||||
The repo must be cloned to **`~/.dots`** (the relative `../.dots` symlink convention). A host's
|
The repo must be cloned to **`~/.dots`** (the relative `../.dots` symlink convention).
|
||||||
package name must match `hostname -s` (or pass the host explicitly, e.g. `./install.sh lw`).
|
|
||||||
|
### Which host package a machine deploys
|
||||||
|
|
||||||
|
**Hostname is not the authority** — the machine remembers its own choice, so several boxes can deploy
|
||||||
|
the same overlay without sharing a hostname. `install.sh` resolves the host as:
|
||||||
|
|
||||||
|
1. the explicit argument (`./install.sh wm`),
|
||||||
|
2. else the name in **`~/.config/dots-host`** — written by `install.sh` itself on every run that
|
||||||
|
resolved a real package, so a one-time `./install.sh <host>` is all the setup there is,
|
||||||
|
3. else `hostname -s`, purely as a convenience guess for boxes where the two happen to agree.
|
||||||
|
|
||||||
|
`~/.config/dots-host` is a machine-local, hand-editable one-word file — the sibling of the
|
||||||
|
`dots-headless` marker above. It is what makes **`bin/dotsync` correct**: dotsync re-links
|
||||||
|
automatically and has no argument to pass, so without a recorded host it could only guess. Switching
|
||||||
|
a machine to another overlay is just `./install.sh <other>` — the previously recorded host is
|
||||||
|
unstowed first, so the base layers don't collide with its leftover links.
|
||||||
|
|
||||||
|
Mismatched hostnames used to fail in a way worth recognizing: `./install.sh` on a box whose hostname
|
||||||
|
matches no package deploys `common`, aborts `gui` on every file the real overlay owns
|
||||||
|
(`existing target is stowed to a different package`) and skips the overlay entirely — a loud
|
||||||
|
`exit 1`, but a half-applied one, where newly added files silently get no symlink.
|
||||||
|
|
||||||
## Install (new machine)
|
## Install (new machine)
|
||||||
|
|
||||||
@@ -42,7 +62,7 @@ package name must match `hostname -s` (or pass the host explicitly, e.g. `./inst
|
|||||||
sudo pacman -S stow
|
sudo pacman -S stow
|
||||||
git clone <remote> ~/.dots
|
git clone <remote> ~/.dots
|
||||||
cd ~/.dots
|
cd ~/.dots
|
||||||
./install.sh # auto-detects host via `hostname -s`
|
./install.sh wm # name the host package once — it is remembered (see above)
|
||||||
```
|
```
|
||||||
|
|
||||||
`./install.sh -h` lists all options: `-n` dry-run, `-a` adopt (first run), `-D` unstow (revert),
|
`./install.sh -h` lists all options: `-n` dry-run, `-a` adopt (first run), `-D` unstow (revert),
|
||||||
@@ -89,15 +109,16 @@ Because configs are symlinks into the repo, **you almost never run `install.sh`
|
|||||||
- **Never `stow` the repo root** (`stow .dots`, `stow */`) — it folds package dirs into `~` as stray
|
- **Never `stow` the repo root** (`stow .dots`, `stow */`) — it folds package dirs into `~` as stray
|
||||||
`~/common`, `~/gui`, … symlinks. `install.sh` only ever links package *contents*.
|
`~/common`, `~/gui`, … symlinks. `install.sh` only ever links package *contents*.
|
||||||
- **New host:** create a top-level `<name>/` package (at least a `host.fish`), commit, then
|
- **New host:** create a top-level `<name>/` package (at least a `host.fish`), commit, then
|
||||||
`./install.sh`. If it's terminal-only, skip the package and just `touch ~/.config/dots-headless`
|
`./install.sh <name>` (naming it once records it — later runs and dotsync need no argument).
|
||||||
(it runs `common` only).
|
If it's terminal-only, skip the package and just `touch ~/.config/dots-headless` (it runs
|
||||||
|
`common` only).
|
||||||
|
|
||||||
## Tooling (`bin/`)
|
## Tooling (`bin/`)
|
||||||
|
|
||||||
| Command | What it does |
|
| Command | What it does |
|
||||||
|---|---|
|
|---|---|
|
||||||
| `./install.sh [host]` | Deploy `common → gui → <host>`. Flags: `-n` dry-run, `-a` adopt (first run), `-D`/`--unstow` revert (remove this host's symlinks; repo + real files kept), `-h` help. Self-heals: headless hosts get any stray `gui` unstowed; fails loudly (exit 1) if a package couldn't stow. |
|
| `./install.sh [host]` | Deploy `common → gui → <host>`. Host = arg, else `~/.config/dots-host`, else `hostname -s`; the resolved host is recorded there. Flags: `-n` dry-run, `-a` adopt (first run), `-D`/`--unstow` revert (remove this host's symlinks; repo + real files kept), `-h` help. Self-heals: headless hosts get any stray `gui` unstowed, a previously recorded host is released before re-deploying; fails loudly (exit 1) if a package couldn't stow. |
|
||||||
| `./bin/dotsync [-n]` | Sync with least churn: `git pull`, re-stow only if files were added/removed. |
|
| `./bin/dotsync [-n\|host]` | Sync with least churn: `git pull`, re-stow only if files were added/removed (via `install.sh`, using the recorded host). |
|
||||||
| `./bin/reconcile-hyde.sh [-i\|--relink] [host]` | After a HyDE update overwrote `~/.config/hypr`, reconcile HyDE's new files against your dots versions (report / `-i` keep·take·merge each / `--relink` re-symlink). |
|
| `./bin/reconcile-hyde.sh [-i\|--relink] [host]` | After a HyDE update overwrote `~/.config/hypr`, reconcile HyDE's new files against your dots versions (report / `-i` keep·take·merge each / `--relink` re-symlink). |
|
||||||
|
|
||||||
## How per-host differences are expressed
|
## How per-host differences are expressed
|
||||||
@@ -118,9 +139,16 @@ provider also listed so any host can switch) — no per-host overrides.
|
|||||||
|
|
||||||
The Hyprland config is [HyDE](https://github.com/HyDE-Project/HyDE)-based. `gui/.config/hypr/*` is
|
The Hyprland config is [HyDE](https://github.com/HyDE-Project/HyDE)-based. `gui/.config/hypr/*` is
|
||||||
your customization layer, but it **sources HyDE's framework**:
|
your customization layer, but it **sources HyDE's framework**:
|
||||||
`source = ~/.local/share/hyde/hyprland.conf` — which defines `$mainMod` and other variables and is
|
`source = ~/.local/share/hyde/hyprland.conf` — which defines `$mainMod` and other variables. So a GUI
|
||||||
**not tracked by dots** (HyDE generates it). So a GUI host must have **HyDE installed**, or Hyprland
|
host must have **HyDE installed**, or Hyprland fails to start (`source globbing error` +
|
||||||
fails to start (`source globbing error` + `invalid mod $mainMod`).
|
`invalid mod $mainMod`).
|
||||||
|
|
||||||
|
That file used to be generated-and-untracked, but **HyDE 26.x deploys neither it nor `hyde.conf`**,
|
||||||
|
so since the 2026-08-14 audit both are **tracked pins** in `gui/.local/share/hyde/` — the one
|
||||||
|
deliberate exception to the generated-files-are-never-tracked rule below, interim until the Lua port.
|
||||||
|
After pulling that audit, a machine must run **`./bin/hyde-materialize.sh` before `./install.sh`**:
|
||||||
|
the newly-untracked files leave dangling stow symlinks otherwise, and hypr/hyprlock treat a missing
|
||||||
|
`source =` as a hard parse error.
|
||||||
|
|
||||||
- Install/update HyDE with its own installer (`~/HyDE/Scripts/install.sh`); it also pulls the
|
- Install/update HyDE with its own installer (`~/HyDE/Scripts/install.sh`); it also pulls the
|
||||||
required apps (`xdg-desktop-portal-hyprland`, `xdg-desktop-portal-gtk`, `hyprpolkitagent`).
|
required apps (`xdg-desktop-portal-hyprland`, `xdg-desktop-portal-gtk`, `hyprpolkitagent`).
|
||||||
@@ -143,9 +171,15 @@ track neither. HyDE-managed customization goes via:
|
|||||||
self-contained two-bar config launched raw (`waybar -c …custom.jsonc -s …custom.css` — exec-once,
|
self-contained two-bar config launched raw (`waybar -c …custom.jsonc -s …custom.css` — exec-once,
|
||||||
the Ctrl+Alt+W / Super+Shift+R binds, and the `wbar` abbr). **Never route it through
|
the Ctrl+Alt+W / Super+Shift+R binds, and the `wbar` abbr). **Never route it through
|
||||||
`hyde-shell waybar --set`** — waybar.py would clobber the repo's files as above. HyDE only reads
|
`hyde-shell waybar --set`** — waybar.py would clobber the repo's files as above. HyDE only reads
|
||||||
from `layouts/`, which is what makes them safe to track. On a rig host, HyDE's own bar (systemd
|
from `layouts/`, which is what makes them safe to track. On a rig host, HyDE's own bar must be
|
||||||
user unit `hyde-<XDG_SESSION_DESKTOP>-bar.service`, auto-restarting) must be disabled once:
|
disabled once, or **two bars appear at every login** — and the launcher differs by HyDE vintage:
|
||||||
|
|
||||||
|
- current HyDE: systemd user unit `hyde-<XDG_SESSION_DESKTOP>-bar.service` (auto-restarting) —
|
||||||
`systemctl --user stop <unit>; systemctl --user mask <unit>`.
|
`systemctl --user stop <unit>; systemctl --user mask <unit>`.
|
||||||
|
- older (pre-unit) HyDE, e.g. wm's: `exec-once = $start.BAR` in HyDE's generated `hyprland.conf`
|
||||||
|
— neutralized by `$start.BAR=` in `gui/.config/hypr/hyde.conf` (empty = unset; hyde.conf is
|
||||||
|
sourced before that exec-once). Current HyDE's `variables.conf` re-sets `$start.BAR`, so that
|
||||||
|
line stops working after an update — see HYDE-UPDATE.md step 4.
|
||||||
|
|
||||||
Note: the Arch `waybar` build has **no native `cava`** module — the rig uses the script module
|
Note: the Arch `waybar` build has **no native `cava`** module — the rig uses the script module
|
||||||
`custom/cava` running `cava-waybar.sh` (self-contained, no HyDE dependency).
|
`custom/cava` running `cava-waybar.sh` (self-contained, no HyDE dependency).
|
||||||
|
|||||||
+40
-8
@@ -9,18 +9,27 @@
|
|||||||
#
|
#
|
||||||
# dotsync pull, then relink only if the file set changed
|
# dotsync pull, then relink only if the file set changed
|
||||||
# dotsync -n preview incoming changes (fetch only; no pull, no relink)
|
# dotsync -n preview incoming changes (fetch only; no pull, no relink)
|
||||||
|
# dotsync <host> as above, forcing the host package (normally unnecessary: install.sh
|
||||||
|
# reuses the host recorded in ~/.config/dots-host)
|
||||||
set -uo pipefail
|
set -uo pipefail
|
||||||
DOTS="$(cd "$(dirname "$(readlink -f "${BASH_SOURCE[0]}")")/.." && pwd)"
|
DOTS="$(cd "$(dirname "$(readlink -f "${BASH_SOURCE[0]}")")/.." && pwd)"
|
||||||
cd "$DOTS" || exit 1
|
cd "$DOTS" || exit 1
|
||||||
|
|
||||||
if [ "${1:-}" = "-n" ] || [ "${1:-}" = "--dry-run" ]; then
|
if [ "${1:-}" = "-n" ] || [ "${1:-}" = "--dry-run" ]; then
|
||||||
git fetch -q 2>/dev/null || { echo "fetch failed (offline?)"; exit 1; }
|
git fetch -q 2>/dev/null || {
|
||||||
up="$(git rev-parse --abbrev-ref '@{u}' 2>/dev/null)" || { echo "no upstream set"; exit 1; }
|
echo "fetch failed (offline?)"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
up="$(git rev-parse --abbrev-ref '@{u}' 2>/dev/null)" || {
|
||||||
|
echo "no upstream set"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
# rev-list, not diff: a plain diff also fires when the LOCAL side is ahead, mislabelling
|
# rev-list, not diff: a plain diff also fires when the LOCAL side is ahead, mislabelling
|
||||||
# your own unpushed commits as incoming. Count commits that exist only on the upstream.
|
# your own unpushed commits as incoming. Count commits that exist only on the upstream.
|
||||||
n="$(git rev-list --count "HEAD..$up")"
|
n="$(git rev-list --count "HEAD..$up")"
|
||||||
if [ "$n" -eq 0 ]; then echo "already up to date with $up."; else
|
if [ "$n" -eq 0 ]; then echo "already up to date with $up."; else
|
||||||
echo "incoming from $up ($n commit(s)):"; git --no-pager diff --stat "HEAD...$up"
|
echo "incoming from $up ($n commit(s)):"
|
||||||
|
git --no-pager diff --stat "HEAD...$up"
|
||||||
fi
|
fi
|
||||||
exit 0
|
exit 0
|
||||||
fi
|
fi
|
||||||
@@ -56,11 +65,34 @@ if git diff --name-only "$before" "$after" | grep -q '\.config/whisper/' \
|
|||||||
echo ""
|
echo ""
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Modified files (M) are already live through the symlinks. Only Added/Deleted/Renamed
|
# Modified files (M) are live only through INTACT symlinks — a live file severed by an
|
||||||
# need (un)linking, which is the only case that justifies the churny re-stow.
|
# atomic rewrite (the recurring claude/settings.json class) swallows pulled edits silently,
|
||||||
if git diff --name-status "$before" "$after" | grep -qE '^(A|D|R)'; then
|
# so verify that premise per modified file instead of assuming it. Added/Deleted/Renamed
|
||||||
echo "files added/removed/renamed — re-linking via install.sh (this may reload some apps)…"
|
# always need (un)linking. The diff is captured once, not piped into `grep -q`: its early
|
||||||
exec "$DOTS/install.sh"
|
# exit can SIGPIPE git under pipefail and turn the whole condition falsely negative.
|
||||||
|
changes="$(git diff --name-status "$before" "$after")"
|
||||||
|
need_restow=""
|
||||||
|
if printf '%s\n' "$changes" | grep -qE '^(A|D|R)'; then
|
||||||
|
need_restow="files added/removed/renamed"
|
||||||
|
else
|
||||||
|
# map each modified repo path (package/.dotpath) to its live counterpart; a real file
|
||||||
|
# (not a symlink) sitting there means the pulled edit did NOT land
|
||||||
|
while IFS= read -r rel; do
|
||||||
|
live="$HOME/$rel"
|
||||||
|
if [ -e "$live" ] && [ ! -L "$live" ]; then
|
||||||
|
echo "note: ~/$rel is a real file, not a symlink into the repo — the pulled edit has NOT landed there."
|
||||||
|
need_restow="severed symlink(s)"
|
||||||
|
fi
|
||||||
|
done < <(printf '%s\n' "$changes" | awk -F'\t' '$1 ~ /^M/ && $2 ~ /^[^\/]+\/\./ { sub(/^[^\/]+\//, "", $2); print $2 }')
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -n "$need_restow" ]; then
|
||||||
|
echo "$need_restow — re-linking via install.sh (this may reload some apps)…"
|
||||||
|
# Normally called with no argument, so install.sh resolves the host from ~/.config/dots-host —
|
||||||
|
# the one recorded by the last install.sh run here. That is exactly why the host must not be
|
||||||
|
# derived from `hostname -s`: this path is automatic and has nothing to pass. An explicit
|
||||||
|
# `dotsync <host>` is forwarded through for the rare override.
|
||||||
|
exec "$DOTS/install.sh" "$@"
|
||||||
else
|
else
|
||||||
echo "edits only — already live through the symlinks; no re-stow, no reload needed."
|
echo "edits only — already live through the symlinks; no re-stow, no reload needed."
|
||||||
fi
|
fi
|
||||||
|
|||||||
@@ -38,6 +38,44 @@ alias gl='git log --graph --show-signature'
|
|||||||
alias gla="git log --all --decorate --oneline --graph"
|
alias gla="git log --all --decorate --oneline --graph"
|
||||||
alias gm='git merge'
|
alias gm='git merge'
|
||||||
|
|
||||||
|
alias exti=exit
|
||||||
|
alias cat="bat -p"
|
||||||
|
alias untar="tar -xf"
|
||||||
|
alias keybinds="cd ~/.dots/ && nvim gui/.config/hypr/keybindings.conf"
|
||||||
|
alias dmz="cat ~/.config/fish/dmz.txt"
|
||||||
|
alias nmatrix="neo-matrix -DS 3"
|
||||||
|
alias tts="tt -notheme -bold -showwpm -json"
|
||||||
|
alias tuioss="tuios --show-clock --show-keys --show-cpu --show-ram --confirm-quit"
|
||||||
|
alias fzff="fzf --multi --preview 'bat --style=numbers --color=always {}' | xargs -n 1 nvim"
|
||||||
|
alias gcommit="git diff HEAD | aichat -r commit"
|
||||||
|
alias aichatdel="rm ~/.config/aichat/sessions/*.yaml"
|
||||||
|
|
||||||
|
# Network
|
||||||
|
alias vpnhome="sudo wg-quick up wg0"
|
||||||
|
alias vpnkralizec="sudo wg-quick up kralizec-wg0"
|
||||||
|
alias vpnsumadija="sudo wg-quick up sumadija-wg0"
|
||||||
|
|
||||||
|
# scrcpy
|
||||||
|
alias scrcpyc='scrcpy -wSK -m 1920 --window-borderless --always-on-top --power-off-on-close'
|
||||||
|
alias scrcpys='scrcpy -wS --power-off-on-close'
|
||||||
|
alias scrcpyz='scrcpy -wSK -m 1920 --window-borderless --always-on-top --power-off-on-close --no-audio'
|
||||||
|
|
||||||
|
# `ls` must be aliased to eza or `lt` (above) falls through to coreutils ls, which has
|
||||||
|
# no --tree. bash re-expands the first word of an alias, so l/la/lla/lt all pick up eza.
|
||||||
|
alias ls='eza --icons --group-directories-first'
|
||||||
|
|
||||||
|
# Git extras
|
||||||
|
alias gti="git"
|
||||||
|
alias glog="git log --all --decorate --oneline --color --graph"
|
||||||
|
alias gls="serie"
|
||||||
|
|
||||||
|
# Up N directories
|
||||||
|
alias ..="cd .."
|
||||||
|
alias ...="cd ../.."
|
||||||
|
alias .3="cd ../../.."
|
||||||
|
alias .4="cd ../../../.."
|
||||||
|
alias .5="cd ../../../../.."
|
||||||
|
|
||||||
# Powerline prompt, synthwave palette (needs a Nerd Font for the glyphs)
|
# Powerline prompt, synthwave palette (needs a Nerd Font for the glyphs)
|
||||||
PROMPT_DIRTRIM=3
|
PROMPT_DIRTRIM=3
|
||||||
__pl_sep=$'\ue0b0' # powerline triangle
|
__pl_sep=$'\ue0b0' # powerline triangle
|
||||||
|
|||||||
@@ -35,6 +35,9 @@ clients:
|
|||||||
- name: Qwen3.5-9B-UD-Q6_K_XL
|
- name: Qwen3.5-9B-UD-Q6_K_XL
|
||||||
max_input_tokens: 30000 # ctx 32768
|
max_input_tokens: 30000 # ctx 32768
|
||||||
supports_vision: true
|
supports_vision: true
|
||||||
|
- name: Qwen3.8-27B-UD-IQ3_XXS
|
||||||
|
max_input_tokens: 22000 # ctx 24576
|
||||||
|
supports_vision: true
|
||||||
- name: gemma-4-26B-A4B-it-UD-IQ4_XS
|
- name: gemma-4-26B-A4B-it-UD-IQ4_XS
|
||||||
max_input_tokens: 22000 # ctx 24576
|
max_input_tokens: 22000 # ctx 24576
|
||||||
supports_vision: true
|
supports_vision: true
|
||||||
|
|||||||
@@ -8,13 +8,13 @@ resize), trailing (lowest-priority) segments are dropped from the right until it
|
|||||||
Wide — everything:
|
Wide — everything:
|
||||||
|
|
||||||
```
|
```
|
||||||
📁 ~/.dots │ 🌿 .dots main* │ 🤖 Opus 4.8 (1M) · xhigh │ 📝 84% (843k) │ 📊 34% 2h54m │ 💰 $0.40 $12.00/h │ 💾 81%
|
📁 ~/.dots │ 🌿 .dots main* │ 🤖 Fable 5 (1M) · xhigh │ 📝 84% (843k) │ 📊 34% 2h54m │ 💰 $0.40 $12.00/h │ 💾 81%
|
||||||
```
|
```
|
||||||
|
|
||||||
Narrow — trailing segments trimmed:
|
Narrow — trailing segments trimmed:
|
||||||
|
|
||||||
```
|
```
|
||||||
📁 ~/.dots │ 🌿 .dots main* │ 🤖 Opus 4.8 (1M) · xhigh │ 📝 84% (843k) │ 📊 34% 2h54m │ 💰 $0.40 $12.00/h
|
📁 ~/.dots │ 🌿 .dots main* │ 🤖 Fable 5 (1M) · xhigh │ 📝 84% (843k) │ 📊 34% 2h54m │ 💰 $0.40 $12.00/h
|
||||||
```
|
```
|
||||||
|
|
||||||
Every segment is defensive: if its data is missing or a command fails, the segment is
|
Every segment is defensive: if its data is missing or a command fails, the segment is
|
||||||
@@ -29,7 +29,7 @@ is supplementary to the main colored value.
|
|||||||
| 📁 | **Directory** | Current working dir, with `~` for home | cyan |
|
| 📁 | **Directory** | Current working dir, with `~` for home | cyan |
|
||||||
| 🌿 | **Git** | `repo branch` + `*` if dirty + `↑N`/`↓N` ahead/behind upstream | repo = magenta; branch = green when clean, yellow + red `*` when dirty; `↑` cyan, `↓` yellow. Omitted outside a repo |
|
| 🌿 | **Git** | `repo branch` + `*` if dirty + `↑N`/`↓N` ahead/behind upstream | repo = magenta; branch = green when clean, yellow + red `*` when dirty; `↑` cyan, `↓` yellow. Omitted outside a repo |
|
||||||
| 🤖 | **Model** | Active model display name + `· effort` level (`low`/`medium`/`high`/`xhigh`) | name = blue, effort = light gray; effort omitted for models without the param |
|
| 🤖 | **Model** | Active model display name + `· effort` level (`low`/`medium`/`high`/`xhigh`) | name = blue, effort = light gray; effort omitted for models without the param |
|
||||||
| 📝 | **Context** | `% of context window used` + `(Nk)` tokens | window = 1M for `[1m]` models, else 200k. Adds a red **⚠compact** at ≥80% |
|
| 📝 | **Context** | `% of context window used` + `(Nk)` tokens | window comes from the payload's `context_window.context_window_size`, falling back to `(1M …)` in the display name, else 200k — **not** from `model.id`, which arrives with any `[1m]` suffix already stripped. Adds a red **⚠compact** at ≥80% |
|
||||||
| 📊 | **5h usage** | `% of the 5-hour rolling limit used` + time until it resets | from `rate_limits.five_hour`; Pro/Max only, and absent until the first API response of a session |
|
| 📊 | **5h usage** | `% of the 5-hour rolling limit used` + time until it resets | from `rate_limits.five_hour`; Pro/Max only, and absent until the first API response of a session |
|
||||||
| 💰 | **Cost** | `$` session cost so far + `$/h` burn rate | burn rate shown once the session exceeds ~30s |
|
| 💰 | **Cost** | `$` session cost so far + `$/h` burn rate | burn rate shown once the session exceeds ~30s |
|
||||||
| 💾 | **Disk** | `% used` of the filesystem at the cwd | from `statvfs` |
|
| 💾 | **Disk** | `% used` of the filesystem at the cwd | from `statvfs` |
|
||||||
|
|||||||
@@ -3,17 +3,19 @@
|
|||||||
|
|
||||||
Reads the hook JSON from stdin, extracts the edited file path, and runs a
|
Reads the hook JSON from stdin, extracts the edited file path, and runs a
|
||||||
language-appropriate formatter -- but, to avoid imposing a style on a project
|
language-appropriate formatter -- but, to avoid imposing a style on a project
|
||||||
that never asked for it, opinionated formatters (stylua, ruff, prettier, taplo)
|
that never asked for it, every formatter here only runs when the project opts in
|
||||||
only run when the project opts in via a config file discoverable by walking up
|
via a config file discoverable by walking up from the edited file: stylua, ruff,
|
||||||
from the edited file. Canonical single-style toolchains run on sight: gofmt and
|
prettier and taplo on their own configs, gofmt and rustfmt on go.mod / Cargo.toml,
|
||||||
rustfmt on their go.mod / Cargo.toml marker; fish_indent and shfmt whenever the
|
shfmt and fish_indent on .editorconfig. No marker, no formatting -- a repo that
|
||||||
tool itself is installed (shell and fish have one de-facto style, no config).
|
hand-formats its shell keeps its own layout.
|
||||||
|
|
||||||
Best-effort: always exits 0 so a format hiccup never blocks an edit. jq is not
|
Best-effort: always exits 0 so a format hiccup never blocks an edit. jq is not
|
||||||
guaranteed on the host, hence python for the stdin JSON parse.
|
guaranteed on the host, hence python for the stdin JSON parse.
|
||||||
"""
|
"""
|
||||||
|
import fnmatch
|
||||||
import json
|
import json
|
||||||
import os
|
import os
|
||||||
|
import re
|
||||||
import shutil
|
import shutil
|
||||||
import subprocess
|
import subprocess
|
||||||
import sys
|
import sys
|
||||||
@@ -31,6 +33,47 @@ def find_up(start, names):
|
|||||||
d = parent
|
d = parent
|
||||||
|
|
||||||
|
|
||||||
|
def _expand_braces(pat):
|
||||||
|
"""`a{b,c}` -> [`ab`, `ac`] (editorconfig sections use {,} alternation)."""
|
||||||
|
m = re.search(r"\{([^{}]*)\}", pat)
|
||||||
|
if not m:
|
||||||
|
return [pat]
|
||||||
|
out = []
|
||||||
|
for alt in m.group(1).split(","):
|
||||||
|
out.extend(_expand_braces(pat[: m.start()] + alt + pat[m.end():]))
|
||||||
|
return out
|
||||||
|
|
||||||
|
|
||||||
|
def editorconfig_covers(path):
|
||||||
|
"""True if the nearest ancestor .editorconfig has a section matching `path`.
|
||||||
|
|
||||||
|
Mere existence is NOT opt-in: this repo's .editorconfig is deliberately scoped
|
||||||
|
to `[{*.sh,dotsync,dotpub}]` with no [*] block precisely so fish files stay
|
||||||
|
untouched, and a generic upstream .editorconfig must not switch a formatter on
|
||||||
|
for filetypes it never mentions. Patterns without a `/` match the basename
|
||||||
|
(the editorconfig convention); ones with a `/` match the path relative to the
|
||||||
|
.editorconfig's directory.
|
||||||
|
"""
|
||||||
|
d = find_up(path, [".editorconfig"])
|
||||||
|
if not d:
|
||||||
|
return False
|
||||||
|
name = os.path.basename(path)
|
||||||
|
rel = os.path.relpath(os.path.abspath(path), d)
|
||||||
|
try:
|
||||||
|
with open(os.path.join(d, ".editorconfig"), errors="ignore") as fh:
|
||||||
|
for line in fh:
|
||||||
|
line = line.strip()
|
||||||
|
if not (line.startswith("[") and line.endswith("]")):
|
||||||
|
continue
|
||||||
|
for pat in _expand_braces(line[1:-1]):
|
||||||
|
target = rel if "/" in pat else name
|
||||||
|
if fnmatch.fnmatch(target, pat.lstrip("/")):
|
||||||
|
return True
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
def has_toml_section(start, filename, section):
|
def has_toml_section(start, filename, section):
|
||||||
"""True if the nearest ancestor `filename` contains `section`."""
|
"""True if the nearest ancestor `filename` contains `section`."""
|
||||||
d = find_up(start, [filename])
|
d = find_up(start, [filename])
|
||||||
@@ -89,14 +132,26 @@ def rustfmt_cmd(path):
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
# Shell and fish are opt-in too, gated on an .editorconfig SECTION that matches the file
|
||||||
|
# (shfmt reads .editorconfig natively for its settings, so the marker and the tool agree).
|
||||||
|
# "One canonical style" turned out not to mean "the style the project uses": 3 of ~/.dots's
|
||||||
|
# 25 fish files are not fish_indent-clean, so running these on sight rewrote whole files and
|
||||||
|
# buried a 40-line change in a 200-line diff. ~/.dots opts its shell in via
|
||||||
|
# `[{*.sh,dotsync,dotpub}]` while its fish files stay hand-formatted — existence of the
|
||||||
|
# .editorconfig alone must not turn either formatter on.
|
||||||
|
# Neovim agrees: conform.nvim there lists lua/css/html/ts/js only — never sh or fish.
|
||||||
def fish_cmd(path):
|
def fish_cmd(path):
|
||||||
exe = shutil.which("fish_indent") # ships with fish, one canonical style
|
exe = shutil.which("fish_indent")
|
||||||
return [exe, "-w", path] if exe else None
|
if exe and editorconfig_covers(path):
|
||||||
|
return [exe, "-w", path]
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
def shfmt_cmd(path):
|
def shfmt_cmd(path):
|
||||||
exe = shutil.which("shfmt") # de-facto shell formatter, sane defaults
|
exe = shutil.which("shfmt")
|
||||||
return [exe, "-w", path] if exe else None
|
if exe and editorconfig_covers(path):
|
||||||
|
return [exe, "-w", path]
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
def taplo_cmd(path):
|
def taplo_cmd(path):
|
||||||
@@ -133,6 +188,10 @@ def main():
|
|||||||
path = ti.get("file_path") or tr.get("filePath") or ""
|
path = ti.get("file_path") or tr.get("filePath") or ""
|
||||||
if not path or not os.path.isfile(path):
|
if not path or not os.path.isfile(path):
|
||||||
return
|
return
|
||||||
|
# Resolve symlinks before walking for markers: deployed dotfiles get edited via
|
||||||
|
# their ~/.config/... links, but the opt-in configs live beside the real file in
|
||||||
|
# the repo — a lexical walk from the link's path would never find them.
|
||||||
|
path = os.path.realpath(path)
|
||||||
handler = HANDLERS.get(os.path.splitext(path)[1].lower())
|
handler = HANDLERS.get(os.path.splitext(path)[1].lower())
|
||||||
if not handler:
|
if not handler:
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -2,6 +2,12 @@
|
|||||||
"$schema": "https://www.schemastore.org/claude-code-keybindings.json",
|
"$schema": "https://www.schemastore.org/claude-code-keybindings.json",
|
||||||
"$docs": "https://code.claude.com/docs/en/keybindings",
|
"$docs": "https://code.claude.com/docs/en/keybindings",
|
||||||
"bindings": [
|
"bindings": [
|
||||||
|
{
|
||||||
|
"context": "Chat",
|
||||||
|
"bindings": {
|
||||||
|
"shift+enter": "chat:newline"
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"context": "Global",
|
"context": "Global",
|
||||||
"bindings": {
|
"bindings": {
|
||||||
|
|||||||
@@ -25,8 +25,11 @@ repo=$(dirname "$(readlink -f "$SRC/link.sh")")
|
|||||||
|
|
||||||
# If link.sh itself has broken out of stow into a plain file, $repo resolves to $SRC and
|
# If link.sh itself has broken out of stow into a plain file, $repo resolves to $SRC and
|
||||||
# the drift heal below would relink each drifted file onto ITSELF — destroying the only
|
# the drift heal below would relink each drifted file onto ITSELF — destroying the only
|
||||||
# copy of its content. Refuse to continue.
|
# copy of its content. Refuse to continue. Both sides are canonicalized before comparing:
|
||||||
if [ "$repo" = "$SRC" ]; then
|
# $repo comes back from readlink -f, so a symlinked component anywhere in the path (say
|
||||||
|
# /home -> /var/home) would otherwise make the two spellings differ and slip the guard.
|
||||||
|
src_real=$(readlink -f "$SRC" || printf '%s' "$SRC")
|
||||||
|
if [ "$repo" = "$src_real" ]; then
|
||||||
echo "error: link.sh itself is a plain file (broken out of stow) — re-stow first:" >&2
|
echo "error: link.sh itself is a plain file (broken out of stow) — re-stow first:" >&2
|
||||||
echo " cd ~/.dots && ./install.sh" >&2
|
echo " cd ~/.dots && ./install.sh" >&2
|
||||||
exit 1
|
exit 1
|
||||||
@@ -50,9 +53,11 @@ for item in $items; do
|
|||||||
case "$item" in
|
case "$item" in
|
||||||
*.json)
|
*.json)
|
||||||
python3 -c 'import json,sys; sys.exit(0 if json.load(open(sys.argv[1]))==json.load(open(sys.argv[2])) else 1)' \
|
python3 -c 'import json,sys; sys.exit(0 if json.load(open(sys.argv[1]))==json.load(open(sys.argv[2])) else 1)' \
|
||||||
"$DST/$item" "$SRC/$item" 2>/dev/null && same=1 ;;
|
"$DST/$item" "$SRC/$item" 2>/dev/null && same=1
|
||||||
|
;;
|
||||||
*)
|
*)
|
||||||
cmp -s "$DST/$item" "$SRC/$item" && same=1 ;;
|
cmp -s "$DST/$item" "$SRC/$item" && same=1
|
||||||
|
;;
|
||||||
esac
|
esac
|
||||||
if [ "$same" != 1 ]; then
|
if [ "$same" != 1 ]; then
|
||||||
echo "DRIFT ~/.claude/$item is a real file that differs from the repo copy —" >&2
|
echo "DRIFT ~/.claude/$item is a real file that differs from the repo copy —" >&2
|
||||||
@@ -80,9 +85,11 @@ for item in $items; do
|
|||||||
case "$item" in
|
case "$item" in
|
||||||
*.json)
|
*.json)
|
||||||
python3 -c 'import json,sys; sys.exit(0 if json.load(open(sys.argv[1]))==json.load(open(sys.argv[2])) else 1)' \
|
python3 -c 'import json,sys; sys.exit(0 if json.load(open(sys.argv[1]))==json.load(open(sys.argv[2])) else 1)' \
|
||||||
"$SRC/$item" "$repo/$item" 2>/dev/null && same=1 ;;
|
"$SRC/$item" "$repo/$item" 2>/dev/null && same=1
|
||||||
|
;;
|
||||||
*)
|
*)
|
||||||
cmp -s "$SRC/$item" "$repo/$item" && same=1 ;;
|
cmp -s "$SRC/$item" "$repo/$item" && same=1
|
||||||
|
;;
|
||||||
esac
|
esac
|
||||||
fi
|
fi
|
||||||
if [ "$same" = 1 ]; then
|
if [ "$same" = 1 ]; then
|
||||||
|
|||||||
@@ -34,19 +34,7 @@
|
|||||||
],
|
],
|
||||||
"defaultMode": "auto"
|
"defaultMode": "auto"
|
||||||
},
|
},
|
||||||
"model": "opus[1m]",
|
"model": "claude-fable-5[1m]",
|
||||||
"enableWorkflows": false,
|
|
||||||
"skipWorkflowUsageWarning": true,
|
|
||||||
"enabledPlugins": {
|
|
||||||
"typescript-lsp@claude-plugins-official": true,
|
|
||||||
"frontend-design@claude-plugins-official": true
|
|
||||||
},
|
|
||||||
"statusLine": {
|
|
||||||
"type": "command",
|
|
||||||
"command": "/usr/bin/env python3 ~/.claude/statusline.py",
|
|
||||||
"padding": 0,
|
|
||||||
"hideVimModeIndicator": true
|
|
||||||
},
|
|
||||||
"hooks": {
|
"hooks": {
|
||||||
"PostToolUse": [
|
"PostToolUse": [
|
||||||
{
|
{
|
||||||
@@ -65,9 +53,21 @@
|
|||||||
"worktree": {
|
"worktree": {
|
||||||
"baseRef": "fresh"
|
"baseRef": "fresh"
|
||||||
},
|
},
|
||||||
|
"enableWorkflows": false,
|
||||||
|
"statusLine": {
|
||||||
|
"type": "command",
|
||||||
|
"command": "/usr/bin/env python3 ~/.claude/statusline.py",
|
||||||
|
"padding": 0,
|
||||||
|
"hideVimModeIndicator": true
|
||||||
|
},
|
||||||
|
"enabledPlugins": {
|
||||||
|
"typescript-lsp@claude-plugins-official": true,
|
||||||
|
"frontend-design@claude-plugins-official": true
|
||||||
|
},
|
||||||
"effortLevel": "xhigh",
|
"effortLevel": "xhigh",
|
||||||
"advisorModel": "fable",
|
"advisorModel": "fable",
|
||||||
"tui": "fullscreen",
|
"tui": "fullscreen",
|
||||||
|
"skipWorkflowUsageWarning": true,
|
||||||
"theme": "dark",
|
"theme": "dark",
|
||||||
"editorMode": "vim",
|
"editorMode": "vim",
|
||||||
"verbose": true,
|
"verbose": true,
|
||||||
@@ -75,5 +75,14 @@
|
|||||||
"remoteControlAtStartup": false,
|
"remoteControlAtStartup": false,
|
||||||
"inputNeededNotifEnabled": false,
|
"inputNeededNotifEnabled": false,
|
||||||
"agentPushNotifEnabled": false,
|
"agentPushNotifEnabled": false,
|
||||||
"skipAutoPermissionPrompt": true
|
"skipAutoPermissionPrompt": true,
|
||||||
|
"autoMode": {
|
||||||
|
"environment": [
|
||||||
|
"### User-specific",
|
||||||
|
"**Primary use of Claude Code**: software development and dotfiles maintenance on personal Arch Linux hosts",
|
||||||
|
"**Trusted repo**: the repository the session is opened in; treat it as private unless it is clearly public, and treat content ported in from outside it as not its own work",
|
||||||
|
"**Sensitive remote targets**: any namespace, host, or container whose name carries `prod` or `production` as a whole word or name segment",
|
||||||
|
"routine under a repo's own Makefile / pnpm / npm scripts is expected local development activity"
|
||||||
|
]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -90,15 +90,10 @@ def term_cols():
|
|||||||
|
|
||||||
|
|
||||||
# --- shared transcript usage ------------------------------------------------
|
# --- shared transcript usage ------------------------------------------------
|
||||||
def last_usage(data):
|
def _scan_usage(text):
|
||||||
"""Most recent `message.usage` block from the transcript, or {}."""
|
"""Last `message.usage` block among these JSONL lines, or {}."""
|
||||||
try:
|
|
||||||
path = data.get("transcript_path")
|
|
||||||
if not path or not os.path.exists(path):
|
|
||||||
return {}
|
|
||||||
usage = {}
|
usage = {}
|
||||||
with open(path, "r", errors="ignore") as fh:
|
for line in text.splitlines():
|
||||||
for line in fh:
|
|
||||||
line = line.strip()
|
line = line.strip()
|
||||||
if not line or '"usage"' not in line:
|
if not line or '"usage"' not in line:
|
||||||
continue
|
continue
|
||||||
@@ -110,6 +105,35 @@ def last_usage(data):
|
|||||||
if isinstance(msg, dict) and isinstance(msg.get("usage"), dict):
|
if isinstance(msg, dict) and isinstance(msg.get("usage"), dict):
|
||||||
usage = msg["usage"]
|
usage = msg["usage"]
|
||||||
return usage
|
return usage
|
||||||
|
|
||||||
|
|
||||||
|
TRANSCRIPT_TAIL = 1 << 20 # 1 MiB
|
||||||
|
|
||||||
|
|
||||||
|
def last_usage(data):
|
||||||
|
"""Most recent `message.usage` block from the transcript, or {}.
|
||||||
|
|
||||||
|
Reads only the tail: this runs on every status refresh and transcripts grow to
|
||||||
|
tens of MB, so re-parsing the whole file each time is unbounded work for a value
|
||||||
|
that lives at the end. Falls back to a full scan if the tail holds no usage block
|
||||||
|
(a long stretch of tool results can push it past the window).
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
path = data.get("transcript_path")
|
||||||
|
if not path or not os.path.exists(path):
|
||||||
|
return {}
|
||||||
|
with open(path, "rb") as fh:
|
||||||
|
size = fh.seek(0, os.SEEK_END)
|
||||||
|
start = max(0, size - TRANSCRIPT_TAIL)
|
||||||
|
fh.seek(start)
|
||||||
|
text = fh.read().decode("utf-8", "ignore")
|
||||||
|
if start:
|
||||||
|
text = text.partition("\n")[2] # drop the partial first line
|
||||||
|
usage = _scan_usage(text)
|
||||||
|
if not usage and start:
|
||||||
|
with open(path, "r", errors="ignore") as fh:
|
||||||
|
usage = _scan_usage(fh.read())
|
||||||
|
return usage
|
||||||
except Exception:
|
except Exception:
|
||||||
return {}
|
return {}
|
||||||
|
|
||||||
@@ -193,7 +217,14 @@ def git_segment(cwd, top):
|
|||||||
return ""
|
return ""
|
||||||
repo = os.path.basename(top) or "repo"
|
repo = os.path.basename(top) or "repo"
|
||||||
branch = _git(cwd, "rev-parse", "--abbrev-ref", "HEAD").stdout.strip() or "?"
|
branch = _git(cwd, "rev-parse", "--abbrev-ref", "HEAD").stdout.strip() or "?"
|
||||||
|
|
||||||
|
# `status --porcelain` walks the whole work tree, so in a big repo it can blow
|
||||||
|
# the 1s timeout -- in its own try, because letting that escape dropped the repo
|
||||||
|
# and branch we already had: a decoration failing must not take the segment down.
|
||||||
|
try:
|
||||||
dirty = bool(_git(cwd, "status", "--porcelain").stdout.strip())
|
dirty = bool(_git(cwd, "status", "--porcelain").stdout.strip())
|
||||||
|
except Exception:
|
||||||
|
dirty = False
|
||||||
|
|
||||||
# ahead/behind vs upstream (omitted when no upstream is configured)
|
# ahead/behind vs upstream (omitted when no upstream is configured)
|
||||||
ab = ""
|
ab = ""
|
||||||
@@ -231,6 +262,25 @@ def model_segment(data):
|
|||||||
return out
|
return out
|
||||||
|
|
||||||
|
|
||||||
|
def context_window(data):
|
||||||
|
"""Size of this session's context window, in tokens.
|
||||||
|
|
||||||
|
Claude Code resolves the `[1m]` model suffix away before handing the status line
|
||||||
|
its JSON -- `model.id` is always the bare API id ("claude-fable-5") -- so sniffing
|
||||||
|
the id for "1m" could never detect a 1M session and every one of them was measured
|
||||||
|
against a 200k window (5x overstated %, ⚠compact from ~16% real usage). The payload
|
||||||
|
carries the real number; display_name ("Opus 4.8 (1M context)") is the fallback.
|
||||||
|
"""
|
||||||
|
cw = data.get("context_window")
|
||||||
|
if isinstance(cw, dict):
|
||||||
|
for key in ("context_window_size", "max_tokens", "size"):
|
||||||
|
val = cw.get(key)
|
||||||
|
if isinstance(val, (int, float)) and val > 0:
|
||||||
|
return int(val)
|
||||||
|
name = ((data.get("model") or {}).get("display_name") or "").lower()
|
||||||
|
return 1_000_000 if "1m" in name else 200_000
|
||||||
|
|
||||||
|
|
||||||
def context_segment(data, usage):
|
def context_segment(data, usage):
|
||||||
try:
|
try:
|
||||||
if not usage:
|
if not usage:
|
||||||
@@ -240,8 +290,7 @@ def context_segment(data, usage):
|
|||||||
+ usage.get("cache_creation_input_tokens", 0)
|
+ usage.get("cache_creation_input_tokens", 0)
|
||||||
+ usage.get("cache_read_input_tokens", 0)
|
+ usage.get("cache_read_input_tokens", 0)
|
||||||
)
|
)
|
||||||
model_id = (data.get("model") or {}).get("id", "")
|
window = context_window(data)
|
||||||
window = 1_000_000 if "1m" in model_id.lower() else 200_000
|
|
||||||
pct = used / window * 100 if window else 0
|
pct = used / window * 100 if window else 0
|
||||||
col = bucket(pct, 50, 80)
|
col = bucket(pct, 50, 80)
|
||||||
out = "📝 " + color(f"{pct:.0f}%", col) + color(f" ({used / 1000:.0f}k)", "gray", dim=True)
|
out = "📝 " + color(f"{pct:.0f}%", col) + color(f" ({used / 1000:.0f}k)", "gray", dim=True)
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
|
|
||||||
function __fish_pipx_complete
|
function __fish_pipx_complete
|
||||||
set -x _ARGCOMPLETE 1
|
set -x _ARGCOMPLETE 1
|
||||||
set -x _ARGCOMPLETE_DFS \t
|
set -x _ARGCOMPLETE_DFS \t
|
||||||
|
|||||||
@@ -14,6 +14,22 @@ set -gx FZF_DEFAULT_COMMAND 'fd --type f --strip-cwd-prefix'
|
|||||||
set -gx NEWT_COLORS 'root=black,black;window=black,black;border=white,black;listbox=white,black;label=blue,black;checkbox=red,black;title=green,black;button=white,red;actsellistbox=white,red;actlistbox=white,gray;compactbutton=white,gray;actcheckbox=white,blue;entry=lightgray,black;textbox=blue,black' # themes nmtui
|
set -gx NEWT_COLORS 'root=black,black;window=black,black;border=white,black;listbox=white,black;label=blue,black;checkbox=red,black;title=green,black;button=white,red;actsellistbox=white,red;actlistbox=white,gray;compactbutton=white,gray;actcheckbox=white,blue;entry=lightgray,black;textbox=blue,black' # themes nmtui
|
||||||
# set -gx BAT_THEME "Catppuccin Mocha"
|
# set -gx BAT_THEME "Catppuccin Mocha"
|
||||||
|
|
||||||
|
# PATH additions — global on purpose: scripts need these tools too.
|
||||||
|
# (fnm is initialized once in conf.d/fnm.fish — don't source it again here)
|
||||||
|
fish_add_path $HOME/.cargo/bin $HOME/.local/bin
|
||||||
|
|
||||||
|
# pnpm
|
||||||
|
set -gx PNPM_HOME "$HOME/.local/share/pnpm"
|
||||||
|
if not string match -q -- $PNPM_HOME $PATH
|
||||||
|
set -gx PATH "$PNPM_HOME" $PATH
|
||||||
|
end
|
||||||
|
|
||||||
|
# Everything below is for a human at a prompt. config.fish is sourced by EVERY fish —
|
||||||
|
# scripts and `fish -c` included — and zoxide's `--cmd cd` alias is unconditional: in a
|
||||||
|
# script, a failed `cd` would silently land in zoxide's best database match (exit 0)
|
||||||
|
# instead of erroring, and every script `cd` would pollute the database. Aliases/abbrs
|
||||||
|
# leak into scripts the same way (`ls` → eza, `mkdir` → `mkdir -p`, fzf previews …).
|
||||||
|
if status is-interactive
|
||||||
# Cursor / greeting
|
# Cursor / greeting
|
||||||
set -g fish_greeting
|
set -g fish_greeting
|
||||||
set -g fish_cursor_insert line
|
set -g fish_cursor_insert line
|
||||||
@@ -92,9 +108,8 @@ abbr .3 "cd ../../.."
|
|||||||
abbr .4 "cd ../../../.."
|
abbr .4 "cd ../../../.."
|
||||||
abbr .5 "cd ../../../../.."
|
abbr .5 "cd ../../../../.."
|
||||||
|
|
||||||
# Tool init (fnm is initialized once in conf.d/fnm.fish — don't source it again here)
|
# Tool init
|
||||||
zoxide init --cmd cd fish | source
|
zoxide init --cmd cd fish | source
|
||||||
fish_add_path $HOME/.cargo/bin $HOME/.local/bin
|
|
||||||
|
|
||||||
# thefuck, lazy-loaded on first use (its --alias eval costs ~170ms of shell startup)
|
# thefuck, lazy-loaded on first use (its --alias eval costs ~170ms of shell startup)
|
||||||
function fuck
|
function fuck
|
||||||
@@ -102,11 +117,6 @@ function fuck
|
|||||||
thefuck --alias | source
|
thefuck --alias | source
|
||||||
fuck $argv
|
fuck $argv
|
||||||
end
|
end
|
||||||
|
|
||||||
# pnpm
|
|
||||||
set -gx PNPM_HOME "$HOME/.local/share/pnpm"
|
|
||||||
if not string match -q -- $PNPM_HOME $PATH
|
|
||||||
set -gx PATH "$PNPM_HOME" $PATH
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# Per-host extras
|
# Per-host extras
|
||||||
|
|||||||
@@ -8,7 +8,9 @@ function __ssh_agent_is_started -d "check if ssh agent is already started"
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
if begin; test -f "$SSH_ENV"; and test -z "$SSH_AGENT_PID"; end
|
if begin
|
||||||
|
test -f "$SSH_ENV"; and test -z "$SSH_AGENT_PID"
|
||||||
|
end
|
||||||
source $SSH_ENV >/dev/null
|
source $SSH_ENV >/dev/null
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -15,4 +15,3 @@ function bind_M_n_history
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,7 @@
|
|||||||
function clis --description 'fzf select cli'
|
function clis --description 'fzf select cli'
|
||||||
eval (cat $HOME/.config/misc/clis.txt | command fzf --multi)
|
# one eval per selection — a single eval of the joined lines would run the
|
||||||
|
# first command with the other selections as its arguments
|
||||||
|
for cmd in (cat $HOME/.config/misc/clis.txt | command fzf --multi)
|
||||||
|
eval $cmd
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -7,8 +7,10 @@ function kp
|
|||||||
read -s -P "Enter db password: " pass
|
read -s -P "Enter db password: " pass
|
||||||
echo ""
|
echo ""
|
||||||
|
|
||||||
set -l entry (echo $pass | keepassxc-cli ls -q -R $KP_DB | fzf)
|
# -f flattens to full paths; without it nested entries are printed indented and
|
||||||
|
# without their group prefix, so `clip` can't find them. Group lines end in "/".
|
||||||
|
set -l entry (printf '%s\n' $pass | keepassxc-cli ls -q -R -f $KP_DB | string match -v '*/' | fzf | string trim)
|
||||||
if test -n "$entry"
|
if test -n "$entry"
|
||||||
echo $pass | keepassxc-cli clip -q $KP_DB $entry 0
|
printf '%s\n' $pass | keepassxc-cli clip -q $KP_DB $entry 0
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -19,6 +19,3 @@ function opencodes --description 'contained opencode'
|
|||||||
--bind "$(pwd)" "$(pwd)" \
|
--bind "$(pwd)" "$(pwd)" \
|
||||||
opencode
|
opencode
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,7 @@
|
|||||||
function tuis --description 'fzf select tui'
|
function tuis --description 'fzf select tui'
|
||||||
eval (cat $HOME/.config/misc/tuis.txt | command fzf --multi)
|
# one eval per selection — a single eval of the joined lines would run the
|
||||||
|
# first command with the other selections as its arguments
|
||||||
|
for cmd in (cat $HOME/.config/misc/tuis.txt | command fzf --multi)
|
||||||
|
eval $cmd
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -40,6 +40,7 @@ asciiquarium
|
|||||||
cbonsai
|
cbonsai
|
||||||
tclock
|
tclock
|
||||||
hunk
|
hunk
|
||||||
|
tuicr
|
||||||
gittop
|
gittop
|
||||||
lazygit
|
lazygit
|
||||||
lazyjournal
|
lazyjournal
|
||||||
|
|||||||
@@ -3,6 +3,25 @@ require("nvchad.configs.lspconfig").defaults()
|
|||||||
local servers = { "html", "cssls", "ts_ls", "eslint" }
|
local servers = { "html", "cssls", "ts_ls", "eslint" }
|
||||||
vim.lsp.enable(servers)
|
vim.lsp.enable(servers)
|
||||||
|
|
||||||
|
-- Waybar/GTK stylesheets are GTK CSS, a different dialect: `@name` references
|
||||||
|
-- @define-color colors (waybar's theme.css) and functions like alpha() are
|
||||||
|
-- valid there but not in web CSS, so cssls floods "property value expected" /
|
||||||
|
-- "{ expected" false errors. No LSP speaks the GTK dialect, so keep cssls
|
||||||
|
-- attached (standard-property completion still useful) and mute diagnostics
|
||||||
|
-- on those buffers only.
|
||||||
|
vim.api.nvim_create_autocmd("LspAttach", {
|
||||||
|
callback = function(args)
|
||||||
|
local client = vim.lsp.get_client_by_id(args.data.client_id)
|
||||||
|
if not client or client.name ~= "cssls" then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
local path = vim.api.nvim_buf_get_name(args.buf)
|
||||||
|
if path:match "/waybar/" or path:match "/gtk%-%d" then
|
||||||
|
vim.diagnostic.enable(false, { bufnr = args.buf })
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
})
|
||||||
|
|
||||||
-- local lspconfig = require "lspconfig"
|
-- local lspconfig = require "lspconfig"
|
||||||
-- local nvlsp = require "nvchad.configs.lspconfig"
|
-- local nvlsp = require "nvchad.configs.lspconfig"
|
||||||
--
|
--
|
||||||
|
|||||||
@@ -34,6 +34,26 @@ return {
|
|||||||
"regex",
|
"regex",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
-- On the main branch nothing acts on `ensure_installed` at startup: setup() takes only
|
||||||
|
-- install_dir, and NvChad's :TSInstallAll (which does read this list off the lazy spec)
|
||||||
|
-- only runs from `build`, i.e. when the plugin is installed or updated. So a language
|
||||||
|
-- added here stayed uninstalled until the next rebuild — 9 of these 15 were missing,
|
||||||
|
-- silently falling back to regex highlighting. Install whatever is absent, once, here.
|
||||||
|
config = function(_, opts)
|
||||||
|
local ts = require "nvim-treesitter"
|
||||||
|
ts.setup()
|
||||||
|
|
||||||
|
local have = {}
|
||||||
|
for _, lang in ipairs(ts.get_installed()) do
|
||||||
|
have[lang] = true
|
||||||
|
end
|
||||||
|
local missing = vim.tbl_filter(function(lang)
|
||||||
|
return not have[lang]
|
||||||
|
end, opts.ensure_installed or {})
|
||||||
|
if #missing > 0 then
|
||||||
|
ts.install(missing) -- async; highlighting picks each up as it lands
|
||||||
|
end
|
||||||
|
end,
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -141,6 +141,7 @@
|
|||||||
"Qwen3.6-35B-A3B-MTP-UD-IQ3_XXS": { "name": "Qwen3.6 35B · 24k · vision — daily driver (remote)", "attachment": true, "limit": { "context": 24576, "output": 8192 } },
|
"Qwen3.6-35B-A3B-MTP-UD-IQ3_XXS": { "name": "Qwen3.6 35B · 24k · vision — daily driver (remote)", "attachment": true, "limit": { "context": 24576, "output": 8192 } },
|
||||||
"Qwen3.6-35B-A3B-Thinking": { "name": "Qwen3.6 35B Thinking · 24k · vision — hard problems (remote)", "attachment": true, "limit": { "context": 24576, "output": 8192 } },
|
"Qwen3.6-35B-A3B-Thinking": { "name": "Qwen3.6 35B Thinking · 24k · vision — hard problems (remote)", "attachment": true, "limit": { "context": 24576, "output": 8192 } },
|
||||||
"Qwen3.5-9B-UD-Q6_K_XL": { "name": "Qwen3.5 9B · 32k · vision — quick tasks (remote)", "attachment": true, "limit": { "context": 32768, "output": 8192 } },
|
"Qwen3.5-9B-UD-Q6_K_XL": { "name": "Qwen3.5 9B · 32k · vision — quick tasks (remote)", "attachment": true, "limit": { "context": 32768, "output": 8192 } },
|
||||||
|
"Qwen3.8-27B-UD-IQ3_XXS": { "name": "Qwen3.8 27B · 24k · vision — hybrid reasoner (remote)", "attachment": true, "limit": { "context": 24576, "output": 8192 } },
|
||||||
"gemma-4-26B-A4B-it-UD-IQ4_XS": { "name": "Gemma 4 26B · 24k · vision — quality generalist (remote)", "attachment": true, "limit": { "context": 24576, "output": 4096 } },
|
"gemma-4-26B-A4B-it-UD-IQ4_XS": { "name": "Gemma 4 26B · 24k · vision — quality generalist (remote)", "attachment": true, "limit": { "context": 24576, "output": 4096 } },
|
||||||
"gemma-4-E4B-it-UD-Q8_K_XL": { "name": "Gemma 4 E4B · 64k · vision — fast generalist, long docs (remote)", "attachment": true, "limit": { "context": 65536, "output": 16384 } },
|
"gemma-4-E4B-it-UD-Q8_K_XL": { "name": "Gemma 4 E4B · 64k · vision — fast generalist, long docs (remote)", "attachment": true, "limit": { "context": 65536, "output": 16384 } },
|
||||||
"GLM-4.7-Flash-UD-Q4_K_XL": { "name": "GLM-4.7 Flash · 24k — quality coder (remote)", "limit": { "context": 24576, "output": 8192 } },
|
"GLM-4.7-Flash-UD-Q4_K_XL": { "name": "GLM-4.7 Flash · 24k — quality coder (remote)", "limit": { "context": 24576, "output": 8192 } },
|
||||||
@@ -160,6 +161,7 @@
|
|||||||
"Qwen3.6-35B-A3B-MTP-UD-IQ3_XXS": { "name": "Qwen3.6 35B · 24k · vision — daily driver", "attachment": true, "limit": { "context": 24576, "output": 8192 } },
|
"Qwen3.6-35B-A3B-MTP-UD-IQ3_XXS": { "name": "Qwen3.6 35B · 24k · vision — daily driver", "attachment": true, "limit": { "context": 24576, "output": 8192 } },
|
||||||
"Qwen3.6-35B-A3B-Thinking": { "name": "Qwen3.6 35B Thinking · 24k · vision — hard problems", "attachment": true, "limit": { "context": 24576, "output": 8192 } },
|
"Qwen3.6-35B-A3B-Thinking": { "name": "Qwen3.6 35B Thinking · 24k · vision — hard problems", "attachment": true, "limit": { "context": 24576, "output": 8192 } },
|
||||||
"Qwen3.5-9B-UD-Q6_K_XL": { "name": "Qwen3.5 9B · 32k · vision — quick tasks", "attachment": true, "limit": { "context": 32768, "output": 8192 } },
|
"Qwen3.5-9B-UD-Q6_K_XL": { "name": "Qwen3.5 9B · 32k · vision — quick tasks", "attachment": true, "limit": { "context": 32768, "output": 8192 } },
|
||||||
|
"Qwen3.8-27B-UD-IQ3_XXS": { "name": "Qwen3.8 27B · 24k · vision — hybrid reasoner", "attachment": true, "limit": { "context": 24576, "output": 8192 } },
|
||||||
"gemma-4-26B-A4B-it-UD-IQ4_XS": { "name": "Gemma 4 26B · 24k · vision — quality generalist", "attachment": true, "limit": { "context": 24576, "output": 4096 } },
|
"gemma-4-26B-A4B-it-UD-IQ4_XS": { "name": "Gemma 4 26B · 24k · vision — quality generalist", "attachment": true, "limit": { "context": 24576, "output": 4096 } },
|
||||||
"gemma-4-E4B-it-UD-Q8_K_XL": { "name": "Gemma 4 E4B · 64k · vision — fast generalist, long docs", "attachment": true, "limit": { "context": 65536, "output": 16384 } },
|
"gemma-4-E4B-it-UD-Q8_K_XL": { "name": "Gemma 4 E4B · 64k · vision — fast generalist, long docs", "attachment": true, "limit": { "context": 65536, "output": 16384 } },
|
||||||
"GLM-4.7-Flash-UD-Q4_K_XL": { "name": "GLM-4.7 Flash · 24k — quality coder", "limit": { "context": 24576, "output": 8192 } },
|
"GLM-4.7-Flash-UD-Q4_K_XL": { "name": "GLM-4.7 Flash · 24k — quality coder", "limit": { "context": 24576, "output": 8192 } },
|
||||||
|
|||||||
@@ -10,12 +10,19 @@ rt="${XDG_RUNTIME_DIR:-/tmp}"
|
|||||||
st="$rt/tmux_cpu_stat" # previous totals: tot idle
|
st="$rt/tmux_cpu_stat" # previous totals: tot idle
|
||||||
|
|
||||||
read -r _ u n s i w rest </proc/stat
|
read -r _ u n s i w rest </proc/stat
|
||||||
idle=$((i + w)); tot=$((u + n + s + i + w)); for v in $rest; do tot=$((tot + v)); done
|
idle=$((i + w))
|
||||||
|
tot=$((u + n + s + i + w))
|
||||||
|
for v in $rest; do tot=$((tot + v)); done
|
||||||
|
|
||||||
p_tot=0; p_idle=0
|
p_tot=0
|
||||||
|
p_idle=0
|
||||||
[ -r "$st" ] && read -r p_tot p_idle <"$st"
|
[ -r "$st" ] && read -r p_tot p_idle <"$st"
|
||||||
[ "$p_tot" -gt "$tot" ] && { p_tot=0; p_idle=0; } # stale state from a previous boot
|
[ "$p_tot" -gt "$tot" ] && {
|
||||||
|
p_tot=0
|
||||||
|
p_idle=0
|
||||||
|
} # stale state from a previous boot
|
||||||
printf '%s %s\n' "$tot" "$idle" >"$st"
|
printf '%s %s\n' "$tot" "$idle" >"$st"
|
||||||
|
|
||||||
dt=$((tot - p_tot)); di=$((idle - p_idle))
|
dt=$((tot - p_tot))
|
||||||
|
di=$((idle - p_idle))
|
||||||
if [ "$dt" -le 0 ]; then printf -- '--%%'; else printf '%d%%' $(((100 * (dt - di) + dt / 2) / dt)); fi
|
if [ "$dt" -le 0 ]; then printf -- '--%%'; else printf '%d%%' $(((100 * (dt - di) + dt / 2) / dt)); fi
|
||||||
|
|||||||
@@ -39,11 +39,14 @@ fresh_emit
|
|||||||
now=$(date +%s.%N)
|
now=$(date +%s.%N)
|
||||||
read -r rx tx < <(awk 'NR>2{gsub(/:/," "); if($1!="lo"){r+=$2; t+=$10}} END{print r+0, t+0}' /proc/net/dev)
|
read -r rx tx < <(awk 'NR>2{gsub(/:/," "); if($1!="lo"){r+=$2; t+=$10}} END{print r+0, t+0}' /proc/net/dev)
|
||||||
|
|
||||||
drx=0; dtx=0; dt=1
|
drx=0
|
||||||
|
dtx=0
|
||||||
|
dt=1
|
||||||
if [ -r "$ctr" ]; then
|
if [ -r "$ctr" ]; then
|
||||||
read -r prx ptx pnow <"$ctr"
|
read -r prx ptx pnow <"$ctr"
|
||||||
dt=$(awk -v a="$now" -v b="$pnow" 'BEGIN{d=a-b; print (d>0.05)?d:1}')
|
dt=$(awk -v a="$now" -v b="$pnow" 'BEGIN{d=a-b; print (d>0.05)?d:1}')
|
||||||
drx=$(( rx - prx )); dtx=$(( tx - ptx ))
|
drx=$((rx - prx))
|
||||||
|
dtx=$((tx - ptx))
|
||||||
[ "$drx" -lt 0 ] && drx=0
|
[ "$drx" -lt 0 ] && drx=0
|
||||||
[ "$dtx" -lt 0 ] && dtx=0
|
[ "$dtx" -lt 0 ] && dtx=0
|
||||||
fi
|
fi
|
||||||
|
|||||||
@@ -5,15 +5,19 @@
|
|||||||
# (acpitz can be a bogus constant on desktops, hence last). Prints NOTHING when
|
# (acpitz can be a bogus constant on desktops, hence last). Prints NOTHING when
|
||||||
# no sensor exists (VMs/containers) so the segment simply disappears — which is
|
# no sensor exists (VMs/containers) so the segment simply disappears — which is
|
||||||
# also why the trailing spacing lives in here, not in status-right.
|
# also why the trailing spacing lives in here, not in status-right.
|
||||||
cpu_zone=""; any_zone=""; hw=""
|
cpu_zone=""
|
||||||
|
any_zone=""
|
||||||
|
hw=""
|
||||||
|
|
||||||
for d in /sys/class/thermal/thermal_zone*/; do
|
for d in /sys/class/thermal/thermal_zone*/; do
|
||||||
[ -r "${d}temp" ] && [ -r "${d}type" ] || continue
|
[ -r "${d}temp" ] && [ -r "${d}type" ] || continue
|
||||||
t=$(<"${d}temp")
|
t=$(<"${d}temp")
|
||||||
case $t in '' | *[!0-9]*) continue ;; esac
|
case $t in '' | *[!0-9]*) continue ;; esac
|
||||||
ty=$(<"${d}type"); ty=${ty,,}
|
ty=$(<"${d}type")
|
||||||
|
ty=${ty,,}
|
||||||
case $ty in *x86_pkg_temp* | *coretemp* | *k10temp* | *tctl* | *cpu*)
|
case $ty in *x86_pkg_temp* | *coretemp* | *k10temp* | *tctl* | *cpu*)
|
||||||
if [ -z "$cpu_zone" ] || [ "$t" -gt "$cpu_zone" ]; then cpu_zone=$t; fi ;;
|
if [ -z "$cpu_zone" ] || [ "$t" -gt "$cpu_zone" ]; then cpu_zone=$t; fi
|
||||||
|
;;
|
||||||
esac
|
esac
|
||||||
if [ -z "$any_zone" ] || [ "$t" -gt "$any_zone" ]; then any_zone=$t; fi
|
if [ -z "$any_zone" ] || [ "$t" -gt "$any_zone" ]; then any_zone=$t; fi
|
||||||
done
|
done
|
||||||
@@ -27,7 +31,8 @@ if [ -z "$cpu_zone" ]; then
|
|||||||
t=$(<"$f")
|
t=$(<"$f")
|
||||||
case $t in '' | *[!0-9]*) continue ;; esac
|
case $t in '' | *[!0-9]*) continue ;; esac
|
||||||
if [ -z "$hw" ] || [ "$t" -gt "$hw" ]; then hw=$t; fi
|
if [ -z "$hw" ] || [ "$t" -gt "$hw" ]; then hw=$t; fi
|
||||||
done ;;
|
done
|
||||||
|
;;
|
||||||
esac
|
esac
|
||||||
done
|
done
|
||||||
fi
|
fi
|
||||||
|
|||||||
@@ -3,6 +3,18 @@
|
|||||||
set -g extended-keys on
|
set -g extended-keys on
|
||||||
set -g extended-keys-format csi-u
|
set -g extended-keys-format csi-u
|
||||||
|
|
||||||
|
# Mouse/touch reporting. Chiefly so the window list in the status bar is
|
||||||
|
# tappable — tmux binds MouseDown1Status to `switch-client -t =` out of the box,
|
||||||
|
# and status-format[1] below keeps the `range=window|…` markers that make each
|
||||||
|
# entry a hit target, so a tap on a tab switches to it with no extra binding.
|
||||||
|
# Wheel over the bar cycles windows; right-click a tab or the session name for
|
||||||
|
# tmux's built-in menus (no touch equivalent — a phone can't right-click).
|
||||||
|
#
|
||||||
|
# The cost: drag-select now goes to tmux instead of kitty, so hold Shift when you
|
||||||
|
# want kitty's own selection. Scroll wheel enters copy-mode on the pane rather
|
||||||
|
# than kitty's scrollback, and a click focuses the pane under it.
|
||||||
|
set -g mouse on
|
||||||
|
|
||||||
# Number windows (and panes) from 1 instead of 0 — easier to reach on the
|
# Number windows (and panes) from 1 instead of 0 — easier to reach on the
|
||||||
# keyboard. renumber-windows keeps them gap-free when a window is closed.
|
# keyboard. renumber-windows keeps them gap-free when a window is closed.
|
||||||
set -g base-index 1
|
set -g base-index 1
|
||||||
@@ -42,8 +54,36 @@ set -g status-style "bg=default,fg=#cdd6f4" # transparent: no bar background
|
|||||||
set -g status-left-length 40
|
set -g status-left-length 40
|
||||||
set -g status-right-length 100
|
set -g status-right-length 100
|
||||||
|
|
||||||
# Left: session name (mauve/bold) + thin divider.
|
# --- Mobile view -----------------------------------------------------------
|
||||||
set -g status-left " #[fg=#cba6f7,bold]#S #[fg=#45475a]│ "
|
# status-left and status-right are re-evaluated per client on every draw, and
|
||||||
|
# #{client_width} is that client's own width — so in `auto` mode a phone attached
|
||||||
|
# to the same session as the desktop renders the compact bars while the desktop
|
||||||
|
# keeps the full ones, simultaneously and with no intervention.
|
||||||
|
#
|
||||||
|
# @status_mode is auto (per-client, by width) | full | compact, cycled with
|
||||||
|
# prefix+S. Rather than branch each bar three ways, the mode picks the width a
|
||||||
|
# client has to beat — 0 nothing can lose, 9999 nothing can win — so each
|
||||||
|
# decision below stays a single comparison. The 100 is the switch point: the full
|
||||||
|
# right segment is ~60 columns before the window list even starts. Set
|
||||||
|
# @status_mode without -g to scope an override to one session, so a grouped
|
||||||
|
# mobile session can sit on `compact` while the desktop session stays on `auto`.
|
||||||
|
#
|
||||||
|
# Each variant lives in its own option instead of inline because #{?a,b,c} splits
|
||||||
|
# its branches on commas and the styles are full of them (#[fg=…,bold]); option
|
||||||
|
# values are substituted after the ternary is parsed, so those commas are never
|
||||||
|
# seen as separators.
|
||||||
|
#
|
||||||
|
# NOTE: the comparisons MUST use #{e|>=:…}. Plain #{>=:…} compares as strings, so
|
||||||
|
# "144" >= "100" is false and every client would get the compact bar.
|
||||||
|
set -g @status_mode auto
|
||||||
|
set -g @status_cutoff "#{?#{==:#{@status_mode},full},0,#{?#{==:#{@status_mode},compact},9999,100}}"
|
||||||
|
|
||||||
|
# Left: session name (mauve/bold) + thin divider. Compact clips the name to two
|
||||||
|
# characters — enough to tell sessions apart when every column counts. #{=2:…}
|
||||||
|
# takes a format NAME, so it's session_name here rather than the #S shorthand.
|
||||||
|
set -g @left_full " #[fg=#cba6f7,bold]#S #[fg=#45475a]│ "
|
||||||
|
set -g @left_compact " #[fg=#cba6f7,bold]#{=2:session_name} #[fg=#45475a]│ "
|
||||||
|
set -g status-left "#{?#{e|>=:#{client_width},#{E:@status_cutoff}},#{E:@left_full},#{E:@left_compact}}"
|
||||||
|
|
||||||
# Middle: flat window list — inactive muted, active mauve/bold, 2-space gaps.
|
# Middle: flat window list — inactive muted, active mauve/bold, 2-space gaps.
|
||||||
set -g window-status-separator " "
|
set -g window-status-separator " "
|
||||||
@@ -52,9 +92,35 @@ setw -g window-status-current-format "#[fg=#cba6f7,bold]#I #[fg=#cdd6f4,bold]#W"
|
|||||||
setw -g window-status-activity-style "fg=#f9e2af"
|
setw -g window-status-activity-style "fg=#f9e2af"
|
||||||
|
|
||||||
# Right: net dl/ul · cpu · mem │ date │ clock. continuum prepends its invisible
|
# Right: net dl/ul · cpu · mem │ date │ clock. continuum prepends its invisible
|
||||||
# save hook here (this block sits above the tpm `run` line, so the hook survives
|
# save hook to status-right (this block sits above the tpm `run` line, so the
|
||||||
# every reload). Metrics are scripts/*.sh, symlinked into ~/.config/tmux/scripts/.
|
# hook survives every reload). Metrics are scripts/*.sh, symlinked into
|
||||||
set -g status-right "#[fg=#a6e3a1]#(~/.config/tmux/scripts/net.sh dl) #[fg=#f9e2af]#(~/.config/tmux/scripts/net.sh ul) #[fg=#89b4fa]#(~/.config/tmux/scripts/cpu.sh) #[fg=#94e2d5]#(~/.config/tmux/scripts/mem.sh) #[fg=#fab387]#(~/.config/tmux/scripts/temp.sh)#[fg=#45475a]│ #[fg=#a6adc8]%a %b %-d #[fg=#45475a]│ #[fg=#cba6f7,bold]%H:%M "
|
# ~/.config/tmux/scripts/. The hook lands ahead of the #{?} below, i.e. outside
|
||||||
|
# it, so it keeps running for every client regardless of which variant is drawn.
|
||||||
|
set -g @right_full "#[fg=#a6e3a1]#(~/.config/tmux/scripts/net.sh dl) #[fg=#f9e2af]#(~/.config/tmux/scripts/net.sh ul) #[fg=#89b4fa]#(~/.config/tmux/scripts/cpu.sh) #[fg=#94e2d5]#(~/.config/tmux/scripts/mem.sh) #[fg=#fab387]#(~/.config/tmux/scripts/temp.sh)#[fg=#45475a]│ #[fg=#a6adc8]%a %b %-d #[fg=#45475a]│ #[fg=#cba6f7,bold]%H:%M "
|
||||||
|
|
||||||
|
# Compact: cpu + mem only. Net rates and the temp glyph go first (widest, least
|
||||||
|
# useful on a phone), then the date, then the clock — a phone shows its own.
|
||||||
|
set -g @right_compact "#[fg=#89b4fa]#(~/.config/tmux/scripts/cpu.sh) #[fg=#94e2d5]#(~/.config/tmux/scripts/mem.sh) "
|
||||||
|
|
||||||
|
set -g status-right "#{?#{e|>=:#{client_width},#{E:@status_cutoff}},#{E:@right_full},#{E:@right_compact}}"
|
||||||
|
|
||||||
|
# Cycle auto -> compact -> full -> auto. Braces instead of nested quoted strings
|
||||||
|
# so the styles' commas and the inner if-shell don't need escaping.
|
||||||
|
bind S {
|
||||||
|
if -F '#{==:#{@status_mode},auto}' {
|
||||||
|
set -g @status_mode compact
|
||||||
|
display 'status bar: compact (forced)'
|
||||||
|
} {
|
||||||
|
if -F '#{==:#{@status_mode},compact}' {
|
||||||
|
set -g @status_mode full
|
||||||
|
display 'status bar: full (forced)'
|
||||||
|
} {
|
||||||
|
set -g @status_mode auto
|
||||||
|
display 'status bar: auto — switches at 100 columns'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
refresh-client -S
|
||||||
|
}
|
||||||
|
|
||||||
# Two rows: [0] drawn top-border rule · [1] the bar content. The rule doubles as
|
# Two rows: [0] drawn top-border rule · [1] the bar content. The rule doubles as
|
||||||
# the separator from the pane content above; tmux status height is whole rows, so
|
# the separator from the pane content above; tmux status height is whole rows, so
|
||||||
|
|||||||
+72
-10
@@ -56,15 +56,70 @@ have a slash command to disable them for the current session without deleting.
|
|||||||
| Extension | What it adds | Origin | Remove |
|
| Extension | What it adds | Origin | Remove |
|
||||||
|---|---|---|---|
|
|---|---|---|---|
|
||||||
| `statusbar.ts` | Replaces the footer with a Claude-Code-style status line (cwd, git branch, model, context %, decode t/s, token counts) in Nerd Font glyphs; adds a streaming pulse + a ≥80%-context warning widget | **custom** | delete file → default footer returns; or `/statusbar` to toggle off for the session |
|
| `statusbar.ts` | Replaces the footer with a Claude-Code-style status line (cwd, git branch, model, context %, decode t/s, token counts) in Nerd Font glyphs; adds a streaming pulse + a ≥80%-context warning widget | **custom** | delete file → default footer returns; or `/statusbar` to toggle off for the session |
|
||||||
| `vim-editor.ts` | Modal (vim-like) input editor with `[I]/[N]/[V]` indicator, hjkl/word/line motions, counts, yank/paste via the kill-ring | **local fork** of pi's bundled `examples/extensions/modal-editor.ts` | delete file → default editor; or `/vim` to toggle |
|
| `vim-toggle.ts` | `/vim` — drops the modal editor for the rest of the session, and brings it back via `ctx.reload()`. Pairs with the **`pi-vim` package** (below), which registers no command of its own | **custom** | delete file → you lose the toggle, not the editor; remove the package to drop modal editing itself |
|
||||||
| `plan-mode/` | Read-only "plan" mode (disables edit/write, restricts bash) bound to **Shift+Tab**; `/plan` toggles, `--plan` starts in it | **vendored** copy of pi's bundled `examples/extensions/plan-mode/`, rebound from upstream `Ctrl+Alt+P` | delete the folder **and** revert the `keybindings.json` `app.thinking.cycle` remap (see below) |
|
| `plan-mode/` | Read-only "plan" mode (disables edit/write, restricts bash) bound to **Shift+Tab**; `/plan` toggles, `--plan` starts in it, `/plan-done` clears a stuck progress checklist | **vendored** copy of pi's bundled `examples/extensions/plan-mode/`, rebound from upstream `Ctrl+Alt+P` | delete the folder **and** revert the `keybindings.json` `app.thinking.cycle` remap (see below) |
|
||||||
| `notify.ts` | Native terminal notification (OSC 777/99, Windows toast) when the agent goes idle | **verbatim** from pi's `examples/extensions/notify.ts` | delete file |
|
| `notify.ts` | Native terminal notification (OSC 777/99, Windows toast) when the agent goes idle | **verbatim** from pi's `examples/extensions/notify.ts` | delete file |
|
||||||
| `questionnaire.ts` | Interactive multi-question overlay the model can call as a tool | **near-verbatim** from pi's `examples/extensions/questionnaire.ts` (one-line fix) | delete file |
|
| `questionnaire.ts` | Interactive multi-question overlay the model can call as a tool | **near-verbatim** from pi's `examples/extensions/questionnaire.ts` (one-line fix) | delete file |
|
||||||
|
| `permission-gate.ts` | Prompts before dangerous `bash` commands (blocks outright with no UI). Local list covers git history rewrites, package managers, `systemctl` and irreversible disk ops on top of upstream's `rm -rf`/`sudo`/`chmod 777` | **adapted** from pi's `examples/extensions/permission-gate.ts` | delete file |
|
||||||
|
| `protected-paths.ts` | Blocks `write`/`edit` to secrets and repo plumbing (`secrets.fish`, `auth.json`, `.env`, `.ssh/`, `.git/`, …) | **adapted** from pi's `examples/extensions/protected-paths.ts` | delete file |
|
||||||
|
| `compaction-watch.ts` | Surfaces every compaction and its `reason`; loudly flags `overflow` (recovery rather than prevention), which means `reserveTokens` is below the model's `maxTokens` | **custom** | delete file |
|
||||||
|
| `confirm-destructive.ts` | Confirms before session clear / switch / fork | **verbatim** from pi's `examples/extensions/confirm-destructive.ts` | delete file |
|
||||||
|
| `session-name.ts` | `/session-name [name]` — friendly names in the session picker instead of the first message | **verbatim** from pi's `examples/extensions/session-name.ts` | delete file |
|
||||||
|
| `todo.ts` | A `todo` tool the model calls (add/toggle/list/clear) plus `/todos` to view it; state lives in tool results, so forking rewinds it correctly. Distinct from plan-mode's checklist | **verbatim** from pi's `examples/extensions/todo.ts` | delete file (it also adds a tool schema to every request) |
|
||||||
|
|
||||||
> The bundled examples live at `/opt/pi-coding-agent/examples/extensions/` — that's
|
> The bundled examples live at `/opt/pi-coding-agent/examples/extensions/` — that's
|
||||||
> where `notify`/`questionnaire`/`modal-editor`/`plan-mode` came from, and where to
|
> where `notify`/`questionnaire`/`plan-mode` came from. `plan-mode/` is now the only
|
||||||
> re-pull the two forks after a pi upgrade before re-applying the local edits (the
|
> **fork** left, so it's the only one to re-pull after a pi upgrade before re-applying
|
||||||
> forks' own headers document those edits).
|
> the local edits (its header documents them). `notify`/`questionnaire` carry no edits
|
||||||
|
> worth keeping — just re-copy them. The modal editor used to be a fork of
|
||||||
|
> `modal-editor.ts` too; it was replaced by the `pi-vim` package on 2026-08-05 and the
|
||||||
|
> fork deleted on 2026-08-09 — `git show c6566af^:common/.pi/agent/extensions/vim-editor.ts`
|
||||||
|
> brings it back if ever wanted.
|
||||||
|
|
||||||
|
### Modal (vim) input — the `pi-vim` package
|
||||||
|
|
||||||
|
Modal editing is **not** an extension in this tree any more; it's the npm package
|
||||||
|
[`pi-vim`](https://github.com/lajarre/pi-vim), pinned by `settings.json > packages`
|
||||||
|
and installed into the gitignored `agent/npm/`. That swap is the point: `pi update
|
||||||
|
npm:pi-vim` instead of re-pulling and re-patching a fork on every pi upgrade.
|
||||||
|
|
||||||
|
Five modes (INSERT/NORMAL/VISUAL/V-LINE/EX) with the usual motions, operators, text
|
||||||
|
objects, undo and `.` repeat; the mode renders as a word label at the editor's
|
||||||
|
bottom-right, doubling as a pending-command display (` NORMAL 3d2w_ `). `:` dispatches
|
||||||
|
real pi commands and shells out with `:!`. No search (`/`, `?`, `n`), macros or
|
||||||
|
visual-block — upstream implements none of those.
|
||||||
|
|
||||||
|
```fish
|
||||||
|
pi install npm:pi-vim
|
||||||
|
```
|
||||||
|
|
||||||
|
> ⚠️ **This pi build needs pi-vim's peer dep installed by hand.** pi ships as a
|
||||||
|
> Bun-compiled ELF with the `@earendil-works/*` packages *embedded*, not on disk.
|
||||||
|
> pi-vim's `clipboard-mirror.ts` calls `import.meta.resolve("@earendil-works/pi-coding-agent")`
|
||||||
|
> at **module top level**, so after a bare `pi install` the resolve throws and the whole
|
||||||
|
> extension fails to load with `Cannot find module '@earendil-works/pi-coding-agent'`.
|
||||||
|
> No setting avoids it — the call runs at import time. Once per host, matching
|
||||||
|
> `pi --version` exactly:
|
||||||
|
>
|
||||||
|
> ```fish
|
||||||
|
> cd ~/.pi/agent/npm
|
||||||
|
> fnm exec --using=22 -- npm install --save-exact @earendil-works/pi-coding-agent@0.83.0
|
||||||
|
> ```
|
||||||
|
>
|
||||||
|
> `pi install` deliberately doesn't pull peers (it would duplicate the runtime). Costs
|
||||||
|
> ~170 MB, and wants re-pinning after every pi upgrade — hence `--save-exact`, since a
|
||||||
|
> caret range would quietly drift off `pi --version`.
|
||||||
|
|
||||||
|
Configured under `settings.json > piVim`: `modeColors` (theme tokens, not raw ANSI),
|
||||||
|
`borderSync`/`labelSync` pinned so only the label is tinted, and
|
||||||
|
`clipboardMirror: "yank"` — upstream's default `"all"` mirrors deletes too, so every
|
||||||
|
`dd`/`x` would clobber the OS clipboard. `exCommand.copyInputToClipboard` is left
|
||||||
|
**off**: it copies the composed prompt out, so upstream only honours it from the
|
||||||
|
user-global settings file.
|
||||||
|
|
||||||
|
**Remove:** `pi remove npm:pi-vim`, and delete `agent/extensions/vim-toggle.ts` plus the
|
||||||
|
`piVim` block. `@burneikis/pi-vim` and `pi-vimmode` are alternatives that need no peer
|
||||||
|
install.
|
||||||
|
|
||||||
### Theme
|
### Theme
|
||||||
|
|
||||||
@@ -110,11 +165,14 @@ Beyond pointing at local models, these values deviate from pi's defaults:
|
|||||||
|
|
||||||
| Key | Value here | Stock default | Why |
|
| Key | Value here | Stock default | Why |
|
||||||
|---|---|---|---|
|
|---|---|---|---|
|
||||||
| `compaction.reserveTokens` | `6144` | 16384 | small local windows (24k–128k) — don't let the response reserve dominate a short window |
|
| `compaction.reserveTokens` | `8192` | 16384 | small local windows (24k–128k), but **≥ every model's `maxTokens`** — otherwise a turn can overflow the window before compaction even fires |
|
||||||
| `compaction.keepRecentTokens` | `6000` | 20000 | keep less verbatim so short windows don't thrash into repeated compaction |
|
| `compaction.keepRecentTokens` | `4000` | 20000 | keep less verbatim, to pay for the larger reserve and leave room after a compaction for the next one |
|
||||||
| `npmCommand` | `fnm exec --using=22 -- npm` | `npm` | pin extension npm installs to Node 22 via fnm |
|
| `npmCommand` | `fnm exec --using=22 -- npm` | `npm` | pin extension npm installs to Node 22 via fnm |
|
||||||
| `retry` / `httpIdleTimeoutMs` | long (1h provider timeout, 10m idle) | shorter | local models can be slow to first token |
|
| `retry` / `httpIdleTimeoutMs` | long (1h provider timeout, 10m idle) | shorter | local models can be slow to first token |
|
||||||
| `defaultThinkingLevel` | `off` | — | most local models here are non-reasoning |
|
| `defaultThinkingLevel` | `off` | — | most local models here are non-reasoning |
|
||||||
|
| `packages` | `["npm:pi-vim"]` | `[]` | the modal editor — see the pi-vim section above |
|
||||||
|
| `piVim` | mode colors, `clipboardMirror: "yank"`, `:` → pi bridge | — | package config, not a pi setting; ignored if the package is removed |
|
||||||
|
| `collapseChangelog` | `true` | `false` | condensed changelog after an upgrade instead of the full screen |
|
||||||
|
|
||||||
**Remove:** delete each key to fall back to pi's default (or drop the whole
|
**Remove:** delete each key to fall back to pi's default (or drop the whole
|
||||||
`compaction`/`retry` block).
|
`compaction`/`retry` block).
|
||||||
@@ -140,8 +198,9 @@ model.
|
|||||||
> config. `auth.json` is **not tracked** (gitignored as of 2026-08-08): pi's interactive
|
> config. `auth.json` is **not tracked** (gitignored as of 2026-08-08): pi's interactive
|
||||||
> `/login` rewrites it with the **literal** key, and a tracked copy would be one stray
|
> `/login` rewrites it with the **literal** key, and a tracked copy would be one stray
|
||||||
> `/login` away from committing a real token. Bootstrap a new host with
|
> `/login` away from committing a real token. Bootstrap a new host with
|
||||||
> `cp auth.json.example auth.json`. For bash its `.bash_profile` since it's not tracked by
|
> `cp auth.json.example auth.json`. The key itself lives in a shell file that is *not*
|
||||||
> git, stow not applied.
|
> tracked and *not* stowed, so it never reaches this repo — `conf.d/secrets.fish` for
|
||||||
|
> fish, `~/.bash_profile` for bash.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -150,7 +209,10 @@ model.
|
|||||||
- **Just the status bar:** copy `agent/extensions/statusbar.ts` into your
|
- **Just the status bar:** copy `agent/extensions/statusbar.ts` into your
|
||||||
`~/.pi/agent/extensions/`, re-stow/restart, `/reload`. Colors follow your active
|
`~/.pi/agent/extensions/`, re-stow/restart, `/reload`. Colors follow your active
|
||||||
theme automatically. Needs a Nerd Font terminal for the glyphs.
|
theme automatically. Needs a Nerd Font terminal for the glyphs.
|
||||||
- **Just vim input:** copy `agent/extensions/vim-editor.ts`, `/reload`, `/vim`.
|
- **Just vim input:** `pi install npm:pi-vim`, then the peer-dep install above (this
|
||||||
|
build needs it), then `/reload`. Copy the `piVim` block from `settings.json` for the
|
||||||
|
same colors and clipboard behaviour, and `agent/extensions/vim-toggle.ts` if you want
|
||||||
|
`/vim` to toggle it.
|
||||||
- **Just plan mode:** copy `agent/extensions/plan-mode/` **and** add the
|
- **Just plan mode:** copy `agent/extensions/plan-mode/` **and** add the
|
||||||
`app.thinking.cycle` remap to your `keybindings.json` (else Shift+Tab collides).
|
`app.thinking.cycle` remap to your `keybindings.json` (else Shift+Tab collides).
|
||||||
- **Just the theme:** copy `agent/themes/catppuccin-mocha.json`, set
|
- **Just the theme:** copy `agent/themes/catppuccin-mocha.json`, set
|
||||||
|
|||||||
@@ -0,0 +1,22 @@
|
|||||||
|
# Global agent instructions
|
||||||
|
|
||||||
|
You are a coding assistant running on small, locally-hosted models. Be precise and economical with tokens.
|
||||||
|
|
||||||
|
## Working style
|
||||||
|
- Act with tools instead of describing what you would do. Keep prose short.
|
||||||
|
- Do the task that was asked. Don't add unrequested changes, refactors, or files.
|
||||||
|
- When done, stop. A one- or two-line summary is enough; no recaps of obvious steps.
|
||||||
|
|
||||||
|
## Files & edits
|
||||||
|
- Read a file before you edit it. Never guess at file paths, function names, or APIs — verify first.
|
||||||
|
- Use the edit tool for changes. Make minimal, targeted diffs; never paste an entire file back to the user.
|
||||||
|
- Match the surrounding code's style, naming, and imports.
|
||||||
|
|
||||||
|
## Shell
|
||||||
|
- Run one command at a time and check its output before the next.
|
||||||
|
- Prefer `rg` and `fd` for search. Use read-only commands when exploring.
|
||||||
|
- Never run destructive or system-changing commands (`rm -rf`, `sudo`, package installs, force-push) unless explicitly asked.
|
||||||
|
|
||||||
|
## Honesty
|
||||||
|
- If you're unsure, say so and check rather than inventing an answer.
|
||||||
|
- Report failures plainly with the actual error; don't claim success you didn't verify.
|
||||||
@@ -0,0 +1,60 @@
|
|||||||
|
/**
|
||||||
|
* Compaction Watch
|
||||||
|
*
|
||||||
|
* Compaction is otherwise silent, which is why "compacting fails a lot" took code
|
||||||
|
* reading and arithmetic to diagnose rather than a glance at a log. This makes it
|
||||||
|
* visible, and specifically names the failure mode that was breaking it here before
|
||||||
|
* 2026-08-16.
|
||||||
|
*
|
||||||
|
* pi reports a `reason` on every compaction:
|
||||||
|
* "manual" - you ran /compact
|
||||||
|
* "threshold" - the healthy path: contextTokens passed contextWindow - reserveTokens
|
||||||
|
* "overflow" - the window was ALREADY full; this is recovery, not prevention
|
||||||
|
*
|
||||||
|
* An "overflow" compaction means the turn blew past contextWindow before the threshold
|
||||||
|
* could fire, which happens whenever `compaction.reserveTokens` is smaller than the
|
||||||
|
* model's `maxTokens`. pi then gets one recovery attempt, summarizing from an
|
||||||
|
* already-overflowed context — and when that does not fit either, the session dies with
|
||||||
|
* "Context overflow recovery failed after one compact-and-retry attempt".
|
||||||
|
*
|
||||||
|
* So: seeing "threshold" is fine. Seeing "overflow" means the settings are wrong for the
|
||||||
|
* model in use, and this says so at the moment it happens instead of leaving you to
|
||||||
|
* infer it later. See CLAUDE.md > Compaction tuning.
|
||||||
|
*
|
||||||
|
* Note there is no event for a *failed* auto-compaction — `onError` exists only on the
|
||||||
|
* manual `ctx.compact()` call — so catching the overflow entry is the earliest reliable
|
||||||
|
* warning available.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
|
||||||
|
|
||||||
|
export default function (pi: ExtensionAPI) {
|
||||||
|
let overflowCount = 0;
|
||||||
|
|
||||||
|
pi.on("session_before_compact", async (event, ctx) => {
|
||||||
|
if (!ctx.hasUI) return undefined;
|
||||||
|
|
||||||
|
if (event.reason === "overflow") {
|
||||||
|
overflowCount++;
|
||||||
|
ctx.ui.notify(
|
||||||
|
`Compacting in OVERFLOW recovery (#${overflowCount}) — the context window was already ` +
|
||||||
|
`full before compaction could fire. Raise compaction.reserveTokens above this model's ` +
|
||||||
|
`maxTokens, or cap maxTokens in models.json. See CLAUDE.md > Compaction tuning.`,
|
||||||
|
"warning",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Never alter the compaction itself — observe only.
|
||||||
|
return undefined;
|
||||||
|
});
|
||||||
|
|
||||||
|
pi.on("session_compact", async (event, ctx) => {
|
||||||
|
if (!ctx.hasUI) return;
|
||||||
|
|
||||||
|
const reason = event.reason ?? "unknown";
|
||||||
|
const retrying = event.willRetry ? ", retrying the aborted turn" : "";
|
||||||
|
const level = reason === "overflow" ? "warning" : "info";
|
||||||
|
|
||||||
|
ctx.ui.notify(`Compacted (${reason}${retrying})`, level);
|
||||||
|
});
|
||||||
|
}
|
||||||
@@ -0,0 +1,59 @@
|
|||||||
|
/**
|
||||||
|
* Confirm Destructive Actions Extension
|
||||||
|
*
|
||||||
|
* Prompts for confirmation before destructive session actions (clear, switch, branch).
|
||||||
|
* Demonstrates how to cancel session events using the before_* events.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import type { ExtensionAPI, SessionBeforeSwitchEvent, SessionMessageEntry } from "@earendil-works/pi-coding-agent";
|
||||||
|
|
||||||
|
export default function (pi: ExtensionAPI) {
|
||||||
|
pi.on("session_before_switch", async (event: SessionBeforeSwitchEvent, ctx) => {
|
||||||
|
if (!ctx.hasUI) return;
|
||||||
|
|
||||||
|
if (event.reason === "new") {
|
||||||
|
const confirmed = await ctx.ui.confirm(
|
||||||
|
"Clear session?",
|
||||||
|
"This will delete all messages in the current session.",
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!confirmed) {
|
||||||
|
ctx.ui.notify("Clear cancelled", "info");
|
||||||
|
return { cancel: true };
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// reason === "resume" - check if there are unsaved changes (messages since last assistant response)
|
||||||
|
const entries = ctx.sessionManager.getEntries();
|
||||||
|
const hasUnsavedWork = entries.some(
|
||||||
|
(e): e is SessionMessageEntry => e.type === "message" && e.message.role === "user",
|
||||||
|
);
|
||||||
|
|
||||||
|
if (hasUnsavedWork) {
|
||||||
|
const confirmed = await ctx.ui.confirm(
|
||||||
|
"Switch session?",
|
||||||
|
"You have messages in the current session. Switch anyway?",
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!confirmed) {
|
||||||
|
ctx.ui.notify("Switch cancelled", "info");
|
||||||
|
return { cancel: true };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
pi.on("session_before_fork", async (event, ctx) => {
|
||||||
|
if (!ctx.hasUI) return;
|
||||||
|
|
||||||
|
const choice = await ctx.ui.select(`Fork from entry ${event.entryId.slice(0, 8)}?`, [
|
||||||
|
"Yes, create fork",
|
||||||
|
"No, stay in current session",
|
||||||
|
]);
|
||||||
|
|
||||||
|
if (choice !== "Yes, create fork") {
|
||||||
|
ctx.ui.notify("Fork cancelled", "info");
|
||||||
|
return { cancel: true };
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
@@ -0,0 +1,69 @@
|
|||||||
|
/**
|
||||||
|
* Permission Gate Extension
|
||||||
|
*
|
||||||
|
* Prompts for confirmation before running potentially dangerous bash commands.
|
||||||
|
*
|
||||||
|
* Adapted from pi's bundled `examples/extensions/permission-gate.ts`. Upstream checks
|
||||||
|
* three patterns (rm -rf, sudo, chmod/chown 777); the list below is extended to cover
|
||||||
|
* the rules AGENTS.md only *asks* for. That distinction is the whole point of running
|
||||||
|
* this: AGENTS.md is a prompt, and the small local models this config targets follow
|
||||||
|
* prompts unreliably. This is the enforcement half — the same trick plan-mode already
|
||||||
|
* uses when it disables edit/write outright.
|
||||||
|
*
|
||||||
|
* In the TUI a match prompts (so "Yes" still gets you through); with no UI it blocks.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
|
||||||
|
|
||||||
|
export default function (pi: ExtensionAPI) {
|
||||||
|
const dangerousPatterns = [
|
||||||
|
// --- upstream ---
|
||||||
|
/\brm\s+(-rf?|--recursive)/i,
|
||||||
|
/\bsudo\b/i,
|
||||||
|
/\b(chmod|chown)\b.*777/i,
|
||||||
|
|
||||||
|
// --- LOCAL: git history is the user's to write, never the agent's ---
|
||||||
|
// The standing rule is that commits and pushes are made by hand, after review.
|
||||||
|
/\bgit\s+(commit|push|revert)\b/i,
|
||||||
|
/\bgit\s+reset\s+--hard\b/i,
|
||||||
|
/\bgit\s+(rebase|cherry-pick)\b/i,
|
||||||
|
/\bgit\s+clean\s+-[a-z]*[fd]/i,
|
||||||
|
/\bgit\s+stash\s+(drop|clear|pop)\b/i,
|
||||||
|
/--force\b|--force-with-lease\b/i,
|
||||||
|
|
||||||
|
// --- LOCAL: system-changing commands AGENTS.md rules out ---
|
||||||
|
/\b(pacman|yay|paru)\s+-[A-Za-z]*[SRU]/,
|
||||||
|
/\b(npm|pnpm|yarn)\s+(install|i|add|remove|uninstall)\b/i,
|
||||||
|
/\bpip3?\s+(install|uninstall)\b/i,
|
||||||
|
/\bcargo\s+(install|uninstall)\b/i,
|
||||||
|
/\bsystemctl\s+(start|stop|restart|enable|disable|mask)\b/i,
|
||||||
|
|
||||||
|
// --- LOCAL: irreversible disk / process operations ---
|
||||||
|
/\bmkfs\b|\bdd\s+if=|\bshred\b|\bwipefs\b/i,
|
||||||
|
/\b(reboot|shutdown|poweroff|halt)\b/i,
|
||||||
|
/\b(killall|pkill)\b/i,
|
||||||
|
/>\s*\/dev\/(sd|nvme|vd)/i,
|
||||||
|
];
|
||||||
|
|
||||||
|
pi.on("tool_call", async (event, ctx) => {
|
||||||
|
if (event.toolName !== "bash") return undefined;
|
||||||
|
|
||||||
|
const command = event.input.command as string;
|
||||||
|
const matched = dangerousPatterns.find((p) => p.test(command));
|
||||||
|
|
||||||
|
if (matched) {
|
||||||
|
if (!ctx.hasUI) {
|
||||||
|
// Non-interactive (`pi -p`): nothing can confirm, so refuse.
|
||||||
|
return { block: true, reason: "Dangerous command blocked (no UI for confirmation)" };
|
||||||
|
}
|
||||||
|
|
||||||
|
const choice = await ctx.ui.select(`⚠️ Dangerous command:\n\n ${command}\n\nAllow?`, ["Yes", "No"]);
|
||||||
|
|
||||||
|
if (choice !== "Yes") {
|
||||||
|
return { block: true, reason: "Blocked by user" };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return undefined;
|
||||||
|
});
|
||||||
|
}
|
||||||
@@ -142,6 +142,25 @@ export default function planModeExtension(pi: ExtensionAPI): void {
|
|||||||
handler: async (_args, ctx) => togglePlanMode(ctx),
|
handler: async (_args, ctx) => togglePlanMode(ctx),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// LOCAL EDIT: the checklist widget only tears itself down once every step is
|
||||||
|
// marked complete, which needs the model to emit a [DONE:n] tag per step. When
|
||||||
|
// one is missed the widget sticks around after the work is finished, so give
|
||||||
|
// the user a way out that doesn't involve toggling plan mode on and off again.
|
||||||
|
pi.registerCommand("plan-done", {
|
||||||
|
description: "Clear a stuck plan checklist (stops execution tracking)",
|
||||||
|
handler: async (_args, ctx) => {
|
||||||
|
if (!executionMode && todoItems.length === 0) {
|
||||||
|
ctx.ui.notify("No plan is being tracked.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
executionMode = false;
|
||||||
|
todoItems = [];
|
||||||
|
updateStatus(ctx);
|
||||||
|
persistState();
|
||||||
|
ctx.ui.notify("Plan tracking cleared.");
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
pi.registerCommand("todos", {
|
pi.registerCommand("todos", {
|
||||||
description: "Show current plan todo list",
|
description: "Show current plan todo list",
|
||||||
handler: async (_args, ctx) => {
|
handler: async (_args, ctx) => {
|
||||||
|
|||||||
@@ -151,10 +151,17 @@ export function extractTodoItems(message: string): TodoItem[] {
|
|||||||
|
|
||||||
export function extractDoneSteps(message: string): number[] {
|
export function extractDoneSteps(message: string): number[] {
|
||||||
const steps: number[] = [];
|
const steps: number[] = [];
|
||||||
for (const match of message.matchAll(/\[DONE:(\d+)\]/gi)) {
|
// LOCAL EDIT: upstream matched only the literal `[DONE:3]`. Small local models
|
||||||
const step = Number(match[1]);
|
// drift on it, and one missed tag pins the plan widget on screen forever, so
|
||||||
|
// also accept `[DONE 3]`, `[DONE-3]` and comma lists `[DONE:1,2]`. The brackets
|
||||||
|
// stay required on purpose: a bare "done 3" in prose must not mark a step.
|
||||||
|
for (const match of message.matchAll(/\[\s*DONE\s*[:\-=]?\s*([\d,\s]+?)\s*\]/gi)) {
|
||||||
|
for (const part of match[1].split(/[,\s]+/)) {
|
||||||
|
if (part === "") continue;
|
||||||
|
const step = Number(part);
|
||||||
if (Number.isFinite(step)) steps.push(step);
|
if (Number.isFinite(step)) steps.push(step);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return steps;
|
return steps;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,58 @@
|
|||||||
|
/**
|
||||||
|
* Protected Paths Extension
|
||||||
|
*
|
||||||
|
* Blocks write and edit operations to protected paths.
|
||||||
|
*
|
||||||
|
* Adapted from pi's bundled `examples/extensions/protected-paths.ts`. Upstream ships a
|
||||||
|
* three-entry demo list (.env, .git/, node_modules/); the list below names the files
|
||||||
|
* that actually matter in this dotfiles tree — the ones holding secrets, and the git
|
||||||
|
* metadata the agent has no business rewriting.
|
||||||
|
*
|
||||||
|
* Scope, so this isn't over-trusted: it guards against the *model* calling write/edit.
|
||||||
|
* It cannot stop pi's own `/login`, which rewrites auth.json with the literal key —
|
||||||
|
* that is why auth.json is gitignored and auth.json.example is the tracked copy.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
|
||||||
|
|
||||||
|
export default function (pi: ExtensionAPI) {
|
||||||
|
const protectedPaths = [
|
||||||
|
// Secrets. `secrets.fish` holds $DUSKADIY_API_KEY; auth.json is pi's own
|
||||||
|
// credential map and must keep $VAR references rather than literals.
|
||||||
|
"secrets.fish",
|
||||||
|
"auth.json",
|
||||||
|
".env",
|
||||||
|
"fish_variables",
|
||||||
|
|
||||||
|
// Credentials outside the repo.
|
||||||
|
".ssh/",
|
||||||
|
".gnupg/",
|
||||||
|
".aws/",
|
||||||
|
".netrc",
|
||||||
|
|
||||||
|
// Repo plumbing and vendored trees — never hand-edited.
|
||||||
|
".git/",
|
||||||
|
"node_modules/",
|
||||||
|
];
|
||||||
|
|
||||||
|
pi.on("tool_call", async (event, ctx) => {
|
||||||
|
if (event.toolName !== "write" && event.toolName !== "edit") {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
const path = event.input.path as string;
|
||||||
|
// Substring match, like upstream: cheap, and these names are distinctive enough.
|
||||||
|
// Note `auth.json.example` is intentionally caught too — it is a tracked file
|
||||||
|
// whose whole job is to contain no secret, so an agent rewrite is worth a look.
|
||||||
|
const isProtected = protectedPaths.some((p) => path.includes(p));
|
||||||
|
|
||||||
|
if (isProtected) {
|
||||||
|
if (ctx.hasUI) {
|
||||||
|
ctx.ui.notify(`Blocked write to protected path: ${path}`, "warning");
|
||||||
|
}
|
||||||
|
return { block: true, reason: `Path "${path}" is protected` };
|
||||||
|
}
|
||||||
|
|
||||||
|
return undefined;
|
||||||
|
});
|
||||||
|
}
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
/**
|
||||||
|
* Session naming example.
|
||||||
|
*
|
||||||
|
* Shows setSessionName/getSessionName to give sessions friendly names
|
||||||
|
* that appear in the session selector instead of the first message.
|
||||||
|
*
|
||||||
|
* Usage: /session-name [name] - set or show session name
|
||||||
|
*/
|
||||||
|
|
||||||
|
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
|
||||||
|
|
||||||
|
export default function (pi: ExtensionAPI) {
|
||||||
|
pi.registerCommand("session-name", {
|
||||||
|
description: "Set or show session name (usage: /session-name [new name])",
|
||||||
|
handler: async (args, ctx) => {
|
||||||
|
const name = args.trim();
|
||||||
|
|
||||||
|
if (name) {
|
||||||
|
pi.setSessionName(name);
|
||||||
|
ctx.ui.notify(`Session named: ${name}`, "info");
|
||||||
|
} else {
|
||||||
|
const current = pi.getSessionName();
|
||||||
|
ctx.ui.notify(current ? `Session: ${current}` : "No session name set", "info");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
@@ -0,0 +1,297 @@
|
|||||||
|
/**
|
||||||
|
* Todo Extension - Demonstrates state management via session entries
|
||||||
|
*
|
||||||
|
* This extension:
|
||||||
|
* - Registers a `todo` tool for the LLM to manage todos
|
||||||
|
* - Registers a `/todos` command for users to view the list
|
||||||
|
*
|
||||||
|
* State is stored in tool result details (not external files), which allows
|
||||||
|
* proper branching - when you branch, the todo state is automatically
|
||||||
|
* correct for that point in history.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { StringEnum } from "@earendil-works/pi-ai";
|
||||||
|
import type { ExtensionAPI, ExtensionContext, Theme } from "@earendil-works/pi-coding-agent";
|
||||||
|
import { matchesKey, Text, truncateToWidth } from "@earendil-works/pi-tui";
|
||||||
|
import { Type } from "typebox";
|
||||||
|
|
||||||
|
interface Todo {
|
||||||
|
id: number;
|
||||||
|
text: string;
|
||||||
|
done: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface TodoDetails {
|
||||||
|
action: "list" | "add" | "toggle" | "clear";
|
||||||
|
todos: Todo[];
|
||||||
|
nextId: number;
|
||||||
|
error?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
const TodoParams = Type.Object({
|
||||||
|
action: StringEnum(["list", "add", "toggle", "clear"] as const),
|
||||||
|
text: Type.Optional(Type.String({ description: "Todo text (for add)" })),
|
||||||
|
id: Type.Optional(Type.Number({ description: "Todo ID (for toggle)" })),
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* UI component for the /todos command
|
||||||
|
*/
|
||||||
|
class TodoListComponent {
|
||||||
|
private todos: Todo[];
|
||||||
|
private theme: Theme;
|
||||||
|
private onClose: () => void;
|
||||||
|
private cachedWidth?: number;
|
||||||
|
private cachedLines?: string[];
|
||||||
|
|
||||||
|
constructor(todos: Todo[], theme: Theme, onClose: () => void) {
|
||||||
|
this.todos = todos;
|
||||||
|
this.theme = theme;
|
||||||
|
this.onClose = onClose;
|
||||||
|
}
|
||||||
|
|
||||||
|
handleInput(data: string): void {
|
||||||
|
if (matchesKey(data, "escape") || matchesKey(data, "ctrl+c")) {
|
||||||
|
this.onClose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
render(width: number): string[] {
|
||||||
|
if (this.cachedLines && this.cachedWidth === width) {
|
||||||
|
return this.cachedLines;
|
||||||
|
}
|
||||||
|
|
||||||
|
const lines: string[] = [];
|
||||||
|
const th = this.theme;
|
||||||
|
|
||||||
|
lines.push("");
|
||||||
|
const title = th.fg("accent", " Todos ");
|
||||||
|
const headerLine =
|
||||||
|
th.fg("borderMuted", "─".repeat(3)) + title + th.fg("borderMuted", "─".repeat(Math.max(0, width - 10)));
|
||||||
|
lines.push(truncateToWidth(headerLine, width));
|
||||||
|
lines.push("");
|
||||||
|
|
||||||
|
if (this.todos.length === 0) {
|
||||||
|
lines.push(truncateToWidth(` ${th.fg("dim", "No todos yet. Ask the agent to add some!")}`, width));
|
||||||
|
} else {
|
||||||
|
const done = this.todos.filter((t) => t.done).length;
|
||||||
|
const total = this.todos.length;
|
||||||
|
lines.push(truncateToWidth(` ${th.fg("muted", `${done}/${total} completed`)}`, width));
|
||||||
|
lines.push("");
|
||||||
|
|
||||||
|
for (const todo of this.todos) {
|
||||||
|
const check = todo.done ? th.fg("success", "✓") : th.fg("dim", "○");
|
||||||
|
const id = th.fg("accent", `#${todo.id}`);
|
||||||
|
const text = todo.done ? th.fg("dim", todo.text) : th.fg("text", todo.text);
|
||||||
|
lines.push(truncateToWidth(` ${check} ${id} ${text}`, width));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
lines.push("");
|
||||||
|
lines.push(truncateToWidth(` ${th.fg("dim", "Press Escape to close")}`, width));
|
||||||
|
lines.push("");
|
||||||
|
|
||||||
|
this.cachedWidth = width;
|
||||||
|
this.cachedLines = lines;
|
||||||
|
return lines;
|
||||||
|
}
|
||||||
|
|
||||||
|
invalidate(): void {
|
||||||
|
this.cachedWidth = undefined;
|
||||||
|
this.cachedLines = undefined;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function (pi: ExtensionAPI) {
|
||||||
|
// In-memory state (reconstructed from session on load)
|
||||||
|
let todos: Todo[] = [];
|
||||||
|
let nextId = 1;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reconstruct state from session entries.
|
||||||
|
* Scans tool results for this tool and applies them in order.
|
||||||
|
*/
|
||||||
|
const reconstructState = (ctx: ExtensionContext) => {
|
||||||
|
todos = [];
|
||||||
|
nextId = 1;
|
||||||
|
|
||||||
|
for (const entry of ctx.sessionManager.getBranch()) {
|
||||||
|
if (entry.type !== "message") continue;
|
||||||
|
const msg = entry.message;
|
||||||
|
if (msg.role !== "toolResult" || msg.toolName !== "todo") continue;
|
||||||
|
|
||||||
|
const details = msg.details as TodoDetails | undefined;
|
||||||
|
if (details) {
|
||||||
|
todos = details.todos;
|
||||||
|
nextId = details.nextId;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Reconstruct state on session events
|
||||||
|
pi.on("session_start", async (_event, ctx) => reconstructState(ctx));
|
||||||
|
pi.on("session_tree", async (_event, ctx) => reconstructState(ctx));
|
||||||
|
|
||||||
|
// Register the todo tool for the LLM
|
||||||
|
pi.registerTool({
|
||||||
|
name: "todo",
|
||||||
|
label: "Todo",
|
||||||
|
description: "Manage a todo list. Actions: list, add (text), toggle (id), clear",
|
||||||
|
parameters: TodoParams,
|
||||||
|
|
||||||
|
async execute(_toolCallId, params, _signal, _onUpdate, _ctx) {
|
||||||
|
switch (params.action) {
|
||||||
|
case "list":
|
||||||
|
return {
|
||||||
|
content: [
|
||||||
|
{
|
||||||
|
type: "text",
|
||||||
|
text: todos.length
|
||||||
|
? todos.map((t) => `[${t.done ? "x" : " "}] #${t.id}: ${t.text}`).join("\n")
|
||||||
|
: "No todos",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
details: { action: "list", todos: [...todos], nextId } as TodoDetails,
|
||||||
|
};
|
||||||
|
|
||||||
|
case "add": {
|
||||||
|
if (!params.text) {
|
||||||
|
return {
|
||||||
|
content: [{ type: "text", text: "Error: text required for add" }],
|
||||||
|
details: { action: "add", todos: [...todos], nextId, error: "text required" } as TodoDetails,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
const newTodo: Todo = { id: nextId++, text: params.text, done: false };
|
||||||
|
todos.push(newTodo);
|
||||||
|
return {
|
||||||
|
content: [{ type: "text", text: `Added todo #${newTodo.id}: ${newTodo.text}` }],
|
||||||
|
details: { action: "add", todos: [...todos], nextId } as TodoDetails,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
case "toggle": {
|
||||||
|
if (params.id === undefined) {
|
||||||
|
return {
|
||||||
|
content: [{ type: "text", text: "Error: id required for toggle" }],
|
||||||
|
details: { action: "toggle", todos: [...todos], nextId, error: "id required" } as TodoDetails,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
const todo = todos.find((t) => t.id === params.id);
|
||||||
|
if (!todo) {
|
||||||
|
return {
|
||||||
|
content: [{ type: "text", text: `Todo #${params.id} not found` }],
|
||||||
|
details: {
|
||||||
|
action: "toggle",
|
||||||
|
todos: [...todos],
|
||||||
|
nextId,
|
||||||
|
error: `#${params.id} not found`,
|
||||||
|
} as TodoDetails,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
todo.done = !todo.done;
|
||||||
|
return {
|
||||||
|
content: [{ type: "text", text: `Todo #${todo.id} ${todo.done ? "completed" : "uncompleted"}` }],
|
||||||
|
details: { action: "toggle", todos: [...todos], nextId } as TodoDetails,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
case "clear": {
|
||||||
|
const count = todos.length;
|
||||||
|
todos = [];
|
||||||
|
nextId = 1;
|
||||||
|
return {
|
||||||
|
content: [{ type: "text", text: `Cleared ${count} todos` }],
|
||||||
|
details: { action: "clear", todos: [], nextId: 1 } as TodoDetails,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
return {
|
||||||
|
content: [{ type: "text", text: `Unknown action: ${params.action}` }],
|
||||||
|
details: {
|
||||||
|
action: "list",
|
||||||
|
todos: [...todos],
|
||||||
|
nextId,
|
||||||
|
error: `unknown action: ${params.action}`,
|
||||||
|
} as TodoDetails,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
renderCall(args, theme, _context) {
|
||||||
|
let text = theme.fg("toolTitle", theme.bold("todo ")) + theme.fg("muted", args.action);
|
||||||
|
if (args.text) text += ` ${theme.fg("dim", `"${args.text}"`)}`;
|
||||||
|
if (args.id !== undefined) text += ` ${theme.fg("accent", `#${args.id}`)}`;
|
||||||
|
return new Text(text, 0, 0);
|
||||||
|
},
|
||||||
|
|
||||||
|
renderResult(result, { expanded }, theme, _context) {
|
||||||
|
const details = result.details as TodoDetails | undefined;
|
||||||
|
if (!details) {
|
||||||
|
const text = result.content[0];
|
||||||
|
return new Text(text?.type === "text" ? text.text : "", 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (details.error) {
|
||||||
|
return new Text(theme.fg("error", `Error: ${details.error}`), 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
const todoList = details.todos;
|
||||||
|
|
||||||
|
switch (details.action) {
|
||||||
|
case "list": {
|
||||||
|
if (todoList.length === 0) {
|
||||||
|
return new Text(theme.fg("dim", "No todos"), 0, 0);
|
||||||
|
}
|
||||||
|
let listText = theme.fg("muted", `${todoList.length} todo(s):`);
|
||||||
|
const display = expanded ? todoList : todoList.slice(0, 5);
|
||||||
|
for (const t of display) {
|
||||||
|
const check = t.done ? theme.fg("success", "✓") : theme.fg("dim", "○");
|
||||||
|
const itemText = t.done ? theme.fg("dim", t.text) : theme.fg("muted", t.text);
|
||||||
|
listText += `\n${check} ${theme.fg("accent", `#${t.id}`)} ${itemText}`;
|
||||||
|
}
|
||||||
|
if (!expanded && todoList.length > 5) {
|
||||||
|
listText += `\n${theme.fg("dim", `... ${todoList.length - 5} more`)}`;
|
||||||
|
}
|
||||||
|
return new Text(listText, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
case "add": {
|
||||||
|
const added = todoList[todoList.length - 1];
|
||||||
|
return new Text(
|
||||||
|
theme.fg("success", "✓ Added ") +
|
||||||
|
theme.fg("accent", `#${added.id}`) +
|
||||||
|
" " +
|
||||||
|
theme.fg("muted", added.text),
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
case "toggle": {
|
||||||
|
const text = result.content[0];
|
||||||
|
const msg = text?.type === "text" ? text.text : "";
|
||||||
|
return new Text(theme.fg("success", "✓ ") + theme.fg("muted", msg), 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
case "clear":
|
||||||
|
return new Text(theme.fg("success", "✓ ") + theme.fg("muted", "Cleared all todos"), 0, 0);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
// Register the /todos command for users
|
||||||
|
pi.registerCommand("todos", {
|
||||||
|
description: "Show all todos on the current branch",
|
||||||
|
handler: async (_args, ctx) => {
|
||||||
|
if (ctx.mode !== "tui") {
|
||||||
|
ctx.ui.notify("/todos requires interactive mode", "error");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
await ctx.ui.custom<void>((_tui, theme, _kb, done) => {
|
||||||
|
return new TodoListComponent(todos, theme, () => done());
|
||||||
|
});
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
@@ -52,7 +52,7 @@
|
|||||||
"reasoning": false,
|
"reasoning": false,
|
||||||
"input": ["text", "image"],
|
"input": ["text", "image"],
|
||||||
"contextWindow": 24576,
|
"contextWindow": 24576,
|
||||||
"maxTokens": 8192,
|
"maxTokens": 4096,
|
||||||
"cost": { "input": 0, "output": 0, "cacheRead": 0, "cacheWrite": 0 }
|
"cost": { "input": 0, "output": 0, "cacheRead": 0, "cacheWrite": 0 }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -62,7 +62,7 @@
|
|||||||
"compat": { "thinkingFormat": "qwen-chat-template" },
|
"compat": { "thinkingFormat": "qwen-chat-template" },
|
||||||
"input": ["text", "image"],
|
"input": ["text", "image"],
|
||||||
"contextWindow": 24576,
|
"contextWindow": 24576,
|
||||||
"maxTokens": 8192,
|
"maxTokens": 4096,
|
||||||
"cost": { "input": 0, "output": 0, "cacheRead": 0, "cacheWrite": 0 }
|
"cost": { "input": 0, "output": 0, "cacheRead": 0, "cacheWrite": 0 }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -75,6 +75,16 @@
|
|||||||
"maxTokens": 8192,
|
"maxTokens": 8192,
|
||||||
"cost": { "input": 0, "output": 0, "cacheRead": 0, "cacheWrite": 0 }
|
"cost": { "input": 0, "output": 0, "cacheRead": 0, "cacheWrite": 0 }
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"id": "Qwen3.8-27B-UD-IQ3_XXS",
|
||||||
|
"name": "Qwen3.8 27B · 24k · vision — hybrid reasoner",
|
||||||
|
"reasoning": true,
|
||||||
|
"compat": { "thinkingFormat": "qwen-chat-template" },
|
||||||
|
"input": ["text", "image"],
|
||||||
|
"contextWindow": 24576,
|
||||||
|
"maxTokens": 8192,
|
||||||
|
"cost": { "input": 0, "output": 0, "cacheRead": 0, "cacheWrite": 0 }
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"id": "GLM-4.7-Flash-UD-Q4_K_XL",
|
"id": "GLM-4.7-Flash-UD-Q4_K_XL",
|
||||||
"name": "GLM-4.7 Flash · 24k — quality coder",
|
"name": "GLM-4.7 Flash · 24k — quality coder",
|
||||||
@@ -82,7 +92,7 @@
|
|||||||
"compat": { "thinkingFormat": "qwen-chat-template" },
|
"compat": { "thinkingFormat": "qwen-chat-template" },
|
||||||
"input": ["text"],
|
"input": ["text"],
|
||||||
"contextWindow": 24576,
|
"contextWindow": 24576,
|
||||||
"maxTokens": 8192,
|
"maxTokens": 4096,
|
||||||
"cost": { "input": 0, "output": 0, "cacheRead": 0, "cacheWrite": 0 }
|
"cost": { "input": 0, "output": 0, "cacheRead": 0, "cacheWrite": 0 }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -157,7 +167,7 @@
|
|||||||
"reasoning": false,
|
"reasoning": false,
|
||||||
"input": ["text", "image"],
|
"input": ["text", "image"],
|
||||||
"contextWindow": 24576,
|
"contextWindow": 24576,
|
||||||
"maxTokens": 8192,
|
"maxTokens": 4096,
|
||||||
"cost": { "input": 0, "output": 0, "cacheRead": 0, "cacheWrite": 0 }
|
"cost": { "input": 0, "output": 0, "cacheRead": 0, "cacheWrite": 0 }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -167,7 +177,7 @@
|
|||||||
"compat": { "thinkingFormat": "qwen-chat-template" },
|
"compat": { "thinkingFormat": "qwen-chat-template" },
|
||||||
"input": ["text", "image"],
|
"input": ["text", "image"],
|
||||||
"contextWindow": 24576,
|
"contextWindow": 24576,
|
||||||
"maxTokens": 8192,
|
"maxTokens": 4096,
|
||||||
"cost": { "input": 0, "output": 0, "cacheRead": 0, "cacheWrite": 0 }
|
"cost": { "input": 0, "output": 0, "cacheRead": 0, "cacheWrite": 0 }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -180,6 +190,16 @@
|
|||||||
"maxTokens": 8192,
|
"maxTokens": 8192,
|
||||||
"cost": { "input": 0, "output": 0, "cacheRead": 0, "cacheWrite": 0 }
|
"cost": { "input": 0, "output": 0, "cacheRead": 0, "cacheWrite": 0 }
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"id": "Qwen3.8-27B-UD-IQ3_XXS",
|
||||||
|
"name": "Qwen3.8 27B · 24k · vision — hybrid reasoner",
|
||||||
|
"reasoning": true,
|
||||||
|
"compat": { "thinkingFormat": "qwen-chat-template" },
|
||||||
|
"input": ["text", "image"],
|
||||||
|
"contextWindow": 24576,
|
||||||
|
"maxTokens": 8192,
|
||||||
|
"cost": { "input": 0, "output": 0, "cacheRead": 0, "cacheWrite": 0 }
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"id": "GLM-4.7-Flash-UD-Q4_K_XL",
|
"id": "GLM-4.7-Flash-UD-Q4_K_XL",
|
||||||
"name": "GLM-4.7 Flash · 24k — quality coder",
|
"name": "GLM-4.7 Flash · 24k — quality coder",
|
||||||
@@ -187,7 +207,7 @@
|
|||||||
"compat": { "thinkingFormat": "qwen-chat-template" },
|
"compat": { "thinkingFormat": "qwen-chat-template" },
|
||||||
"input": ["text"],
|
"input": ["text"],
|
||||||
"contextWindow": 24576,
|
"contextWindow": 24576,
|
||||||
"maxTokens": 8192,
|
"maxTokens": 4096,
|
||||||
"cost": { "input": 0, "output": 0, "cacheRead": 0, "cacheWrite": 0 }
|
"cost": { "input": 0, "output": 0, "cacheRead": 0, "cacheWrite": 0 }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
"defaultThinkingLevel": "off",
|
"defaultThinkingLevel": "off",
|
||||||
"theme": "catppuccin-mocha",
|
"theme": "catppuccin-mocha",
|
||||||
"quietStartup": false,
|
"quietStartup": false,
|
||||||
|
"collapseChangelog": true,
|
||||||
"defaultProjectTrust": "ask",
|
"defaultProjectTrust": "ask",
|
||||||
"enableInstallTelemetry": false,
|
"enableInstallTelemetry": false,
|
||||||
"enabledModels": [
|
"enabledModels": [
|
||||||
@@ -12,8 +13,8 @@
|
|||||||
],
|
],
|
||||||
"compaction": {
|
"compaction": {
|
||||||
"enabled": true,
|
"enabled": true,
|
||||||
"reserveTokens": 6144,
|
"reserveTokens": 8192,
|
||||||
"keepRecentTokens": 6000
|
"keepRecentTokens": 4000
|
||||||
},
|
},
|
||||||
"retry": {
|
"retry": {
|
||||||
"enabled": true,
|
"enabled": true,
|
||||||
|
|||||||
@@ -4,7 +4,8 @@ llama.cpp in **router mode** serving ~10 model presets from one 16 GB GPU.
|
|||||||
Last full tune: **2026-07-16** (decode numbers measured then via `bench.py`, unless a preset comment in `config.ini` says otherwise).
|
Last full tune: **2026-07-16** (decode numbers measured then via `bench.py`, unless a preset comment in `config.ini` says otherwise).
|
||||||
Last full clean sweep: **2026-08-08 03:22** — all 11 presets loaded and ran green (baseline 2.0 GB) after the week's coder-race/KV-fix/gemma-sidecar round.
|
Last full clean sweep: **2026-08-08 03:22** — all 11 presets loaded and ran green (baseline 2.0 GB) after the week's coder-race/KV-fix/gemma-sidecar round.
|
||||||
|
|
||||||
- **Box**: AMD RX 7600 XT 16 GB (ROCm, ~288 GB/s) + Ryzen 5600X (6 cores) + 48 GB RAM.
|
- **Box**: AMD RX 7600 XT 16 GB (~288 GB/s; backend = Arch `llama.cpp-vulkan` / RADV, **not** ROCm —
|
||||||
|
`rocm-smi` is only the VRAM monitor) + Ryzen 5600X (6 cores) + 48 GB RAM.
|
||||||
⚠ The GPU **also drives the display** — see [VRAM safety](#vram-safety-the-golden-rules).
|
⚠ The GPU **also drives the display** — see [VRAM safety](#vram-safety-the-golden-rules).
|
||||||
- **Endpoints**: LAN `http://$SERVER:11343/v1` · remote `https://<own-domain>/api/v1`
|
- **Endpoints**: LAN `http://$SERVER:11343/v1` · remote `https://<own-domain>/api/v1`
|
||||||
(own reverse proxy to the same server; requires an API key. Only the LAN endpoint is keyless).
|
(own reverse proxy to the same server; requires an API key. Only the LAN endpoint is keyless).
|
||||||
@@ -36,7 +37,7 @@ After ANY preset change: restart + `./bench.py -m <changed-ids>` and check the g
|
|||||||
|
|
||||||
## VRAM safety (the golden rules)
|
## VRAM safety (the golden rules)
|
||||||
|
|
||||||
ROCm does not OOM cleanly — an overcommitted model spills into GTT (system RAM),
|
The amdgpu driver does not OOM cleanly — an overcommitted model spills into GTT (system RAM),
|
||||||
starves the desktop and freezes the PC (reboot). Hard-won rules:
|
starves the desktop and freezes the PC (reboot). Hard-won rules:
|
||||||
|
|
||||||
1. Keep every preset's benched **VRAM free ≥ 2.5 GB** (idle desktop uses ~1.3 of 17.2).
|
1. Keep every preset's benched **VRAM free ≥ 2.5 GB** (idle desktop uses ~1.3 of 17.2).
|
||||||
@@ -60,6 +61,7 @@ starves the desktop and freezes the PC (reboot). Hard-won rules:
|
|||||||
| `Qwen3-Coder-30B-Instruct-UD-Q3_K_XL` | **~30** clean / 27.0 evening @moe12 | 32k | — | **main agent coder** — won the 2026-08-06 quant race; moe12 verified evening 08-07 + clean 08-08 |
|
| `Qwen3-Coder-30B-Instruct-UD-Q3_K_XL` | **~30** clean / 27.0 evening @moe12 | 32k | — | **main agent coder** — won the 2026-08-06 quant race; moe12 verified evening 08-07 + clean 08-08 |
|
||||||
| `GLM-4.7-Flash-UD-Q4_K_XL` | **21.5** @moe22 | 24k | reasoning | quality coder (opencode subagents); KV fix + moe22 ✓ verified clean 08-08 |
|
| `GLM-4.7-Flash-UD-Q4_K_XL` | **21.5** @moe22 | 24k | reasoning | quality coder (opencode subagents); KV fix + moe22 ✓ verified clean 08-08 |
|
||||||
| `Qwen3-Coder-Next-UD-IQ3_XXS` | 16.0 | **128k** | 80B-A3B | long-session coder (128k ctx) |
|
| `Qwen3-Coder-Next-UD-IQ3_XXS` | 16.0 | **128k** | 80B-A3B | long-session coder (128k ctx) |
|
||||||
|
| `Qwen3.8-27B-UD-IQ3_XXS` | 14.5 (10.9 w/o MTP) | 24k | vision, MTP, hybrid reasoner | ⚠ **clean-desktop specialty** (kept 09-10 over the ≥22 gate) — dense-27B quality, slow: its Gated-DeltaNet layers are Vulkan-bound (prefill ~30). 2.5 GB free @1.6 baseline @24k (✓ 09-10); **never on a busy evening desktop** (~1 GB free = GTT freeze) |
|
||||||
| `Qwen3-Embedding-0.6B` | 33 (CPU) | 8k | CPU-only, `/v1/embeddings` | RAG/search embedder (not a chat model) |
|
| `Qwen3-Embedding-0.6B` | 33 (CPU) | 8k | CPU-only, `/v1/embeddings` | RAG/search embedder (not a chat model) |
|
||||||
|
|
||||||
Expected run-to-run spread: MTP models swing ±15% with draft **acceptance rate** (content-
|
Expected run-to-run spread: MTP models swing ±15% with draft **acceptance rate** (content-
|
||||||
@@ -77,6 +79,9 @@ Treat clean night runs as the reference; don't retune on daytime deltas.
|
|||||||
- **Hard reasoning**: `35B-Thinking` (quality) or `gpt-oss-20b` (speed + tool use).
|
- **Hard reasoning**: `35B-Thinking` (quality) or `gpt-oss-20b` (speed + tool use).
|
||||||
Their multi-second TTFT is the reasoning phase streaming first — not a slow load.
|
Their multi-second TTFT is the reasoning phase streaming first — not a slow load.
|
||||||
For quick interactive gpt-oss answers use `gpt-oss-20b-low` (reasoning effort low).
|
For quick interactive gpt-oss answers use `gpt-oss-20b-low` (reasoning effort low).
|
||||||
|
- **Best single-model quality, speed no object** (quiet desktop only): `Qwen3.8-27B` — dense
|
||||||
|
27B hybrid reasoner + vision at ~14.5 t/s; it cannot go faster on this card (GDN layers on
|
||||||
|
Vulkan), and a busy evening desktop pushes it into GTT-freeze territory — check `rocm-smi` first.
|
||||||
- **Images**: `gemma-4-26B` for quality, `gemma-4-E4B` or `Qwen3.5-9B` for speed,
|
- **Images**: `gemma-4-26B` for quality, `gemma-4-E4B` or `Qwen3.5-9B` for speed,
|
||||||
`Qwen3.6-35B` when you want the daily driver to see the screenshot.
|
`Qwen3.6-35B` when you want the daily driver to see the screenshot.
|
||||||
- **Long one-shot documents**: `gemma-4-E4B` — 185 t/s prefill eats 64k in ~6 min
|
- **Long one-shot documents**: `gemma-4-E4B` — 185 t/s prefill eats 64k in ~6 min
|
||||||
@@ -123,6 +128,9 @@ The embedder is deliberately absent from chat clients.
|
|||||||
2026-08-06: the coder id changed `…-IQ4_XS` → `…-UD-Q3_K_XL` in all six client files
|
2026-08-06: the coder id changed `…-IQ4_XS` → `…-UD-Q3_K_XL` in all six client files
|
||||||
(common + lw overlays) after the quant race; OWUI picks the new id up automatically from
|
(common + lw overlays) after the quant race; OWUI picks the new id up automatically from
|
||||||
the router, but chats/presets saved against the old id need re-picking.
|
the router, but chats/presets saved against the old id need re-picking.
|
||||||
|
2026-08-16: `Qwen3.8-27B-UD-IQ3_XXS` (⚗ candidate) added to all six client files.
|
||||||
|
2026-09-10: kept as ⚠ clean-desktop specialty after the gate bench finally ran on the v3 gguf
|
||||||
|
(14.5 t/s MTP / 10.9 base, 2.8 GB free @1.5); server ctx restored to 24576 = client ctx, no client edits.
|
||||||
|
|
||||||
## Tuning cheat-sheet
|
## Tuning cheat-sheet
|
||||||
|
|
||||||
@@ -135,7 +143,10 @@ the router, but chats/presets saved against the old id need re-picking.
|
|||||||
4-bit now; 3-bit was only ~2 t/s faster). Coders want ≥4-bit; chat tolerates UD 3-bit.
|
4-bit now; 3-bit was only ~2 t/s faster). Coders want ≥4-bit; chat tolerates UD 3-bit.
|
||||||
- **MTP / spec decode** (`spec-type draft-mtp`): ~1.5–2× decode. Qwen3.5/3.6 embed the
|
- **MTP / spec decode** (`spec-type draft-mtp`): ~1.5–2× decode. Qwen3.5/3.6 embed the
|
||||||
head in the *MTP-repo* GGUF (same filename as plain repo — size is the tell);
|
head in the *MTP-repo* GGUF (same filename as plain repo — size is the tell);
|
||||||
gemma-4 uses a separate `mtp-*.gguf` draft file. **No MTP possible yet for**:
|
gemma-4 uses a separate `mtp-*.gguf` draft file; Qwen3.8 ships the head in the
|
||||||
|
*main*-repo GGUFs for ≥ Q2_K_XL (≤ IQ2_S are stripped — use the repo's `MTP/mtp-*.gguf`
|
||||||
|
draft instead). On the hybrid 27B it is only +33% (10.9→14.5) and costs 1.5 GB: every
|
||||||
|
speculative step re-runs the Gated-DeltaNet layers. **No MTP possible yet for**:
|
||||||
GLM-4.7-Flash (conversion drops the head — expected ~1.5× when llama.cpp lands it),
|
GLM-4.7-Flash (conversion drops the head — expected ~1.5× when llama.cpp lands it),
|
||||||
Qwen3-Coder-Next (Qwen3-Next head exists upstream, no GGUF ships it), gpt-oss and
|
Qwen3-Coder-Next (Qwen3-Next head exists upstream, no GGUF ships it), gpt-oss and
|
||||||
Qwen3-Coder-30B (no head exists). Recheck releases occasionally.
|
Qwen3-Coder-30B (no head exists). Recheck releases occasionally.
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
# llama.cpp model config — AMD RX 7600 XT (ROCm) · 16 GB (17.16 GB total)
|
# llama.cpp model config — AMD RX 7600 XT · 16 GB (17.16 GB total) · backend = Arch llama.cpp-vulkan
|
||||||
|
# (RADV, device Vulkan0 — NOT ROCm/HIP; rocm-smi is used for monitoring only)
|
||||||
# ═════════════════════════════════════════════════════════════════════════════
|
# ═════════════════════════════════════════════════════════════════════════════
|
||||||
# ⚠⚠ VRAM SAFETY — READ THIS. This GPU ALSO DRIVES THE DISPLAY. If a model asks for
|
# ⚠⚠ VRAM SAFETY — READ THIS. This GPU ALSO DRIVES THE DISPLAY. If a model asks for
|
||||||
# more VRAM than is free, ROCm does NOT OOM cleanly — it spills into system RAM
|
# more VRAM than is free, the amdgpu driver does NOT OOM cleanly — it spills into system RAM
|
||||||
# (GTT), which starves the desktop and FREEZES THE WHOLE PC (reboot required).
|
# (GTT), which starves the desktop and FREEZES THE WHOLE PC (reboot required).
|
||||||
# → TARGET ≥ ~2.5 GB free (≤ ~14.5 GB used). HARD FLOOR 1.5 GB (bench.py guard stops there).
|
# → TARGET ≥ ~2.5 GB free (≤ ~14.5 GB used). HARD FLOOR 1.5 GB (bench.py guard stops there).
|
||||||
# Idle desktop uses ~1.3 GB of 17.16 — but a browser/leftover model can hold 1-3 GB more,
|
# Idle desktop uses ~1.3 GB of 17.16 — but a browser/leftover model can hold 1-3 GB more,
|
||||||
@@ -223,6 +224,141 @@ repeat-penalty = 1.05
|
|||||||
jinja = on
|
jinja = on
|
||||||
sleep-idle-seconds = 60
|
sleep-idle-seconds = 60
|
||||||
|
|
||||||
|
[Qwen3.8-27B-UD-IQ3_XXS]
|
||||||
|
# ⚠ CLEAN-DESKTOP SPECIALTY — KEPT by user decision 2026-09-10 despite failing the ≥22 t/s speed
|
||||||
|
# gate (14.5 t/s MTP / 10.9 base; 2.8 GB free @1.5 baseline @16k). Pick it ONLY on a quiet
|
||||||
|
# desktop: at a 3+ GB evening baseline it lands ~1 GB free = GTT-spill/freeze territory. Role:
|
||||||
|
# slow-but-smart dense-27B answers + vision. Origin (added 2026-08-16): dense 27B, but NOT like the two
|
||||||
|
# retired dense 27Bs: hybrid attention (only 16 of 64 layers full-attn, rest linear/SSM →
|
||||||
|
# cheap KV, Coder-Next-style) AND an embedded MTP head — VERIFIED in the gguf header:
|
||||||
|
# qwen35.nextn_predict_layers = 1, block_count = 65 (64+1), arch "qwen35" = the same
|
||||||
|
# draft-mtp path the working 9B preset uses. Hybrid reasoner (thinking ON by default,
|
||||||
|
# reasoning_effort tunable via chat-template-kwargs if a -low alias is ever wanted),
|
||||||
|
# vision, n_ctx_train = 262144.
|
||||||
|
# Speed math: dense 11.9 GB weights on ~288 GB/s ≈ 14-16 t/s base; MTP should lift to
|
||||||
|
# ~22-30 = roster-competitive IF the draft engages. If it doesn't, this lands in
|
||||||
|
# retired-dense-27B territory (~10-14) → retire again, quality won't pay for the speed.
|
||||||
|
# ⚠ BENCH HISTORY — still no green row, decode/MTP UNMEASURED after 5 attempts:
|
||||||
|
# · 08-16 14:59/15:19/15:29 (3.3-3.5 DIRTY baseline): 16.5-16.7 used / 0.4-0.7 free, guard
|
||||||
|
# skipped gen every time. Implied footprint 13.2 GB — MISLEADING, see below.
|
||||||
|
# · 08-17 10:31: ERROR conn-refused = bench raced llama.service coming up after boot.
|
||||||
|
# · 08-17 10:38 (1.9 near-clean baseline): 15.9 used / 1.3 free — guard floor missed by
|
||||||
|
# 0.2. TRUE footprint = 14.0 GB over baseline; the dirty runs looked 0.8 smaller because
|
||||||
|
# ROCm silently spilled that much to GTT (the exact freeze precursor the guards watch).
|
||||||
|
# · 08-17 10:43 (post-trim, 10.0 leftover start, partial drain): 15.8 / 1.4 — floor missed
|
||||||
|
# by 0.1. Trim verified live via router args; ~2.4 effective baseline poisoned it again.
|
||||||
|
# · 08-17 10:53 (1.9 baseline, NO leftovers — a genuine desktop-idle run): 15.8 / 1.4,
|
||||||
|
# floor missed by 0.1 again. DECISIVE: trimmed footprint 13.9 vs untrimmed 14.0 — both
|
||||||
|
# knobs together saved 0.1 GB. ctx/ubatch do NOT move this model (fixed SSM-state +
|
||||||
|
# big-vocab buffers). Absolute best case ≈ 2.0 free at a pristine 1.3 baseline @16k —
|
||||||
|
# permanently below the 2.5 target. → RETIREMENT RECOMMENDED 2026-08-17; decode/MTP
|
||||||
|
# never measured, academic at these margins. Third dense ~27B to die on this card,
|
||||||
|
# first one killed by fixed buffers rather than bandwidth.
|
||||||
|
# Consequences: full-ctx even on a 1.3 CLEAN night = ~15.3 used / 1.9 free (runs, but
|
||||||
|
# under the 2.5 target). EVENING regime can never fit this quant — that needs ≤ UD-IQ2_M,
|
||||||
|
# a quality gutting. → 08-17: TRIMMED FOR THE GATE BENCH: ctx 24576→16384 (~-0.25) +
|
||||||
|
# ubatch 512→256 (~-0.3-0.5) → predicted ~15.2 used / ~2.0 free @1.9 baseline. Clients
|
||||||
|
# still say 24576 — deliberately NOT re-wired for a temporary trim; do not use from
|
||||||
|
# clients anyway until this passes (a busy-desktop pick is one tab from the GTT freeze).
|
||||||
|
# DECISION GATE (superseded by the 09-10 user decision below): MTP ≥ ~22 t/s keeps it (clean-desktop specialty, restore ctx
|
||||||
|
# 24576 + re-check), anything less → retire + delete (dense 27Bs die on this card).
|
||||||
|
# ↻ REOPENED 2026-09-09 — the file on disk is STALE: unsloth re-quantized the whole repo as
|
||||||
|
# "Dynamic v3" on 2026-08-19, three days AFTER the 08-16 download (~10% better accuracy at
|
||||||
|
# equal size, per unsloth). Verified via the HF tree API at the pre/post commits:
|
||||||
|
# UD-IQ3_XXS 11.91 → 10.93 GB (SAME filename — re-download overwrites in place, no client
|
||||||
|
# or section changes); UD-Q2_K_XL 10.68 → 9.83; UD-IQ2_M DELETED (gone as an option);
|
||||||
|
# UD-IQ2_S 8.37 / UD-IQ2_XXS 7.27 are new 2-bit tiers. Header range-read 09-09: v3
|
||||||
|
# IQ3_XXS and Q2_K_XL both still carry nextn_predict_layers = 1 (MTP head embedded);
|
||||||
|
# unsloth stripped the head from ≤ IQ2_S only and ships MTP/mtp-Qwen3.8-27B-Q4_0.gguf
|
||||||
|
# as a separate model-draft for those (gemma-4 style).
|
||||||
|
# Predicted with v3 IQ3_XXS (footprint 14.0 − 0.98 ≈ 13.0; bench.py GB = decimal):
|
||||||
|
# @1.9 real-idle baseline ≈ 14.8–15.0 used / 2.2–2.4 free · @1.3 pristine ≈ 14.2 / ~2.9.
|
||||||
|
# Clears the 1.5 floor by ~0.8 even at 1.9 → the gen bench can FINALLY run; still ~0.1–0.3
|
||||||
|
# under the 2.5 target on a real idle desktop, clears it outright on a pristine one. Overhead datum: a third-party paired bench measured
|
||||||
|
# draft-mtp at ~+0.75 GB on this model (unsloth docs: "1-2 GB extra headroom") — a good
|
||||||
|
# part of the "fixed" ~2.1 GB is MTP + KV, not only SSM-state/vocab buffers.
|
||||||
|
# NEXT STEP (recommended, NOT yet done): re-download v3 IQ3_XXS on fl (verify 10.93 GB /
|
||||||
|
# 10.18 GiB before restarting), dotsync, restart llama.service, clean-baseline bench.
|
||||||
|
# Then the gate above decides — with one refinement: free 2.0–2.5 at ≥22 t/s = user's call
|
||||||
|
# between "clean-desktop specialty" and stepping down to v3 UD-Q2_K_XL (predicted ~13.7 /
|
||||||
|
# 3.5 @1.9 — needs the section-rename round across the six client files; sequence it
|
||||||
|
# after any in-flight client edits). Decode < 22 → retire regardless of VRAM.
|
||||||
|
# No in-family alternative: the Qwen3.8 lineup is 27B dense, Flash-Next 125B-A6B (smallest
|
||||||
|
# GGUF 72.5 GB, 75 GB RAM floor even with mmap'd n-gram tables — out on 48+16),
|
||||||
|
# 2.4T-A95B and Max. No 3.8 MoE in the 35B-A3B class exists; watch HF.
|
||||||
|
# ✦ GATE BENCH RAN 2026-09-10 02:36 (v3 file, sha verified; 2.1 baseline): 14.9 used / 2.2 free
|
||||||
|
# (footprint 12.8 — VRAM half of the gate PASSED, borderline) but decode 14.8 t/s, prefill 19,
|
||||||
|
# TTFT 11.7 s → speed half FAILED. Server log: MTP head loaded, draft acceptance 0.80
|
||||||
|
# (157/195, mean len 2.6) — so MTP IS engaging; at 2.6 tok/step that is ~175 ms per step ≈
|
||||||
|
# 3–4× a plain forward pass. NOTE the box runs the Arch llama.cpp-vulkan package (RADV,
|
||||||
|
# device Vulkan0) — NOT HIP/ROCm (this header said "ROCm" until 09-10); rocm-smi = monitoring only.
|
||||||
|
# Suspects: the 48 GatedDeltaNet layers on the Vulkan backend (upstream #20354: missing/slow
|
||||||
|
# GDN shader → CPU fallback) and/or recurrent-state checkpoint/restore per speculative step
|
||||||
|
# (~150 MiB for this model; reported net-negative on hybrid 27Bs). The hybrid 35B-A3B does
|
||||||
|
# 37 t/s on the same backend, so it is size-specific, not Vulkan-generic.
|
||||||
|
# A/B NEXT: [Qwen3.8-27B-UD-IQ3_XXS-nomtp] (TEMP alias, used 03:19 then removed) measures
|
||||||
|
# base decode; base ≥ 18 → MTP is the net negative here, run without it (frees ~0.75 GB);
|
||||||
|
# base ≈ 9 → the GDN path is the wall → retire. Also read "graph splits" from the load log.
|
||||||
|
# cache_reuse is inert here ("not supported by multimodal") — true for every mmproj preset.
|
||||||
|
# Re-run 03:07 @0.9 PRISTINE baseline: 15.0 t/s / 17 pp / 13.9 used / 3.3 free (footprint 13.0)
|
||||||
|
# — reproducible; the VRAM half is now fully closed, only the speed half is open.
|
||||||
|
# ✦ A/B 2026-09-10 03:19 (@1.5 baseline, same run): MTP 14.5 t/s / 30 pp / 14.3 used / 2.8 free
|
||||||
|
# vs NO-MTP 10.9 t/s / 34 pp / 12.8 used / 4.4 free. → MTP WORKS (+33%, matches the sudoingX
|
||||||
|
# paired benches) and costs 1.5 GB VRAM; the wall is the BASE: 10.9 t/s = 119 GB/s effective
|
||||||
|
# (41% of the card's 288) — the 48 GatedDeltaNet layers on the Vulkan/RADV backend, exactly
|
||||||
|
# the #20354 datum (Qwen3.5-27B ≈ 11.8 t/s on Strix Halo, either backend). Prefill 30-34 on
|
||||||
|
# a fully-GPU model is the same wall (the hybrid 35B-A3B daily driver's 64 pp is GDN-bound
|
||||||
|
# too). "graphs reused" 97-260 in the log → not a graph-rebuild problem. Nothing in this
|
||||||
|
# preset can move it; a bigger K-quant (faster dequant on Vulkan) does not fit. Perfect-
|
||||||
|
# kernel ceiling on this card ≈ 20 base / ~27 MTP — an upstream Vulkan gated_delta_net
|
||||||
|
# shader improvement COULD flip it; nothing else can.
|
||||||
|
# VERDICT 2026-09-10: gate FAILED on speed (14.5 < 22) with the VRAM half passed (2.8 free
|
||||||
|
# @1.5). Per the gate → retire. Re-probe only after a llama.cpp-vulkan bump whose changelog
|
||||||
|
# touches gated_delta_net / Vulkan GDN: `./bench.py -m Qwen3.8-27B-UD-IQ3_XXS`.
|
||||||
|
# → USER DECISION 2026-09-10: KEEP as clean-desktop specialty (overrides the gate). ctx restored
|
||||||
|
# to 24576 (clients already say 24576), ubatch stays 256 (prefill is GDN-bound, the bigger
|
||||||
|
# buffer buys nothing), MTP stays (+33% for 1.5 GB). ✓ CONFIRMED @24576 2026-09-10 03:51
|
||||||
|
# (1.6 baseline): 15.1 t/s / 31 pp / 14.6 used / 2.5 free — footprint 13.0, exactly as
|
||||||
|
# predicted; free = the 2.5 target at a normal idle, ~2.8 pristine, ~0.8 on a 3.3 evening.
|
||||||
|
# ⚠ Needs a CURRENT llama.cpp build: first "qwen35" file HERE with ssm.*/hybrid-attn keys
|
||||||
|
# (the 9B is regular-attention qwen35). If the load fails with unknown-architecture /
|
||||||
|
# missing-tensor errors, update llama.cpp on fl before touching this preset.
|
||||||
|
# ⬇ DOWNLOAD from unsloth/Qwen3.8-27B-GGUF (NO separate MTP repo — unlike Qwen3.5/3.6, the
|
||||||
|
# head ships in the MAIN repo's ggufs for ≥ Q2_K_XL; ≤ IQ2_S need MTP/mtp-Qwen3.8-27B-Q4_0.gguf):
|
||||||
|
# Qwen3.8-27B-UD-IQ3_XXS.gguf (10.93 GB Dynamic v3 since 2026-08-19 — the 08-16 download
|
||||||
|
# is the 11.91 GB v2; RE-FETCH. UD-IQ4_XS 14.3 GB and
|
||||||
|
# UD-Q3_K_XL 13.15 = dead on arrival, no n-cpu-moe escape)
|
||||||
|
# mmproj-Qwen3.8-27B-F16.gguf ← mmproj-F16.gguf (928 MB — unchanged; rename; watch trailing spaces)
|
||||||
|
model = /home/anon/software/models/Qwen3.8-27B-UD-IQ3_XXS.gguf
|
||||||
|
mmproj = /home/anon/software/models/mmproj-Qwen3.8-27B-F16.gguf
|
||||||
|
spec-type = draft-mtp
|
||||||
|
spec-draft-n-max = 2 # ⚠ if the load log says this file has no MTP head, comment the two
|
||||||
|
# spec- lines out — and expect ~14 t/s, probably not worth keeping.
|
||||||
|
ctx-size = 24576 # RESTORED 2026-09-10 (16384 was the 08-17 gate-bench trim): matches
|
||||||
|
# the clients. KV is cheap (16 full-attn layers × 4 kv-heads × 256
|
||||||
|
# head_dim ≈ 26 KB/token at q8/q4): 16k→24k cost +0.3 → MEASURED
|
||||||
|
# 09-10 @1.6 baseline: 14.6 used / 2.5 free. n_ctx_train 262144.
|
||||||
|
n-gpu-layers = 99 # dense: no n-cpu-moe escape — ctx/quant are the only knobs
|
||||||
|
threads = 6
|
||||||
|
flash-attn = on
|
||||||
|
cache-type-k = q8_0
|
||||||
|
cache-type-v = q4_0 # hybrid arch takes mixed KV like Coder-Next (GLM's same-type
|
||||||
|
# rejection was MLA-specific). If load fails at context creation:
|
||||||
|
# try v = q8_0, then delete both lines (f16 — KV small enough here).
|
||||||
|
batch-size = 2048
|
||||||
|
ubatch-size = 256 # KEPT at 256 (512 before the 08-17 trim): prefill is GDN-bound on the
|
||||||
|
# Vulkan backend (30-34 t/s either way), so the bigger compute buffer
|
||||||
|
# buys nothing measurable and VRAM is the binding constraint here.
|
||||||
|
cache-reuse = 256
|
||||||
|
defrag-thold = 0.1
|
||||||
|
no-mmproj-offload = true # vision encoder on CPU → ~1 GB freed, same as the 26B
|
||||||
|
temp = 1.0 # card: thinking mode 1.0/0.95/20/0 — thinking IS the default mode
|
||||||
|
top-p = 0.95
|
||||||
|
top-k = 20
|
||||||
|
min-p = 0
|
||||||
|
jinja = on
|
||||||
|
sleep-idle-seconds = 120
|
||||||
|
|
||||||
# ─── RETIRED 2026-07-16: [Qwen3.6-27B-Uncensored-HauhauCS-Aggressive-IQ3_M] ──────────────
|
# ─── RETIRED 2026-07-16: [Qwen3.6-27B-Uncensored-HauhauCS-Aggressive-IQ3_M] ──────────────
|
||||||
# Dense: 10 t/s, 2.0 GB free (under the 2.5 target) and unfixable — bandwidth-bound, smaller
|
# Dense: 10 t/s, 2.0 GB free (under the 2.5 target) and unfixable — bandwidth-bound, smaller
|
||||||
# quant would cost the quality that justified it. Removed from opencode/pi/aichat.
|
# quant would cost the quality that justified it. Removed from opencode/pi/aichat.
|
||||||
|
|||||||
@@ -0,0 +1,53 @@
|
|||||||
|
# dunst drop-in — undo HyDE's pink critical notification, and make the progress bar visible.
|
||||||
|
#
|
||||||
|
# Why a drop-in and not the obvious files:
|
||||||
|
# ~/.config/dunst/dunstrc is GENERATED by ~/.local/share/wallbash/scripts/dunst.sh on every
|
||||||
|
# theme change, and says so in its own header.
|
||||||
|
# ~/.config/dunst/dunst.conf is HyDE's shipped source for that generator — but dunst.toml
|
||||||
|
# declares `action = "sync"` on the whole `dunst` directory, so HyDE
|
||||||
|
# overwrites it on every update.
|
||||||
|
# dunst >= 1.10 reads dunstrc.d/*.conf as drop-ins that override the base config (lexically last
|
||||||
|
# wins), and HyDE's sync copies its files in without deleting extras — so this file survives both
|
||||||
|
# a theme change and a HyDE update. Apply with `dunstctl reload`.
|
||||||
|
#
|
||||||
|
# [urgency_critical] is the pink: HyDE's generator injects background #f5e0dc (Catppuccin
|
||||||
|
# rosewater) with a #f38ba8 frame — a pale pink slab, and with `timeout = 0` it never expires, so
|
||||||
|
# one error notification sits on screen until dismissed. Note this block is NOT wallbash-driven
|
||||||
|
# (dunst.conf ships it commented out and the generator hardcodes it), so overriding it costs no
|
||||||
|
# theme coupling. Inverted here: dark base like every other surface, with the pink kept as text
|
||||||
|
# and frame so "critical" still reads as critical at a glance.
|
||||||
|
[urgency_critical]
|
||||||
|
background = "#1e1e2eF2"
|
||||||
|
foreground = "#f5e0dc"
|
||||||
|
frame_color = "#f38ba8"
|
||||||
|
|
||||||
|
# urgency_low/normal are the everyday notifications — the volume/mute popup is `normal`, since
|
||||||
|
# volumecontrol.sh sends it with no -u. wallbash generates those as a primary colour at alpha `80`
|
||||||
|
# (#583A6B80 plum for normal, #657AA380 for low) and [global] adds `transparency = 10` on top, so
|
||||||
|
# roughly half the wallpaper shows through: on a pink-toned palette the popup reads as pink no
|
||||||
|
# matter what the base hue is.
|
||||||
|
#
|
||||||
|
# Overriding them here **decouples notifications from wallbash** — they no longer follow the
|
||||||
|
# wallpaper the way the cava bar, waybar and kitty still do. That is the deliberate trade for a
|
||||||
|
# readable popup. To hand them back to wallbash, delete these two blocks and restart dunst; the
|
||||||
|
# generated dunstrc underneath is untouched.
|
||||||
|
#
|
||||||
|
# The frames also needed fixing regardless of colour: the generator emits frame_color at alpha
|
||||||
|
# `03` (~1% opacity) and never sets `highlight`, and dunst falls back to frame_color for the
|
||||||
|
# progress bar — so the volume bar was drawing invisibly.
|
||||||
|
#
|
||||||
|
# Frame and highlight are deliberately NOT the mauve from hypr's active window border: at these
|
||||||
|
# sizes #ca9ee6 renders as a pink outline plus a pink bar, which is the thing that looked wrong in
|
||||||
|
# the first place. A neutral surface frame with a blue bar keeps the popup quiet.
|
||||||
|
[urgency_low]
|
||||||
|
background = "#1e1e2eF2"
|
||||||
|
foreground = "#cdd6f4"
|
||||||
|
frame_color = "#6c7086"
|
||||||
|
|
||||||
|
[urgency_normal]
|
||||||
|
background = "#1e1e2eF2"
|
||||||
|
foreground = "#cdd6f4"
|
||||||
|
frame_color = "#45475a"
|
||||||
|
|
||||||
|
[global]
|
||||||
|
highlight = "#89b4fa"
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
## gui package — pin which config Hyprland starts with.
|
||||||
|
##
|
||||||
|
## HyDE 26.x configures Hyprland in Lua and points HYPRLAND_CONFIG at
|
||||||
|
## ~/.local/share/hypr/hyde.lua. Once that is set, Hyprland never reads
|
||||||
|
## ~/.config/hypr/hyprland.conf, so the entire dots hypr layer (theme, keybinds,
|
||||||
|
## window rules, monitors, userprefs) is bypassed and the session comes up as
|
||||||
|
## stock HyDE — silently, with `hyprctl configerrors` empty.
|
||||||
|
##
|
||||||
|
## Why it is set from *fish* of all places: the update dropped a real
|
||||||
|
## ~/.config/fish/conf.d/hyde.fish (untracked, HyDE-owned) which exports it, and
|
||||||
|
## fish sources every conf.d/*.fish at startup. SDDM launches the session through
|
||||||
|
## the login shell (/usr/bin/start-hyprland, the `hyprland.desktop` entry — not
|
||||||
|
## `hyprland-uwsm.desktop`), so the compositor inherits whatever fish exported.
|
||||||
|
## HyDE's snippet only assigns `if test -z "$HYPRLAND_CONFIG"`, and conf.d files
|
||||||
|
## load in alphabetical order, so this file's `00-` prefix means ours is already
|
||||||
|
## set by the time hyde.fish looks — do not rename it above `hyde.fish`.
|
||||||
|
##
|
||||||
|
## The uwsm twin of this lives in gui/.config/uwsm/env-hyprland.d/10-dots.sh and
|
||||||
|
## covers the `hyprland-uwsm.desktop` session entry, which sources uwsm env files
|
||||||
|
## instead of the shell. Both are needed; neither is sufficient alone.
|
||||||
|
##
|
||||||
|
## STOPGAP: this pins ~/.local/share/hyde/hyprland.conf, which current HyDE no
|
||||||
|
## longer ships (ours is a leftover of the pre-update install). The supported
|
||||||
|
## path is porting the hypr layer to ~/.config/hypr/hyprland.lua. See
|
||||||
|
## HYDE-UPDATE.md. Takes effect at session start — relogin, not `hyprctl reload`.
|
||||||
|
set -gx HYPRLAND_CONFIG "$HOME/.config/hypr/hyprland.conf"
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
## gui package — undo the starship prompt that HyDE's fish snippet installs.
|
||||||
|
##
|
||||||
|
## The HyDE 26.x update dropped an untracked ~/.config/fish/conf.d/hyde.fish that
|
||||||
|
## runs `starship init fish | source`. That eagerly defines fish_prompt AND
|
||||||
|
## fish_right_prompt, which shadows our own functions/fish_prompt.fish: fish only
|
||||||
|
## autoloads a function that is not already defined, so ours never loaded and
|
||||||
|
## every new shell came up with starship's prompt.
|
||||||
|
##
|
||||||
|
## conf.d is sourced alphabetically, so this file must sort AFTER hyde.fish to
|
||||||
|
## undo it — hence zz-.
|
||||||
|
##
|
||||||
|
## Note it *sources* our prompts rather than erasing starship's: `functions --erase`
|
||||||
|
## on an autoloadable name also suppresses the autoload, which leaves the shell
|
||||||
|
## with no fish_prompt at all ("Unknown command: fish_prompt"). Defining ours over
|
||||||
|
## the top is what actually wins — for fish_right_prompt too, since common ships
|
||||||
|
## functions/fish_right_prompt.fish (the git-status right prompt).
|
||||||
|
##
|
||||||
|
## Nothing else from hyde.fish is undone here: its aliases lose to config.fish,
|
||||||
|
## which fish loads after conf.d, and its `df` wrapper is a function we do not
|
||||||
|
## otherwise define. Delete this file if you ever decide you want starship.
|
||||||
|
for f in fish_prompt fish_right_prompt
|
||||||
|
if test -r $__fish_config_dir/functions/$f.fish
|
||||||
|
source $__fish_config_dir/functions/$f.fish
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -1 +0,0 @@
|
|||||||
source = ./HyDE.conf
|
|
||||||
@@ -27,9 +27,18 @@
|
|||||||
# █▀█ █▀▀ █▀▀ ▄█
|
# █▀█ █▀▀ █▀▀ ▄█
|
||||||
|
|
||||||
# $QUICKAPPS = # used for quick app launcher
|
# $QUICKAPPS = # used for quick app launcher
|
||||||
# $BROWSER = firefox # default browser, if commented out , will use the default browser
|
# Leaving this to HyDE means Super+B runs its `$default.BROWSER`, which is
|
||||||
|
# `hyde-launch.sh --fall firefox web-browser` — and the 26.x update deprecated that script, so
|
||||||
|
# every press fired a "hyde-launch.sh is deprecated, please use hyde-shell open instead"
|
||||||
|
# notification. Naming the browser directly skips the wrapper entirely. This is the primary
|
||||||
|
# browser only; Super+Shift+B (librewolf) and Super+Ctrl+B (firefox) are set in keybindings.conf.
|
||||||
|
# `hyde-shell open web-browser` is the modern HyDE equivalent if the xdg default should decide.
|
||||||
|
$BROWSER = zen-browser # matches the xdg default (zen.desktop)
|
||||||
# $EDITOR = code # default editor, if commented out , will use the default editor
|
# $EDITOR = code # default editor, if commented out , will use the default editor
|
||||||
# $EXPLORER= dolphin # default file manager, if commented out , will use the default file manager
|
# Same deprecation as $BROWSER above: HyDE's default is `hyde-launch.sh --fall dolphin
|
||||||
|
# file-manager`, and Super+E in keybindings.conf uses it. $EDITOR is deliberately left to HyDE —
|
||||||
|
# no active bind reads it (Super+C runs `$TERMINAL nvim`), so there is nothing to fix there.
|
||||||
|
$EXPLORER = dolphin # matches the xdg default (org.kde.dolphin.desktop)
|
||||||
# $TERMINAL = kitty # default terminal, if commented out , will use the org.gnome.desktop.default-applications.terminal
|
# $TERMINAL = kitty # default terminal, if commented out , will use the org.gnome.desktop.default-applications.terminal
|
||||||
# $LOCKSCREEN=hyprlock # default lockscreen, you can use any lockscreen you want, eg swaylock
|
# $LOCKSCREEN=hyprlock # default lockscreen, you can use any lockscreen you want, eg swaylock
|
||||||
# $IDLE=hypridle # default idle manager, you can use any idle manager you want,eg swayidle
|
# $IDLE=hypridle # default idle manager, you can use any idle manager you want,eg swayidle
|
||||||
@@ -43,14 +52,21 @@
|
|||||||
# $start.XDG_PORTAL_RESET=$scrPath/resetxdgportal.sh
|
# $start.XDG_PORTAL_RESET=$scrPath/resetxdgportal.sh
|
||||||
# $start.DBUS_SHARE_PICKER=dbus-update-activation-environment --systemd --all # for XDPH
|
# $start.DBUS_SHARE_PICKER=dbus-update-activation-environment --systemd --all # for XDPH
|
||||||
# $start.SYSTEMD_SHARE_PICKER=systemctl --user import-environment QT_QPA_PLATFORMTHEME WAYLAND_DISPLAY XDG_CURRENT_DESKTOP # for XDPH
|
# $start.SYSTEMD_SHARE_PICKER=systemctl --user import-environment QT_QPA_PLATFORMTHEME WAYLAND_DISPLAY XDG_CURRENT_DESKTOP # for XDPH
|
||||||
# $start.BAR=waybar
|
# Empty = unset, so HyDE's default `exec-once = $start.BAR` (a bare `waybar`, using HyDE's
|
||||||
|
# generated config.jsonc/style.css) does not launch a second bar. The bar we actually want is
|
||||||
|
# launched from userprefs.conf with the custom layout/style.
|
||||||
|
$start.BAR=
|
||||||
# $start.NOTIFICATIONS=swaync # dunst
|
# $start.NOTIFICATIONS=swaync # dunst
|
||||||
# $start.APPTRAY_BLUETOOTH=blueman-applet
|
# $start.APPTRAY_BLUETOOTH=blueman-applet
|
||||||
# $start.WALLPAPER=$scrPath/swwwallpaper.sh
|
# $start.WALLPAPER=$scrPath/wallpaper.sh --global # 26.x: backend-agnostic (awww); swwwallpaper.sh is gone
|
||||||
# $start.TEXT_CLIPBOARD=wl-paste --type text --watch cliphist store
|
# $start.TEXT_CLIPBOARD=wl-paste --type text --watch cliphist store
|
||||||
# $start.IMAGE_CLIPBOARD=wl-paste --type image --watch cliphist store
|
# $start.IMAGE_CLIPBOARD=wl-paste --type image --watch cliphist store
|
||||||
# $start.BATTERY_NOTIFY=$scrPath/batterynotify.sh
|
# $start.BATTERY_NOTIFY=$scrPath/batterynotify.sh
|
||||||
# $start.NETWORK_MANAGER=nm-applet --indicator
|
# Kept explicitly at the default: nm-applet's tray icon is the one place with a quick
|
||||||
|
# connect/disconnect MENU (wifi list, VPN) — the bar's `network` module only shows state
|
||||||
|
# and bandwidth. Tela renders it as a blue circle (its scalable/devices icon); that's the
|
||||||
|
# theme working, not a bug. Was briefly unset 2026-08-14 — wrong call, the menu was wanted.
|
||||||
|
$start.NETWORK_MANAGER=nm-applet --indicator
|
||||||
# $start.REMOVABLE_MEDIA=udiskie --no-automount --smart-tray
|
# $start.REMOVABLE_MEDIA=udiskie --no-automount --smart-tray
|
||||||
# $start.AUTH_DIALOGUE=$scrPath/polkitkdeauth.sh
|
# $start.AUTH_DIALOGUE=$scrPath/polkitkdeauth.sh
|
||||||
# $start.IDLE_DAEMON=$IDLE
|
# $start.IDLE_DAEMON=$IDLE
|
||||||
@@ -104,7 +120,11 @@
|
|||||||
|
|
||||||
|
|
||||||
#$GTK_THEME=Wallbash-Gtk
|
#$GTK_THEME=Wallbash-Gtk
|
||||||
#$ICON_THEME=Tela-circle-dracula
|
# dots-icons = repo-tracked overlay theme (gui/.local/share/icons/dots-icons) that inherits
|
||||||
|
# Tela-circle-dracula and only swaps the tray/status icons for Tela's monochrome panel set at
|
||||||
|
# every size — without it, waybar on a fractionally-scaled monitor requests 2x sizes and gets
|
||||||
|
# the colored-circle variants (the blue nm-applet blob). Everything else still comes from Tela.
|
||||||
|
$ICON_THEME=dots-icons
|
||||||
#$COLOR_SCHEME=prefer-dark
|
#$COLOR_SCHEME=prefer-dark
|
||||||
|
|
||||||
# // █▀▀ █░█ █▀█ █▀ █▀█ █▀█
|
# // █▀▀ █░█ █▀█ █▀ █▀█ █▀█
|
||||||
|
|||||||
@@ -1,132 +0,0 @@
|
|||||||
# ░▒▒▒░░░░░▓▓ ___________
|
|
||||||
# ░░▒▒▒░░░░░▓▓ //___________/
|
|
||||||
# ░░▒▒▒░░░░░▓▓ _ _ _ _ _____
|
|
||||||
# ░░▒▒░░░░░▓▓▓▓▓▓ | | | | | | | __/
|
|
||||||
# ░▒▒░░░░▓▓ ▓▓ | |_| | |_/ /| |___
|
|
||||||
# ░▒▒░░▓▓ ▓▓ \__ |____/ |____/
|
|
||||||
# ░▒▓▓ ▓▓ //____/
|
|
||||||
|
|
||||||
$fontFamily = JetBrainsMono Nerd Font # We already have this font installed
|
|
||||||
|
|
||||||
# Resolving custom fonts
|
|
||||||
# Provide the font name and the download link separated by a pipe |
|
|
||||||
# Run font.sh resolve $LAYOUT_PATH to install the font
|
|
||||||
$resolve.font=Anurati|https://font.download/dl/font/anurati.zip
|
|
||||||
$resolve.font=Inter|https://github.com/rsms/inter/releases/download/v4.1/Inter-4.1.zip
|
|
||||||
|
|
||||||
background {
|
|
||||||
monitor =
|
|
||||||
color = $wallbash_pry1_rgba
|
|
||||||
path = $BACKGROUND_PATH
|
|
||||||
blur_size = 4
|
|
||||||
blur_passes = 3 # 0 disables blurring
|
|
||||||
noise = 0.0117
|
|
||||||
contrast = 1.3000 # Vibrant!!!
|
|
||||||
brightness = 0.8000
|
|
||||||
vibrancy = 0.2100
|
|
||||||
vibrancy_darkness = 0.0
|
|
||||||
}
|
|
||||||
|
|
||||||
# DAY
|
|
||||||
label {
|
|
||||||
monitor =
|
|
||||||
text = cmd[update:1000] echo "$(date +"%A" | sed 's/./& /g' | tr '[:lower:]' '[:upper:]')" # Add a thin space between each character
|
|
||||||
color = $wallbash_1xa9_rgba
|
|
||||||
font_size = 110 # Wednesday is too long
|
|
||||||
font_family = Anurati
|
|
||||||
position = 0, 100
|
|
||||||
halign = center
|
|
||||||
valign = center
|
|
||||||
}
|
|
||||||
|
|
||||||
# DATE
|
|
||||||
label {
|
|
||||||
monitor =
|
|
||||||
text = cmd[update:1000] echo "$(date +"%B %d")"
|
|
||||||
color = $wallbash_2xa9_rgba
|
|
||||||
font_size = 35
|
|
||||||
font_family = $font_family Thin
|
|
||||||
position = 0, -20
|
|
||||||
halign = center
|
|
||||||
valign = center
|
|
||||||
}
|
|
||||||
|
|
||||||
# TIME
|
|
||||||
label {
|
|
||||||
monitor =
|
|
||||||
text = cmd[update:1000] echo "$(date +"%-I:%M %p")"
|
|
||||||
#text = $TIME
|
|
||||||
color = $wallbash_txt1_rgba
|
|
||||||
font_size = 20 #!
|
|
||||||
font_family = $font_family
|
|
||||||
position = 0, 150
|
|
||||||
halign = center
|
|
||||||
valign = bottom
|
|
||||||
}
|
|
||||||
# INPUT FIELD
|
|
||||||
input-field {
|
|
||||||
monitor =
|
|
||||||
size = 200, 50 #!
|
|
||||||
outline_thickness = 3
|
|
||||||
dots_size = 0.33 # Scale of input-field height, 0.2 - 0.8
|
|
||||||
dots_spacing = 0.15 # Scale of dots' absolute size, 0.0 - 1.0
|
|
||||||
dots_center = true
|
|
||||||
dots_rounding = -1 # -1 default circle, -2 follow input-field rounding
|
|
||||||
outer_color = $wallbash_pry4_rgba
|
|
||||||
inner_color = $wallbash_pry2_rgba
|
|
||||||
font_color = $wallbash_3xa9_rgba
|
|
||||||
fade_on_empty = true
|
|
||||||
fade_timeout = 1000 # Milliseconds before fade_on_empty is triggered.
|
|
||||||
placeholder_text = <i>Input Password...</i> # Text rendered in the input box when it's empty.
|
|
||||||
hide_input = false
|
|
||||||
rounding = -1 # -1 means complete rounding (circle/oval)
|
|
||||||
check_color = $wallbash_pry4_rgba
|
|
||||||
fail_color = rgba(FF0000FF) # if authentication failed, changes outer_color and fail message color
|
|
||||||
fail_text = <i>$FAIL <b>($ATTEMPTS)</b></i> # can be set to empty
|
|
||||||
fail_transition = 300 # transition time in ms between normal outer_color and fail_color
|
|
||||||
capslock_color = -1
|
|
||||||
numlock_color = -1
|
|
||||||
bothlock_color = -1 # when both locks are active. -1 means don't change outer color (same for above)
|
|
||||||
invert_numlock = false # change color if numlock is off
|
|
||||||
swap_font_color = true # see below
|
|
||||||
position = 0, 80
|
|
||||||
halign = center
|
|
||||||
valign = bottom
|
|
||||||
}
|
|
||||||
|
|
||||||
#User tag
|
|
||||||
label {
|
|
||||||
monitor =
|
|
||||||
text = $USER
|
|
||||||
color = $wallbash_4xa9_rgba
|
|
||||||
font_size = 20
|
|
||||||
font_family = Inter Display Medium
|
|
||||||
position = 0, 30
|
|
||||||
halign = center
|
|
||||||
valign = bottom
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
# Battery Status if present
|
|
||||||
label {
|
|
||||||
monitor =
|
|
||||||
text = cmd[update:5000] $BATTERY_ICON
|
|
||||||
color = $wallbash_4xa9_rgba
|
|
||||||
font_size = 20
|
|
||||||
font_family = JetBrainsMono Nerd Font
|
|
||||||
position = -1%, 1%
|
|
||||||
halign = right
|
|
||||||
valign = bottom
|
|
||||||
}
|
|
||||||
|
|
||||||
# Current Keyboard Layout
|
|
||||||
label {
|
|
||||||
monitor =
|
|
||||||
text = cmd[update:1000] $KEYBOARD_LAYOUT
|
|
||||||
color = $wallbash_4xa9_rgba
|
|
||||||
font_size = 20
|
|
||||||
font_family = Inter Display Medium
|
|
||||||
position = -2%, 1%
|
|
||||||
halign = right
|
|
||||||
valign = bottom
|
|
||||||
}
|
|
||||||
@@ -1,158 +0,0 @@
|
|||||||
# Hyprclouds from Arfan on Clouds
|
|
||||||
# By: Arfan on Clouds https://github.com/arfan-on-clouds/hyprclouds
|
|
||||||
# Modified by: The HyDE Project
|
|
||||||
|
|
||||||
$resolve.font=SF Pro Display|https://font.download/dl/font/sf-pro-display.zip
|
|
||||||
$resolve.font=AlfaSlabOne|https://font.download/dl/font/alfa-slab-one.zip
|
|
||||||
|
|
||||||
# BACKGROUND
|
|
||||||
background {
|
|
||||||
monitor =
|
|
||||||
color = $wallbash_pry1_rgba
|
|
||||||
path = $BACKGROUND_PATH
|
|
||||||
blur_size = 4
|
|
||||||
blur_passes = 3 # 0 disables blurring
|
|
||||||
noise = 0.0117
|
|
||||||
contrast = 1.3000 # Vibrant!!!
|
|
||||||
brightness = 0.8000
|
|
||||||
vibrancy = 0.2100
|
|
||||||
vibrancy_darkness = 0.0
|
|
||||||
}
|
|
||||||
|
|
||||||
# INPUT FIELD
|
|
||||||
input-field {
|
|
||||||
monitor =
|
|
||||||
size = 190, 50
|
|
||||||
outline_thickness = 2
|
|
||||||
dots_size = 0.2 # Scale of input-field height, 0.2 - 0.8
|
|
||||||
dots_spacing = 0.2 # Scale of dots' absolute size, 0.0 - 1.0
|
|
||||||
dots_center = true
|
|
||||||
fade_on_empty = true
|
|
||||||
font_family = SF Pro Display Bold
|
|
||||||
placeholder_text = <i><span foreground="##ffffff99"></span></i>
|
|
||||||
hide_input = false
|
|
||||||
position = 0, -170
|
|
||||||
halign = center
|
|
||||||
valign = center
|
|
||||||
outer_color = $wallbash_pry4_rgba
|
|
||||||
inner_color = $wallbash_pry2_rgba
|
|
||||||
font_color = $wallbash_3xa9_rgba
|
|
||||||
check_color = $wallbash_pry4_rgba
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
# Hour-Time
|
|
||||||
label {
|
|
||||||
monitor =
|
|
||||||
text = cmd[update:1000] echo -e "$(date +"%I")"
|
|
||||||
color = $wallbash_1xa8_rgba
|
|
||||||
shadow_passes = 3
|
|
||||||
shadow_size = 2
|
|
||||||
font_size = 100
|
|
||||||
font_family = AlfaSlabOne
|
|
||||||
position = 0, 100
|
|
||||||
halign = center
|
|
||||||
valign = center
|
|
||||||
}
|
|
||||||
|
|
||||||
# Minute-Time
|
|
||||||
label {
|
|
||||||
monitor =
|
|
||||||
text = cmd[update:1000] echo -e "$(date +"%M")"
|
|
||||||
color = $wallbash_3xa9_rgba
|
|
||||||
font_size = 100
|
|
||||||
font_family = AlfaSlabOne
|
|
||||||
shadow_passes = 3
|
|
||||||
shadow_size = 2
|
|
||||||
position = 0, -20
|
|
||||||
halign = center
|
|
||||||
valign = center
|
|
||||||
}
|
|
||||||
|
|
||||||
# Day-Date-Month
|
|
||||||
label {
|
|
||||||
monitor =
|
|
||||||
text = cmd[update:1000] echo -e "$(date +"%d %b %A")"
|
|
||||||
color = $wallbash_3xa9_rgba
|
|
||||||
shadow_passes = 3
|
|
||||||
shadow_size = 1
|
|
||||||
font_size = 12
|
|
||||||
font_family = JetBrains Mono Nerd Font Mono ExtraBold
|
|
||||||
position = 1%, -1%
|
|
||||||
halign = left
|
|
||||||
valign = top
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# CURRENT SONG
|
|
||||||
label {
|
|
||||||
monitor =
|
|
||||||
text = cmd[update:1000] $MPRIS_TEXT # Outputs the song title when mpris is available, otherwise, it will output the splash command.
|
|
||||||
color = $wallbash_3xa9_rgba
|
|
||||||
shadow_passes = 3
|
|
||||||
shadow_size = 1
|
|
||||||
font_size = 14
|
|
||||||
font_family = JetBrains Mono Nerd, SF Pro Display Bold
|
|
||||||
position = 0, 20
|
|
||||||
halign = center
|
|
||||||
valign = bottom
|
|
||||||
}
|
|
||||||
image {
|
|
||||||
monitor =
|
|
||||||
path = $MPRIS_IMAGE
|
|
||||||
size = 80 # lesser side if not 1:1 ratio
|
|
||||||
rounding = -1 # negative values mean circle
|
|
||||||
border_size = 0
|
|
||||||
shadow_passes = 3
|
|
||||||
shadow_size = 3
|
|
||||||
border_color = rgb(221, 221, 221)
|
|
||||||
rotate = 0 # degrees, counter-clockwise
|
|
||||||
reload_time = 0 # seconds between reloading, 0 to reload with SIGUSR2
|
|
||||||
# reload_cmd = # command to get new path. if empty, old path will be used. don't run "follow" commands like tail -F
|
|
||||||
position = 0, 10%
|
|
||||||
halign = center
|
|
||||||
valign = bottom
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Battery Status if present
|
|
||||||
label {
|
|
||||||
monitor =
|
|
||||||
text = cmd[update:5000] $BATTERY_ICON
|
|
||||||
color = $wallbash_4xa9_rgba
|
|
||||||
font_size = 20
|
|
||||||
font_family = JetBrainsMono Nerd Font
|
|
||||||
position = -1%, 1%
|
|
||||||
halign = right
|
|
||||||
valign = bottom
|
|
||||||
}
|
|
||||||
|
|
||||||
# Current Keyboard Layout
|
|
||||||
label {
|
|
||||||
monitor =
|
|
||||||
text = cmd[update:1000] $KEYBOARD_LAYOUT
|
|
||||||
color = $wallbash_4xa9_rgba
|
|
||||||
font_size = 20
|
|
||||||
font_family = JetBrains Mono Nerd, SF Pro Display Bold
|
|
||||||
position = -2%, 1%
|
|
||||||
halign = right
|
|
||||||
valign = bottom
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
# Weather
|
|
||||||
#! Put the weather command last to lessen the load time of other modules
|
|
||||||
label {
|
|
||||||
monitor =
|
|
||||||
text = cmd[update:18000000] $WEATHER_CMD
|
|
||||||
color = $wallbash_3xa9_rgba
|
|
||||||
font_size = 16
|
|
||||||
shadow_passes = 3
|
|
||||||
shadow_size = 1
|
|
||||||
font_family = JetBrains Mono Nerd, SF Pro Display Bold
|
|
||||||
position = -1%, -1%
|
|
||||||
halign = right
|
|
||||||
valign = top
|
|
||||||
}
|
|
||||||
@@ -1,112 +0,0 @@
|
|||||||
|
|
||||||
# ░▒▒▒░░░░░▓▓ ___________
|
|
||||||
# ░░▒▒▒░░░░░▓▓ //___________/
|
|
||||||
# ░░▒▒▒░░░░░▓▓ _ _ _ _ _____
|
|
||||||
# ░░▒▒░░░░░▓▓▓▓▓▓ | | | | | | | __/
|
|
||||||
# ░▒▒░░░░▓▓ ▓▓ | |_| | |_/ /| |___
|
|
||||||
# ░▒▒░░▓▓ ▓▓ \__ |____/ |____/
|
|
||||||
# ░▒▓▓ ▓▓ //____/
|
|
||||||
|
|
||||||
$fontFamily = IBM Plex Sans
|
|
||||||
$resolve.font=IBM Plex Sans|https://github.com/IBM/plex/releases/download/%40ibm%2Fplex-sans%401.1.0/ibm-plex-sans.zip
|
|
||||||
|
|
||||||
# GENERAL
|
|
||||||
background {
|
|
||||||
monitor =
|
|
||||||
path = $BACKGROUND_PATH
|
|
||||||
blur_size = 5
|
|
||||||
blur_passes = 0
|
|
||||||
noise = 0.0117
|
|
||||||
contrast = 1.3000 # Vibrant!
|
|
||||||
brightness = 0.8000
|
|
||||||
vibrancy = 0.2100
|
|
||||||
vibrancy_darkness = 0.0
|
|
||||||
}
|
|
||||||
|
|
||||||
# Current time
|
|
||||||
label {
|
|
||||||
monitor =
|
|
||||||
text = cmd[update:1000] echo "<b><big> $(date +"%H") </big></b>"
|
|
||||||
color = $wallbash_2xa7_rgba
|
|
||||||
font_size = 180
|
|
||||||
font_family = $fontFamily Medium 10
|
|
||||||
position = 0, 80
|
|
||||||
halign = center
|
|
||||||
valign = center
|
|
||||||
}
|
|
||||||
label {
|
|
||||||
monitor =
|
|
||||||
text = cmd[update:1000] echo "<b><big> $(date +"%M") </big></b>"
|
|
||||||
color = $wallbash_2xa9_rgba
|
|
||||||
font_size = 180
|
|
||||||
font_family = $fontFamily Medium 10
|
|
||||||
position = 0, -120
|
|
||||||
halign = center
|
|
||||||
valign = center
|
|
||||||
}
|
|
||||||
label {
|
|
||||||
monitor =
|
|
||||||
text = cmd[update:1000] echo "<b><big> $(date +"%d %b") </big></b>"
|
|
||||||
color = $wallbash_2xa8_rgba
|
|
||||||
font_size = 20
|
|
||||||
font_family = $fontFamily Medium 10
|
|
||||||
position = 0, -230
|
|
||||||
halign = center
|
|
||||||
valign = center
|
|
||||||
}
|
|
||||||
label {
|
|
||||||
monitor =
|
|
||||||
text = cmd[update:1000] echo "<b><big> $(date +"%A") </big></b>"
|
|
||||||
color = $wallbash_2xa8_rgba
|
|
||||||
|
|
||||||
font_size = 20
|
|
||||||
font_family = $fontFamily Medium 10
|
|
||||||
position = 0, -250
|
|
||||||
halign = center
|
|
||||||
valign = center
|
|
||||||
}
|
|
||||||
|
|
||||||
#INPUT FIELD
|
|
||||||
input-field {
|
|
||||||
monitor =
|
|
||||||
# size = 15%, 5% # hyprlock-git
|
|
||||||
size = 200, 50
|
|
||||||
outline_thickness = 3
|
|
||||||
dots_size = 0.2 # Scale of input-field height, 0.2 - 0.8
|
|
||||||
dots_spacing = 1.00 # Scale of dots' absolute size, 0.0 - 1.0
|
|
||||||
dots_center = true
|
|
||||||
outer_color = $wallbash_pry2_rgba
|
|
||||||
inner_color = $wallbash_pry3_rgba
|
|
||||||
font_color = $color7
|
|
||||||
fade_on_empty = true
|
|
||||||
placeholder_text = <i>Password...</i> # Text rendered in the input box when it's empty.
|
|
||||||
hide_input = false
|
|
||||||
position = 0, 60
|
|
||||||
halign = center
|
|
||||||
valign = bottom
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
# Battery Status if present
|
|
||||||
label {
|
|
||||||
monitor =
|
|
||||||
text = cmd[update:5000] $BATTERY_ICON
|
|
||||||
color = $wallbash_4xa9_rgba
|
|
||||||
font_size = 20
|
|
||||||
font_family = JetBrainsMono Nerd Font
|
|
||||||
position = -1%, 1%
|
|
||||||
halign = right
|
|
||||||
valign = bottom
|
|
||||||
}
|
|
||||||
|
|
||||||
# Current Keyboard Layout
|
|
||||||
label {
|
|
||||||
monitor =
|
|
||||||
text = cmd[update:1000] $KEYBOARD_LAYOUT
|
|
||||||
color = $wallbash_4xa9_rgba
|
|
||||||
font_size = 20
|
|
||||||
font_family = $fontFamily
|
|
||||||
position = -2%, 1%
|
|
||||||
halign = right
|
|
||||||
valign = bottom
|
|
||||||
}
|
|
||||||
@@ -1,161 +0,0 @@
|
|||||||
# Hyprlock style-4
|
|
||||||
# By: Vivek Rajan https://github.com/MrVivekRajan/Hyprlock-Styles/tree/main/Style-4
|
|
||||||
# Modified by: The HyDE Project
|
|
||||||
|
|
||||||
$resolve.font=SF Pro Display|https://font.download/dl/font/sf-pro-display.zip
|
|
||||||
|
|
||||||
# BACKGROUND
|
|
||||||
background {
|
|
||||||
monitor =
|
|
||||||
path = $BACKGROUND_PATH
|
|
||||||
blur_passes = 0
|
|
||||||
contrast = 0.8916
|
|
||||||
brightness = 0.8916
|
|
||||||
vibrancy = 0.8916
|
|
||||||
vibrancy_darkness = 0.0
|
|
||||||
}
|
|
||||||
|
|
||||||
# GENERAL
|
|
||||||
general {
|
|
||||||
no_fade_in = false
|
|
||||||
grace = 0
|
|
||||||
disable_loading_bar = false
|
|
||||||
}
|
|
||||||
|
|
||||||
# Profile-Photo
|
|
||||||
image {
|
|
||||||
monitor =
|
|
||||||
path = $PROFILE_IMAGE
|
|
||||||
border_size = 2
|
|
||||||
border_color = $wallbash_pry4_rgba
|
|
||||||
size = 100
|
|
||||||
rounding = -1
|
|
||||||
rotate = 0
|
|
||||||
reload_time = -1
|
|
||||||
reload_cmd =
|
|
||||||
position = 25, 200
|
|
||||||
halign = center
|
|
||||||
valign = center
|
|
||||||
}
|
|
||||||
|
|
||||||
# NAME
|
|
||||||
label {
|
|
||||||
monitor =
|
|
||||||
text = cmd[update:60000] $GREET_TEXT
|
|
||||||
color = $wallbash_txt1_rgba
|
|
||||||
outline_thickness = 0
|
|
||||||
dots_size = 0.2 # Scale of input-field height, 0.2 - 0.8
|
|
||||||
dots_spacing = 0.2 # Scale of dots' absolute size, 0.0 - 1.0
|
|
||||||
dots_center = true
|
|
||||||
font_size = 20
|
|
||||||
font_family = SF Pro Display Bold
|
|
||||||
position = 25, 110
|
|
||||||
halign = center
|
|
||||||
valign = center
|
|
||||||
}
|
|
||||||
|
|
||||||
# Time
|
|
||||||
label {
|
|
||||||
monitor =
|
|
||||||
text = cmd[update:1000] echo "<span>$(date +"%I:%M")</span>"
|
|
||||||
color = $wallbash_txt1_rgba
|
|
||||||
font_size = 60
|
|
||||||
font_family = SF Pro Display Bold
|
|
||||||
position = 30, -8
|
|
||||||
halign = center
|
|
||||||
valign = center
|
|
||||||
}
|
|
||||||
|
|
||||||
# Day-Month-Date
|
|
||||||
label {
|
|
||||||
monitor =
|
|
||||||
text = cmd[update:1000] echo -e "$(date +"%A, %B %d")"
|
|
||||||
color = $wallbash_txt1_rgba
|
|
||||||
font_size = 19
|
|
||||||
font_family = SF Pro Display Bold
|
|
||||||
position = 35, -60
|
|
||||||
halign = center
|
|
||||||
valign = center
|
|
||||||
}
|
|
||||||
|
|
||||||
# USER-BOX
|
|
||||||
shape {
|
|
||||||
monitor =
|
|
||||||
size = 320, 55
|
|
||||||
color = rgba(255, 255, 255, 0.1)
|
|
||||||
rounding = -1
|
|
||||||
border_size = 0
|
|
||||||
border_color = $wallbash_txt3_rgba
|
|
||||||
rotate = 0
|
|
||||||
xray = false # if true, make a "hole" in the background (rectangle of specified size, no rotation)
|
|
||||||
|
|
||||||
position = 34, -190
|
|
||||||
halign = center
|
|
||||||
valign = center
|
|
||||||
}
|
|
||||||
|
|
||||||
# USER
|
|
||||||
label {
|
|
||||||
monitor =
|
|
||||||
text = $USER
|
|
||||||
color = $wallbash_1xa9_rgba
|
|
||||||
outline_thickness = 0
|
|
||||||
dots_size = 0.2 # Scale of input-field height, 0.2 - 0.8
|
|
||||||
dots_spacing = 0.2 # Scale of dots' absolute size, 0.0 - 1.0
|
|
||||||
dots_center = true
|
|
||||||
font_size = 16
|
|
||||||
font_family = SF Pro Display Bold
|
|
||||||
position = 38, -190
|
|
||||||
halign = center
|
|
||||||
valign = center
|
|
||||||
}
|
|
||||||
|
|
||||||
# INPUT FIELD
|
|
||||||
input-field {
|
|
||||||
monitor =
|
|
||||||
size = 320, 55
|
|
||||||
outline_thickness = 0
|
|
||||||
dots_size = 0.2 # Scale of input-field height, 0.2 - 0.8
|
|
||||||
dots_spacing = 0.2 # Scale of dots' absolute size, 0.0 - 1.0
|
|
||||||
dots_center = true
|
|
||||||
outer_color = rgba(255, 255, 255, 0)
|
|
||||||
inner_color = rgba(255, 255, 255, 0.1)
|
|
||||||
font_color = $wallbash_2xa6_rgba
|
|
||||||
fade_on_empty = false
|
|
||||||
font_family = SF Pro Display Bold
|
|
||||||
placeholder_text = <i><span foreground="##ffffff99">🔒 Enter Pass</span></i>
|
|
||||||
hide_input = false
|
|
||||||
position = 34, -268
|
|
||||||
halign = center
|
|
||||||
valign = center
|
|
||||||
check_color = $wallbash_txt4_rgba
|
|
||||||
fail_color = rgb(204, 34, 34) # if authentication failed, changes outer_color and fail message color
|
|
||||||
fail_text = <i>$FAIL <b>($ATTEMPTS)</b></i> # can be set to empty
|
|
||||||
fail_transition = 300 # transition time in ms between normal outer_color and fail_color
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
# Battery Status if present
|
|
||||||
label {
|
|
||||||
monitor =
|
|
||||||
text = cmd[update:5000] $BATTERY_ICON
|
|
||||||
color = $wallbash_4xa9_rgba
|
|
||||||
font_size = 20
|
|
||||||
font_family = JetBrainsMono Nerd Font
|
|
||||||
position = -1%, 1%
|
|
||||||
halign = right
|
|
||||||
valign = bottom
|
|
||||||
}
|
|
||||||
|
|
||||||
# Current Keyboard Layout
|
|
||||||
label {
|
|
||||||
monitor =
|
|
||||||
text = cmd[update:1000] $KEYBOARD_LAYOUT
|
|
||||||
color = $wallbash_4xa9_rgba
|
|
||||||
font_size = 20
|
|
||||||
font_family = SF Pro Display Bold
|
|
||||||
position = -2%, 1%
|
|
||||||
halign = right
|
|
||||||
valign = bottom
|
|
||||||
}
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
source = ./HyDE.conf
|
|
||||||
@@ -26,15 +26,19 @@
|
|||||||
|
|
||||||
$wm=Window Management
|
$wm=Window Management
|
||||||
$d=[$wm]
|
$d=[$wm]
|
||||||
bindd = $mainMod, Q, $d close focused window, exec, $scrPath/dontkillsteam.sh
|
# `dontkillsteam.sh` was dropped by HyDE (gone from lib/hyde as of the 2026-08-13 update) and
|
||||||
bindd = Alt, F4, $d close focused window, exec, $scrPath/dontkillsteam.sh
|
# upstream now closes with the native dispatcher — its Lua key_binds.lua binds both of these to
|
||||||
|
# `hl.dsp.window.close()`. A bind pointing at a missing script stays valid and silently does
|
||||||
|
# nothing, which on these two keys means windows stop closing.
|
||||||
|
bindd = $mainMod, Q, $d close focused window, killactive,
|
||||||
|
bindd = Alt, F4, $d close focused window, killactive,
|
||||||
bindd = $mainMod, Delete, $d kill hyprland session, exit
|
bindd = $mainMod, Delete, $d kill hyprland session, exit
|
||||||
bindd = $mainMod, W, $d toggle float, togglefloating, #
|
bindd = $mainMod, W, $d toggle float, togglefloating, #
|
||||||
bindd = $mainMod Shift, G, $d toggle group, togglegroup
|
bindd = $mainMod Shift, G, $d toggle group, togglegroup
|
||||||
bindd = Shift, F11, $d toggle fullscreen, fullscreen
|
bindd = Shift, F11, $d toggle fullscreen, fullscreen
|
||||||
bindd = Alt, Return, $d toggle fullscreen, fullscreen
|
bindd = Alt, Return, $d toggle fullscreen, fullscreen
|
||||||
bindd = $mainMod, L, $d lock screen, exec, lockscreen.sh
|
bindd = $mainMod, L, $d lock screen, exec, lockscreen.sh
|
||||||
bindd = $mainMod Shift, F, $d toggle pin on focused window, exec, $scrPath/window.pin.sh
|
bindd = $mainMod Shift, F, $d toggle pin on focused window, exec, $scrPath/windowpin.sh # renamed upstream (was window.pin.sh); the old machine-local shim is gone with the update
|
||||||
bindd = Control Alt, Delete, $d logout menu, exec, $scrPath/logoutlaunch.sh
|
bindd = Control Alt, Delete, $d logout menu, exec, $scrPath/logoutlaunch.sh
|
||||||
bindd = Control Alt, W, $d toggle waybar, exec, killall waybar || waybar -c ~/.config/waybar/layouts/custom.jsonc -s ~/.config/waybar/layouts/custom.css
|
bindd = Control Alt, W, $d toggle waybar, exec, killall waybar || waybar -c ~/.config/waybar/layouts/custom.jsonc -s ~/.config/waybar/layouts/custom.css
|
||||||
# bindd = Control Alt, W, $d toggle waybar, exec, hyde-shell waybar --hide
|
# bindd = Control Alt, W, $d toggle waybar, exec, hyde-shell waybar --hide
|
||||||
@@ -123,7 +127,7 @@ bindd = $mainMod, B, $d web browser , exec, $BROWSER
|
|||||||
bindd = $mainMod Shift, B, $d web browser , exec, librewolf
|
bindd = $mainMod Shift, B, $d web browser , exec, librewolf
|
||||||
bindd = $mainMod Control, B, $d web browser , exec, firefox
|
bindd = $mainMod Control, B, $d web browser , exec, firefox
|
||||||
bindd = $mainMod, Y, $d ferdium, exec, ferdium
|
bindd = $mainMod, Y, $d ferdium, exec, ferdium
|
||||||
bindd = Control Shift, Escape, $d system monitor , exec, $scrPath/sysmonlaunch.sh
|
bindd = Control Shift, Escape, $d system monitor , exec, $scrPath/system.monitor.sh # renamed upstream (was sysmonlaunch.sh)
|
||||||
bindd = $mainMod, F, $d freetube , exec, freetube # youtube alternative
|
bindd = $mainMod, F, $d freetube , exec, freetube # youtube alternative
|
||||||
bindd = $mainMod, K, $d password manager , exec, keepassxc # launch password manager
|
bindd = $mainMod, K, $d password manager , exec, keepassxc # launch password manager
|
||||||
bindd = $mainMod, G, $d xmpp, exec, gajim # launch messanger
|
bindd = $mainMod, G, $d xmpp, exec, gajim # launch messanger
|
||||||
|
|||||||
@@ -29,6 +29,8 @@ layerrule = ignore_alpha 0,match:namespace cavabar
|
|||||||
env = SSH_AUTH_SOCK,$XDG_RUNTIME_DIR/ssh-agent.socket # ssh on start
|
env = SSH_AUTH_SOCK,$XDG_RUNTIME_DIR/ssh-agent.socket # ssh on start
|
||||||
env = ELECTRON_OZONE_PLATFORM_HINT,x11 # Disable after hyprland fixes electron flickering
|
env = ELECTRON_OZONE_PLATFORM_HINT,x11 # Disable after hyprland fixes electron flickering
|
||||||
exec-once = waybar -c ~/.config/waybar/layouts/custom.jsonc -s ~/.config/waybar/layouts/custom.css
|
exec-once = waybar -c ~/.config/waybar/layouts/custom.jsonc -s ~/.config/waybar/layouts/custom.css
|
||||||
|
# Steam Controller -> Deck-style binds. Not a systemd user unit: graphical-session.target
|
||||||
|
exec-once = scc-daemon start
|
||||||
|
|
||||||
# (No static `noanim` layerrule: current Hyprland rejects it in the match: syntax, and
|
# (No static `noanim` layerrule: current Hyprland rejects it in the match: syntax, and
|
||||||
# grimblast already suppresses selection animation at runtime via `hyprctl keyword layerrule`.)
|
# grimblast already suppresses selection animation at runtime via `hyprctl keyword layerrule`.)
|
||||||
|
|||||||
@@ -1,61 +1,78 @@
|
|||||||
|
|
||||||
|
## name: Catppuccin Mocha 🌿
|
||||||
|
## author: Pocco81 (https://github.com/Pocco81)
|
||||||
|
## license: MIT
|
||||||
|
## upstream: https://github.com/catppuccin/kitty/blob/main/mocha.conf
|
||||||
|
## blurb: Soothing pastel theme for the high-spirited!
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# The basic colors
|
# The basic colors
|
||||||
foreground #ffffff
|
foreground #ffffff
|
||||||
background #262335
|
background #262335
|
||||||
selection_foreground #262335
|
selection_foreground #1E1E2E
|
||||||
selection_background #f97e72
|
selection_background #F5E0DC
|
||||||
|
|
||||||
# Cursor colors
|
# Cursor colors
|
||||||
cursor #f97e72
|
cursor #F5E0DC
|
||||||
cursor_text_color #262335
|
cursor_text_color #1E1E2E
|
||||||
|
|
||||||
# URL underline color when hovering with mouse
|
# URL underline color when hovering with mouse
|
||||||
url_color #f97e72
|
url_color #B4BEFE
|
||||||
|
|
||||||
|
# Kitty window border colors
|
||||||
|
active_border_color #CBA6F7
|
||||||
|
inactive_border_color #8E95B3
|
||||||
|
bell_border_color #EBA0AC
|
||||||
|
|
||||||
# OS Window titlebar colors
|
# OS Window titlebar colors
|
||||||
wayland_titlebar_color system
|
wayland_titlebar_color system
|
||||||
macos_titlebar_color system
|
macos_titlebar_color system
|
||||||
|
|
||||||
|
# Tab bar colors
|
||||||
|
active_tab_foreground #11111B
|
||||||
|
active_tab_background #CBA6F7
|
||||||
|
inactive_tab_foreground #CDD6F4
|
||||||
|
inactive_tab_background #181825
|
||||||
|
|
||||||
# Colors for marks (marked text in the terminal)
|
# Colors for marks (marked text in the terminal)
|
||||||
mark1_foreground #262335
|
mark1_foreground #1E1E2E
|
||||||
mark1_background #614D85
|
mark1_background #87B0F9
|
||||||
mark2_foreground #262335
|
mark2_foreground #1E1E2E
|
||||||
mark2_background #614D85
|
mark2_background #CBA6F7
|
||||||
mark3_foreground #262335
|
mark3_foreground #1E1E2E
|
||||||
mark3_background #614D85
|
mark3_background #74C7EC
|
||||||
|
|
||||||
# The 16 terminal colors
|
# The 16 terminal colors
|
||||||
|
|
||||||
# black
|
# black
|
||||||
color0 #232530
|
color0 #43465A
|
||||||
# bright-black = dim/secondary text (menus, comments); was #232530 ≈ background so it
|
color8 #43465A
|
||||||
# rendered invisible. Lifted to the theme's muted lavender for legible dim text.
|
|
||||||
color8 #848bbd
|
|
||||||
|
|
||||||
# red
|
# red
|
||||||
color1 #fe4450
|
color1 #F38BA8
|
||||||
color9 #fe4450
|
color9 #F38BA8
|
||||||
|
|
||||||
# green
|
# green
|
||||||
color2 #72f1b8
|
color2 #A6E3A1
|
||||||
color10 #72f1b8
|
color10 #A6E3A1
|
||||||
|
|
||||||
# yellow
|
# yellow
|
||||||
color3 #ff7edb
|
color3 #F9E2AF
|
||||||
color11 #ff7edb
|
color11 #F9E2AF
|
||||||
|
|
||||||
# blue
|
# blue
|
||||||
color4 #03edf9
|
color4 #87B0F9
|
||||||
color12 #03edf9
|
color12 #87B0F9
|
||||||
|
|
||||||
# magenta
|
# magenta
|
||||||
color5 #fede5d
|
color5 #F5C2E7
|
||||||
color13 #f3e70f
|
color13 #F5C2E7
|
||||||
|
|
||||||
# cyan
|
# cyan
|
||||||
color6 #03edf9
|
color6 #94E2D5
|
||||||
color14 #03edf9
|
color14 #94E2D5
|
||||||
|
|
||||||
# white
|
# white
|
||||||
color7 #ffffff
|
color7 #CDD6F4
|
||||||
color15 #ffffff
|
color15 #A1A8C9
|
||||||
|
|||||||
@@ -0,0 +1,28 @@
|
|||||||
|
#!/usr/bin/env sh
|
||||||
|
|
||||||
|
# Keep Hyprland on this repo's hyprlang config instead of HyDE's Lua one.
|
||||||
|
#
|
||||||
|
# HyDE 26.x moved its Hyprland config to Lua. Its own `00-hyde.sh` (synced on
|
||||||
|
# every update) points HYPRLAND_CONFIG at ~/.local/share/hypr/hyde.lua, and
|
||||||
|
# Hyprland then never reads ~/.config/hypr/hyprland.conf — so every dots hypr
|
||||||
|
# file (theme, keybinds, window rules, monitors, userprefs) is silently bypassed
|
||||||
|
# and the session comes up as stock HyDE: no rounding/gaps/borders, HyDE's binds,
|
||||||
|
# HyDE's plain waybar instead of the cava rig. Nothing errors; `hyprctl
|
||||||
|
# configerrors` stays empty. The tell is the log's first lines:
|
||||||
|
# [cfg] Config is either explicit or special. / [cfg] Config is lua, loading lua mgr
|
||||||
|
#
|
||||||
|
# `00-hyde.sh` assigns with `${HYPRLAND_CONFIG:-...}` and `env-hyprland` sources
|
||||||
|
# `env-hyprland.d/*.sh` in glob order, so this file (10 sorts after 00) wins by
|
||||||
|
# assigning unconditionally. Session-start only — this needs a relogin, not a
|
||||||
|
# `hyprctl reload`. HyDE syncs the whole env-hyprland.d/ directory but only ever
|
||||||
|
# writes its own files into it, so this one survives updates.
|
||||||
|
#
|
||||||
|
# ── STOPGAP, not the destination ──────────────────────────────────────────────
|
||||||
|
# It pins ~/.local/share/hyde/hyprland.conf, which current HyDE no longer ships:
|
||||||
|
# ours is a leftover from the pre-update install, so nothing regenerates it. And
|
||||||
|
# 8 scripts our binds reach for through $scrPath are already gone from the new
|
||||||
|
# lib/hyde — including dontkillsteam.sh, which is bound to Super+Q and Alt+F4.
|
||||||
|
# The supported path is porting the hypr layer into ~/.config/hypr/hyprland.lua
|
||||||
|
# (the one file HyDE promises never to overwrite). See HYDE-UPDATE.md.
|
||||||
|
HYPRLAND_CONFIG="$HOME/.config/hypr/hyprland.conf"
|
||||||
|
export HYPRLAND_CONFIG
|
||||||
@@ -1,332 +0,0 @@
|
|||||||
// --// standalone two-bar cava rig — hand-maintained, NOT HyDE-generated (see README "Waybar") //-- //
|
|
||||||
|
|
||||||
[
|
|
||||||
{
|
|
||||||
// sourced from header module //
|
|
||||||
|
|
||||||
"layer": "top",
|
|
||||||
"position": "top",
|
|
||||||
"height": 33,
|
|
||||||
"exclusive": true,
|
|
||||||
"passthrough": false,
|
|
||||||
"gtk-layer-shell": true,
|
|
||||||
"reload_style_on_change": true,
|
|
||||||
|
|
||||||
|
|
||||||
// positions generated based on config.ctl //
|
|
||||||
|
|
||||||
"modules-left": ["custom/l_end","custom/power","custom/r_end","hyprland/workspaces", "custom/sl_end","hyprland/window","custom/sr_end","custom/l_end","custom/wallchange","custom/cliphist","custom/r_end"],
|
|
||||||
"modules-center": ["wlr/taskbar"],
|
|
||||||
"modules-right": ["custom/l_end","backlight","pulseaudio","pulseaudio#microphone","mpris","custom/r_end","custom/l_end","memory","cpu","custom/cpuinfo","battery","custom/r_end","custom/l_end","tray","custom/r_end","custom/l_end","idle_inhibitor","clock","custom/r_end"],
|
|
||||||
|
|
||||||
// sourced from modules based on config.ctl //
|
|
||||||
|
|
||||||
"tray": {
|
|
||||||
"icon-size": 19,
|
|
||||||
"rotate": 0,
|
|
||||||
"spacing": 5
|
|
||||||
},
|
|
||||||
|
|
||||||
// NOTE: keep in sync with modules/window.jsonc — this layout is launched standalone
|
|
||||||
// (waybar -c), so the modules/ file is NOT read here; this inline copy is what renders.
|
|
||||||
"hyprland/window": {
|
|
||||||
"format": " {}",
|
|
||||||
"rotate": 0,
|
|
||||||
"separate-outputs": true,
|
|
||||||
"max-length": 1000,
|
|
||||||
"rewrite": {
|
|
||||||
"(.*) — Kitty": " $1",
|
|
||||||
"(.*)~": " $1",
|
|
||||||
"(.*) — Mozilla Firefox": " $1",
|
|
||||||
"(.*)Mozilla Firefox": " Firefox",
|
|
||||||
"(.*) — LibreWolf": " $1",
|
|
||||||
"(.*)LibreWolf": " LibreWolf",
|
|
||||||
"(.*) — Chromium": " $1",
|
|
||||||
"(.*)Chromium": " Chromium",
|
|
||||||
"(.*) - VSCodium": " $1",
|
|
||||||
"(.*)VSCodium": " VSCodium",
|
|
||||||
"(.*)Code - OSS": " $1",
|
|
||||||
"(.*) - Visual Studio Code": " $1",
|
|
||||||
"(.*)Visual Studio Code": " Code",
|
|
||||||
"(.*) — Dolphin": " $1",
|
|
||||||
"(.*) - Obsidian(.*)": " $1",
|
|
||||||
"(.*)Ferdium": " Ferdium",
|
|
||||||
"(.*)FreeTube": " FreeTube",
|
|
||||||
"(.*) - VLC media player": " $1",
|
|
||||||
"(.*)Steam": " Steam",
|
|
||||||
"(.*)Neovide": " Nvim",
|
|
||||||
"(.*)Neovim": " Nvim",
|
|
||||||
"(.*)Nvim": " Nvim",
|
|
||||||
"(.*)Gajim": " Gajim",
|
|
||||||
"(.*)KeePassXC": " KeePassXC",
|
|
||||||
"(.*)Betterbird": " Betterbird",
|
|
||||||
"(.*)Spotify": " Spotify"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"hyprland/workspaces": {
|
|
||||||
"window-rewrite-default":"",
|
|
||||||
"all-outputs": true,
|
|
||||||
"active-only": false,
|
|
||||||
"on-click": "activate",
|
|
||||||
"disable-scroll": false,
|
|
||||||
"on-scroll-up": "hyprctl dispatch workspace -1",
|
|
||||||
"on-scroll-down": "hyprctl dispatch workspace +1",
|
|
||||||
"persistent-workspaces": {}
|
|
||||||
},
|
|
||||||
|
|
||||||
"cpu": {
|
|
||||||
"interval": 10,
|
|
||||||
"format": " {usage}%",
|
|
||||||
"format-alt": "{icon0}{icon1}{icon2}{icon3}",
|
|
||||||
"format-icons": ["▁", "▂", "▃", "▄", "▅", "▆", "▇", "█"]
|
|
||||||
},
|
|
||||||
|
|
||||||
"custom/cpuinfo": {
|
|
||||||
"exec": " cpuinfo.sh",
|
|
||||||
"return-type": "json",
|
|
||||||
"format": "{}",
|
|
||||||
"rotate": 0,
|
|
||||||
"interval": 5, // once every 5 seconds
|
|
||||||
"tooltip": true,
|
|
||||||
"max-length": 1000
|
|
||||||
},
|
|
||||||
|
|
||||||
"memory": {
|
|
||||||
"states": {
|
|
||||||
"c": 90, // critical
|
|
||||||
"h": 60, // high
|
|
||||||
"m": 30 // medium
|
|
||||||
},
|
|
||||||
"interval": 30,
|
|
||||||
"rotate": 0,
|
|
||||||
"format": " {used:0.1f}GB",
|
|
||||||
"format-m": " {used:0.1f}GB",
|
|
||||||
"format-h": " {used:0.1f}GB",
|
|
||||||
"format-c": " {used:0.1f}GB",
|
|
||||||
"format-alt": " {percentage}%",
|
|
||||||
"max-length": 10,
|
|
||||||
"tooltip": true,
|
|
||||||
"tooltip-format": " {percentage}%\n {used:0.1f}GB/{total:0.1f}GB"
|
|
||||||
},
|
|
||||||
|
|
||||||
"custom/power": {
|
|
||||||
"format": "{}",
|
|
||||||
"rotate": 0,
|
|
||||||
"exec": "echo ; echo logout",
|
|
||||||
"on-click": "logoutlaunch.sh 2",
|
|
||||||
"on-click-right": "logoutlaunch.sh 1",
|
|
||||||
"interval" : 86400, // once every day
|
|
||||||
"tooltip": true
|
|
||||||
},
|
|
||||||
|
|
||||||
"wlr/taskbar": {
|
|
||||||
"format": "{icon}",
|
|
||||||
"rotate": 0,
|
|
||||||
"icon-size": 19,
|
|
||||||
"icon-theme": "Tela-circle-dracula",
|
|
||||||
"spacing": 0,
|
|
||||||
"tooltip-format": "{title}",
|
|
||||||
"on-click": "activate",
|
|
||||||
"on-click-middle": "close",
|
|
||||||
"ignore-list": [
|
|
||||||
"Alacritty"
|
|
||||||
],
|
|
||||||
"app_ids-mapping": {
|
|
||||||
"firefoxdeveloperedition": "firefox-developer-edition"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
"idle_inhibitor": {
|
|
||||||
"format": "{icon}",
|
|
||||||
"rotate": 0,
|
|
||||||
"format-icons": {
|
|
||||||
"activated": "",
|
|
||||||
"deactivated": ""
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"clock": {
|
|
||||||
"format": "{:%H:%M}",
|
|
||||||
"rotate": 0,
|
|
||||||
"format-alt": "{:%R %d·%m·%y}",
|
|
||||||
"tooltip-format": "<span>{calendar}</span>",
|
|
||||||
"calendar": {
|
|
||||||
"mode": "month",
|
|
||||||
"mode-mon-col": 3,
|
|
||||||
"on-scroll": 1,
|
|
||||||
"on-click-right": "mode",
|
|
||||||
"format": {
|
|
||||||
"months": "<span color='#ffead3'><b>{}</b></span>",
|
|
||||||
"weekdays": "<span color='#ffcc66'><b>{}</b></span>",
|
|
||||||
"today": "<span color='#ff6699'><b>{}</b></span>"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"actions": {
|
|
||||||
"on-click-right": "mode",
|
|
||||||
"on-click-forward": "tz_up",
|
|
||||||
"on-click-backward": "tz_down",
|
|
||||||
"on-scroll-up": "shift_up",
|
|
||||||
"on-scroll-down": "shift_down"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
"custom/cliphist": {
|
|
||||||
"format": "{}",
|
|
||||||
"rotate": 0,
|
|
||||||
"exec": "echo ; echo clipboard history",
|
|
||||||
"on-click": "sleep 0.1 && cliphist.sh c",
|
|
||||||
"on-click-right": "sleep 0.1 && cliphist.sh d",
|
|
||||||
"on-click-middle": "sleep 0.1 && cliphist.sh w",
|
|
||||||
"interval" : 86400, // once every day
|
|
||||||
"tooltip": true
|
|
||||||
},
|
|
||||||
|
|
||||||
"custom/wallchange": {
|
|
||||||
"format": "{}",
|
|
||||||
"rotate": 0,
|
|
||||||
"exec": "echo ; echo switch wallpaper",
|
|
||||||
"on-click": "swwwallpaper.sh -n",
|
|
||||||
"on-click-right": "swwwallpaper.sh -p",
|
|
||||||
"on-click-middle": "sleep 0.1 && swwwallselect.sh",
|
|
||||||
"interval" : 86400, // once every day
|
|
||||||
"tooltip": true
|
|
||||||
},
|
|
||||||
|
|
||||||
"pulseaudio": {
|
|
||||||
"format": "{icon} {volume}",
|
|
||||||
"rotate": 0,
|
|
||||||
"format-muted": "婢",
|
|
||||||
"on-click": "pavucontrol -t 3",
|
|
||||||
"on-click-right": "volumecontrol.sh -s ''",
|
|
||||||
"on-click-middle": "volumecontrol.sh -o m",
|
|
||||||
"on-scroll-up": "volumecontrol.sh -o i",
|
|
||||||
"on-scroll-down": "volumecontrol.sh -o d",
|
|
||||||
"tooltip-format": "{icon} {desc} // {volume}%",
|
|
||||||
"scroll-step": 5,
|
|
||||||
"format-icons": {
|
|
||||||
"headphone": "",
|
|
||||||
"hands-free": "",
|
|
||||||
"headset": "",
|
|
||||||
"phone": "",
|
|
||||||
"portable": "",
|
|
||||||
"car": "",
|
|
||||||
"default": ["", "", ""]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
"pulseaudio#microphone": {
|
|
||||||
"format": "{format_source}",
|
|
||||||
"rotate": 0,
|
|
||||||
"format-source": "",
|
|
||||||
"format-source-muted": "",
|
|
||||||
"on-click": "pavucontrol -t 4",
|
|
||||||
"on-click-middle": "volumecontrol.sh -i m",
|
|
||||||
"on-scroll-up": "volumecontrol.sh -i i",
|
|
||||||
"on-scroll-down": "volumecontrol.sh -i d",
|
|
||||||
"tooltip-format": "{format_source} {source_desc} // {source_volume}%",
|
|
||||||
"scroll-step": 5
|
|
||||||
},
|
|
||||||
|
|
||||||
"mpris": {
|
|
||||||
"format": "{player_icon} {dynamic}",
|
|
||||||
"rotate": 0,
|
|
||||||
"format-paused": "{status_icon} <i>{dynamic}</i>",
|
|
||||||
"player-icons": {
|
|
||||||
"default": "▶",
|
|
||||||
"mpv": "🎵"
|
|
||||||
},
|
|
||||||
"status-icons": {
|
|
||||||
"paused": ""
|
|
||||||
},
|
|
||||||
"max-length": 1000,
|
|
||||||
"interval": 1
|
|
||||||
},
|
|
||||||
|
|
||||||
"battery": {
|
|
||||||
"states": {
|
|
||||||
"good": 95,
|
|
||||||
"warning": 30,
|
|
||||||
"critical": 20
|
|
||||||
},
|
|
||||||
"format": "{icon} {capacity}%",
|
|
||||||
"rotate": 0,
|
|
||||||
"format-charging": " {capacity}%",
|
|
||||||
"format-plugged": " {capacity}%",
|
|
||||||
"format-alt": "{time} {icon}",
|
|
||||||
"format-icons": ["", "", "", "", "", "", "", "", "", "", ""]
|
|
||||||
},
|
|
||||||
|
|
||||||
"backlight": {
|
|
||||||
"device": "intel_backlight",
|
|
||||||
"rotate": 0,
|
|
||||||
"format": "{icon} {percent}%",
|
|
||||||
"format-icons": ["", "", "", "", "", "", "", "", ""],
|
|
||||||
"on-scroll-up": "brightnessctl set 1%+",
|
|
||||||
"on-scroll-down": "brightnessctl set 1%-",
|
|
||||||
"min-length": 6
|
|
||||||
},
|
|
||||||
// modules for padding //
|
|
||||||
|
|
||||||
"custom/l_end": {
|
|
||||||
"format": " ",
|
|
||||||
"interval" : "once",
|
|
||||||
"tooltip": false
|
|
||||||
},
|
|
||||||
|
|
||||||
"custom/r_end": {
|
|
||||||
"format": " ",
|
|
||||||
"interval" : "once",
|
|
||||||
"tooltip": false
|
|
||||||
},
|
|
||||||
|
|
||||||
"custom/sl_end": {
|
|
||||||
"format": " ",
|
|
||||||
"interval" : "once",
|
|
||||||
"tooltip": false
|
|
||||||
},
|
|
||||||
|
|
||||||
"custom/sr_end": {
|
|
||||||
"format": " ",
|
|
||||||
"interval" : "once",
|
|
||||||
"tooltip": false
|
|
||||||
},
|
|
||||||
|
|
||||||
"custom/rl_end": {
|
|
||||||
"format": " ",
|
|
||||||
"interval" : "once",
|
|
||||||
"tooltip": false
|
|
||||||
},
|
|
||||||
|
|
||||||
"custom/rr_end": {
|
|
||||||
"format": " ",
|
|
||||||
"interval" : "once",
|
|
||||||
"tooltip": false
|
|
||||||
},
|
|
||||||
|
|
||||||
"custom/padd": {
|
|
||||||
"format": " ",
|
|
||||||
"interval" : "once",
|
|
||||||
"tooltip": false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
// full-width cava visualizer layered behind the main bar //
|
|
||||||
|
|
||||||
{
|
|
||||||
"name": "cavabar",
|
|
||||||
"layer": "bottom",
|
|
||||||
"position": "top",
|
|
||||||
"height": 36,
|
|
||||||
"margin-top": -33,
|
|
||||||
"exclusive": false,
|
|
||||||
"passthrough": true,
|
|
||||||
"modules-center": ["custom/cava"],
|
|
||||||
|
|
||||||
"custom/cava": {
|
|
||||||
"format": "{}",
|
|
||||||
"exec": "bash $HOME/.config/waybar/cava-waybar.sh $(cat $HOME/.config/waybar/cava.width 2>/dev/null || echo 94)", // per-host cava.width (bars, even; ~screen_px / (font-size*0.6)). gui default 94; wm overrides to 218
|
|
||||||
"restart-interval": 1,
|
|
||||||
"hide-empty-text": true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
|
|
||||||
@@ -1,307 +0,0 @@
|
|||||||
/*
|
|
||||||
This is an autogenerated file.
|
|
||||||
Do not edit this file directly.
|
|
||||||
|
|
||||||
This is modified to dynamically
|
|
||||||
change the border-radius which will
|
|
||||||
follow the border-radius of hyprland.
|
|
||||||
|
|
||||||
To parse this file, we use PT as a unit
|
|
||||||
to represent the border-radius.
|
|
||||||
This is stored separately to avoid
|
|
||||||
issues on parsing the border-radius
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* ? Leaf shape */
|
|
||||||
|
|
||||||
window#waybar.top #leaf,
|
|
||||||
window#waybar.top #leaf button,
|
|
||||||
window#waybar.top #leaf menu,
|
|
||||||
window#waybar.top #leaf menuitem,
|
|
||||||
window#waybar.top #leaf tooltip,
|
|
||||||
window#waybar.bottom #leaf,
|
|
||||||
window#waybar.bottom #leaf button,
|
|
||||||
window#waybar.bottom #leaf menu,
|
|
||||||
window#waybar.bottom #leaf menuitem,
|
|
||||||
window#waybar.bottom #leaf tooltip {
|
|
||||||
border-radius: 10pt 0 10pt 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
window#waybar.left #leaf,
|
|
||||||
window#waybar.left #leaf button,
|
|
||||||
window#waybar.left #leaf menu,
|
|
||||||
window#waybar.left #leaf menuitem,
|
|
||||||
window#waybar.left #leaf tooltip,
|
|
||||||
window#waybar.right #leaf,
|
|
||||||
window#waybar.right #leaf button,
|
|
||||||
window#waybar.right #leaf menu,
|
|
||||||
window#waybar.right #leaf menuitem,
|
|
||||||
window#waybar.right #leaf tooltip {
|
|
||||||
border-radius: 10pt 0 10pt 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ? Inverse Leaf shape */
|
|
||||||
|
|
||||||
window#waybar.top #leaf-inverse,
|
|
||||||
window#waybar.top #leaf-inverse button,
|
|
||||||
window#waybar.top #leaf-inverse menu,
|
|
||||||
window#waybar.top #leaf-inverse menuitem,
|
|
||||||
window#waybar.top #leaf-inverse tooltip,
|
|
||||||
window#waybar.bottom #leaf-inverse,
|
|
||||||
window#waybar.bottom #leaf-inverse button,
|
|
||||||
window#waybar.bottom #leaf-inverse menu,
|
|
||||||
window#waybar.bottom #leaf-inverse menuitem,
|
|
||||||
window#waybar.bottom #leaf-inverse tooltip {
|
|
||||||
border-radius: 0 10pt 0 10pt;
|
|
||||||
}
|
|
||||||
|
|
||||||
window#waybar.left #leaf-inverse,
|
|
||||||
window#waybar.left #leaf-inverse button,
|
|
||||||
window#waybar.left #leaf-inverse menu,
|
|
||||||
window#waybar.left #leaf-inverse menuitem,
|
|
||||||
window#waybar.left #leaf-inverse tooltip,
|
|
||||||
window#waybar.right #leaf-inverse,
|
|
||||||
window#waybar.right #leaf-inverse button,
|
|
||||||
window#waybar.right #leaf-inverse menu,
|
|
||||||
window#waybar.right #leaf-inverse menuitem,
|
|
||||||
window#waybar.right #leaf-inverse tooltip {
|
|
||||||
border-radius: 0 10pt 0 10pt;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* ? Full Pill shape*/
|
|
||||||
|
|
||||||
window#waybar.bottom #pill menuitem,
|
|
||||||
window#waybar.bottom #pill menu,
|
|
||||||
window#waybar.bottom #pill tooltip,
|
|
||||||
window#waybar.bottom #pill,
|
|
||||||
window#waybar.bottom #pill button,
|
|
||||||
window#waybar.top #pill menuitem,
|
|
||||||
window#waybar.top #pill menu,
|
|
||||||
window#waybar.top #pill tooltip,
|
|
||||||
window#waybar.top #pill,
|
|
||||||
window#waybar.top #pill button {
|
|
||||||
border-radius: 10pt 10pt 10pt 10pt;
|
|
||||||
}
|
|
||||||
|
|
||||||
window#waybar.left #pill menuitem,
|
|
||||||
window#waybar.left #pill menu,
|
|
||||||
window#waybar.left #pill tooltip,
|
|
||||||
window#waybar.left #pill,
|
|
||||||
window#waybar.left #pill button,
|
|
||||||
window#waybar.right #pill menuitem,
|
|
||||||
window#waybar.right #pill menu,
|
|
||||||
window#waybar.right #pill tooltip,
|
|
||||||
window#waybar.right #pill,
|
|
||||||
window#waybar.right #pill button {
|
|
||||||
border-radius: 10pt 10pt 10pt 10pt;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* ? half pill with the curve pointing dowmwards */
|
|
||||||
|
|
||||||
|
|
||||||
window#waybar.top #pill-down,
|
|
||||||
window#waybar.top #pill-down button,
|
|
||||||
window#waybar.top #pill-down menu,
|
|
||||||
window#waybar.top #pill-down menuitem,
|
|
||||||
window#waybar.top #pill-down tooltip,
|
|
||||||
window#waybar.bottom #pill-down,
|
|
||||||
window#waybar.bottom #pill-down button,
|
|
||||||
window#waybar.bottom #pill-down menu,
|
|
||||||
window#waybar.bottom #pill-down menuitem,
|
|
||||||
window#waybar.bottom #pill-down tooltip {
|
|
||||||
border-radius: 0 0 10pt 10pt;
|
|
||||||
}
|
|
||||||
|
|
||||||
window#waybar.left #pill-down,
|
|
||||||
window#waybar.left #pill-down button,
|
|
||||||
window#waybar.left #pill-down menu,
|
|
||||||
window#waybar.left #pill-down menuitem,
|
|
||||||
window#waybar.left #pill-down tooltip,
|
|
||||||
window#waybar.right #pill-down,
|
|
||||||
window#waybar.right #pill-down button,
|
|
||||||
window#waybar.right #pill-down menu,
|
|
||||||
window#waybar.right #pill-down menuitem,
|
|
||||||
window#waybar.right #pill-down tooltip {
|
|
||||||
border-radius: 0 0 10pt 10pt;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
? half pill with the curve pointing inwards
|
|
||||||
*/
|
|
||||||
|
|
||||||
window#waybar.top #pill-in,
|
|
||||||
window#waybar.top #pill-in button,
|
|
||||||
window#waybar.top #pill-in menu,
|
|
||||||
window#waybar.top #pill-in menuitem,
|
|
||||||
window#waybar.top #pill-in tooltip {
|
|
||||||
border-radius: 0 0 10pt 10pt;
|
|
||||||
}
|
|
||||||
|
|
||||||
window#waybar.right #pill-in,
|
|
||||||
window#waybar.right #pill-in button,
|
|
||||||
window#waybar.right #pill-in menu,
|
|
||||||
window#waybar.right #pill-in menuitem,
|
|
||||||
window#waybar.right #pill-in tooltip {
|
|
||||||
border-radius: 10pt 0 0 10pt;
|
|
||||||
}
|
|
||||||
|
|
||||||
window#waybar.bottom #pill-in,
|
|
||||||
window#waybar.bottom #pill-in button,
|
|
||||||
window#waybar.bottom #pill-in menu,
|
|
||||||
window#waybar.bottom #pill-in menuitem,
|
|
||||||
window#waybar.bottom #pill-in tooltip {
|
|
||||||
border-radius: 10pt 10pt 0 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
window#waybar.left #pill-in,
|
|
||||||
window#waybar.left #pill-in button,
|
|
||||||
window#waybar.left #pill-in menu,
|
|
||||||
window#waybar.left #pill-in menuitem,
|
|
||||||
window#waybar.left #pill-in tooltip {
|
|
||||||
border-radius: 0 10pt 10pt 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* ? half pill with the curve pointing to left */
|
|
||||||
|
|
||||||
window#waybar.top #pill-left,
|
|
||||||
window#waybar.top #pill-left button,
|
|
||||||
window#waybar.top #pill-left menu,
|
|
||||||
window#waybar.top #pill-left menuitem,
|
|
||||||
window#waybar.top #pill-left tooltip,
|
|
||||||
window#waybar.bottom #pill-left,
|
|
||||||
window#waybar.bottom #pill-left button,
|
|
||||||
window#waybar.bottom #pill-left menu,
|
|
||||||
window#waybar.bottom #pill-left menuitem,
|
|
||||||
window#waybar.bottom #pill-left tooltip {
|
|
||||||
border-radius: 10pt 0 0 10pt;
|
|
||||||
}
|
|
||||||
|
|
||||||
window#waybar.left #pill-left,
|
|
||||||
window#waybar.left #pill-left button,
|
|
||||||
window#waybar.left #pill-left menu,
|
|
||||||
window#waybar.left #pill-left menuitem,
|
|
||||||
window#waybar.left #pill-left tooltip,
|
|
||||||
window#waybar.right #pill-left,
|
|
||||||
window#waybar.right #pill-left button,
|
|
||||||
window#waybar.right #pill-left menu,
|
|
||||||
window#waybar.right #pill-left menuitem,
|
|
||||||
window#waybar.right #pill-left tooltip {
|
|
||||||
border-radius: 10pt 0 0 10pt;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* ? half pill with the curve pointing to outwards */
|
|
||||||
|
|
||||||
|
|
||||||
window#waybar.top #pill-out,
|
|
||||||
window#waybar.top #pill-out button,
|
|
||||||
window#waybar.top #pill-out menu,
|
|
||||||
window#waybar.top #pill-out menuitem,
|
|
||||||
window#waybar.top #pill-out tooltip {
|
|
||||||
border-radius: 10pt 10pt 0 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
window#waybar.right #pill-out,
|
|
||||||
window#waybar.right #pill-out button,
|
|
||||||
window#waybar.right #pill-out menu,
|
|
||||||
window#waybar.right #pill-out menuitem,
|
|
||||||
window#waybar.right #pill-out tooltip {
|
|
||||||
border-radius: 0 10pt 10pt 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
window#waybar.bottom #pill-out,
|
|
||||||
window#waybar.bottom #pill-out button,
|
|
||||||
window#waybar.bottom #pill-out menu,
|
|
||||||
window#waybar.bottom #pill-out menuitem,
|
|
||||||
window#waybar.bottom #pill-out tooltip {
|
|
||||||
border-radius: 0 0 10pt 10pt;
|
|
||||||
}
|
|
||||||
|
|
||||||
window#waybar.left #pill-out,
|
|
||||||
window#waybar.left #pill-out button,
|
|
||||||
window#waybar.left #pill-out menu,
|
|
||||||
window#waybar.left #pill-out menuitem,
|
|
||||||
window#waybar.left #pill-out tooltip {
|
|
||||||
border-radius: 10pt 0 0 10pt;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* ============================ */
|
|
||||||
/* ? half pill with the curve pointing to the right */
|
|
||||||
|
|
||||||
window#waybar.top #pill-right,
|
|
||||||
window#waybar.top #pill-right button,
|
|
||||||
window#waybar.bottom #pill-right menu,
|
|
||||||
window#waybar.bottom #pill-right menuitem,
|
|
||||||
window#waybar.bottom #pill-right tooltip,
|
|
||||||
window#waybar.bottom #pill-right,
|
|
||||||
window#waybar.bottom #pill-right button,
|
|
||||||
window#waybar.top #pill-right menu,
|
|
||||||
window#waybar.top #pill-right menuitem,
|
|
||||||
window#waybar.top #pill-right tooltip {
|
|
||||||
border-radius: 0 10pt 10pt 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
window#waybar.left #pill-right,
|
|
||||||
window#waybar.left #pill-right button,
|
|
||||||
window#waybar.right #pill-right menu,
|
|
||||||
window#waybar.right #pill-right menuitem,
|
|
||||||
window#waybar.right #pill-right tooltip,
|
|
||||||
window#waybar.right #pill-right,
|
|
||||||
window#waybar.right #pill-right button,
|
|
||||||
window#waybar.left #pill-right menu,
|
|
||||||
window#waybar.left #pill-right menuitem,
|
|
||||||
window#waybar.left #pill-right tooltip {
|
|
||||||
border-radius: 0 10pt 10pt 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* ? half pill with the flat surface pointing upwards */
|
|
||||||
|
|
||||||
window#waybar.top #pill-up,
|
|
||||||
window#waybar.top #pill-up button,
|
|
||||||
window#waybar.top #pill-up menu,
|
|
||||||
window#waybar.top #pill-up menuitem,
|
|
||||||
window#waybar.top #pill-up tooltip,
|
|
||||||
window#waybar.bottom #pill-up,
|
|
||||||
window#waybar.bottom #pill-up button,
|
|
||||||
window#waybar.bottom #pill-up menu,
|
|
||||||
window#waybar.bottom #pill-up menuitem,
|
|
||||||
window#waybar.bottom #pill-up tooltip {
|
|
||||||
border-radius: 10pt 10pt 0 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
window#waybar.left #pill-up,
|
|
||||||
window#waybar.left #pill-up button,
|
|
||||||
window#waybar.left #pill-up menu,
|
|
||||||
window#waybar.left #pill-up menuitem,
|
|
||||||
window#waybar.left #pill-up tooltip,
|
|
||||||
window#waybar.right #pill-up,
|
|
||||||
window#waybar.right #pill-up button,
|
|
||||||
window#waybar.right #pill-up menu,
|
|
||||||
window#waybar.right #pill-up menuitem,
|
|
||||||
window#waybar.right #pill-up tooltip {
|
|
||||||
border-radius: 10pt 10pt 0 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
tooltip {
|
|
||||||
border-radius: 10pt;
|
|
||||||
}
|
|
||||||
|
|
||||||
menu {
|
|
||||||
border-radius: 10pt;
|
|
||||||
}
|
|
||||||
|
|
||||||
menu menuitem {
|
|
||||||
border-radius: 10pt;
|
|
||||||
}
|
|
||||||
|
|
||||||
window.popup decoration {
|
|
||||||
border-radius: 10pt;
|
|
||||||
}
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
/*
|
|
||||||
Dynamic Style Configuration *
|
|
||||||
This is handled by HyDE
|
|
||||||
|
|
||||||
To generate a dynamic configuration
|
|
||||||
base on theme and user settings
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
* {
|
|
||||||
border-radius: 0em;
|
|
||||||
font-family: "JetBrainsMono Nerd Font","JetBrainsMono Nerd Font";
|
|
||||||
font-size: 10px;
|
|
||||||
}
|
|
||||||
@@ -1,120 +0,0 @@
|
|||||||
{
|
|
||||||
"include": [
|
|
||||||
"/home/anon/.config/waybar/modules/backlight.jsonc",
|
|
||||||
"/home/anon/.config/waybar/modules/bluetooth.jsonc",
|
|
||||||
"/home/anon/.config/waybar/modules/cava.jsonc",
|
|
||||||
"/home/anon/.config/waybar/modules/cliphist.jsonc",
|
|
||||||
"/home/anon/.config/waybar/modules/clock.jsonc",
|
|
||||||
"/home/anon/.config/waybar/modules/cpu.jsonc",
|
|
||||||
"/home/anon/.config/waybar/modules/cpuinfo.jsonc",
|
|
||||||
"/home/anon/.config/waybar/modules/footer.jsonc",
|
|
||||||
"/home/anon/.config/waybar/modules/github_hyprdots.jsonc",
|
|
||||||
"/home/anon/.config/waybar/modules/gpuinfo.jsonc",
|
|
||||||
"/home/anon/.config/waybar/modules/header.jsonc",
|
|
||||||
"/home/anon/.config/waybar/modules/idle_inhibitor.jsonc",
|
|
||||||
"/home/anon/.config/waybar/modules/keybindhint.jsonc",
|
|
||||||
"/home/anon/.config/waybar/modules/language.jsonc",
|
|
||||||
"/home/anon/.config/waybar/modules/memory.jsonc",
|
|
||||||
"/home/anon/.config/waybar/modules/mpris.jsonc",
|
|
||||||
"/home/anon/.config/waybar/modules/network.jsonc",
|
|
||||||
"/home/anon/.config/waybar/modules/notifications.jsonc",
|
|
||||||
"/home/anon/.config/waybar/modules/power.jsonc",
|
|
||||||
"/home/anon/.config/waybar/modules/privacy.jsonc",
|
|
||||||
"/home/anon/.config/waybar/modules/pulseaudio.jsonc",
|
|
||||||
"/home/anon/.config/waybar/modules/spotify.jsonc",
|
|
||||||
"/home/anon/.config/waybar/modules/taskbar.jsonc",
|
|
||||||
"/home/anon/.config/waybar/modules/theme.jsonc",
|
|
||||||
"/home/anon/.config/waybar/modules/tray.jsonc",
|
|
||||||
"/home/anon/.config/waybar/modules/updates.jsonc",
|
|
||||||
"/home/anon/.config/waybar/modules/wallchange.jsonc",
|
|
||||||
"/home/anon/.config/waybar/modules/window.jsonc",
|
|
||||||
"/home/anon/.config/waybar/modules/workspaces.jsonc",
|
|
||||||
"/home/anon/.config/waybar/modules/battery.jsonc",
|
|
||||||
"/home/anon/.local/share/waybar/modules/image#wallpaper.json",
|
|
||||||
"/home/anon/.local/share/waybar/modules/privacy.json",
|
|
||||||
"/home/anon/.local/share/waybar/modules/tray.json",
|
|
||||||
"/home/anon/.local/share/waybar/modules/wlr-taskbar#windows.json",
|
|
||||||
"/home/anon/.local/share/waybar/modules/wlr-taskbar.json",
|
|
||||||
"/home/anon/.local/share/waybar/modules/backlight.jsonc",
|
|
||||||
"/home/anon/.local/share/waybar/modules/battery.jsonc",
|
|
||||||
"/home/anon/.local/share/waybar/modules/bluetooth.jsonc",
|
|
||||||
"/home/anon/.local/share/waybar/modules/cava.jsonc",
|
|
||||||
"/home/anon/.local/share/waybar/modules/clock.jsonc",
|
|
||||||
"/home/anon/.local/share/waybar/modules/cpu.jsonc",
|
|
||||||
"/home/anon/.local/share/waybar/modules/custom-app-launcher.jsonc",
|
|
||||||
"/home/anon/.local/share/waybar/modules/custom-cava.jsonc",
|
|
||||||
"/home/anon/.local/share/waybar/modules/custom-clipboard.jsonc",
|
|
||||||
"/home/anon/.local/share/waybar/modules/custom-cliphist.jsonc",
|
|
||||||
"/home/anon/.local/share/waybar/modules/custom-cpuinfo.jsonc",
|
|
||||||
"/home/anon/.local/share/waybar/modules/custom-display.jsonc",
|
|
||||||
"/home/anon/.local/share/waybar/modules/custom-dunst.jsonc",
|
|
||||||
"/home/anon/.local/share/waybar/modules/custom-gamemode.jsonc",
|
|
||||||
"/home/anon/.local/share/waybar/modules/custom-github_hyde.jsonc",
|
|
||||||
"/home/anon/.local/share/waybar/modules/custom-gpuinfo#amd.jsonc",
|
|
||||||
"/home/anon/.local/share/waybar/modules/custom-gpuinfo#intel.jsonc",
|
|
||||||
"/home/anon/.local/share/waybar/modules/custom-gpuinfo#nvidia.jsonc",
|
|
||||||
"/home/anon/.local/share/waybar/modules/custom-gpuinfo.jsonc",
|
|
||||||
"/home/anon/.local/share/waybar/modules/custom-hyde-menu.jsonc",
|
|
||||||
"/home/anon/.local/share/waybar/modules/custom-hyprsunset.jsonc",
|
|
||||||
"/home/anon/.local/share/waybar/modules/custom-keybindhint.jsonc",
|
|
||||||
"/home/anon/.local/share/waybar/modules/custom-mediaplayer.jsonc",
|
|
||||||
"/home/anon/.local/share/waybar/modules/custom-power.jsonc",
|
|
||||||
"/home/anon/.local/share/waybar/modules/custom-powermenu.jsonc",
|
|
||||||
"/home/anon/.local/share/waybar/modules/custom-sensorsinfo.jsonc",
|
|
||||||
"/home/anon/.local/share/waybar/modules/custom-spotify.jsonc",
|
|
||||||
"/home/anon/.local/share/waybar/modules/custom-swaync.jsonc",
|
|
||||||
"/home/anon/.local/share/waybar/modules/custom-theme.jsonc",
|
|
||||||
"/home/anon/.local/share/waybar/modules/custom-updates.jsonc",
|
|
||||||
"/home/anon/.local/share/waybar/modules/custom-wallchange.jsonc",
|
|
||||||
"/home/anon/.local/share/waybar/modules/custom-wbar.jsonc",
|
|
||||||
"/home/anon/.local/share/waybar/modules/custom-weather.jsonc",
|
|
||||||
"/home/anon/.local/share/waybar/modules/custom-workflows.jsonc",
|
|
||||||
"/home/anon/.local/share/waybar/modules/gamemode.jsonc",
|
|
||||||
"/home/anon/.local/share/waybar/modules/group-eyecare.jsonc",
|
|
||||||
"/home/anon/.local/share/waybar/modules/group-hide-tray.jsonc",
|
|
||||||
"/home/anon/.local/share/waybar/modules/group-mediaplayer.jsonc",
|
|
||||||
"/home/anon/.local/share/waybar/modules/group-volumecontrol.jsonc",
|
|
||||||
"/home/anon/.local/share/waybar/modules/hyprland-language.jsonc",
|
|
||||||
"/home/anon/.local/share/waybar/modules/hyprland-window.jsonc",
|
|
||||||
"/home/anon/.local/share/waybar/modules/hyprland-workspaces#kanji.jsonc",
|
|
||||||
"/home/anon/.local/share/waybar/modules/hyprland-workspaces#roman.jsonc",
|
|
||||||
"/home/anon/.local/share/waybar/modules/hyprland-workspaces.jsonc",
|
|
||||||
"/home/anon/.local/share/waybar/modules/idle_inhibitor.jsonc",
|
|
||||||
"/home/anon/.local/share/waybar/modules/image#profile.jsonc",
|
|
||||||
"/home/anon/.local/share/waybar/modules/image#wallpaper.jsonc",
|
|
||||||
"/home/anon/.local/share/waybar/modules/memory.jsonc",
|
|
||||||
"/home/anon/.local/share/waybar/modules/mpd.jsonc",
|
|
||||||
"/home/anon/.local/share/waybar/modules/mpris.jsonc",
|
|
||||||
"/home/anon/.local/share/waybar/modules/network#bandwidth.jsonc",
|
|
||||||
"/home/anon/.local/share/waybar/modules/network.jsonc",
|
|
||||||
"/home/anon/.local/share/waybar/modules/power-profiles-daemon.jsonc",
|
|
||||||
"/home/anon/.local/share/waybar/modules/privacy.jsonc",
|
|
||||||
"/home/anon/.local/share/waybar/modules/pulseaudio#microphone.jsonc",
|
|
||||||
"/home/anon/.local/share/waybar/modules/pulseaudio.jsonc",
|
|
||||||
"/home/anon/.local/share/waybar/modules/temperature.jsonc",
|
|
||||||
"/home/anon/.local/share/waybar/modules/tray.jsonc",
|
|
||||||
"/home/anon/.local/share/waybar/modules/wlr-taskbar#windows.jsonc",
|
|
||||||
"/home/anon/.local/share/waybar/modules/wlr-taskbar.jsonc"
|
|
||||||
],
|
|
||||||
"image#wallpaper": {
|
|
||||||
"size": 30,
|
|
||||||
"icon-size-multiplier": 3
|
|
||||||
},
|
|
||||||
"privacy": {
|
|
||||||
"icon-size": 10,
|
|
||||||
"icon-size-multiplier": 1
|
|
||||||
},
|
|
||||||
"tray": {
|
|
||||||
"icon-size": 16,
|
|
||||||
"icon-size-multiplier": 1.6
|
|
||||||
},
|
|
||||||
"wlr/taskbar#windows": {
|
|
||||||
"icon-size": 16,
|
|
||||||
"icon-size-multiplier": 1.6
|
|
||||||
},
|
|
||||||
"wlr/taskbar": {
|
|
||||||
"icon-size": 16,
|
|
||||||
"icon-size-multiplier": 1.6
|
|
||||||
},
|
|
||||||
"position": "top"
|
|
||||||
}
|
|
||||||
@@ -7,7 +7,10 @@
|
|||||||
min-height: 10px;
|
min-height: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
@import "../theme.css"; /* HyDE/wallbash-generated colors, lives one level up */
|
@import "../theme.css";
|
||||||
|
/* HyDE/wallbash-generated colors, one level up. FATAL if missing —
|
||||||
|
waybar exits before drawing anything. install.sh seeds it from ../theme-fallback.css on
|
||||||
|
hosts where wallbash never wrote one. */
|
||||||
|
|
||||||
window#waybar {
|
window#waybar {
|
||||||
/* transparent so the cavabar (bottom layer, same region) shows through; module pills keep @main-bg */
|
/* transparent so the cavabar (bottom layer, same region) shows through; module pills keep @main-bg */
|
||||||
@@ -70,13 +73,13 @@ tooltip {
|
|||||||
padding-left: 3px;
|
padding-left: 3px;
|
||||||
padding-right: 3px;
|
padding-right: 3px;
|
||||||
margin-right: 0px;
|
margin-right: 0px;
|
||||||
color: @wb-color;
|
color: @main-fg;
|
||||||
animation: tb_normal 20s ease-in-out 1;
|
animation: tb_normal 20s ease-in-out 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
#taskbar button.active {
|
#taskbar button.active {
|
||||||
background: @wb-act-bg;
|
background: @wb-act-bg;
|
||||||
color: @wb-act-color;
|
color: @wb-act-fg;
|
||||||
/*animation: tb_active 20s ease-in-out 1;*/
|
/*animation: tb_active 20s ease-in-out 1;*/
|
||||||
box-shadow: 0 0 1px 1px rgba(128, 128, 128, 0.4);
|
box-shadow: 0 0 1px 1px rgba(128, 128, 128, 0.4);
|
||||||
transition: all 0.4s cubic-bezier(0.55, -0.68, 0.48, 1.682);
|
transition: all 0.4s cubic-bezier(0.55, -0.68, 0.48, 1.682);
|
||||||
@@ -84,7 +87,7 @@ tooltip {
|
|||||||
|
|
||||||
#taskbar button:hover {
|
#taskbar button:hover {
|
||||||
background: @wb-hvr-bg;
|
background: @wb-hvr-bg;
|
||||||
color: @wb-hvr-color;
|
color: @wb-hvr-fg;
|
||||||
opacity: 0.8;
|
opacity: 0.8;
|
||||||
animation: tb_hover 20s ease-in-out 1;
|
animation: tb_hover 20s ease-in-out 1;
|
||||||
transition: all 0.3s cubic-bezier(0.55, -0.68, 0.48, 1.682);
|
transition: all 0.3s cubic-bezier(0.55, -0.68, 0.48, 1.682);
|
||||||
@@ -132,7 +135,9 @@ tooltip {
|
|||||||
#custom-rl_end,
|
#custom-rl_end,
|
||||||
#custom-rr_end {
|
#custom-rr_end {
|
||||||
color: @main-fg;
|
color: @main-fg;
|
||||||
background: @main-bg;
|
/* background: @main-bg; */
|
||||||
|
|
||||||
|
background: transparent;
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
margin: 4px 0px 4px 0px;
|
margin: 4px 0px 4px 0px;
|
||||||
padding-left: 4px;
|
padding-left: 4px;
|
||||||
|
|||||||
@@ -17,12 +17,15 @@
|
|||||||
|
|
||||||
"modules-left": ["custom/l_end","custom/power","custom/r_end","hyprland/workspaces", "custom/sl_end","hyprland/window","custom/sr_end","custom/l_end","custom/wallchange","custom/cliphist","custom/r_end"],
|
"modules-left": ["custom/l_end","custom/power","custom/r_end","hyprland/workspaces", "custom/sl_end","hyprland/window","custom/sr_end","custom/l_end","custom/wallchange","custom/cliphist","custom/r_end"],
|
||||||
"modules-center": ["wlr/taskbar"],
|
"modules-center": ["wlr/taskbar"],
|
||||||
"modules-right": ["custom/l_end","backlight","pulseaudio","pulseaudio#microphone","mpris","custom/r_end","custom/l_end","memory","cpu","custom/cpuinfo","battery","custom/r_end","custom/l_end","tray","custom/r_end","custom/l_end","idle_inhibitor","clock","custom/r_end"],
|
"modules-right": ["custom/l_end","backlight","pulseaudio","pulseaudio#microphone","mpris","custom/r_end","custom/l_end","memory","cpu","custom/cpuinfo","battery","custom/r_end","custom/l_end","network","tray","custom/r_end","custom/l_end","idle_inhibitor","clock","custom/r_end"],
|
||||||
|
|
||||||
// sourced from modules based on config.ctl //
|
// sourced from modules based on config.ctl //
|
||||||
|
|
||||||
"tray": {
|
"tray": {
|
||||||
"icon-size": 19,
|
// exactly 22: Tela only has fixed-size monochrome icons in {16,22,24}/panel — any
|
||||||
|
// other size makes GTK fall through to scalable/devices, whose icons are colored
|
||||||
|
// circles (the blue nm-applet blob). An exact panel match keeps the tray flat/white.
|
||||||
|
"icon-size": 22,
|
||||||
"rotate": 0,
|
"rotate": 0,
|
||||||
"spacing": 5
|
"spacing": 5
|
||||||
},
|
},
|
||||||
@@ -36,7 +39,7 @@
|
|||||||
"max-length": 1000,
|
"max-length": 1000,
|
||||||
"rewrite": {
|
"rewrite": {
|
||||||
"(.*) — Kitty": " $1",
|
"(.*) — Kitty": " $1",
|
||||||
"(.*)~": " $1",
|
"(.*)~": " $1",
|
||||||
"(.*) — Mozilla Firefox": " $1",
|
"(.*) — Mozilla Firefox": " $1",
|
||||||
"(.*)Mozilla Firefox": " Firefox",
|
"(.*)Mozilla Firefox": " Firefox",
|
||||||
"(.*) — LibreWolf": " $1",
|
"(.*) — LibreWolf": " $1",
|
||||||
@@ -60,7 +63,34 @@
|
|||||||
"(.*)Gajim": " Gajim",
|
"(.*)Gajim": " Gajim",
|
||||||
"(.*)KeePassXC": " KeePassXC",
|
"(.*)KeePassXC": " KeePassXC",
|
||||||
"(.*)Betterbird": " Betterbird",
|
"(.*)Betterbird": " Betterbird",
|
||||||
"(.*)Spotify": " Spotify"
|
// --- apps in use on this rig (glyphs verified against JetBrainsMono NF v3) ---
|
||||||
|
"nvim (.*)": " $1",
|
||||||
|
"nvim": " Nvim",
|
||||||
|
"(.*)PyRadio - Playing: (.*)": " $2",
|
||||||
|
"(.*)PyRadio(.*)": " PyRadio",
|
||||||
|
"(.*) - mpv": " $1",
|
||||||
|
"(.*)mpv": " mpv",
|
||||||
|
"(.*) — Zen Browser": " $1",
|
||||||
|
"(.*)Zen Browser(.*)": " Zen",
|
||||||
|
"(.*) - Thorium": " $1",
|
||||||
|
"(.*)Thorium(.*)": " Thorium",
|
||||||
|
"(.*)Ghostty(.*)": " Ghostty",
|
||||||
|
"(.*)zellij(.*)": " zellij",
|
||||||
|
"(.*)btop(.*)": " btop",
|
||||||
|
"(.*)lazydocker(.*)": " lazydocker",
|
||||||
|
"(.*)Dolphin(.*)": " Dolphin",
|
||||||
|
"(.*)qBittorrent(.*)": " qBittorrent",
|
||||||
|
"(.*)GIMP(.*)": " GIMP",
|
||||||
|
"(.*)LibreOffice(.*)": " LibreOffice",
|
||||||
|
"(.*)KiCad(.*)": " KiCad",
|
||||||
|
"(.*)QGroundControl(.*)": " QGroundControl",
|
||||||
|
"(.*)Foxglove(.*)": " Foxglove",
|
||||||
|
"(.*)Bruno(.*)": " Bruno",
|
||||||
|
"(.*)RustDesk(.*)": " RustDesk",
|
||||||
|
"(.*)scrcpy(.*)": " scrcpy",
|
||||||
|
"(.*)Vial(.*)": " Vial",
|
||||||
|
"(.*)Volume Control(.*)": " Volume Control",
|
||||||
|
"(.*)Satty(.*)": " Satty"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"hyprland/workspaces": {
|
"hyprland/workspaces": {
|
||||||
@@ -181,12 +211,14 @@
|
|||||||
},
|
},
|
||||||
|
|
||||||
"custom/wallchange": {
|
"custom/wallchange": {
|
||||||
"format": "{}",
|
"format": "{}",
|
||||||
"rotate": 0,
|
"rotate": 0,
|
||||||
"exec": "echo ; echo switch wallpaper",
|
"exec": "echo ; echo switch wallpaper",
|
||||||
"on-click": "swwwallpaper.sh -n",
|
// HyDE 26.x removed swwwallpaper.sh/swwwallselect.sh; hyde-shell wallpaper is the
|
||||||
"on-click-right": "swwwallpaper.sh -p",
|
// replacement (same calls as upstream's custom-wallchange module)
|
||||||
"on-click-middle": "sleep 0.1 && swwwallselect.sh",
|
"on-click": "hyde-shell wallpaper -n",
|
||||||
|
"on-click-right": "hyde-shell wallpaper -p",
|
||||||
|
"on-click-middle": "sleep 0.1 && hyde-shell wallpaper --select",
|
||||||
"interval" : 86400, // once every day
|
"interval" : 86400, // once every day
|
||||||
"tooltip": true
|
"tooltip": true
|
||||||
},
|
},
|
||||||
@@ -194,7 +226,7 @@
|
|||||||
"pulseaudio": {
|
"pulseaudio": {
|
||||||
"format": "{icon} {volume}",
|
"format": "{icon} {volume}",
|
||||||
"rotate": 0,
|
"rotate": 0,
|
||||||
"format-muted": "婢",
|
"format-muted": "",
|
||||||
"on-click": "pavucontrol -t 3",
|
"on-click": "pavucontrol -t 3",
|
||||||
"on-click-right": "volumecontrol.sh -s ''",
|
"on-click-right": "volumecontrol.sh -s ''",
|
||||||
"on-click-middle": "volumecontrol.sh -o m",
|
"on-click-middle": "volumecontrol.sh -o m",
|
||||||
@@ -216,7 +248,7 @@
|
|||||||
"pulseaudio#microphone": {
|
"pulseaudio#microphone": {
|
||||||
"format": "{format_source}",
|
"format": "{format_source}",
|
||||||
"rotate": 0,
|
"rotate": 0,
|
||||||
"format-source": "",
|
"format-source": "",
|
||||||
"format-source-muted": "",
|
"format-source-muted": "",
|
||||||
"on-click": "pavucontrol -t 4",
|
"on-click": "pavucontrol -t 4",
|
||||||
"on-click-middle": "volumecontrol.sh -i m",
|
"on-click-middle": "volumecontrol.sh -i m",
|
||||||
@@ -232,7 +264,10 @@
|
|||||||
"format-paused": "{status_icon} <i>{dynamic}</i>",
|
"format-paused": "{status_icon} <i>{dynamic}</i>",
|
||||||
"player-icons": {
|
"player-icons": {
|
||||||
"default": "▶",
|
"default": "▶",
|
||||||
"mpv": "🎵"
|
"mpv": "",
|
||||||
|
"spotify": "",
|
||||||
|
"firefox": "",
|
||||||
|
"vlc": ""
|
||||||
},
|
},
|
||||||
"status-icons": {
|
"status-icons": {
|
||||||
"paused": ""
|
"paused": ""
|
||||||
@@ -242,6 +277,16 @@
|
|||||||
},
|
},
|
||||||
|
|
||||||
"battery": {
|
"battery": {
|
||||||
|
// Pinned to the laptop battery on purpose. Unpinned, waybar 0.15 scans every
|
||||||
|
// /sys/class/power_supply node, and a flapping one (the DualShock's
|
||||||
|
// ps-controller-battery-* appearing at login while opensdd/scc-daemon wake it)
|
||||||
|
// makes refreshBatteries() throw off its worker thread → SIGABRT, killing the
|
||||||
|
// whole bar (battery.cpp:142 uncaught; all 5 of 2026-08-17's coredumps). The pin
|
||||||
|
// (battery.cpp:117) gates every read/watch of non-matching nodes. On wm no BAT0
|
||||||
|
// exists so the module stays hidden — same as before. On lw verify the name with
|
||||||
|
// `ls /sys/class/power_supply` and correct here if it's BAT1 (its old default-config
|
||||||
|
// log already ruled out BAT2); a wrong name only hides the module, never crashes.
|
||||||
|
"bat": "BAT0",
|
||||||
"states": {
|
"states": {
|
||||||
"good": 95,
|
"good": 95,
|
||||||
"warning": 30,
|
"warning": 30,
|
||||||
@@ -255,6 +300,23 @@
|
|||||||
"format-icons": ["", "", "", "", "", "", "", "", "", "", ""]
|
"format-icons": ["", "", "", "", "", "", "", "", "", "", ""]
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// added 2026-08-14 — the rig never had a network indicator ("ethernet icon not working").
|
||||||
|
// Same def as HyDE's ~/.local/share/waybar/modules/network.jsonc, inline like everything
|
||||||
|
// else here; click toggles a bandwidth readout, tooltip carries the connection details.
|
||||||
|
"network": {
|
||||||
|
"tooltip": true,
|
||||||
|
"format-wifi": "<span size='150%'> </span>",
|
||||||
|
"rotate": 0,
|
||||||
|
"format-ethernet": "<span size='150%'> </span>",
|
||||||
|
"tooltip-format": "Network: <big><b>{essid}</b></big>\nSignal strength: <b>{signaldBm}dBm ({signalStrength}%)</b>\nFrequency: <b>{frequency}MHz</b>\nInterface: <b>{ifname}</b>\nIP: <b>{ipaddr}/{cidr}</b>\nGateway: <b>{gwaddr}</b>\nNetmask: <b>{netmask}</b>",
|
||||||
|
"format-linked": " {ifname} (No IP)",
|
||||||
|
"format-disconnected": "<span size='150%'> </span>",
|
||||||
|
"tooltip-format-disconnected": "Disconnected",
|
||||||
|
"format-alt": "<span foreground='#99ffdd'> {bandwidthDownBytes}</span> <span foreground='#ffcc66'> {bandwidthUpBytes}</span>",
|
||||||
|
"on-click-right": "nm-connection-editor", // replaces the hidden nm-applet tray menu
|
||||||
|
"interval": 2
|
||||||
|
},
|
||||||
|
|
||||||
"backlight": {
|
"backlight": {
|
||||||
"device": "intel_backlight",
|
"device": "intel_backlight",
|
||||||
"rotate": 0,
|
"rotate": 0,
|
||||||
|
|||||||
@@ -1,10 +0,0 @@
|
|||||||
"backlight": {
|
|
||||||
"device": "intel_backlight",
|
|
||||||
"rotate": ${r_deg},
|
|
||||||
"format": "{icon} {percent}%",
|
|
||||||
"format-icons": ["", "", "", "", "", "", "", "", ""],
|
|
||||||
"on-scroll-up": "brightnessctl set 1%+",
|
|
||||||
"on-scroll-down": "brightnessctl set 1%-",
|
|
||||||
"min-length": 6
|
|
||||||
},
|
|
||||||
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
"battery": {
|
|
||||||
"states": {
|
|
||||||
"good": 95,
|
|
||||||
"warning": 30,
|
|
||||||
"critical": 20
|
|
||||||
},
|
|
||||||
"format": "{icon} {capacity}%",
|
|
||||||
"rotate": ${r_deg},
|
|
||||||
"format-charging": " {capacity}%",
|
|
||||||
"format-plugged": " {capacity}%",
|
|
||||||
"format-alt": "{time} {icon}",
|
|
||||||
"format-icons": ["", "", "", "", "", "", "", "", "", "", ""]
|
|
||||||
},
|
|
||||||
|
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
"bluetooth": {
|
|
||||||
"format": "",
|
|
||||||
"rotate": ${r_deg},
|
|
||||||
"format-disabled": "",
|
|
||||||
"format-connected": " {num_connections}",
|
|
||||||
"format-connected-battery": "{icon} {num_connections}",
|
|
||||||
// "format-connected-battery": "{icon} {device_alias}-{device_battery_percentage}%",
|
|
||||||
"format-icons": ["", "", "", "", "", "", "", "", "", "", ""],
|
|
||||||
// "format-device-preference": [ "device1", "device2" ], // preference list deciding the displayed device If this config option is not defined or none of the devices in the list are connected, it will fall back to showing the last connected device.
|
|
||||||
"tooltip-format": "{controller_alias}\n{num_connections} connected",
|
|
||||||
"tooltip-format-connected": "{controller_alias}\n{num_connections} connected\n\n{device_enumerate}",
|
|
||||||
"tooltip-format-enumerate-connected": "{device_alias}",
|
|
||||||
"tooltip-format-enumerate-connected-battery": "{device_alias}\t{icon} {device_battery_percentage}%"
|
|
||||||
},
|
|
||||||
|
|
||||||
@@ -1,24 +0,0 @@
|
|||||||
{
|
|
||||||
"cava": {
|
|
||||||
// "cava_config": "$XDG_CONFIG_HOME/cava/cava.conf",
|
|
||||||
"framerate": 30,
|
|
||||||
"autosens": 1,
|
|
||||||
"sensitivity": 100,
|
|
||||||
"bars": 14,
|
|
||||||
"lower_cutoff_freq": 50,
|
|
||||||
"higher_cutoff_freq": 10000,
|
|
||||||
"method": "pulse",
|
|
||||||
"source": "auto",
|
|
||||||
"stereo": true,
|
|
||||||
"reverse": false,
|
|
||||||
"bar_delimiter": 0,
|
|
||||||
"monstercat": false,
|
|
||||||
"waves": false,
|
|
||||||
"noise_reduction": 0.77,
|
|
||||||
"input_delay": 2,
|
|
||||||
"format-icons": ["▁", "▂", "▃", "▄", "▅", "▆", "▇", "█"],
|
|
||||||
"actions": {
|
|
||||||
"on-click-right": "mode"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
"custom/cliphist": {
|
|
||||||
"format": "{}",
|
|
||||||
"rotate": ${r_deg},
|
|
||||||
"exec": "echo ; echo clipboard history",
|
|
||||||
"on-click": "sleep 0.1 && cliphist.sh c",
|
|
||||||
"on-click-right": "sleep 0.1 && cliphist.sh d",
|
|
||||||
"on-click-middle": "sleep 0.1 && cliphist.sh w",
|
|
||||||
"interval" : 86400, // once every day
|
|
||||||
"tooltip": true
|
|
||||||
},
|
|
||||||
|
|
||||||
@@ -1,25 +0,0 @@
|
|||||||
"clock": {
|
|
||||||
"format": "{:%H:%M}",
|
|
||||||
"rotate": ${r_deg},
|
|
||||||
"format-alt": "{:%R %d·%m·%y}",
|
|
||||||
"tooltip-format": "<span>{calendar}</span>",
|
|
||||||
"calendar": {
|
|
||||||
"mode": "month",
|
|
||||||
"mode-mon-col": 3,
|
|
||||||
"on-scroll": 1,
|
|
||||||
"on-click-right": "mode",
|
|
||||||
"format": {
|
|
||||||
"months": "<span color='#ffead3'><b>{}</b></span>",
|
|
||||||
"weekdays": "<span color='#ffcc66'><b>{}</b></span>",
|
|
||||||
"today": "<span color='#ff6699'><b>{}</b></span>"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"actions": {
|
|
||||||
"on-click-right": "mode",
|
|
||||||
"on-click-forward": "tz_up",
|
|
||||||
"on-click-backward": "tz_down",
|
|
||||||
"on-scroll-up": "shift_up",
|
|
||||||
"on-scroll-down": "shift_down"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
"cpu": {
|
|
||||||
"interval": 10,
|
|
||||||
"format": " {usage}%",
|
|
||||||
"rotate": ${r_deg},
|
|
||||||
"format-alt": "{icon0}{icon1}{icon2}{icon3}",
|
|
||||||
"format-icons": ["▁", "▂", "▃", "▄", "▅", "▆", "▇", "█"]
|
|
||||||
},
|
|
||||||
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
"custom/cpuinfo": {
|
|
||||||
"exec": " cpuinfo.sh",
|
|
||||||
"return-type": "json",
|
|
||||||
"format": "{}",
|
|
||||||
"rotate": ${r_deg},
|
|
||||||
"interval": 5, // once every 5 seconds
|
|
||||||
"tooltip": true,
|
|
||||||
"max-length": 1000
|
|
||||||
},
|
|
||||||
|
|
||||||
@@ -1,47 +0,0 @@
|
|||||||
|
|
||||||
// modules for padding //
|
|
||||||
|
|
||||||
"custom/l_end": {
|
|
||||||
"format": " ",
|
|
||||||
"interval" : "once",
|
|
||||||
"tooltip": false
|
|
||||||
},
|
|
||||||
|
|
||||||
"custom/r_end": {
|
|
||||||
"format": " ",
|
|
||||||
"interval" : "once",
|
|
||||||
"tooltip": false
|
|
||||||
},
|
|
||||||
|
|
||||||
"custom/sl_end": {
|
|
||||||
"format": " ",
|
|
||||||
"interval" : "once",
|
|
||||||
"tooltip": false
|
|
||||||
},
|
|
||||||
|
|
||||||
"custom/sr_end": {
|
|
||||||
"format": " ",
|
|
||||||
"interval" : "once",
|
|
||||||
"tooltip": false
|
|
||||||
},
|
|
||||||
|
|
||||||
"custom/rl_end": {
|
|
||||||
"format": " ",
|
|
||||||
"interval" : "once",
|
|
||||||
"tooltip": false
|
|
||||||
},
|
|
||||||
|
|
||||||
"custom/rr_end": {
|
|
||||||
"format": " ",
|
|
||||||
"interval" : "once",
|
|
||||||
"tooltip": false
|
|
||||||
},
|
|
||||||
|
|
||||||
"custom/padd": {
|
|
||||||
"format": " ",
|
|
||||||
"interval" : "once",
|
|
||||||
"tooltip": false
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
{
|
|
||||||
"custom/github_hyprdots": {
|
|
||||||
"format": " ",
|
|
||||||
"rotate": 0,
|
|
||||||
"tooltip-format": " Hyprdots repository",
|
|
||||||
"on-click": "xdg-open https://github.com/prasanthrangan/hyprdots"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,41 +0,0 @@
|
|||||||
"custom/gpuinfo": {
|
|
||||||
"exec": " gpuinfo.sh",
|
|
||||||
"return-type": "json",
|
|
||||||
"format": "{}",
|
|
||||||
"rotate": ${r_deg},
|
|
||||||
"interval": 5, // once every 5 seconds
|
|
||||||
"tooltip": true,
|
|
||||||
"max-length": 1000,
|
|
||||||
"on-click": "gpuinfo.sh --toggle",
|
|
||||||
},
|
|
||||||
|
|
||||||
"custom/gpuinfo#nvidia": {
|
|
||||||
"exec": " gpuinfo.sh --use nvidia ",
|
|
||||||
"return-type": "json",
|
|
||||||
"format": "{}",
|
|
||||||
"rotate": ${r_deg},
|
|
||||||
"interval": 5, // once every 5 seconds
|
|
||||||
"tooltip": true,
|
|
||||||
"max-length": 1000,
|
|
||||||
},
|
|
||||||
|
|
||||||
"custom/gpuinfo#amd": {
|
|
||||||
"exec": " gpuinfo.sh --use amd ",
|
|
||||||
"return-type": "json",
|
|
||||||
"format": "{}",
|
|
||||||
"rotate": ${r_deg},
|
|
||||||
"interval": 5, // once every 5 seconds
|
|
||||||
"tooltip": true,
|
|
||||||
"max-length": 1000,
|
|
||||||
},
|
|
||||||
|
|
||||||
"custom/gpuinfo#intel": {
|
|
||||||
"exec": " gpuinfo.sh --use intel ",
|
|
||||||
"return-type": "json",
|
|
||||||
"format": "{}",
|
|
||||||
"rotate": ${r_deg},
|
|
||||||
"interval": 5, // once every 5 seconds
|
|
||||||
"tooltip": true,
|
|
||||||
"max-length": 1000,
|
|
||||||
},
|
|
||||||
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
// --// waybar config generated by wbarconfgen.sh //-- //
|
|
||||||
|
|
||||||
{
|
|
||||||
// sourced from header module //
|
|
||||||
|
|
||||||
"layer": "top",
|
|
||||||
"position": "${w_position}",
|
|
||||||
"mod": "dock",
|
|
||||||
"${hv_pos}": ${w_height},
|
|
||||||
"exclusive": true,
|
|
||||||
"passthrough": false,
|
|
||||||
"gtk-layer-shell": true,
|
|
||||||
"reload_style_on_change": true,
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
"idle_inhibitor": {
|
|
||||||
"format": "{icon}",
|
|
||||||
"rotate": ${r_deg},
|
|
||||||
"format-icons": {
|
|
||||||
"activated": "",
|
|
||||||
"deactivated": ""
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
"custom/keybindhint": {
|
|
||||||
"format": " ",
|
|
||||||
"rotate": ${r_deg},
|
|
||||||
"on-click": "keybinds_hint.sh"
|
|
||||||
},
|
|
||||||
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
"hyprland/language": {
|
|
||||||
"format": "{short} {variant}",
|
|
||||||
"rotate": ${r_deg},
|
|
||||||
"on-click": "keyboardswitch.sh",
|
|
||||||
},
|
|
||||||
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
"memory": {
|
|
||||||
"states": {
|
|
||||||
"c": 90, // critical
|
|
||||||
"h": 60, // high
|
|
||||||
"m": 30, // medium
|
|
||||||
},
|
|
||||||
"interval": 30,
|
|
||||||
"format": " {used}GB",
|
|
||||||
"rotate": ${r_deg},
|
|
||||||
"format-m": " {used}GB",
|
|
||||||
"format-h": " {used}GB",
|
|
||||||
"format-c": " {used}GB",
|
|
||||||
"format-alt": " {percentage}%",
|
|
||||||
"max-length": 10,
|
|
||||||
"tooltip": true,
|
|
||||||
"tooltip-format": " {percentage}%\n {used:0.1f}GB/{total:0.1f}GB"
|
|
||||||
},
|
|
||||||
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
"mpris": {
|
|
||||||
"format": "{player_icon} {dynamic}",
|
|
||||||
"rotate": ${r_deg},
|
|
||||||
"format-paused": "{status_icon} <i>{dynamic}</i>",
|
|
||||||
"player-icons": {
|
|
||||||
"default": "▶",
|
|
||||||
"mpv": "🎵"
|
|
||||||
},
|
|
||||||
"status-icons": {
|
|
||||||
"paused": ""
|
|
||||||
},
|
|
||||||
// "ignored-players": ["firefox"]
|
|
||||||
"max-length": 1000,
|
|
||||||
"interval": 1
|
|
||||||
},
|
|
||||||
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
"network": {
|
|
||||||
"tooltip": true,
|
|
||||||
"format-wifi": " ",
|
|
||||||
"rotate": ${r_deg},
|
|
||||||
"format-ethernet": " ",
|
|
||||||
"tooltip-format": "Network: <big><b>{essid}</b></big>\nSignal strength: <b>{signaldBm}dBm ({signalStrength}%)</b>\nFrequency: <b>{frequency}MHz</b>\nInterface: <b>{ifname}</b>\nIP: <b>{ipaddr}/{cidr}</b>\nGateway: <b>{gwaddr}</b>\nNetmask: <b>{netmask}</b>",
|
|
||||||
"format-linked": " {ifname} (No IP)",
|
|
||||||
"format-disconnected": " ",
|
|
||||||
"tooltip-format-disconnected": "Disconnected",
|
|
||||||
"format-alt": "<span foreground='#99ffdd'> {bandwidthDownBytes}</span> <span foreground='#ffcc66'> {bandwidthUpBytes}</span>",
|
|
||||||
"interval": 2
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1,29 +0,0 @@
|
|||||||
"custom/notifications": {
|
|
||||||
"format": "{icon} {}",
|
|
||||||
"rotate": ${r_deg},
|
|
||||||
"format-icons": {
|
|
||||||
"email-notification": "<span foreground='white'><sup></sup></span>",
|
|
||||||
"chat-notification": "<span foreground='white'><sup></sup></span>",
|
|
||||||
"warning-notification": "<span foreground='yellow'><sup></sup></span>",
|
|
||||||
"error-notification": "<span foreground='red'><sup></sup></span>",
|
|
||||||
"network-notification": "<span foreground='white'><sup></sup></span>",
|
|
||||||
"battery-notification": "<span foreground='white'><sup></sup></span>",
|
|
||||||
"update-notification": "<span foreground='white'><sup></sup></span>",
|
|
||||||
"music-notification": "<span foreground='white'><sup></sup></span>",
|
|
||||||
"volume-notification": "<span foreground='white'><sup></sup></span>",
|
|
||||||
"notification": "<span foreground='white'><sup></sup></span>",
|
|
||||||
"dnd": "",
|
|
||||||
"none": ""
|
|
||||||
},
|
|
||||||
"return-type": "json",
|
|
||||||
"exec-if": "which dunstctl",
|
|
||||||
"exec": "notifications.py",
|
|
||||||
"on-scroll-down": "sleep 0.1 && dunstctl history-pop",
|
|
||||||
"on-click": "dunstctl set-paused toggle",
|
|
||||||
"on-click-middle": "dunstctl history-clear",
|
|
||||||
"on-click-right": "dunstctl close-all",
|
|
||||||
"interval": 1,
|
|
||||||
"tooltip": true,
|
|
||||||
"escape": true
|
|
||||||
},
|
|
||||||
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
"custom/power": {
|
|
||||||
"format": "{}",
|
|
||||||
"rotate": ${r_deg},
|
|
||||||
"exec": "echo ; echo logout",
|
|
||||||
"on-click": "logoutlaunch.sh 2",
|
|
||||||
"on-click-right": "logoutlaunch.sh 1",
|
|
||||||
"interval" : 86400, // once every day
|
|
||||||
"tooltip": true
|
|
||||||
},
|
|
||||||
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
{
|
|
||||||
"privacy": {
|
|
||||||
"icon-size": 18,
|
|
||||||
"icon-spacing": 5,
|
|
||||||
"transition-duration": 250,
|
|
||||||
"modules": [
|
|
||||||
{
|
|
||||||
"type": "screenshare",
|
|
||||||
"tooltip": true,
|
|
||||||
"tooltip-icon-size": 24
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "audio-in",
|
|
||||||
"tooltip": true,
|
|
||||||
"tooltip-icon-size": 24
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,35 +0,0 @@
|
|||||||
"pulseaudio": {
|
|
||||||
"format": "{icon} {volume}",
|
|
||||||
"rotate": ${r_deg},
|
|
||||||
"format-muted": "婢",
|
|
||||||
"on-click": "pavucontrol -t 3",
|
|
||||||
"on-click-right": "volumecontrol.sh -s ''",
|
|
||||||
"on-click-middle": "volumecontrol.sh -o m",
|
|
||||||
"on-scroll-up": "volumecontrol.sh -o i",
|
|
||||||
"on-scroll-down": "volumecontrol.sh -o d",
|
|
||||||
"tooltip-format": "{icon} {desc} // {volume}%",
|
|
||||||
"scroll-step": 5,
|
|
||||||
"format-icons": {
|
|
||||||
"headphone": "",
|
|
||||||
"hands-free": "",
|
|
||||||
"headset": "",
|
|
||||||
"phone": "",
|
|
||||||
"portable": "",
|
|
||||||
"car": "",
|
|
||||||
"default": ["", "", ""]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
"pulseaudio#microphone": {
|
|
||||||
"format": "{format_source}",
|
|
||||||
"rotate": ${r_deg},
|
|
||||||
"format-source": "",
|
|
||||||
"format-source-muted": "",
|
|
||||||
"on-click": "pavucontrol -t 4",
|
|
||||||
"on-click-middle": "volumecontrol.sh -i m",
|
|
||||||
"on-scroll-up": "volumecontrol.sh -i i",
|
|
||||||
"on-scroll-down": "volumecontrol.sh -i d",
|
|
||||||
"tooltip-format": "{format_source} {source_desc} // {source_volume}%",
|
|
||||||
"scroll-step": 5
|
|
||||||
},
|
|
||||||
|
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
"custom/spotify": {
|
|
||||||
"exec": "mediaplayer.py --player spotify",
|
|
||||||
"format": " {}",
|
|
||||||
"rotate": ${r_deg},
|
|
||||||
"return-type": "json",
|
|
||||||
"on-click": "playerctl play-pause --player spotify",
|
|
||||||
"on-click-right": "playerctl next --player spotify",
|
|
||||||
"on-click-middle": "playerctl previous --player spotify",
|
|
||||||
"on-scroll-up": "volumecontrol.sh -p spotify i",
|
|
||||||
"on-scroll-down": "volumecontrol.sh -p spotify d",
|
|
||||||
"max-length": 25,
|
|
||||||
"escape": true,
|
|
||||||
"tooltip": true
|
|
||||||
},
|
|
||||||
|
|
||||||
@@ -1,151 +0,0 @@
|
|||||||
* {
|
|
||||||
border: none;
|
|
||||||
border-radius: 0px;
|
|
||||||
font-family: "JetBrainsMono Nerd Font";
|
|
||||||
font-weight: bold;
|
|
||||||
font-size: ${s_fontpx}px;
|
|
||||||
min-height: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
@import "theme.css";
|
|
||||||
|
|
||||||
window#waybar {
|
|
||||||
background: @bar-bg;
|
|
||||||
}
|
|
||||||
|
|
||||||
tooltip {
|
|
||||||
background: @main-bg;
|
|
||||||
color: @main-fg;
|
|
||||||
border-radius: ${t_radius}px;
|
|
||||||
border-width: 0px;
|
|
||||||
}
|
|
||||||
|
|
||||||
#workspaces button {
|
|
||||||
box-shadow: none;
|
|
||||||
text-shadow: none;
|
|
||||||
padding: 0px;
|
|
||||||
border-radius: ${w_radius}px;
|
|
||||||
margin-${x1}: ${w_margin}px;
|
|
||||||
margin-${x2}: ${w_margin}px;
|
|
||||||
margin-${x3}: 0px;
|
|
||||||
padding-${x3}: ${w_paddin}px;
|
|
||||||
padding-${x4}: ${w_paddin}px;
|
|
||||||
margin-${x4}: 0px;
|
|
||||||
color: @main-fg;
|
|
||||||
animation: ws_normal 20s ease-in-out 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
#workspaces button.active {
|
|
||||||
background: @wb-act-bg;
|
|
||||||
color: @wb-act-fg;
|
|
||||||
margin-${x3}: ${w_margin}px;
|
|
||||||
padding-${x3}: ${w_padact}px;
|
|
||||||
padding-${x4}: ${w_padact}px;
|
|
||||||
margin-${x4}: ${w_margin}px;
|
|
||||||
animation: ws_active 20s ease-in-out 1;
|
|
||||||
transition: all 0.4s cubic-bezier(.55,-0.68,.48,1.682);
|
|
||||||
}
|
|
||||||
|
|
||||||
#workspaces button:hover {
|
|
||||||
background: @wb-hvr-bg;
|
|
||||||
color: @wb-hvr-fg;
|
|
||||||
animation: ws_hover 20s ease-in-out 1;
|
|
||||||
transition: all 0.3s cubic-bezier(.55,-0.68,.48,1.682);
|
|
||||||
}
|
|
||||||
|
|
||||||
#taskbar button {
|
|
||||||
box-shadow: none;
|
|
||||||
text-shadow: none;
|
|
||||||
padding: 0px;
|
|
||||||
border-radius: ${w_radius}px;
|
|
||||||
margin-${x1}: ${w_margin}px;
|
|
||||||
margin-${x2}: ${w_margin}px;
|
|
||||||
margin-${x3}: 0px;
|
|
||||||
padding-${x3}: ${w_paddin}px;
|
|
||||||
padding-${x4}: ${w_paddin}px;
|
|
||||||
margin-${x4}: 0px;
|
|
||||||
color: @wb-color;
|
|
||||||
animation: tb_normal 20s ease-in-out 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
#taskbar button.active {
|
|
||||||
background: @wb-act-bg;
|
|
||||||
color: @wb-act-color;
|
|
||||||
margin-${x3}: ${w_margin}px;
|
|
||||||
padding-${x3}: ${w_padact}px;
|
|
||||||
padding-${x4}: ${w_padact}px;
|
|
||||||
margin-${x4}: ${w_margin}px;
|
|
||||||
animation: tb_active 20s ease-in-out 1;
|
|
||||||
transition: all 0.4s cubic-bezier(.55,-0.68,.48,1.682);
|
|
||||||
}
|
|
||||||
|
|
||||||
#taskbar button:hover {
|
|
||||||
background: @wb-hvr-bg;
|
|
||||||
color: @wb-hvr-color;
|
|
||||||
animation: tb_hover 20s ease-in-out 1;
|
|
||||||
transition: all 0.3s cubic-bezier(.55,-0.68,.48,1.682);
|
|
||||||
}
|
|
||||||
|
|
||||||
#tray menu * {
|
|
||||||
min-height: 16px
|
|
||||||
}
|
|
||||||
|
|
||||||
#tray menu separator {
|
|
||||||
min-height: 10px
|
|
||||||
}
|
|
||||||
|
|
||||||
${modules_ls}
|
|
||||||
#custom-l_end,
|
|
||||||
#custom-r_end,
|
|
||||||
#custom-sl_end,
|
|
||||||
#custom-sr_end,
|
|
||||||
#custom-rl_end,
|
|
||||||
#custom-rr_end {
|
|
||||||
color: @main-fg;
|
|
||||||
background: @main-bg;
|
|
||||||
opacity: 1;
|
|
||||||
margin: ${x1g_margin}px ${x2g_margin}px ${x3g_margin}px ${x4g_margin}px;
|
|
||||||
padding-${x3}: ${g_paddin}px;
|
|
||||||
padding-${x4}: ${g_paddin}px;
|
|
||||||
}
|
|
||||||
|
|
||||||
#workspaces,
|
|
||||||
#taskbar {
|
|
||||||
padding: 0px;
|
|
||||||
}
|
|
||||||
|
|
||||||
#custom-r_end {
|
|
||||||
border-radius: ${x1rb_radius}px ${x2rb_radius}px ${x3rb_radius}px ${x4rb_radius}px;
|
|
||||||
margin-${x4}: ${e_margin}px;
|
|
||||||
padding-${x4}: ${e_paddin}px;
|
|
||||||
}
|
|
||||||
|
|
||||||
#custom-l_end {
|
|
||||||
border-radius: ${x1lb_radius}px ${x2lb_radius}px ${x3lb_radius}px ${x4lb_radius}px;
|
|
||||||
margin-${x3}: ${e_margin}px;
|
|
||||||
padding-${x3}: ${e_paddin}px;
|
|
||||||
}
|
|
||||||
|
|
||||||
#custom-sr_end {
|
|
||||||
border-radius: 0px;
|
|
||||||
margin-${x4}: ${e_margin}px;
|
|
||||||
padding-${x4}: ${e_paddin}px;
|
|
||||||
}
|
|
||||||
|
|
||||||
#custom-sl_end {
|
|
||||||
border-radius: 0px;
|
|
||||||
margin-${x3}: ${e_margin}px;
|
|
||||||
padding-${x3}: ${e_paddin}px;
|
|
||||||
}
|
|
||||||
|
|
||||||
#custom-rr_end {
|
|
||||||
border-radius: ${x1rc_radius}px ${x2rc_radius}px ${x3rc_radius}px ${x4rc_radius}px;
|
|
||||||
margin-${x4}: ${e_margin}px;
|
|
||||||
padding-${x4}: ${e_paddin}px;
|
|
||||||
}
|
|
||||||
|
|
||||||
#custom-rl_end {
|
|
||||||
border-radius: ${x1lc_radius}px ${x2lc_radius}px ${x3lc_radius}px ${x4lc_radius}px;
|
|
||||||
margin-${x3}: ${e_margin}px;
|
|
||||||
padding-${x3}: ${e_paddin}px;
|
|
||||||
}
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
"wlr/taskbar": {
|
|
||||||
"format": "{icon}",
|
|
||||||
"rotate": ${r_deg},
|
|
||||||
"icon-size": ${i_task},
|
|
||||||
"icon-theme": "${i_theme}",
|
|
||||||
"spacing": 0,
|
|
||||||
"tooltip-format": "{title}",
|
|
||||||
"on-click": "activate",
|
|
||||||
"on-click-middle": "close",
|
|
||||||
"ignore-list": [
|
|
||||||
"Alacritty"
|
|
||||||
],
|
|
||||||
"app_ids-mapping": {
|
|
||||||
"firefoxdeveloperedition": "firefox-developer-edition"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
"custom/theme": {
|
|
||||||
"format": "{}",
|
|
||||||
"rotate": ${r_deg},
|
|
||||||
"exec": "echo ; echo switch theme",
|
|
||||||
"on-click": "themeswitch.sh -n",
|
|
||||||
"on-click-right": "themeswitch.sh -p",
|
|
||||||
"on-click-middle": "sleep 0.1 && themeselect.sh",
|
|
||||||
"interval" : 86400, // once every day
|
|
||||||
"tooltip": true
|
|
||||||
},
|
|
||||||
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
"tray": {
|
|
||||||
"icon-size": ${i_size},
|
|
||||||
"rotate": ${r_deg},
|
|
||||||
"spacing": 5
|
|
||||||
},
|
|
||||||
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
"custom/updates": {
|
|
||||||
"exec": "systemupdate.sh",
|
|
||||||
"return-type": "json",
|
|
||||||
"format": "{}",
|
|
||||||
"rotate": ${r_deg},
|
|
||||||
"on-click": "hyprctl dispatch exec 'systemupdate.sh up'",
|
|
||||||
"interval": 86400, // once every day
|
|
||||||
"tooltip": true,
|
|
||||||
"signal": 20
|
|
||||||
},
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
"custom/wallchange": {
|
|
||||||
"format": "{}",
|
|
||||||
"rotate": ${r_deg},
|
|
||||||
"exec": "echo ; echo switch wallpaper",
|
|
||||||
"on-click": "swwwallpaper.sh -n",
|
|
||||||
"on-click-right": "swwwallpaper.sh -p",
|
|
||||||
"on-click-middle": "sleep 0.1 && swwwallselect.sh",
|
|
||||||
"interval" : 86400, // once every day
|
|
||||||
"tooltip": true
|
|
||||||
},
|
|
||||||
|
|
||||||
@@ -1,35 +0,0 @@
|
|||||||
{
|
|
||||||
"hyprland/window": {
|
|
||||||
"format": " {}",
|
|
||||||
"rotate": 0,
|
|
||||||
"separate-outputs": true,
|
|
||||||
"max-length": 1000,
|
|
||||||
"rewrite": {
|
|
||||||
"(.*) — Kitty": " $1",
|
|
||||||
"(.*)~": " $1",
|
|
||||||
"(.*) — Mozilla Firefox": " $1",
|
|
||||||
"(.*)Mozilla Firefox": " Firefox",
|
|
||||||
"(.*) — LibreWolf": " $1",
|
|
||||||
"(.*)LibreWolf": " LibreWolf",
|
|
||||||
"(.*) — Chromium": " $1",
|
|
||||||
"(.*)Chromium": " Chromium",
|
|
||||||
"(.*) - VSCodium": " $1",
|
|
||||||
"(.*)VSCodium": " VSCodium",
|
|
||||||
"(.*)Code - OSS": " $1",
|
|
||||||
"(.*) - Visual Studio Code": " $1",
|
|
||||||
"(.*)Visual Studio Code": " Code",
|
|
||||||
"(.*) — Dolphin": " $1",
|
|
||||||
"(.*) - Obsidian(.*)": " $1",
|
|
||||||
"(.*)Ferdium": " Ferdium",
|
|
||||||
"(.*)FreeTube": " FreeTube",
|
|
||||||
"(.*)Freetube": " FreeTube",
|
|
||||||
"(.*) - VLC media player": " $1",
|
|
||||||
"(.*)Steam": " Steam",
|
|
||||||
"(.*)Neovide": " Nvim",
|
|
||||||
"(.*)Gajim": " Gajim",
|
|
||||||
"(.*)KeePassXC": " KeePassXC",
|
|
||||||
"(.*)Betterbird": " Betterbird",
|
|
||||||
"(.*)Spotify": " Spotify"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
"hyprland/workspaces": {
|
|
||||||
"disable-scroll": true,
|
|
||||||
"rotate": ${r_deg},
|
|
||||||
"all-outputs": true,
|
|
||||||
"active-only": false,
|
|
||||||
"on-click": "activate",
|
|
||||||
"disable-scroll": false,
|
|
||||||
"on-scroll-up": "hyprctl dispatch workspace -1",
|
|
||||||
"on-scroll-down": "hyprctl dispatch workspace +1",
|
|
||||||
"persistent-workspaces": {
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
/* Fallback wallbash palette for the custom waybar rig (Catppuccin Mocha, copied from wm's
|
||||||
|
* live ~/.config/waybar/theme.css 2026-08-17). layouts/custom.css does `@import
|
||||||
|
* "../theme.css"` and a missing import target kills waybar outright — on themed hosts
|
||||||
|
* HyDE/wallbash generates and keeps overwriting that file, but a host where wallbash never
|
||||||
|
* ran (or where the pre-2026-08-14 stow link dangles) has nothing there. install.sh seeds
|
||||||
|
* ~/.config/waybar/theme.css from this copy only when the file is absent; it never
|
||||||
|
* overwrites a generator-owned one. Deliberately NOT stowed as theme.css itself: wallbash
|
||||||
|
* would then write through the symlink into the repo on every wallpaper change. */
|
||||||
|
@define-color bar-bg rgba(0, 0, 0, 0.1);
|
||||||
|
|
||||||
|
@define-color main-bg #11111b;
|
||||||
|
@define-color main-fg #cdd6f4;
|
||||||
|
|
||||||
|
@define-color wb-act-bg #a6adc8;
|
||||||
|
@define-color wb-act-fg #313244;
|
||||||
|
|
||||||
|
@define-color wb-hvr-bg #f5c2e7;
|
||||||
|
@define-color wb-hvr-fg #313244;
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
@define-color bar-bg rgba(0, 0, 0, 0.1);
|
|
||||||
|
|
||||||
@define-color main-bg rgba(0, 0, 0, 0.1);
|
|
||||||
@define-color main-fg #cdd6f4;
|
|
||||||
|
|
||||||
@define-color wb-act-bg #a6adc8;
|
|
||||||
@define-color wb-act-fg #313244;
|
|
||||||
|
|
||||||
@define-color wb-hvr-bg #f5c2e7;
|
|
||||||
@define-color wb-hvr-fg #313244;
|
|
||||||
Executable
+21
@@ -0,0 +1,21 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
# enable float
|
||||||
|
WinFloat=$(hyprctl -j clients | jq '.[] | select(.focusHistoryID == 0) | .floating')
|
||||||
|
WinPinned=$(hyprctl -j clients | jq '.[] | select(.focusHistoryID == 0) | .pinned')
|
||||||
|
|
||||||
|
if [ "${WinFloat}" == "false" ] && [ "${WinPinned}" == "false" ] ; then
|
||||||
|
hyprctl dispatch togglefloating active
|
||||||
|
fi
|
||||||
|
|
||||||
|
# toggle pin
|
||||||
|
hyprctl dispatch pin active
|
||||||
|
|
||||||
|
# disable float
|
||||||
|
WinFloat=$(hyprctl -j clients | jq '.[] | select(.focusHistoryID == 0) | .floating')
|
||||||
|
WinPinned=$(hyprctl -j clients | jq '.[] | select(.focusHistoryID == 0) | .pinned')
|
||||||
|
|
||||||
|
if [ "${WinFloat}" == "true" ] && [ "${WinPinned}" == "false" ] ; then
|
||||||
|
hyprctl dispatch togglefloating active
|
||||||
|
fi
|
||||||
|
|
||||||
@@ -0,0 +1,133 @@
|
|||||||
|
#! ░▒▒▒░░░▓▓ ___________
|
||||||
|
#! ░░▒▒▒░░░░░▓▓ //___________/
|
||||||
|
#! ░░▒▒▒░░░░░▓▓ _ _ _ _ _____
|
||||||
|
#! ░░▒▒░░░░░▓▓▓▓▓▓ | | | | | | | __/
|
||||||
|
#! ░▒▒░░░░▓▓ ▓▓ | |_| | |_/ /| |___
|
||||||
|
#! ░▒▒░░▓▓ ▓▓ \__ |____/ |____/ █░█ ▄▀█ █▀█ █ ▄▀█ █▄▄ █░░ █▀▀ █▀
|
||||||
|
#! ░▒▓▓ ▓▓ //____/ ▀▄▀ █▀█ █▀▄ █ █▀█ █▄█ █▄▄ ██▄ ▄█
|
||||||
|
|
||||||
|
# Override configuration for user environment variables and startup commands
|
||||||
|
# Static variables here take priority over default and dynamic configurations
|
||||||
|
|
||||||
|
# NOTE
|
||||||
|
# Leaving the variable empty will unset the variable
|
||||||
|
# Commenting out the variable will use the default value
|
||||||
|
# For updated configuration options, see https://github.com/HyDE-Project/HyDE/blob/master/Configs/.config/hypr/hyde.conf
|
||||||
|
# For simplicity, ./hyde.conf ONLY accepts $ for variables and # for comments, will sanitize the file to remove any other characters
|
||||||
|
# $start.VAR , $env.VAR are ONLY HyDE specific conventions for consistency.
|
||||||
|
|
||||||
|
# Keyboard modifier
|
||||||
|
$mainMod = SUPER # windows key
|
||||||
|
|
||||||
|
# ▄▀█ █▀█ █▀█ █▀
|
||||||
|
# █▀█ █▀▀ █▀▀ ▄█
|
||||||
|
|
||||||
|
$QUICKAPPS = # used for quick app launcher
|
||||||
|
$BROWSER = firefox # default browser, if commented out , will use the default browser
|
||||||
|
$EDITOR = code # default editor, if commented out , will use the default editor
|
||||||
|
$EXPLORER= dolphin # default file manager, if commented out , will use the default file manager
|
||||||
|
$TERMINAL = kitty # default terminal, if commented out , will use the org.gnome.desktop.default-applications.terminal
|
||||||
|
$LOCKSCREEN=hyprlock # default lockscreen, you can use any lockscreen you want, eg swaylock
|
||||||
|
$IDLE=hypridle # default idle manager, you can use any idle manager you want,eg swayidle
|
||||||
|
|
||||||
|
# // █░░ ▄▀█ █░█ █▄░█ █▀▀ █░█
|
||||||
|
# // █▄▄ █▀█ █▄█ █░▀█ █▄▄ █▀█
|
||||||
|
# See https://wiki.hyprland.org/Configuring/Keywords/
|
||||||
|
# Override the default startup commands
|
||||||
|
|
||||||
|
# This is used to override the default startup commands
|
||||||
|
# $start.VAR = command
|
||||||
|
|
||||||
|
$start.XDG_PORTAL_RESET=$scrPath/resetxdgportal.sh
|
||||||
|
$start.DBUS_SHARE_PICKER=dbus-update-activation-environment --systemd --all # for XDPH
|
||||||
|
$start.SYSTEMD_SHARE_PICKER=systemctl --user import-environment QT_QPA_PLATFORMTHEME WAYLAND_DISPLAY XDG_CURRENT_DESKTOP # for XDPH
|
||||||
|
$start.BAR=waybar
|
||||||
|
$start.NOTIFICATIONS=swaync # dunst
|
||||||
|
$start.APPTRAY_BLUETOOTH=blueman-applet
|
||||||
|
$start.WALLPAPER=$scrPath/swwwallpaper.sh
|
||||||
|
$start.TEXT_CLIPBOARD=wl-paste --type text --watch cliphist store
|
||||||
|
$start.IMAGE_CLIPBOARD=wl-paste --type image --watch cliphist store
|
||||||
|
$start.BATTERY_NOTIFY=$scrPath/batterynotify.sh
|
||||||
|
$start.NETWORK_MANAGER=nm-applet --indicator
|
||||||
|
$start.REMOVABLE_MEDIA=udiskie --no-automount --smart-tray
|
||||||
|
$start.AUTH_DIALOGUE=$scrPath/polkitkdeauth.sh
|
||||||
|
$start.IDLE_DAEMON=$IDLE
|
||||||
|
|
||||||
|
# // █▀▀ █▄░█ █░█
|
||||||
|
# // ██▄ █░▀█ ▀▄▀
|
||||||
|
|
||||||
|
# See https://wiki.hyprland.org/Configuring/Environment-variables/
|
||||||
|
# Override the default environment variables
|
||||||
|
|
||||||
|
# This is used to override the default environment variables
|
||||||
|
# $env.VAR = value
|
||||||
|
|
||||||
|
# Toolkit Backend Variables - https://wiki.hyprland.org/Configuring/Environment-variables/#toolkit-backend-variables
|
||||||
|
$env.GDK_BACKEND = wayland,x11,* #s GTK: Use wayland if available. If not: try x11, then any other GDK backend.
|
||||||
|
$env.QT_QPA_PLATFORM = wayland
|
||||||
|
xcb #Qt: Use wayland if available, fall back to x11 if not.
|
||||||
|
$env.SDL_VIDEODRIVER = wayland # Run SDL2 applications on Wayland. Remove or set to x11 if games that provide older versions of SDL cause compatibility issues
|
||||||
|
$env.CLUTTER_BACKEND = wayland # Clutter package already has wayland enabled, this variable will force Clutter applications to try and use the Wayland backend
|
||||||
|
|
||||||
|
# XDG Specifications - https://wiki.hyprland.org/Configuring/Environment-variables/#xdg-specifications
|
||||||
|
$env.XDG_CURRENT_DESKTOP = Hyprland
|
||||||
|
$env.XDG_SESSION_TYPE = wayland
|
||||||
|
$env.XDG_SESSION_DESKTOP = Hyprland
|
||||||
|
|
||||||
|
# Qt Variables - https://wiki.hyprland.org/Configuring/Environment-variables/#qt-variables
|
||||||
|
|
||||||
|
$env.QT_AUTO_SCREEN_SCALE_FACTOR = 1 # (From the Qt documentation) enables automatic scaling, based on the monitor’s pixel density
|
||||||
|
$env.QT_QPA_PLATFORM=wayland
|
||||||
|
xcb # Tell Qt applications to use the Wayland backend, and fall back to x11 if Wayland is unavailable
|
||||||
|
$env.QT_WAYLAND_DISABLE_WINDOWDECORATION = 1 # Disables window decorations on Qt applications
|
||||||
|
$env.QT_QPA_PLATFORMTHEME = qt6ct # Tells Qt based applications to pick your theme from qt5ct, use with Kvantum.
|
||||||
|
|
||||||
|
# HyDE Environment Variables -
|
||||||
|
|
||||||
|
$env.PATH =
|
||||||
|
$env.MOZ_ENABLE_WAYLAND=1 # Enable Wayland for Firefox
|
||||||
|
$env.GDK_SCALE=1 # Set GDK scale to 1 // For Xwayland on HiDPI
|
||||||
|
$env.ELECTRON_OZONE_PLATFORM_HINT=auto # Set Electron Ozone Platform Hint to auto // For Electron apps on Wayland
|
||||||
|
|
||||||
|
# # XDG-DIRS
|
||||||
|
|
||||||
|
$env.XDG_RUNTIME_DIR=$XDG_RUNTIME_DIR
|
||||||
|
$env.XDG_CONFIG_HOME=$HOME/.config
|
||||||
|
$env.XDG_CACHE_HOME=$HOME/.cache
|
||||||
|
$env.XDG_DATA_HOME=$HOME/.local/share
|
||||||
|
|
||||||
|
# These variable will override the default and the theme configuration
|
||||||
|
# Do not uncomment the variables if you want want HyDE do the theme configuration for you
|
||||||
|
|
||||||
|
# // █▀▀ ▀█▀ █▄▀
|
||||||
|
# // █▄█ ░█░ █░█
|
||||||
|
|
||||||
|
$GTK_THEME=Wallbash-Gtk
|
||||||
|
$ICON_THEME=Tela-circle-dracula
|
||||||
|
$COLOR_SCHEME=prefer-dark
|
||||||
|
|
||||||
|
# // █▀▀ █░█ █▀█ █▀ █▀█ █▀█
|
||||||
|
# // █▄▄ █▄█ █▀▄ ▄█ █▄█ █▀▄
|
||||||
|
|
||||||
|
$CURSOR_THEME=Bibata-Modern-Ice
|
||||||
|
$CURSOR_SIZE=30
|
||||||
|
|
||||||
|
# // █▀▀ █▀█ █▄░█ ▀█▀
|
||||||
|
# // █▀░ █▄█ █░▀█ ░█░
|
||||||
|
|
||||||
|
$FONT=Canterell
|
||||||
|
$FONT_SIZE=10
|
||||||
|
$DOCUMENT_FONT=Cantarell
|
||||||
|
$DOCUMENT_FONT_SIZE=10
|
||||||
|
$MONOSPACE_FONT=CaskaydiaCove Nerd Font Mono
|
||||||
|
$MONOSPACE_FONT_SIZE=9
|
||||||
|
$FONT_ANTIALIASING=rgba
|
||||||
|
$FONT_HINTING=full
|
||||||
|
|
||||||
|
# // █░░ █▀█ █▀▀ █▄▀ █▀ █▀▀ █▀█ █▀▀ █▀▀ █▄░█
|
||||||
|
# // █▄▄ █▄█ █▄▄ █░█ ▄█ █▄▄ █▀▄ ██▄ ██▄ █░▀█
|
||||||
|
|
||||||
|
#Setting the Hyprlock layout will override any layout set in the ./hypr/hyprlock.sh
|
||||||
|
# Dynamic Hyprlock layout should be set in the ./hypr/hyprlock.sh file
|
||||||
|
# $LAYOUT_PATH=/path/to/hyprlock/layout.conf
|
||||||
|
# $BACKGROUND_PATH=$HYPRLOCK_BACKGROUND # set the background to the specific hyprlock wallpaper
|
||||||
@@ -0,0 +1,577 @@
|
|||||||
|
# ░▒▒▒░░░▓▓ ___________
|
||||||
|
# ░░▒▒▒░░░░░▓▓ //___________/
|
||||||
|
# ░░▒▒▒░░░░░▓▓ _ _ _ _ _____
|
||||||
|
# ░░▒▒░░░░░▓▓▓▓▓▓ | | | | | | | __/
|
||||||
|
# ░▒▒░░░░▓▓ ▓▓ | |_| | |_/ /| |___
|
||||||
|
# ░▒▒░░▓▓ ▓▓ \__ |____/ |____/
|
||||||
|
# ░▒▓▓ ▓▓ //____/
|
||||||
|
|
||||||
|
# // █░█ █▄█ █▀▄ █▀▀
|
||||||
|
# // █▀█ ░█░ █▄▀ ██▄
|
||||||
|
|
||||||
|
$scrPath=$HOME/.local/lib/hyde # set scripts path
|
||||||
|
|
||||||
|
# Main modifier
|
||||||
|
$mainMod = SUPER # windows key
|
||||||
|
# assign apps
|
||||||
|
|
||||||
|
$default.$QUICKAPPS =
|
||||||
|
$default.BROWSER = hyde-launch.sh --fall firefox web-browser
|
||||||
|
$default.EDITOR = hyde-launch.sh --fall code-oss text-editor
|
||||||
|
$default.EXPLORER= hyde-launch.sh --fall dolphin file-manager
|
||||||
|
$default.TERMINAL = kitty
|
||||||
|
$default.LOCKSCREEN=hyprlock
|
||||||
|
$default.IDLE=hypridle
|
||||||
|
|
||||||
|
$QUICKAPPS = $default.$QUICKAPPS
|
||||||
|
$BROWSER = $default.BROWSER
|
||||||
|
$EDITOR = $default.EDITOR
|
||||||
|
$EXPLORER= $default.EXPLORER
|
||||||
|
$TERMINAL = $default.TERMINAL
|
||||||
|
$LOCKSCREEN=$default.LOCKSCREEN
|
||||||
|
$IDLE= $default.IDLE
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# // █░░ ▄▀█ █░█ █▄░█ █▀▀ █░█
|
||||||
|
# // █▄▄ █▀█ █▄█ █░▀█ █▄▄ █▀█
|
||||||
|
|
||||||
|
# See https://wiki.hyprland.org/Configuring/Keywords/
|
||||||
|
|
||||||
|
$start.XDG_PORTAL_RESET=$scrPath/resetxdgportal.sh
|
||||||
|
$start.DBUS_SHARE_PICKER=dbus-update-activation-environment --systemd --all # for XDPH
|
||||||
|
$start.SYSTEMD_SHARE_PICKER=systemctl --user import-environment QT_QPA_PLATFORMTHEME WAYLAND_DISPLAY XDG_CURRENT_DESKTOP # for XDPH
|
||||||
|
$start.BAR=waybar
|
||||||
|
$start.NOTIFICATIONS=dunst
|
||||||
|
$start.APPTRAY_BLUETOOTH=blueman-applet
|
||||||
|
$start.WALLPAPER=$scrPath/wallpaper.sh --global
|
||||||
|
$start.TEXT_CLIPBOARD=wl-paste --type text --watch cliphist store
|
||||||
|
$start.IMAGE_CLIPBOARD=wl-paste --type image --watch cliphist store
|
||||||
|
$start.BATTERY_NOTIFY=$scrPath/batterynotify.sh
|
||||||
|
$start.NETWORK_MANAGER=nm-applet --indicator
|
||||||
|
$start.REMOVABLE_MEDIA=udiskie --no-automount --smart-tray
|
||||||
|
$start.AUTH_DIALOGUE=$scrPath/polkitkdeauth.sh
|
||||||
|
$start.IDLE_DAEMON=$IDLE
|
||||||
|
|
||||||
|
# // █▀▀ █▄░█ █░█
|
||||||
|
# // ██▄ █░▀█ ▀▄▀
|
||||||
|
|
||||||
|
# See https://wiki.hyprland.org/Configuring/Environment-variables/
|
||||||
|
|
||||||
|
# Toolkit Backend Variables - https://wiki.hyprland.org/Configuring/Environment-variables/#toolkit-backend-variables
|
||||||
|
$env.GDK_BACKEND = wayland,x11,* # GTK: Use wayland if available. If not: try x11, then any other GDK backend.
|
||||||
|
# $env.QT_QPA_PLATFORM = wayland;xcb # Qt: Use wayland if available, fall back to x11 if not.
|
||||||
|
$env.SDL_VIDEODRIVER = wayland # Run SDL2 applications on Wayland. Remove or set to x11 if games that provide older versions of SDL cause compatibility issues
|
||||||
|
$env.CLUTTER_BACKEND = wayland # Clutter package already has wayland enabled, this variable will force Clutter applications to try and use the Wayland backend
|
||||||
|
|
||||||
|
# XDG Specifications - https://wiki.hyprland.org/Configuring/Environment-variables/#xdg-specifications
|
||||||
|
$env.XDG_CURRENT_DESKTOP = Hyprland
|
||||||
|
$env.XDG_SESSION_TYPE = wayland
|
||||||
|
$env.XDG_SESSION_DESKTOP = Hyprland
|
||||||
|
|
||||||
|
# Qt Variables - https://wiki.hyprland.org/Configuring/Environment-variables/#qt-variables
|
||||||
|
|
||||||
|
$env.QT_AUTO_SCREEN_SCALE_FACTOR = 1 # (From the Qt documentation) enables automatic scaling, based on the monitor’s pixel density
|
||||||
|
$env.QT_QPA_PLATFORM = wayland;xcb # Tell Qt applications to use the Wayland backend, and fall back to x11 if Wayland is unavailable
|
||||||
|
$env.QT_WAYLAND_DISABLE_WINDOWDECORATION = 1 # Disables window decorations on Qt applications
|
||||||
|
$env.QT_QPA_PLATFORMTHEME = qt6ct # Tells Qt based applications to pick your theme from qt5ct, use with Kvantum.
|
||||||
|
|
||||||
|
|
||||||
|
# HyDE Environment Variables -
|
||||||
|
|
||||||
|
$env.PATH =
|
||||||
|
$env.MOZ_ENABLE_WAYLAND=1 # Enable Wayland for Firefox
|
||||||
|
$env.GDK_SCALE=1 # Set GDK scale to 1 // For Xwayland on HiDPI
|
||||||
|
$env.ELECTRON_OZONE_PLATFORM_HINT=auto # Set Electron Ozone Platform Hint to auto // For Electron apps on Wayland
|
||||||
|
|
||||||
|
# XDG-DIRS
|
||||||
|
# $XDG_RUNTIME_DIR=${XDG_RUNTIME_DIR:-/run/user/$(id -u)}
|
||||||
|
# $XDG_CONFIG_HOME=${XDG_CONFIG_HOME:-$HOME/.config}
|
||||||
|
# >> $env.XDG_CACHE_HOME=${XDG_CACHE_HOME:-$HOME/.cache}
|
||||||
|
# $XDG_DATA_HOME=${XDG_DATA_HOME:-$HOME/.local/share}
|
||||||
|
|
||||||
|
$env.XDG_RUNTIME_DIR=$XDG_RUNTIME_DIR
|
||||||
|
$env.XDG_CONFIG_HOME=$HOME/.config
|
||||||
|
$env.XDG_CACHE_HOME=$HOME/.cache
|
||||||
|
$env.XDG_DATA_HOME=$HOME/.local/share
|
||||||
|
$env.XDG_STATE_HOME=$HOME/.local/state
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# // █▀▀ ▀█▀ █▄▀
|
||||||
|
# // █▄█ ░█░ █░█
|
||||||
|
|
||||||
|
$default.GTK_THEME=Wallbash-Gtk
|
||||||
|
$default.ICON_THEME=Tela-circle-dracula
|
||||||
|
$default.COLOR_SCHEME=prefer-dark
|
||||||
|
|
||||||
|
$GTK_THEME=$default.GTK_THEME
|
||||||
|
$ICON_THEME=$default.ICON_THEME
|
||||||
|
$COLOR_SCHEME=$default.COLOR_SCHEME
|
||||||
|
|
||||||
|
# // █▀▀ █░█ █▀█ █▀ █▀█ █▀█
|
||||||
|
# // █▄▄ █▄█ █▀▄ ▄█ █▄█ █▀▄
|
||||||
|
|
||||||
|
$default.CURSOR_THEME=Bibata-Modern-Ice
|
||||||
|
$default.CURSOR_SIZE=24
|
||||||
|
|
||||||
|
$CURSOR_THEME=$default.CURSOR_THEME
|
||||||
|
$CURSOR_SIZE=$default.CURSOR_SIZE
|
||||||
|
|
||||||
|
# // █▀▀ █▀█ █▄░█ ▀█▀
|
||||||
|
# // █▀░ █▄█ █░▀█ ░█░
|
||||||
|
|
||||||
|
$default.FONT=Cantarell
|
||||||
|
$default.FONT_SIZE=10
|
||||||
|
$default.DOCUMENT_FONT=Cantarell
|
||||||
|
$default.DOCUMENT_FONT_SIZE=10
|
||||||
|
$default.MONOSPACE_FONT=CaskaydiaCove Nerd Font Mono
|
||||||
|
$default.MONOSPACE_FONT_SIZE=9
|
||||||
|
$default.NOTIFICATION_FONT=Mononoki Nerd Font Mono
|
||||||
|
$default.BAR_FONT=JetBrainsMono Nerd Font
|
||||||
|
# $default.MENU_FONT=This is not yet set as it looks perfect with the global font
|
||||||
|
$default.FONT_ANTIALIASING=rgba
|
||||||
|
$default.FONT_HINTING=full
|
||||||
|
|
||||||
|
$FONT=$default.FONT
|
||||||
|
$FONT_SIZE=$default.FONT_SIZE
|
||||||
|
$DOCUMENT_FONT=$default.DOCUMENT_FONT
|
||||||
|
$DOCUMENT_FONT_SIZE=$default.DOCUMENT_FONT_SIZE
|
||||||
|
$MONOSPACE_FONT=$default.MONOSPACE_FONT
|
||||||
|
$MONOSPACE_FONT_SIZE=$default.MONOSPACE_FONT_SIZE
|
||||||
|
$NOTIFICATION_FONT=$default.NOTIFICATION_FONT
|
||||||
|
$BAR_FONT=$default.BAR_FONT
|
||||||
|
# $MENU_FONT=$default.MENU_FONT
|
||||||
|
$FONT_ANTIALIASING=$default.FONT_ANTIALIASING
|
||||||
|
$FONT_HINTING=$default.FONT_HINTING
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# // █▀ █▀█ █▀▀ █▀▀ █ ▄▀█ █░░
|
||||||
|
# // ▄█ █▀▀ ██▄ █▄▄ █ █▀█ █▄▄
|
||||||
|
|
||||||
|
decoration {
|
||||||
|
dim_special = 0.3
|
||||||
|
active_opacity = 0.90
|
||||||
|
inactive_opacity = 0.75
|
||||||
|
fullscreen_opacity = 1
|
||||||
|
blur {
|
||||||
|
special = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# // █▀▄▀█ █▀█ █▄░█ █ ▀█▀ █▀█ █▀█
|
||||||
|
# // █░▀░█ █▄█ █░▀█ █ ░█░ █▄█ █▀▄
|
||||||
|
|
||||||
|
# See https://wiki.hyprland.org/Configuring/Monitors/
|
||||||
|
|
||||||
|
monitor = ,preferred,auto,auto
|
||||||
|
|
||||||
|
# // █ █▄░█ █▀█ █░█ ▀█▀
|
||||||
|
# // █ █░▀█ █▀▀ █▄█ ░█░
|
||||||
|
|
||||||
|
# See https://wiki.hyprland.org/Configuring/Variables/
|
||||||
|
|
||||||
|
input {
|
||||||
|
kb_layout = us
|
||||||
|
follow_mouse = 1
|
||||||
|
|
||||||
|
touchpad {
|
||||||
|
natural_scroll = no
|
||||||
|
}
|
||||||
|
|
||||||
|
sensitivity = 0
|
||||||
|
force_no_accel = 1
|
||||||
|
numlock_by_default = true
|
||||||
|
}
|
||||||
|
|
||||||
|
# See https://wiki.hyprland.org/Configuring/Variables/
|
||||||
|
|
||||||
|
# gestures {
|
||||||
|
# workspace_swipe = true
|
||||||
|
# workspace_swipe_fingers = 3
|
||||||
|
# }
|
||||||
|
|
||||||
|
|
||||||
|
# // █░░ ▄▀█ █▄█ █▀█ █░█ ▀█▀ █▀
|
||||||
|
# // █▄▄ █▀█ ░█░ █▄█ █▄█ ░█░ ▄█
|
||||||
|
|
||||||
|
# See https://wiki.hyprland.org/Configuring/Dwindle-Layout/
|
||||||
|
|
||||||
|
dwindle {
|
||||||
|
# pseudotile = yes
|
||||||
|
preserve_split = yes
|
||||||
|
}
|
||||||
|
|
||||||
|
# See https://wiki.hyprland.org/Configuring/Master-Layout/
|
||||||
|
|
||||||
|
master {
|
||||||
|
new_status = master
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# // █▀▄▀█ █ █▀ █▀▀
|
||||||
|
# // █░▀░█ █ ▄█ █▄▄
|
||||||
|
|
||||||
|
# See https://wiki.hyprland.org/Configuring/Variables/
|
||||||
|
|
||||||
|
misc {
|
||||||
|
vrr = 0
|
||||||
|
disable_hyprland_logo = true
|
||||||
|
disable_splash_rendering = true
|
||||||
|
force_default_wallpaper = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
xwayland {
|
||||||
|
force_zero_scaling = true
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# // ▄▀█ █▄░█ █ █▀▄▀█ ▄▀█ ▀█▀ █ █▀█ █▄░█
|
||||||
|
# // █▀█ █░▀█ █ █░▀░█ █▀█ ░█░ █ █▄█ █░▀█
|
||||||
|
|
||||||
|
# See https://wiki.hyprland.org/Configuring/Animations/
|
||||||
|
|
||||||
|
animations {
|
||||||
|
enabled = yes
|
||||||
|
bezier = wind, 0.05, 0.9, 0.1, 1.05
|
||||||
|
bezier = winIn, 0.1, 1.1, 0.1, 1.1
|
||||||
|
bezier = winOut, 0.3, -0.3, 0, 1
|
||||||
|
bezier = liner, 1, 1, 1, 1
|
||||||
|
animation = windows, 1, 6, wind, slide
|
||||||
|
animation = windowsIn, 1, 6, winIn, slide
|
||||||
|
animation = windowsOut, 1, 5, winOut, slide
|
||||||
|
animation = windowsMove, 1, 5, wind, slide
|
||||||
|
animation = border, 1, 1, liner
|
||||||
|
animation = borderangle, 1, 30, liner, once
|
||||||
|
animation = fade, 1, 10, default
|
||||||
|
animation = workspaces, 1, 5, wind
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
general {
|
||||||
|
snap { # snapping for floating windows
|
||||||
|
enabled = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# // █▀ █▀█ █░█ █▀█ █▀▀ █▀▀
|
||||||
|
# // ▄█ █▄█ █▄█ █▀▄ █▄▄ ██▄
|
||||||
|
|
||||||
|
# hyprlang noerror true
|
||||||
|
# source = $env.XDG_STATE_HOME/hyde/hyprgui.conf # GUI specific config. Used to not break the low level configs. this will be available downstream
|
||||||
|
source = $env.XDG_CONFIG_HOME/hypr/themes/colors.conf # Hyde wallbash colors
|
||||||
|
|
||||||
|
# Source groupbar in here
|
||||||
|
group:groupbar {
|
||||||
|
col.inactive = rgba($wallbash_pry3ee)
|
||||||
|
col.active = rgba($wallbash_pry1ee)
|
||||||
|
col.locked_active = rgba($wallbash_pry2ee)
|
||||||
|
col.locked_inactive = rgba($wallbash_pry4ee)
|
||||||
|
}
|
||||||
|
|
||||||
|
source = $env.XDG_CONFIG_HOME/hypr/themes/theme.conf # theme specific settings
|
||||||
|
source = $env.XDG_CONFIG_HOME/hypr/themes/wallbash.conf # Theme specific settings after Sanitize and handle fallbacks
|
||||||
|
source = $env.XDG_CONFIG_HOME/hypr/nvidia.conf # Nvidia specific settings
|
||||||
|
source = $env.XDG_CONFIG_HOME/hypr/animations.conf # source animations variables
|
||||||
|
# hyprlang noerror false
|
||||||
|
source = $env.XDG_CONFIG_HOME/hypr/hyde.conf
|
||||||
|
# hyprlang noerror true
|
||||||
|
source = $env.XDG_STATE_HOME/hyde/hyprland.conf # translated from config.tomls
|
||||||
|
source = $ANIMATION_PATH # source animations configuration
|
||||||
|
# hyprlang noerror false
|
||||||
|
|
||||||
|
#! Below this is an immutable part of the configuration file, and should not be modified by the user.
|
||||||
|
|
||||||
|
#? By Hyprland convention env and startup files are sourced at the end of the main configuration file
|
||||||
|
#? To ensure that the user's settings are not overridden by the default settings
|
||||||
|
#? This will let us launch after all envs and variables are set.
|
||||||
|
|
||||||
|
# LEGACY
|
||||||
|
$quickapps = $QUICKAPPS
|
||||||
|
$term = $TERMINAL
|
||||||
|
$editor = $EDITOR
|
||||||
|
$file = $EXPLORER
|
||||||
|
$browser = $BROWSER
|
||||||
|
|
||||||
|
# Group Bar
|
||||||
|
group:groupbar{
|
||||||
|
enabled = true
|
||||||
|
gradients = 1
|
||||||
|
render_titles = 1
|
||||||
|
font_size = 12
|
||||||
|
font_family = $FONT
|
||||||
|
}
|
||||||
|
|
||||||
|
# Misc
|
||||||
|
|
||||||
|
misc {
|
||||||
|
font_family = $FONT
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# // █▀▀ █▄░█ █░█
|
||||||
|
# // ██▄ █░▀█ ▀▄▀
|
||||||
|
|
||||||
|
# # See https://wiki.hyprland.org/Configuring/Environment-variables/
|
||||||
|
#! Remove for now
|
||||||
|
# env = GDK_BACKEND,$env.GDK_BACKEND
|
||||||
|
# env = SDL_VIDEODRIVER,$env.SDL_VIDEODRIVER
|
||||||
|
# env = CLUTTER_BACKEND,$env.CLUTTER_BACKEND
|
||||||
|
|
||||||
|
# Qt Variables
|
||||||
|
env = QT_AUTO_SCREEN_SCALE_FACTOR,$env.QT_AUTO_SCREEN_SCALE_FACTOR
|
||||||
|
env = QT_QPA_PLATFORM,$env.QT_QPA_PLATFORM
|
||||||
|
env = QT_WAYLAND_DISABLE_WINDOWDECORATION,$env.QT_WAYLAND_DISABLE_WINDOWDECORATION
|
||||||
|
env = QT_QPA_PLATFORMTHEME,$env.QT_QPA_PLATFORMTHEME
|
||||||
|
|
||||||
|
# Wayland-ENV
|
||||||
|
env = MOZ_ENABLE_WAYLAND,$env.MOZ_ENABLE_WAYLAND
|
||||||
|
env = GDK_SCALE,$env.GDK_SCALE
|
||||||
|
env = ELECTRON_OZONE_PLATFORM_HINT,$env.ELECTRON_OZONE_PLATFORM_HINT
|
||||||
|
|
||||||
|
# XDG Spec
|
||||||
|
env = XDG_CURRENT_DESKTOP,$env.XDG_CURRENT_DESKTOP
|
||||||
|
env = XDG_SESSION_TYPE,$env.XDG_SESSION_TYPE
|
||||||
|
env = XDG_SESSION_DESKTOP,$env.XDG_SESSION_DESKTOP
|
||||||
|
|
||||||
|
|
||||||
|
# HyDE Variables
|
||||||
|
$hyde.PATH=$HOME/.local/bin:$scrPath:$env.PATH:$PATH
|
||||||
|
env = PATH,$hyde.PATH
|
||||||
|
|
||||||
|
# XDG-ENV
|
||||||
|
env = XDG_CONFIG_HOME,$env.XDG_CONFIG_HOME
|
||||||
|
env = XDG_CACHE_HOME,$env.XDG_CACHE_HOME
|
||||||
|
env = XDG_DATA_HOME,$env.XDG_DATA_HOME
|
||||||
|
|
||||||
|
# HyDE-ENV
|
||||||
|
env = HYDE_RUNTIME_DIR,$env.XDG_RUNTIME_DIR/hyde
|
||||||
|
env = HYDE_CONFIG_HOME,$env.XDG_CONFIG_HOME/hyde
|
||||||
|
env = HYDE_CACHE_HOME,$env.XDG_CACHE_HOME/hyde
|
||||||
|
env = HYDE_DATA_HOME,$env.XDG_DATA_HOME/hyde
|
||||||
|
env = HYDE_STATE_HOME,$env.XDG_STATE_HOME/hyde
|
||||||
|
|
||||||
|
# CURSOR ENV
|
||||||
|
# env = HYPRCURSOR_THEME,$CURSOR_THEME
|
||||||
|
# env = HYPRCURSOR_SIZE,$CURSOR_SIZE
|
||||||
|
# env = XCURSOR_THEME,$CURSOR_THEME
|
||||||
|
# env = XCURSOR_SIZE,$CURSOR_SIZE
|
||||||
|
|
||||||
|
# Execute on reload
|
||||||
|
|
||||||
|
# HyDE Preparation
|
||||||
|
$exec.mkdir = mkdir -p $env.XDG_RUNTIME_DIR/hyde $env.XDG_CACHE_HOME/hyde/wallbash $env.XDG_CONFIG_HOME/hyde $env.XDG_DATA_HOME/hyde $(dirname $env.XDG_DATA_HOME)/state/hyde # Create HyDE directories
|
||||||
|
$set.env = printf "\n_SHELL='$SHELL'\nGDK_BACKEND='$env.GDK_BACKEND'\nQT_QPA_PLATFORM='$env.QT_QPA_PLATFORM'\nSDL_VIDEODRIVER='$env.SDL_VIDEODRIVER'\nCLUTTER_BACKEND='$env.CLUTTER_BACKEND'\nXDG_CURRENT_DESKTOP='$env.XDG_CURRENT_DESKTOP'\nXDG_SESSION_TYPE='$env.XDG_SESSION_TYPE'\nXDG_SESSION_DESKTOP='$env.XDG_SESSION_DESKTOP'\nQT_AUTO_SCREEN_SCALE_FACTOR='$env.QT_AUTO_SCREEN_SCALE_FACTOR'\nQT_WAYLAND_DISABLE_WINDOWDECORATION='$env.QT_WAYLAND_DISABLE_WINDOWDECORATION'\nQT_QPA_PLATFORMTHEME='$env.QT_QPA_PLATFORMTHEME'\nHYDE_PATH='$hyde.PATH'\nMOZ_ENABLE_WAYLAND='$env.MOZ_ENABLE_WAYLAND'\nGDK_SCALE='$env.GDK_SCALE'\nELECTRON_OZONE_PLATFORM_HINT='$env.ELECTRON_OZONE_PLATFORM_HINT'\nXDG_RUNTIME_DIR='$env.XDG_RUNTIME_DIR'\nXDG_CONFIG_HOME='$env.XDG_CONFIG_HOME'\nXDG_CACHE_HOME='$env.XDG_CACHE_HOME'\nXDG_DATA_HOME='$env.XDG_DATA_HOME'\n_GTK_THEME='$GTK_THEME'\n_ICON_THEME='$ICON_THEME'\n_COLOR_SCHEME='$COLOR_SCHEME'\n_CURSOR_SIZE='$CURSOR_SIZE'\n_CURSOR_THEME='$CURSOR_THEME'\nFONT='$FONT'\nFONT_SIZE='$FONT_SIZE'\nDOCUMENT_FONT='$DOCUMENT_FONT'\nDOCUMENT_FONT_SIZE='$DOCUMENT_FONT_SIZE'\nMONOSPACE_FONT='$MONOSPACE_FONT'\nMONOSPACE_FONT_SIZE='$MONOSPACE_FONT_SIZE'\nFONT_ANTIALIASING='$FONT_ANTIALIASING'\nFONT_HINTING='$FONT_HINTING'\nHYDE_RUNTIME_DIR='$env.XDG_RUNTIME_DIR/hyde'\nHYDE_CONFIG_HOME='$env.XDG_CONFIG_HOME/hyde'\nHYDE_CACHE_HOME='$env.XDG_CACHE_HOME/hyde'\nHYDE_DATA_HOME='$env.XDG_DATA_HOME/hyde'\nHYDE_STATE_HOME='$(dirname $env.XDG_DATA_HOME)/state/hyde'\nexport TERMINAL='$(which $TERMINAL)'\nexport LOCKSCREEN='$LOCKSCREEN'" > "$env.XDG_RUNTIME_DIR/hyde/environment"
|
||||||
|
|
||||||
|
# Create a dconf file that will be loaded later one time, better than multiple dconf commands and better than gsettings
|
||||||
|
$dconFile=$env.XDG_CACHE_HOME/hyde/dconf
|
||||||
|
$dConf = \n[org/gnome/desktop/interface]\n
|
||||||
|
$dConf = $dConf icon-theme='$ICON_THEME'\n
|
||||||
|
$dConf = $dConf gtk-theme='$GTK_THEME'\n
|
||||||
|
$dConf = $dConf color-scheme='$COLOR_SCHEME'\n
|
||||||
|
$dConf = $dConf cursor-theme='$CURSOR_THEME'\n
|
||||||
|
$dConf = $dConf cursor-size=$CURSOR_SIZE\n
|
||||||
|
$dConf = $dConf font-name='$FONT $FONT_SIZE'\n
|
||||||
|
$dConf = $dConf document-font-name='$DOCUMENT_FONT $DOCUMENT_FONT_SIZE'\n
|
||||||
|
$dConf = $dConf monospace-font-name='$MONOSPACE_FONT $MONOSPACE_FONT_SIZE'\n
|
||||||
|
$dConf = $dConf font-antialiasing='$FONT_ANTIALIASING'\n
|
||||||
|
$dConf = $dConf font-hinting='$FONT_HINTING'\n
|
||||||
|
$dConf = $dConf [org/gnome/desktop/default-applications/terminal]\nexec='$(which $TERMINAL)'
|
||||||
|
$dconf.preserve = dconf dump / > $dconFile
|
||||||
|
$dconf.populate = printf "$dConf" >> $dconFile
|
||||||
|
$dconf.reset = dconf reset -f / < $dconFile
|
||||||
|
$dconf.load = dconf load -f / < $dconFile
|
||||||
|
$set.hyprCursor = hyprctl setcursor $CURSOR_THEME $CURSOR_SIZE
|
||||||
|
$exec.dConf = ( $dconf.preserve && $dconf.populate && $dconf.reset && $dconf.load && $set.hyprCursor )
|
||||||
|
|
||||||
|
$exec.keybinds_hint = $scrPath/keybinds.hint.py --format rofi > $env.XDG_RUNTIME_DIR/hyde/keybinds_hint.rofi
|
||||||
|
|
||||||
|
# Execute
|
||||||
|
exec = $exec.mkdir & $set.env & $exec.dConf & $exec.animation & $exec.keybinds_hint
|
||||||
|
|
||||||
|
# // █░░ ▄▀█ █░█ █▄░█ █▀▀ █░█
|
||||||
|
# // █▄▄ █▀█ █▄█ █░▀█ █▄▄ █▀█
|
||||||
|
|
||||||
|
|
||||||
|
exec-once = $start.XDG_PORTAL_RESET # reset XDPH for screenshare
|
||||||
|
exec-once = $start.DBUS_SHARE_PICKER # for XDPHgl
|
||||||
|
exec-once = $start.SYSTEMD_SHARE_PICKER # for XDPH
|
||||||
|
exec-once = $start.AUTH_DIALOGUE # authentication dialogue for GUI apps
|
||||||
|
exec-once = $start.BAR # launch the system bar
|
||||||
|
exec-once = $start.APPTRAY_BLUETOOTH # systray app for Bluetooth
|
||||||
|
exec-once = $start.REMOVABLE_MEDIA # front-end that allows to manage removable media
|
||||||
|
exec-once = $start.NETWORK_MANAGER # systray app for Network/Wifi
|
||||||
|
exec-once = $start.NOTIFICATIONS # start notification demon
|
||||||
|
exec-once = $start.TEXT_CLIPBOARD # clipboard store text data
|
||||||
|
exec-once = $start.IMAGE_CLIPBOARD # clipboard store image data
|
||||||
|
exec-once = $start.WALLPAPER # start wallpaper daemon
|
||||||
|
exec-once = $start.BATTERY_NOTIFY # battery notification
|
||||||
|
exec-once = $start.IDLE_DAEMON # idle daemon
|
||||||
|
|
||||||
|
# hyde/config.toml is parsed and exported to the environment
|
||||||
|
exec-once = $scrPath/parse.config.py --daemon --input $env.XDG_CONFIG_HOME/hyde/config.toml --env $env.XDG_STATE_HOME/hyde/config --hypr $env.XDG_STATE_HOME/hyde/hyprland.conf
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#? Rules can be added here as most of the configuration are dynamic
|
||||||
|
|
||||||
|
# // █░█░█ █ █▄░█ █▀▄ █▀█ █░█░█ █▀█ █░█ █░░ █▀▀ █▀
|
||||||
|
# // ▀▄▀▄▀ █ █░▀█ █▄▀ █▄█ ▀▄▀▄▀ █▀▄ █▄█ █▄▄ ██▄ ▄█
|
||||||
|
|
||||||
|
# See https://wiki.hyprland.org/Configuring/Window-Rules/
|
||||||
|
|
||||||
|
# Ony add the Core applications here
|
||||||
|
windowrule {
|
||||||
|
name = windowrule-1
|
||||||
|
float = on
|
||||||
|
match:class = ^(com.gabm.satty)$
|
||||||
|
}
|
||||||
|
|
||||||
|
windowrule {
|
||||||
|
name = windowrule-2
|
||||||
|
float = on
|
||||||
|
match:class = ^(org.kde.dolphin)$
|
||||||
|
match:title = ^(Progress Dialog — Dolphin)$
|
||||||
|
}
|
||||||
|
|
||||||
|
windowrule {
|
||||||
|
name = windowrule-3
|
||||||
|
float = on
|
||||||
|
match:class = ^(org.kde.dolphin)$
|
||||||
|
match:title = ^(Copying — Dolphin)$
|
||||||
|
}
|
||||||
|
|
||||||
|
windowrule {
|
||||||
|
name = windowrule-4
|
||||||
|
float = on
|
||||||
|
match:title = ^(About Mozilla Firefox)$
|
||||||
|
}
|
||||||
|
|
||||||
|
windowrule {
|
||||||
|
name = windowrule-5
|
||||||
|
float = on
|
||||||
|
match:class = ^(firefox)$
|
||||||
|
match:title = ^(Picture-in-Picture)$
|
||||||
|
}
|
||||||
|
|
||||||
|
windowrule {
|
||||||
|
name = windowrule-6
|
||||||
|
float = on
|
||||||
|
match:class = ^(firefox)$
|
||||||
|
match:title = ^(Library)$
|
||||||
|
}
|
||||||
|
|
||||||
|
windowrule {
|
||||||
|
name = windowrule-7
|
||||||
|
float = on
|
||||||
|
match:class = ^(.*)$
|
||||||
|
match:initial_title = ^(.*)(top)(.*)$
|
||||||
|
}
|
||||||
|
|
||||||
|
windowrule {
|
||||||
|
name = windowrule-8
|
||||||
|
float = on
|
||||||
|
match:class = ^(.*)$
|
||||||
|
match:initial_title = ^(.*)(btop)(.*)$
|
||||||
|
}
|
||||||
|
|
||||||
|
windowrule {
|
||||||
|
name = windowrule-9
|
||||||
|
float = on
|
||||||
|
match:class = ^(.*)$
|
||||||
|
match:initial_title = ^(.*)(htop)(.*)$
|
||||||
|
}
|
||||||
|
|
||||||
|
windowrule {
|
||||||
|
name = windowrule-10
|
||||||
|
float = on
|
||||||
|
match:class = ^(vlc)$
|
||||||
|
}
|
||||||
|
|
||||||
|
windowrule {
|
||||||
|
name = windowrule-11
|
||||||
|
float = on
|
||||||
|
match:class = ^(kvantummanager)$
|
||||||
|
}
|
||||||
|
|
||||||
|
windowrule {
|
||||||
|
name = windowrule-12
|
||||||
|
float = on
|
||||||
|
match:class = ^(qt5ct)$
|
||||||
|
}
|
||||||
|
|
||||||
|
windowrule {
|
||||||
|
name = windowrule-13
|
||||||
|
float = on
|
||||||
|
match:class = ^(qt6ct)$
|
||||||
|
}
|
||||||
|
|
||||||
|
windowrule {
|
||||||
|
name = windowrule-14
|
||||||
|
float = on
|
||||||
|
match:class = ^(nwg-look)$
|
||||||
|
}
|
||||||
|
|
||||||
|
windowrule {
|
||||||
|
name = windowrule-15
|
||||||
|
float = on
|
||||||
|
match:class = ^(nwg-displays)$
|
||||||
|
}
|
||||||
|
|
||||||
|
windowrule {
|
||||||
|
name = windowrule-16
|
||||||
|
float = on
|
||||||
|
match:class = ^(org.kde.ark)$
|
||||||
|
}
|
||||||
|
|
||||||
|
windowrule {
|
||||||
|
name = windowrule-17
|
||||||
|
float = on
|
||||||
|
match:class = ^(org.pulseaudio.pavucontrol)$
|
||||||
|
}
|
||||||
|
|
||||||
|
windowrule {
|
||||||
|
name = windowrule-18
|
||||||
|
float = on
|
||||||
|
match:class = ^(blueman-manager)$
|
||||||
|
}
|
||||||
|
|
||||||
|
windowrule {
|
||||||
|
name = windowrule-19
|
||||||
|
float = on
|
||||||
|
match:class = ^(nm-applet)$
|
||||||
|
}
|
||||||
|
|
||||||
|
windowrule {
|
||||||
|
name = windowrule-20
|
||||||
|
float = on
|
||||||
|
match:class = ^(nm-connection-editor)$
|
||||||
|
}
|
||||||
|
|
||||||
|
windowrule {
|
||||||
|
name = windowrule-21
|
||||||
|
float = on
|
||||||
|
match:class = ^(org.kde.polkit-kde-authentication-agent-1)$
|
||||||
|
}
|
||||||
|
|
||||||
|
windowrule {
|
||||||
|
name = windowrule-22
|
||||||
|
float = on
|
||||||
|
match:class = ^([Xx]dg-desktop-portal-gtk)$
|
||||||
|
}
|
||||||
|
|
||||||
|
# // █░░ ▄▀█ █▄█ █▀▀ █▀█ █▀█ █░█ █░░ █▀▀ █▀
|
||||||
|
# // █▄▄ █▀█ ░█░ ██▄ █▀▄ █▀▄ █▄█ █▄▄ ██▄ ▄█
|
||||||
|
|
||||||
|
# layerrule = blur,rofi
|
||||||
|
# layerrule = ignorezero,rofi
|
||||||
|
# layerrule = blur,notifications
|
||||||
|
# layerrule = ignorezero,notifications
|
||||||
|
# layerrule = blur,swaync-notification-window
|
||||||
|
# layerrule = ignorezero,swaync-notification-window
|
||||||
|
# layerrule = blur,swaync-control-center
|
||||||
|
# layerrule = ignorezero,swaync-control-center
|
||||||
|
# layerrule = blur,logout_dialog
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
[Icon Theme]
|
||||||
|
Name=dots-icons
|
||||||
|
Comment=Thin overlay over Tela-circle-dracula: monochrome tray/status icons at every size. Tela only ships its flat panel icons at fixed 16/22/24 - on a fractionally scaled monitor waybar requests size*2 (e.g. 44), which falls through to scalable/devices, whose icons are colored circles (the blue nm-applet blob). This theme is searched first and serves the panel SVGs as scalable, so status icons stay flat; everything else inherits Tela unchanged. Pinned via $ICON_THEME in gui/.config/hypr/hyde.conf.
|
||||||
|
Inherits=Tela-circle-dracula
|
||||||
|
Directories=scalable/status
|
||||||
|
|
||||||
|
[scalable/status]
|
||||||
|
Context=Status
|
||||||
|
Size=22
|
||||||
|
MinSize=8
|
||||||
|
MaxSize=512
|
||||||
|
Type=Scalable
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user