Compare commits
379
Commits
4eea14576c
..
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6689e69ece | ||
|
|
5f55438581 | ||
|
|
0ef99e4874 | ||
|
|
df929c5335 | ||
|
|
6ef0859e43 | ||
|
|
01f4e376ae | ||
|
|
31d04a2fe0 | ||
|
|
8866236bda | ||
|
|
f7b207aaf4 | ||
|
|
1cb6f37b5b | ||
|
|
a8468f3402 | ||
|
|
040c98c0a7 | ||
|
|
3c0bba1737 | ||
|
|
489e3cc7de | ||
|
|
7ad3b90503 | ||
|
|
db21efee0c | ||
|
|
207540c093 | ||
|
|
6b2d3bf491 | ||
|
|
c3a2e35465 | ||
|
|
e02919de21 | ||
|
|
516b2ba26c | ||
|
|
a981fa7f0a | ||
|
|
760b8e68fd | ||
|
|
04fd832974 | ||
|
|
77c68558b2 | ||
|
|
0554a3dddc | ||
|
|
fbb6b6e740 | ||
|
|
2cf61b0590 | ||
|
|
d748289c11 | ||
|
|
d2e07effc1 | ||
|
|
9d6923f225 | ||
|
|
c0628dbd4c | ||
|
|
31b47ddfc5 | ||
|
|
9642cd69db | ||
|
|
7fa5ca2568 | ||
|
|
94a4fbe45f | ||
|
|
04a02d089f | ||
|
|
3ef83d1747 | ||
|
|
f865ad766d | ||
|
|
f32e0d0ce5 | ||
|
|
8a937124d3 | ||
|
|
d8feaf7143 | ||
|
|
22dcd31c05 | ||
|
|
cbce46b63f | ||
|
|
8ab69f53ed | ||
|
|
c17f6663db | ||
|
|
20adb8f75c | ||
|
|
0e63b4fbb7 | ||
|
|
adbcd1d3c0 | ||
|
|
9e037f2a08 | ||
|
|
96df21444b | ||
|
|
7875b83a94 | ||
|
|
0765a2726a | ||
|
|
80d4f5d9fa | ||
|
|
391e2b6750 | ||
|
|
fc420fad72 | ||
|
|
dfdc1063ba | ||
|
|
4ff120cc5d
|
||
|
|
7c99b475e3 | ||
|
|
262b53c6c4 | ||
|
|
0ff6be3f81 | ||
|
|
86d20105e5
|
||
|
|
6790bf1430
|
||
|
|
e76668d3b1
|
||
|
|
204b13781d
|
||
|
|
0b9cf5a928 | ||
|
|
93831564a8 | ||
|
|
82d761b026
|
||
|
|
742fd7941d
|
||
|
|
cb74cd84e2
|
||
|
|
89fdfc8e72
|
||
|
|
0e9c3b4b27
|
||
|
|
d5535a38ad
|
||
|
|
01553b71fd
|
||
|
|
ffff95f3b9
|
||
|
|
674a50ea05
|
||
|
|
a2d52e1ec2 | ||
|
|
84c6e9b79d | ||
|
|
2d84bcdf7e
|
||
|
|
935ba904bd
|
||
|
|
8b0b5ee85a | ||
|
|
a1297a417e | ||
|
|
5c54ede483
|
||
|
|
f9086bd2ca
|
||
|
|
f9dfc4ca4c | ||
|
|
a899448fda | ||
|
|
429c407548
|
||
|
|
2fb8e3718b
|
||
|
|
11097e32de
|
||
|
|
9d1acf0fb3 | ||
|
|
7d95e7854c | ||
|
|
1972ea5bb9
|
||
|
|
2b9b8e495c | ||
|
|
231162bd03
|
||
|
|
94e4e0dfab
|
||
|
|
7dca813556 | ||
|
|
0fe183c93e
|
||
|
|
dd28fc784b
|
||
|
|
7183ed712b
|
||
|
|
d91c0c8deb | ||
|
|
d2f3da4a23
|
||
|
|
0d8a2110cf | ||
|
|
7ca9d19b93
|
||
|
|
29daf01b95 | ||
|
|
4202be5d3a | ||
|
|
05db9b57d7
|
||
|
|
a690e814eb | ||
|
|
f2874bf890
|
||
|
|
d085d5c597 | ||
|
|
4a00bc5492
|
||
|
|
5b1d90c59d | ||
|
|
11a9db5fad | ||
|
|
12ee2bac89
|
||
|
|
6feaa0ea9e
|
||
|
|
7bbd705d0f
|
||
|
|
d9c8000f68
|
||
|
|
8dba8a31fe
|
||
|
|
6b484599ae | ||
|
|
6e6f276896 | ||
|
|
bbe8aaf88d
|
||
|
|
f62404c692
|
||
|
|
1192e62eaf | ||
|
|
2c624d1a28 | ||
|
|
69e59806df | ||
|
|
ba6146c343
|
||
|
|
8951644c75 | ||
|
|
e180e8d452
|
||
|
|
3155449ef6 | ||
|
|
528ce2a984
|
||
|
|
afad1c9933
|
||
|
|
ea66507c76
|
||
|
|
3e00f4e321
|
||
|
|
78f957b211 | ||
|
|
d6c37fe0ad
|
||
|
|
e63fd8b525
|
||
|
|
c770afa6c4 | ||
|
|
49e487ac3b | ||
|
|
911e656e5e
|
||
|
|
0f02def439 | ||
|
|
24cdfe4129
|
||
|
|
1b69ff9a7f | ||
|
|
0ba43b6226
|
||
|
|
b898cf1030
|
||
|
|
ce1722d97f | ||
|
|
f02714416c
|
||
|
|
cd08c0782e | ||
|
|
927d28c01a | ||
|
|
25fb02b7ac
|
||
|
|
c126296935
|
||
|
|
48e6a96c6d
|
||
|
|
a5e6efc761
|
||
|
|
ca130ff612 | ||
|
|
51f2c020d1 | ||
|
|
5b43f3bbd3
|
||
|
|
19e5225254 | ||
|
|
c2506bdf9c | ||
|
|
c4980a15b1
|
||
|
|
ddaaf35c85 | ||
|
|
7a0e1f0930 | ||
|
|
ef384b9c7c
|
||
|
|
fe59a7c22c
|
||
|
|
1c671d71ac
|
||
|
|
819a3b1541
|
||
|
|
6ac647e0c1
|
||
|
|
690bfd64d0
|
||
|
|
d972de3df5
|
||
|
|
413b8d8fa1
|
||
|
|
27b6b22f6a | ||
|
|
b6034114ad | ||
|
|
e651566e14
|
||
|
|
f6a3ba0453 | ||
|
|
cd08403416
|
||
|
|
4ca008836c
|
||
|
|
980834e961 | ||
|
|
f2f4d4ef49 | ||
|
|
05ba0a4f10
|
||
|
|
49c8191037 | ||
|
|
ab030d7ec0
|
||
|
|
4f00b5a0f4 | ||
|
|
5c21788c8f | ||
|
|
625a58fa9f
|
||
|
|
e20cff41d4
|
||
|
|
5c24d2c72d | ||
|
|
92bcc49962 | ||
|
|
4197e7faec
|
||
|
|
daf81bf0a4
|
||
|
|
cbd5faa66c
|
||
|
|
a65e05b661
|
||
|
|
00f70e8558
|
||
|
|
8d6ca1797a
|
||
|
|
02c46ebea7
|
||
|
|
5f4306b6ca
|
||
|
|
4c51ef7a33
|
||
|
|
67fb29687c
|
||
|
|
b4a58af23c | ||
|
|
073dbd9b14
|
||
|
|
6cd0de7ccf
|
||
|
|
d23cbfc733 | ||
|
|
1bfcd519b8 | ||
|
|
e684eb6134
|
||
|
|
ab2f03213b
|
||
|
|
16e969ee15
|
||
|
|
936f13f712
|
||
|
|
3bb534f20b
|
||
|
|
a4054de4f6
|
||
|
|
c096433b5d
|
||
|
|
36a03202c6
|
||
|
|
e4ef26fe03
|
||
|
|
424a3c76ab
|
||
|
|
beb89e406a
|
||
|
|
63e71ac9dd
|
||
|
|
61a82540fb
|
||
|
|
3ccc5d2210
|
||
|
|
efa86e8eda
|
||
|
|
83e8c52298 | ||
|
|
f674ae303c | ||
|
|
29b69c7b03
|
||
|
|
8c869cc1b9 | ||
|
|
fcc2f6ccc2 | ||
|
|
38bce499bd
|
||
|
|
f3533835be
|
||
|
|
68eb3b0092 | ||
|
|
3362c33339 | ||
|
|
ec47b0671c
|
||
|
|
8495cbaa24
|
||
|
|
fe3eb818ba | ||
|
|
5930514847 | ||
|
|
8068dcb312 | ||
|
|
7afb470a42
|
||
|
|
4761c48d96
|
||
|
|
0a83bd425c | ||
|
|
83d5bd2d40 | ||
|
|
de349a423e
|
||
|
|
0250669306
|
||
|
|
7caf75b940
|
||
|
|
453b5f1d50
|
||
|
|
5cf5ca07c5
|
||
|
|
fbfc52e675
|
||
|
|
b791010e48
|
||
|
|
c6c13c2e99
|
||
|
|
b82166872f
|
||
|
|
ec99ceb018
|
||
|
|
a422400d72
|
||
|
|
2772b26704
|
||
|
|
180ea9337f
|
||
|
|
72920c04ce
|
||
|
|
614c064524 | ||
|
|
5ee09bf13e | ||
|
|
390072e919
|
||
|
|
cd240f4460 | ||
|
|
f6fd093850 | ||
|
|
67f22c8a60
|
||
|
|
6f8fd855e4
|
||
|
|
93829285d8
|
||
|
|
533ab60321
|
||
|
|
43b3cf51f6
|
||
|
|
26b90ecc72
|
||
|
|
b506f2aa39
|
||
|
|
7a1a213add
|
||
|
|
98a5cb4c7c
|
||
|
|
93554695dc
|
||
|
|
8852ed3108 | ||
|
|
47487ddcc0 | ||
|
|
2a5aef2a64
|
||
|
|
bdf4581b28 | ||
|
|
f92ac6ac37
|
||
|
|
cb30f19c32
|
||
|
|
4a5536aeb6
|
||
|
|
5103ddc43d | ||
|
|
29637799f6 | ||
|
|
ec1f00320b
|
||
|
|
878bc360d9
|
||
|
|
6bd6436c81
|
||
|
|
a76e4de605 | ||
|
|
cf8dc8d7e1 | ||
|
|
d3851fcddc
|
||
|
|
261e663e97
|
||
|
|
83abb5b6c6 | ||
|
|
1433844c2b | ||
|
|
034ebade0d
|
||
|
|
8dfbc2a9be | ||
|
|
ed8de40d46
|
||
|
|
d87582253c | ||
|
|
7079319a09
|
||
|
|
3fcc8a3ab5 | ||
|
|
fdd0733b3f | ||
|
|
c3e39b7a96
|
||
|
|
c7d1e642e5
|
||
|
|
3bdc712fa9 | ||
|
|
b81cbd3b02 | ||
|
|
7474760525
|
||
|
|
70f1ec2eeb
|
||
|
|
46dd6cd3a9
|
||
|
|
58e21eba95
|
||
|
|
5cbb01497c
|
||
|
|
7d277e52bd | ||
|
|
dda63a05ff | ||
|
|
399f481adb | ||
|
|
6a6eff2d00 | ||
|
|
a9190cf7ec
|
||
|
|
0c7f7df4ec | ||
|
|
70b4492986 | ||
|
|
1aac43af62
|
||
|
|
68a9cd17bf
|
||
|
|
7564604c53
|
||
|
|
548df81c08 | ||
|
|
b4bac6a562 | ||
|
|
2ff553f7b6
|
||
|
|
914613c751
|
||
|
|
78df24cba1
|
||
|
|
4f266f691b
|
||
|
|
ca0a35e8c7
|
||
|
|
c2ec031af2
|
||
|
|
3990bd13b4 | ||
|
|
429ccc3876 | ||
|
|
a7e6ae4d21
|
||
|
|
5b74fbe427
|
||
|
|
b998cc652e
|
||
|
|
2e1750b5a4
|
||
|
|
764f2253f6
|
||
|
|
2e6abec499
|
||
|
|
5c3d169572 | ||
|
|
50e4d92249 | ||
|
|
a5966fd982
|
||
|
|
976f46757c
|
||
|
|
2a7cb0f5cb
|
||
|
|
8f845f7cf2
|
||
|
|
69384f6427
|
||
|
|
9f9248deb1
|
||
|
|
3a054021cf
|
||
|
|
015daec928
|
||
|
|
d68bedef95
|
||
|
|
e96f874469
|
||
|
|
178214c812
|
||
|
|
45cba3a15b
|
||
|
|
11dc584104
|
||
|
|
0167370823
|
||
|
|
8d0f425b10
|
||
|
|
a483c30c05
|
||
|
|
3befc07887
|
||
|
|
2a9a7ed2ff
|
||
|
|
d1949953df
|
||
|
|
7463d894f2
|
||
|
|
1e1c2003f3
|
||
|
|
e6de825fb1
|
||
|
|
b6ed77d8f9
|
||
|
|
522fd03c12
|
||
|
|
d68f68bec7 | ||
|
|
a92847e6ed | ||
|
|
682e93c794
|
||
|
|
953aafd055
|
||
|
|
39688b28f4 | ||
|
|
654503062b
|
||
|
|
9d2a498089 | ||
|
|
64c559dbab | ||
|
|
93fc5e0517
|
||
|
|
1253f67c9c | ||
|
|
045f141e30 | ||
|
|
f76a45e273
|
||
|
|
95f2ad9112 | ||
|
|
4210f3b445
|
||
|
|
8b9bd248fd | ||
|
|
b323fedf49 | ||
|
|
4f8c45c4ef
|
||
|
|
16394da0d9
|
||
|
|
7527f01a2b
|
||
|
|
0670fbbdad
|
||
|
|
b5513ccbde
|
||
|
|
4c77f3b0af
|
||
|
|
eb828a09d5
|
||
|
|
ab284641a5
|
||
|
|
fefcb9034b
|
||
|
|
e90cdeb259 | ||
|
|
3eec6c3f89 | ||
|
|
36a303f7d4
|
||
|
|
5c224694ec
|
||
|
|
bc0b67a498
|
||
|
|
a3b60718de
|
||
|
|
7744f4f569 |
@@ -1,48 +0,0 @@
|
||||
name: Generate documentation
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
paths:
|
||||
- "docs/fish-config.md"
|
||||
|
||||
jobs:
|
||||
build-docs:
|
||||
runs-on: racknerd-mini
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
token: ${{ secrets.GITEA_TOKEN }}
|
||||
|
||||
- name: Install pandoc
|
||||
run: sudo apt-get update -qq && sudo apt-get install -y pandoc
|
||||
|
||||
- name: Compile man page
|
||||
run: |
|
||||
pandoc --standalone \
|
||||
--from markdown \
|
||||
--to man \
|
||||
docs/fish-config.md \
|
||||
-o docs/fish-config.1
|
||||
|
||||
- name: Generate chunked HTML docs
|
||||
run: |
|
||||
rm -rf docs/html/
|
||||
pandoc -f gfm -t chunkedhtml --split-level=1 --toc \
|
||||
--include-in-header docs/html-style.html \
|
||||
docs/fish-config.md \
|
||||
-o docs/html/
|
||||
|
||||
- name: Generate wiki markdown
|
||||
run: python3 docs/split-wiki.py
|
||||
|
||||
- name: Commit generated docs
|
||||
run: |
|
||||
git config user.name "Gitea Actions"
|
||||
git config user.email "actions@gitea"
|
||||
git add docs/fish-config.1 docs/html/ docs/wiki/
|
||||
git diff --cached --quiet && echo "No changes to commit" && exit 0
|
||||
git commit -m "chore(docs): regenerate man page, HTML docs, and wiki"
|
||||
git push
|
||||
@@ -1,45 +0,0 @@
|
||||
name: Offline docs drift reminder
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
paths:
|
||||
- "README.md"
|
||||
|
||||
jobs:
|
||||
remind:
|
||||
runs-on: racknerd-mini
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 2
|
||||
|
||||
- name: Check whether offline doc changed in same push
|
||||
id: drift
|
||||
run: |
|
||||
if git diff --name-only HEAD~1 HEAD | grep -q '^docs/fish-config\.md$'; then
|
||||
echo "synced=true" >> "$GITHUB_OUTPUT"
|
||||
else
|
||||
echo "synced=false" >> "$GITHUB_OUTPUT"
|
||||
fi
|
||||
|
||||
- name: Open drift reminder issue
|
||||
if: steps.drift.outputs.synced == 'false'
|
||||
env:
|
||||
GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }}
|
||||
SERVER_URL: ${{ github.server_url }}
|
||||
REPO: ${{ github.repository }}
|
||||
SHA: ${{ github.sha }}
|
||||
BRANCH: ${{ github.ref_name }}
|
||||
run: |
|
||||
curl -s -X POST \
|
||||
-H "Authorization: token ${GITEA_TOKEN}" \
|
||||
-H "Content-Type: application/json" \
|
||||
"${SERVER_URL}/api/v1/repos/${REPO}/issues" \
|
||||
-d "{
|
||||
\"title\": \"docs: README updated — review docs/fish-config.md for drift\",
|
||||
\"body\": \"README.md was modified in commit ${SHA} but \`docs/fish-config.md\` (the offline manual) was not updated in the same push.\n\nPlease review the README diff and update the offline documentation if any functions, keybindings, abbreviations, or configuration options were added, removed, or changed.\n\nCommit: ${SHA}\nBranch: ${BRANCH}\",
|
||||
\"labels\": [\"Kind/Documentation\"]
|
||||
}"
|
||||
@@ -0,0 +1,87 @@
|
||||
name: Generate documentation
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
paths:
|
||||
- "docs/manual/**"
|
||||
- "docs/build-manual.py"
|
||||
- "docs/manualtools.py"
|
||||
- "docs/verify-manual.py"
|
||||
- "docs/site/**"
|
||||
- "functions/**"
|
||||
- "conf.d/**"
|
||||
- "config.fish"
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
build-docs:
|
||||
runs-on: racknerd-mini
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
token: ${{ secrets.GITEA_TOKEN }}
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
sudo apt-get update -qq
|
||||
sudo apt-get install -y software-properties-common
|
||||
sudo add-apt-repository -y ppa:fish-shell/release-4
|
||||
sudo apt-get update -qq
|
||||
sudo apt-get install -y pandoc python3-yaml fish
|
||||
|
||||
- name: Generate concatenated markdown
|
||||
run: python3 docs/build-manual.py --concat -o docs/fish-config.md
|
||||
|
||||
# Regeneration MUST run before verification: verify-manual.py's
|
||||
# test_concat_roundtrips_original compares a freshly-built concat
|
||||
# against docs/fish-config.md on disk. Before this step ran, that
|
||||
# file was still the stale pre-push copy, so any ordinary edit under
|
||||
# docs/manual/** failed the round-trip check before anything was
|
||||
# regenerated. Do not reorder this back — verification still gates
|
||||
# pandoc and the auto-commit below, it just no longer requires a
|
||||
# contributor to hand-sync the generated file before pushing.
|
||||
- name: Verify manual integrity
|
||||
run: python3 docs/verify-manual.py
|
||||
|
||||
- name: Compile man page
|
||||
run: |
|
||||
pandoc --standalone \
|
||||
--from markdown \
|
||||
--to man \
|
||||
docs/fish-config.md \
|
||||
-o docs/fish-config.1
|
||||
|
||||
- name: Set up Node
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: "24"
|
||||
|
||||
- name: Build documentation site
|
||||
run: |
|
||||
python3 docs/build-manual.py --site
|
||||
cd docs/site
|
||||
npm ci
|
||||
npx astro build
|
||||
|
||||
- name: Deploy to Cloudflare Pages
|
||||
env:
|
||||
CLOUDFLARE_API_TOKEN: ${{ secrets.CF_API_TOKEN }}
|
||||
CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CF_ACCOUNT_ID }}
|
||||
run: |
|
||||
cd docs/site
|
||||
npx --yes wrangler pages deploy dist/ \
|
||||
--project-name=fish-config-docs \
|
||||
--branch=main \
|
||||
--commit-dirty=true
|
||||
|
||||
- name: Commit generated docs
|
||||
run: |
|
||||
git config user.name "Gitea Actions"
|
||||
git config user.email "actions@gitea"
|
||||
git add docs/fish-config.md docs/fish-config.1 conf.d/__fish_config_op_registry.fish
|
||||
git diff --cached --quiet && echo "No changes to commit" && exit 0
|
||||
git commit -m "chore(docs): regenerate manual, man page, and component registry"
|
||||
git push
|
||||
+20
@@ -288,3 +288,23 @@ poetry.toml
|
||||
pyrightconfig.json
|
||||
|
||||
# End of https://www.toptal.com/developers/gitignore/api/python
|
||||
|
||||
# ──────────────── Added by agents-init ──────────────────
|
||||
# agents-init --agents
|
||||
AGENTS/
|
||||
# ────────────────────────────────────────────────────────
|
||||
|
||||
# ──────────────── Added by agents-init ──────────────────
|
||||
# agents-init --plugins
|
||||
docs/devlogs
|
||||
# ────────────────────────────────────────────────────────
|
||||
/.cache_ggshield
|
||||
user-dots
|
||||
|
||||
# ──────────────────── Generated Docs Site ───────────────────
|
||||
docs/site/node_modules/
|
||||
docs/site/dist/
|
||||
docs/site/.astro/
|
||||
docs/site/src/content/docs/
|
||||
docs/site/src/sidebar.json
|
||||
/conf.d/uv.env.fish
|
||||
|
||||
@@ -5,9 +5,12 @@ built around a Catppuccin Mocha aesthetic with a curated set of modern
|
||||
CLI tool integrations, smart shell functions, and a heavily customized
|
||||
abbreviation system for keyboard-driven workflows.
|
||||
|
||||
📖 **[Documentation site](https://fish.rootiest.fyi/)**
|
||||
|
||||
## Table of Contents
|
||||
|
||||
- [Overview](#overview)
|
||||
- [Session Logging](#session-logging)
|
||||
- [Documentation](#documentation)
|
||||
- [Installation](#installation)
|
||||
- [Personalization](#personalization)
|
||||
@@ -22,24 +25,128 @@ abbreviation system for keyboard-driven workflows.
|
||||
This config layers on top of the CachyOS base Fish configuration and adds:
|
||||
|
||||
- **Catppuccin Mocha** theming throughout (prompt, FZF, syntax highlighting)
|
||||
- **Starship** prompt with VI key bindings
|
||||
- **Starship** prompt with VI key bindings; Catppuccin Mocha nim-style fallback prompt when Starship is absent or C3 overrides are disabled
|
||||
- **Fisher** plugin manager bootstrapped automatically; manages `sponge` (failed-command history filter); FZF bindings, Catppuccin theme, done, autopair, and puffer-fish are bundled directly with the config as customized versions
|
||||
- **Smart CLI wrappers** that prefer modern tools (`eza`, `bat`, `btop`, `dust`, `prettyping`) with graceful fallbacks
|
||||
- **Auto Python venv** activation on directory change (direnv-aware)
|
||||
- **Kitty terminal** deep integration for splits, tabs, and SSH
|
||||
- **Named background jobs** — `jobrunner` (short: `jr`) starts, lists, inspects, re-attaches to, and kills detached tasks via `tmux` or GNU `screen`, so long-running work survives closing the shell
|
||||
- **Optional session logging** — terminal scrollback, multiplexer panes (tmux/zellij), and AUR-helper output can be captured to `~/.terminal_history`; **off by default**, opt in when you want it (see the caution below and [Session Logging](#session-logging))
|
||||
- **AI workflow** helpers for Claude and Antigravity session management
|
||||
- **WakaTime** shell activity tracking
|
||||
- **Opt-out toggles** for every opinionated component — see [Minimal Mode](#minimal-mode)
|
||||
|
||||
> [!CAUTION]
|
||||
> **This configuration *can* log your terminal sessions to disk.** Logging is
|
||||
> **off by default** — but once enabled it silently captures terminal output to
|
||||
> `~/.terminal_history`: Kitty scrollback when a window closes, live tmux pane
|
||||
> streams, zellij pane snapshots on exit, and full `paru`/`yay` output. These
|
||||
> logs can contain command output, file contents, and anything else printed to
|
||||
> your terminal. Nothing is sent off your machine, but the files persist
|
||||
> locally until pruned.
|
||||
>
|
||||
> To turn logging on, set the C5 category variable:
|
||||
>
|
||||
> ```fish
|
||||
> set -U __fish_config_op_logging on
|
||||
> ```
|
||||
>
|
||||
> Or run **`config-settings`** for an interactive menu to flip logging (and any
|
||||
> other opinionated category) on or off — no variable names to remember.
|
||||
>
|
||||
> This takes effect immediately in every open shell. See [Session Logging](#session-logging)
|
||||
> for exactly what is captured and where, and [Minimal Mode](#minimal-mode) for the
|
||||
> full set of opt-out toggles.
|
||||
|
||||
---
|
||||
|
||||
## Session Logging
|
||||
|
||||
This config can capture terminal output to `~/.terminal_history` (override with
|
||||
`$SCROLLBACK_HISTORY_DIR`) so you can search back through past sessions. It is
|
||||
**off by default** — opt in with `set -U __fish_config_op_logging on`. Once
|
||||
enabled, five sources feed it:
|
||||
|
||||
| Source | When it captures | Log file |
|
||||
|---|---|---|
|
||||
| Kitty scrollback | When a Kitty window/tab closes | `scrollback_<timestamp>.log` |
|
||||
| tmux pane | Continuously while the pane is open (`pipe-pane`) | `tmux_<session>-w<win>-p<pane>_<timestamp>.log` |
|
||||
| zellij pane | Snapshot taken on **clean** shell exit (`dump-screen`) | `zellij_<session>-p<pane>_<timestamp>.log` |
|
||||
| `paru` wrapper | Every `paru` invocation | `paru_<timestamp>.log` |
|
||||
| `yay` wrapper | Every `yay` invocation | `yay_<timestamp>.log` |
|
||||
|
||||
Old logs are pruned automatically to stay within `$SCROLLBACK_HISTORY_MAX_FILES`
|
||||
(default 100) per source, and empty/trivial captures are discarded.
|
||||
|
||||
> **zellij caveat:** zellij has no continuous pipe like tmux, so its pane is
|
||||
> snapshotted only on a clean shell exit (`exit`/Ctrl-D). Closing a pane or
|
||||
> quitting zellij directly tears down the pane/server before it can be dumped,
|
||||
> so those sessions are not logged. End with `exit` to guarantee a log.
|
||||
|
||||
**These logs can contain secrets** — anything printed to your terminal (command
|
||||
output, file dumps, tokens echoed to stdout) ends up in them. They never leave
|
||||
your machine, but treat `~/.terminal_history` as sensitive.
|
||||
|
||||
All of it is controlled by a single universal variable:
|
||||
|
||||
```fish
|
||||
set -U __fish_config_op_logging on # enable; takes effect in every open shell
|
||||
set -U __fish_config_op_logging off # disable again
|
||||
set -Ue __fish_config_op_logging # erase — back to the default (off)
|
||||
```
|
||||
|
||||
Unlike the other categories, C5 is opt-in: an unset variable means off, and
|
||||
`__fish_config_opinionated` cannot turn it on for you.
|
||||
|
||||
Prefer an interactive interface? Run **`config-settings`** for a full-screen
|
||||
picker that flips logging — and every other opinionated category — on or off
|
||||
per session or universally, without memorizing variable names.
|
||||
|
||||
Disabling (or leaving it unset) also removes the generated `paru`/`yay` log
|
||||
wrappers and tells the Kitty watcher to skip capture via a sentinel file — no
|
||||
shell or terminal restart required. Logging is category **C5** in
|
||||
[Minimal Mode](#minimal-mode); `set -U __fish_config_opinionated 0` keeps it
|
||||
off along with everything else.
|
||||
|
||||
The Kitty scrollback capture is provided by a watcher script that fish-config can
|
||||
install and manage for you. Inside Kitty, if it isn't set up yet, you'll see a
|
||||
one-time-per-session reminder. Manage it with:
|
||||
|
||||
| Command | Action |
|
||||
|---|---|
|
||||
| `kitty-logging install` | Symlink the watcher into your Kitty config and wire it into `kitty.conf` |
|
||||
| `kitty-logging uninstall` | Remove the managed block and the watcher symlink |
|
||||
| `kitty-logging status` | Show whether it's wired, the watcher version, and C5 state |
|
||||
| `kitty-logging dismiss` | Stop the per-session reminder without installing |
|
||||
|
||||
`install` adds a clearly-marked managed block to `kitty.conf` and comments out
|
||||
any conflicting `watcher` line. It affects **new** Kitty windows (existing
|
||||
windows keep their current watcher until restarted). With C5 logging off the
|
||||
watcher is inert without needing to be uninstalled, and the reminder stays
|
||||
silent until you enable logging.
|
||||
|
||||
---
|
||||
|
||||
## Documentation
|
||||
|
||||
### [📖 Full Documentation Wiki](docs/wiki/index.md)
|
||||
### [📖 Documentation Site](https://fish.rootiest.fyi/)
|
||||
|
||||
A multi-page Markdown wiki auto-generated from the single source file `docs/fish-config.md`
|
||||
on every push to `main`. It covers configuration variables, key bindings, abbreviations,
|
||||
all functions, the dependency catalog, customization, and more.
|
||||
A Starlight-powered site rebuilt on every push to `main`. It covers
|
||||
configuration variables, key bindings, abbreviations, all functions, the
|
||||
dependency catalog, customization, and more, with full-text search. Also
|
||||
published as [`llms.txt`](https://fish.rootiest.fyi/llms.txt) (with
|
||||
`llms-full.txt` and `llms-small.txt` variants) for AI agents and other
|
||||
LLM tooling.
|
||||
|
||||
Contributing to the docs? There are two sources, split by content type:
|
||||
|
||||
- **Function documentation** comes from the man-page-style comment header
|
||||
above each function in `functions/*.fish`. Edit the function; the entry
|
||||
and its site page are generated from the header.
|
||||
- **Everything else** lives under `docs/manual/**`.
|
||||
|
||||
Never edit the generated `docs/fish-config.md` — it's rebuilt from both
|
||||
sources and any hand-edits are discarded.
|
||||
|
||||
To browse the docs from the terminal:
|
||||
|
||||
@@ -47,10 +154,10 @@ To browse the docs from the terminal:
|
||||
|---|---|
|
||||
| `help config` | Open the terminal manual in the best available pager |
|
||||
| `help config <keyword>` | Jump directly to a section matching the keyword |
|
||||
| `help config --html` | Open the pre-built HTML docs in the default browser |
|
||||
| `help config <keyword> --html` | Open HTML docs at the matching section anchor |
|
||||
| `help config --html` | Open the documentation site in the default browser |
|
||||
| `help config --man` | Open the compiled man page via `man -l` |
|
||||
| `help config <keyword> --man` | Open the man page jumping to the nearest match |
|
||||
| `repo-open` | Open this repo's web page in the browser (deep-links to the current branch and sub-directory) |
|
||||
|
||||
The pager falls back through: **ov** → **bat** → **man -l** → **less** → **cat**.
|
||||
|
||||
@@ -72,7 +179,7 @@ git clone https://git.rootiest.dev/rootiest/fish-config.git ~/.config/fish
|
||||
|
||||
Then open a new Fish shell — Fisher will be installed automatically on first launch and the Catppuccin Mocha theme will be applied. All plugin functionality is bundled directly with this config and requires no additional installation.
|
||||
|
||||
A [chezmoi](https://www.chezmoi.io/) dotfile manager is also configured — secrets are sourced from `~/.config/.user-dots/fish/secrets.fish` and excluded from version control.
|
||||
A [chezmoi](https://www.chezmoi.io/) dotfile manager is also configured — secrets are kept in a private overlay directory (see [Personalization](#personalization)) and excluded from version control.
|
||||
|
||||
> [!IMPORTANT]
|
||||
> `config.fish` ends with a `return` sentinel guard. Any lines appended **after** it by a tool's setup command will silently have no effect. Many tools (starship, zoxide, mise, etc.) offer a setup command that appends an `init | source` line to your `config.fish` — all integrations are managed through `conf.d/` files instead. If you add a new tool and its shell integration appears to do nothing, check whether its setup command appended an init line to the bottom of `config.fish` and create a `conf.d/<tool>.fish` file for it instead.
|
||||
@@ -91,12 +198,18 @@ Pull the latest changes from upstream without needing a configured git remote:
|
||||
|
||||
## Personalization
|
||||
|
||||
Sensitive credentials and machine-specific paths are kept out of version control via a secondary private directory at `~/.config/.user-dots/fish/`. Two files are sourced automatically by `config.fish` if they exist:
|
||||
Sensitive credentials and machine-specific paths are kept out of version control via a private overlay directory. The path defaults to `~/.config/.user-dots/fish/` but can be changed by setting a universal variable:
|
||||
|
||||
```fish
|
||||
set -U __fish_user_dots_path /path/to/your/dots/fish
|
||||
```
|
||||
|
||||
`config.fish` sources `local.fish` from that directory. `local.fish` is responsible for sourcing its own `secrets.fish` companion:
|
||||
|
||||
```
|
||||
~/.config/.user-dots/fish/
|
||||
$__fish_user_dots_path/
|
||||
├── secrets.fish # API keys, tokens, passwords, personal identifiers
|
||||
└── local.fish # Machine-specific paths and environment variables
|
||||
└── local.fish # Machine-specific paths, env vars, and sourcing secrets
|
||||
```
|
||||
|
||||
### secrets.fish
|
||||
@@ -148,39 +261,41 @@ abbr -a dcw 'docker context use work-server'
|
||||
|
||||
### How it works
|
||||
|
||||
`config.fish` sources both files with an existence check so the public config works cleanly on any machine that doesn't have the private repo:
|
||||
`config.fish` sources only `local.fish` with an existence check so the public config works cleanly on any machine without the private repo. `local.fish` is responsible for sourcing its own `secrets.fish`:
|
||||
|
||||
```fish
|
||||
if test -f $HOME/.config/.user-dots/fish/secrets.fish
|
||||
source $HOME/.config/.user-dots/fish/secrets.fish
|
||||
end
|
||||
|
||||
if test -f $HOME/.config/.user-dots/fish/local.fish
|
||||
source $HOME/.config/.user-dots/fish/local.fish
|
||||
end
|
||||
# config.fish resolves the path, then sources local.fish
|
||||
set -q __fish_user_dots_path
|
||||
or set -l __fish_user_dots_path "$XDG_CONFIG_HOME/.user-dots/fish"
|
||||
test -f "$__fish_user_dots_path/local.fish"
|
||||
and source "$__fish_user_dots_path/local.fish"
|
||||
```
|
||||
|
||||
For convenience, a git-ignored `user-dots` symlink in the fish config directory is pointed at `$__fish_user_dots_path` on startup, so the overlay can be browsed from `~/.config/fish/`. It is recreated if missing and repointed if the path variable changes. Creation is a C2 startup side-effect (`__fish_config_op_autoexec`); it only ever manages a symlink and never clobbers a real file or directory at that path.
|
||||
|
||||
To opt out, set `__fish_user_dots_symlink` to a falsy value (or toggle **Dots link** off on the **Paths** page of `config-settings`). Disabling it stops the symlink being generated and removes any existing one immediately — honoured regardless of the C2 master switch.
|
||||
|
||||
`fish_variables` (which fish auto-manages and may contain universal variable state) is excluded from this repo via `.gitignore`.
|
||||
|
||||
---
|
||||
|
||||
## Minimal Mode
|
||||
|
||||
Everything opinionated in this config — command shadows, startup side-effects, key and environment overrides, terminal integrations, logging, and the first-run greeting — is active by default but can be switched off.
|
||||
Everything opinionated in this config — command shadows, startup side-effects, key and environment overrides, terminal integrations, and the first-run greeting — is active by default but can be switched off. Logging (C5) is the exception: it is **opt-in**, off until you explicitly enable it.
|
||||
|
||||
> **The easy way — `config-toggle`:** Run `config-toggle` for an interactive TUI that flips every setting below on, off, or back to default — per-session or universally — without typing a single variable name. Use the arrow keys (or `h`/`j`/`k`/`l`) to navigate and adjust, `Tab` to switch scope, and `q` to quit. Changes apply instantly.
|
||||
> **The easy way — `config-settings`:** Run `config-settings` for an interactive TUI that manages settings across four pages — **Universal** and **Session** (the opinionated category toggles below, persistent or per-shell), **Sponge** (history-scrubbing: delay, exit codes, purge-on-exit, and extra sensitive variable names), and **Paths** (scrollback log dir, max files, and the user-dots path) — without typing a single variable name. Navigate with the arrow keys (or `h`/`j`/`k`/`l`); toggle rows step OFF ← DEFAULT → ON, value rows edit inline with `Enter` and clear with `←`. `Tab`/`Shift-Tab` cycle pages and `q` quits. Changes apply instantly. The panel auto-sizes to your terminal width (four tiers from 52- to 78-wide with a 6-column margin), centers itself horizontally, and redraws within ~0.3 s of a resize.
|
||||
|
||||
If you'd rather set them by hand, each category is controlled by a universal variable. Six category toggles and one master switch are available:
|
||||
|
||||
| Variable | Disables |
|
||||
|---|---|
|
||||
| `__fish_config_op_aliases` | Command shadows: `ls`→eza, `cat`→bat, `cd`→zoxide, `rm`→trash, `top`→btop, and friends; `grep`/`cp`/`mv`/`wget` flag injection |
|
||||
| `__fish_config_op_autoexec` | Startup side-effects: Fisher bootstrap, theme apply, `paru`/`yay` wrapper generation, auto venv activation, WakaTime hook |
|
||||
| `__fish_config_op_overrides` | Vi mode, `exit`→`smart_exit`, `$PAGER`/`$MANPAGER`/`$CDPATH`, bang-bang history expansion, autopair, puffer, Starship prompt, theme colors |
|
||||
| `__fish_config_op_aliases` | Command shadows: `ls`→eza, `cat`→bat, `cd`→zoxide, `rm`→trash, `top`→btop, `edit`→multi-editor launcher, and friends; `grep`/`cp`/`mv`/`wget` flag injection |
|
||||
| `__fish_config_op_autoexec` | Startup side-effects: Fisher bootstrap, theme apply, `paru`/`yay` wrapper generation, auto venv activation, WakaTime hook, auto-pull background fast-forward |
|
||||
| `__fish_config_op_overrides` | Vi mode, `exit`→`smart_exit`, `$PAGER`/`$MANPAGER`/`$CDPATH`/`XDG`/`PATH`, bang-bang history expansion, autopair, puffer, Starship prompt, theme colors |
|
||||
| `__fish_config_op_integrations` | Kitty/WezTerm window abbreviations, `done` notifications, `spwin`/`tab`/`split`, `hist`, `logs`, `upgrade`, WakaTime |
|
||||
| `__fish_config_op_logging` | Scrollback capture on exit, `paru`/`yay` AUR log wrappers, Kitty watcher capture (sentinel-file coordinated) |
|
||||
| `__fish_config_op_logging` | **Opt-in — off unless explicitly enabled.** Scrollback capture on exit, tmux `pipe-pane` pane logging, zellij `dump-screen` capture on exit, `paru`/`yay` AUR log wrappers, Kitty watcher capture (sentinel-file coordinated) |
|
||||
| `__fish_config_op_greeting` | Per-session `fish_greeting` (suppresses distro greetings such as CachyOS fastfetch by overriding with an empty function); first-run welcome banner |
|
||||
| `__fish_config_opinionated` | Master switch — all six categories at once |
|
||||
| `__fish_config_opinionated` | Master switch — disables all six categories at once (it is a master *off* switch; it cannot enable opt-in C5 logging) |
|
||||
|
||||
Set any of them to a falsy value (`0`, `false`, `no`, `off`, `n`) to disable; erase the variable to re-enable. An explicit per-category truthy value overrides a falsy master switch, so you can disable everything with `__fish_config_opinionated=0` and selectively re-enable individual categories:
|
||||
|
||||
@@ -195,6 +310,9 @@ set -U __fish_config_op_aliases off
|
||||
set -U __fish_config_opinionated 0
|
||||
set -U __fish_config_op_greeting 1
|
||||
|
||||
# Opt in to session logging (C5 is off by default)
|
||||
set -U __fish_config_op_logging on
|
||||
|
||||
# Back to full flavor
|
||||
set -Ue __fish_config_opinionated
|
||||
set -Ue __fish_config_op_greeting
|
||||
@@ -202,11 +320,19 @@ set -Ue __fish_config_op_greeting
|
||||
|
||||
Command shadows react immediately; bindings, prompt, and abbreviations take effect in new shells. With aliases disabled, `rm` deletes permanently again instead of trashing. See `help config opinionated` for the full component list.
|
||||
|
||||
Each category further sub-divides into two to six sub-categories with
|
||||
their own `__fish_config_op_<category>_<subcategory>` toggles (e.g.
|
||||
`__fish_config_op_aliases_filesystem`), following the exact same
|
||||
truthy/falsy/unset cascade one level deeper. Run `config-settings` and
|
||||
press Enter on a category row to browse and toggle its sub-categories, or
|
||||
see the [Components Reference](https://fish.rootiest.fyi/08-components-reference/)
|
||||
for the full sub-category list per category.
|
||||
|
||||
---
|
||||
|
||||
## Attribution
|
||||
|
||||
The core of the [Zoxide integration](docs/wiki/2-path-setup.md) in this repository was originally adapted from the [icezyclon/zoxide.fish](https://github.com/icezyclon/zoxide.fish) plugin (MIT Licensed) and has since been heavily customized for performance and Fish 4.x compatibility.
|
||||
The core of the [Zoxide integration](https://fish.rootiest.fyi/02-path-setup/) in this repository was originally adapted from the [icezyclon/zoxide.fish](https://github.com/icezyclon/zoxide.fish) plugin (MIT Licensed) and has since been heavily customized for performance and Fish 4.x compatibility.
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
# Copyright (C) 2026 Rootiest
|
||||
# SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
# Completions for the `auto-pull` registry command.
|
||||
|
||||
function __auto_pull_registered
|
||||
set -l list "$XDG_CONFIG_HOME/.user-dots/fish/auto-pull.list"
|
||||
test -r "$list"; or return
|
||||
for l in (command cat "$list" 2>/dev/null)
|
||||
test -n "$l"; or continue
|
||||
printf '%s\t%s\n' (path basename "$l") "$l"
|
||||
end
|
||||
end
|
||||
|
||||
set -l subcmds list add remove status
|
||||
|
||||
# Subcommands (only as the first argument).
|
||||
complete -c auto-pull -f -n "not __fish_seen_subcommand_from $subcmds" \
|
||||
-a list -d 'Show registered repos'
|
||||
complete -c auto-pull -f -n "not __fish_seen_subcommand_from $subcmds" \
|
||||
-a add -d "Register a repo (default: current)"
|
||||
complete -c auto-pull -f -n "not __fish_seen_subcommand_from $subcmds" \
|
||||
-a remove -d 'Unregister a repo'
|
||||
complete -c auto-pull -f -n "not __fish_seen_subcommand_from $subcmds" \
|
||||
-a status -d 'Show enabled state and registry path'
|
||||
complete -c auto-pull -f -n "not __fish_seen_subcommand_from $subcmds" \
|
||||
-s h -l help -d 'Show help'
|
||||
|
||||
# `add` takes a directory path.
|
||||
complete -c auto-pull -n "__fish_seen_subcommand_from add" -a '(__fish_complete_directories)'
|
||||
|
||||
# `remove` completes registered repo basenames.
|
||||
complete -c auto-pull -f -n "__fish_seen_subcommand_from remove" -a '(__auto_pull_registered)'
|
||||
@@ -0,0 +1,103 @@
|
||||
# fish completion for copilot
|
||||
# Generated by `copilot completion fish`. Do not edit by hand.
|
||||
|
||||
complete -c copilot -n '__fish_use_subcommand' -f -a 'login' -d 'Authenticate with Copilot'
|
||||
complete -c copilot -n '__fish_use_subcommand' -f -a 'help' -d 'Display help information'
|
||||
complete -c copilot -n '__fish_use_subcommand' -f -a 'init' -d 'Initialize Copilot instructions'
|
||||
complete -c copilot -n '__fish_use_subcommand' -f -a 'update' -d 'Download the latest version'
|
||||
complete -c copilot -n '__fish_use_subcommand' -f -a 'version' -d 'Display version information'
|
||||
complete -c copilot -n '__fish_use_subcommand' -f -a 'plugin' -d 'Manage plugins'
|
||||
complete -c copilot -n '__fish_use_subcommand' -f -a 'mcp' -d 'Manage MCP servers'
|
||||
complete -c copilot -n '__fish_use_subcommand' -f -a 'completion' -d 'Generate a shell completion script'
|
||||
complete -c copilot -l version -s v -f -d 'show version information'
|
||||
complete -c copilot -l interactive -s i -r -d 'Start interactive mode and automatically execute this prompt'
|
||||
complete -c copilot -l prompt -s p -r -d 'Execute a prompt in non-interactive mode (exits after completion)'
|
||||
complete -c copilot -l silent -s s -f -d 'Output only the agent response (no stats), useful for scripting with -p'
|
||||
complete -c copilot -l enable-memory -f -d 'Enable memory in prompt mode (disabled by default)'
|
||||
complete -c copilot -l model -r -d 'Set the AI model to use (use \'auto\' to let Copilot pick automatically)'
|
||||
complete -c copilot -l effort -l reasoning-effort -r -d 'Set the reasoning effort level' -a 'none low medium high xhigh max'
|
||||
complete -c copilot -l context -r -d 'Set the context window tier (overrides persisted setting)' -a 'default long_context'
|
||||
complete -c copilot -l enable-reasoning-summaries -f -d 'Request reasoning summaries for OpenAI models'
|
||||
complete -c copilot -l agent -r -d 'Specify a custom agent to use'
|
||||
complete -c copilot -l resume -s r -r -d 'Resume from a previous session (optionally specify existing session ID, task ID, ID prefix, or name; name matching is exact, case-insensitive)'
|
||||
complete -c copilot -l continue -f -d 'Resume the most recent session'
|
||||
complete -c copilot -l name -s n -r -d 'Set a name for the new session'
|
||||
complete -c copilot -l session-id -r -d 'Resume an existing session or task by ID, or set the UUID for a new session'
|
||||
complete -c copilot -l connect -r -d 'Connect directly to a remote session (optionally specify session ID or task ID)'
|
||||
complete -c copilot -l allow-all-tools -f -d 'Allow all tools to run automatically without confirmation; required for non-interactive mode'
|
||||
complete -c copilot -l allow-all-paths -f -d 'Disable file path verification and allow access to any path'
|
||||
complete -c copilot -l disallow-temp-dir -f -d 'Prevent automatic access to the system temporary directory'
|
||||
complete -c copilot -l no-custom-instructions -f -d 'Disable loading of custom instructions from AGENTS.md and related files'
|
||||
complete -c copilot -l no-auto-update -f -d 'Disable downloading CLI update automatically (disabled by default in CI environments)'
|
||||
complete -c copilot -l no-ask-user -f -d 'Disable the ask_user tool (agent works autonomously without asking questions)'
|
||||
complete -c copilot -l banner -f -d 'Show the startup banner'
|
||||
complete -c copilot -l no-color -f -d 'Disable all color output'
|
||||
complete -c copilot -l screen-reader -f -d 'Enable screen reader optimizations'
|
||||
complete -c copilot -l plain-diff -f -d 'Disable rich diff rendering (syntax highlighting via diff tool specified by git config)'
|
||||
complete -c copilot -s C -r -d 'Change working directory before doing anything else'
|
||||
complete -c copilot -l log-dir -r -d 'Set log file directory (default: ~/.copilot/logs/)'
|
||||
complete -c copilot -l extension-sdk-path -r -d 'Override the bundled @github/copilot-sdk injected into extension subprocesses with a local `copilot-sdk/` folder. Invalid paths fall back to the bundled SDK.'
|
||||
complete -c copilot -l log-level -r -d 'Set the log level' -a 'none error warning info debug all default'
|
||||
complete -c copilot -l stream -r -d 'Enable or disable streaming mode' -a 'on off'
|
||||
complete -c copilot -l output-format -r -d 'Output format: \'text\' (default) or \'json\' (JSONL, one JSON object per line)' -a 'text json'
|
||||
complete -c copilot -l share -r -d 'Share session to markdown file after completion in non-interactive mode (default: ./copilot-session-<id>.md)'
|
||||
complete -c copilot -l share-gist -f -d 'Share session to a secret GitHub gist after completion in non-interactive mode'
|
||||
complete -c copilot -l add-dir -r -d 'Add a directory to the allowed list for file access (can be used multiple times)'
|
||||
complete -c copilot -l attachment -r -d 'Attach a file (image or native document) to the initial prompt; only valid in non-interactive mode (can be used multiple times)'
|
||||
complete -c copilot -l disable-mcp-server -r -d 'Disable a specific MCP server (can be used multiple times)'
|
||||
complete -c copilot -l disable-builtin-mcps -f -d 'Disable all built-in MCP servers (currently: github-mcp-server)'
|
||||
complete -c copilot -l enable-all-github-mcp-tools -f -d 'Enable all GitHub MCP server tools instead of the default CLI subset. Overrides --add-github-mcp-toolset and --add-github-mcp-tool options.'
|
||||
complete -c copilot -l add-github-mcp-toolset -r -d 'Add a toolset to enable for the GitHub MCP server instead of the default CLI subset (can be used multiple times). Use "all" for all toolsets.'
|
||||
complete -c copilot -l add-github-mcp-tool -r -d 'Add a tool to enable for the GitHub MCP server instead of the default CLI subset (can be used multiple times). Use "*" for all tools.'
|
||||
complete -c copilot -l plugin-dir -r -d 'Load a plugin from a local directory (can be used multiple times)'
|
||||
complete -c copilot -l additional-mcp-config -r -d 'Additional MCP servers configuration as JSON string or file path (prefix with @) (can be used multiple times; augments config from ~/.copilot/mcp-config.json for this session)'
|
||||
complete -c copilot -l allow-tool -r -d 'Tools the CLI has permission to use; will not prompt for permission'
|
||||
complete -c copilot -l deny-tool -r -d 'Tools the CLI does not have permission to use; will not prompt for permission'
|
||||
complete -c copilot -l available-tools -r -d 'Only these tools will be available to the model'
|
||||
complete -c copilot -l excluded-tools -r -d 'These tools will not be available to the model'
|
||||
complete -c copilot -l secret-env-vars -r -d 'Environment variable names whose values are stripped from shell and MCP server environments and redacted from output (e.g., --secret-env-vars=MY_KEY,OTHER_KEY)'
|
||||
complete -c copilot -l allow-url -r -d 'Allow access to specific URLs or domains'
|
||||
complete -c copilot -l deny-url -r -d 'Deny access to specific URLs or domains, takes precedence over --allow-url'
|
||||
complete -c copilot -l allow-all-urls -f -d 'Allow access to all URLs without confirmation'
|
||||
complete -c copilot -l allow-all -f -d 'Enable all permissions (equivalent to --allow-all-tools --allow-all-paths --allow-all-urls)'
|
||||
complete -c copilot -l yolo -f -d 'Enable all permissions (equivalent to --allow-all-tools --allow-all-paths --allow-all-urls)'
|
||||
complete -c copilot -l max-autopilot-continues -r -d 'Maximum number of continuation messages in autopilot mode'
|
||||
complete -c copilot -l mode -r -d 'Set the initial agent mode' -a 'interactive plan autopilot'
|
||||
complete -c copilot -l autopilot -f -d 'Start in autopilot mode'
|
||||
complete -c copilot -l plan -f -d 'Start in plan mode'
|
||||
complete -c copilot -l experimental -f -d 'Enable experimental features'
|
||||
complete -c copilot -l no-experimental -f -d 'Disable experimental features'
|
||||
complete -c copilot -l bash-env -r -d 'Enable BASH_ENV support for bash shells (on|off)'
|
||||
complete -c copilot -l no-bash-env -f -d 'Disable BASH_ENV support for bash shells'
|
||||
complete -c copilot -l mouse -r -d 'Enable mouse support in alt screen mode (on|off)'
|
||||
complete -c copilot -l no-mouse -f -d 'Disable mouse support in alt screen mode'
|
||||
complete -c copilot -l acp -f -d 'Start as Agent Client Protocol server'
|
||||
complete -c copilot -l remote -f -d 'Enable remote control of your session from GitHub web and mobile'
|
||||
complete -c copilot -l no-remote -f -d 'Disable remote control of your session from GitHub web and mobile'
|
||||
complete -c copilot -n '__fish_seen_subcommand_from login' -l host -r -d 'GitHub host URL (default: https://github.com)'
|
||||
complete -c copilot -n '__fish_seen_subcommand_from plugin' -f -a 'install' -d 'Install a plugin'
|
||||
complete -c copilot -n '__fish_seen_subcommand_from plugin' -f -a 'uninstall' -d 'Uninstall a plugin'
|
||||
complete -c copilot -n '__fish_seen_subcommand_from plugin' -f -a 'update' -d 'Update a plugin'
|
||||
complete -c copilot -n '__fish_seen_subcommand_from plugin' -f -a 'list' -d 'List installed plugins'
|
||||
complete -c copilot -n '__fish_seen_subcommand_from plugin' -f -a 'marketplace' -d 'Manage plugin marketplaces'
|
||||
complete -c copilot -n '__fish_seen_subcommand_from plugin; and __fish_seen_subcommand_from update' -l all -f -d 'Update all installed plugins'
|
||||
complete -c copilot -n '__fish_seen_subcommand_from plugin; and __fish_seen_subcommand_from marketplace' -f -a 'add' -d 'Add a marketplace'
|
||||
complete -c copilot -n '__fish_seen_subcommand_from plugin; and __fish_seen_subcommand_from marketplace' -f -a 'remove' -d 'Remove a marketplace'
|
||||
complete -c copilot -n '__fish_seen_subcommand_from plugin; and __fish_seen_subcommand_from marketplace' -f -a 'list' -d 'List registered marketplaces'
|
||||
complete -c copilot -n '__fish_seen_subcommand_from plugin; and __fish_seen_subcommand_from marketplace' -f -a 'browse' -d 'Browse plugins in a marketplace'
|
||||
complete -c copilot -n '__fish_seen_subcommand_from plugin; and __fish_seen_subcommand_from marketplace' -f -a 'update' -d 'Update marketplace plugin catalogs'
|
||||
complete -c copilot -n '__fish_seen_subcommand_from plugin; and __fish_seen_subcommand_from marketplace; and __fish_seen_subcommand_from remove' -l force -s f -f -d 'Force removal even if plugins are installed'
|
||||
complete -c copilot -n '__fish_seen_subcommand_from mcp' -f -a 'list' -d 'List configured MCP servers'
|
||||
complete -c copilot -n '__fish_seen_subcommand_from mcp' -f -a 'get' -d 'Show server details'
|
||||
complete -c copilot -n '__fish_seen_subcommand_from mcp' -f -a 'add' -d 'Add an MCP server'
|
||||
complete -c copilot -n '__fish_seen_subcommand_from mcp' -f -a 'remove' -d 'Remove an MCP server'
|
||||
complete -c copilot -n '__fish_seen_subcommand_from mcp; and __fish_seen_subcommand_from list' -l json -f -d 'Output as JSON'
|
||||
complete -c copilot -n '__fish_seen_subcommand_from mcp; and __fish_seen_subcommand_from get' -l json -f -d 'Output as JSON'
|
||||
complete -c copilot -n '__fish_seen_subcommand_from mcp; and __fish_seen_subcommand_from get' -l show-secrets -f -d 'Show full environment variable and header values (masked by default)'
|
||||
complete -c copilot -n '__fish_seen_subcommand_from mcp; and __fish_seen_subcommand_from add' -l transport -r -d 'Server transport' -a 'stdio http sse'
|
||||
complete -c copilot -n '__fish_seen_subcommand_from mcp; and __fish_seen_subcommand_from add' -l env -r -d 'Environment variable (KEY=VALUE, can be repeated)'
|
||||
complete -c copilot -n '__fish_seen_subcommand_from mcp; and __fish_seen_subcommand_from add' -l header -r -d 'HTTP header for remote servers, can be repeated'
|
||||
complete -c copilot -n '__fish_seen_subcommand_from mcp; and __fish_seen_subcommand_from add' -l tools -r -d 'Tool filter: "*" for all, comma-separated list, or "" for none'
|
||||
complete -c copilot -n '__fish_seen_subcommand_from mcp; and __fish_seen_subcommand_from add' -l timeout -r -d 'Timeout in milliseconds'
|
||||
complete -c copilot -n '__fish_seen_subcommand_from mcp; and __fish_seen_subcommand_from add' -l json -f -d 'Output added config as JSON'
|
||||
complete -c copilot -n '__fish_seen_subcommand_from mcp; and __fish_seen_subcommand_from add' -l show-secrets -f -d 'Show full environment variable and header values in output, masked by default'
|
||||
@@ -0,0 +1,79 @@
|
||||
# Copyright (C) 2026 Rootiest
|
||||
# SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
# Completions for the `jobrunner` background job manager.
|
||||
# `jr` inherits these via `function jr --wraps jobrunner`.
|
||||
|
||||
# Offer running jobs as name<TAB>description pairs.
|
||||
function __jobrunner_complete_jobs
|
||||
set -l tool ""
|
||||
set -l tokens (commandline -opc)
|
||||
set -l idx 1
|
||||
while test $idx -le (count $tokens)
|
||||
switch $tokens[$idx]
|
||||
case -t --tool
|
||||
set idx (math $idx + 1)
|
||||
if test $idx -le (count $tokens)
|
||||
set tool $tokens[$idx]
|
||||
end
|
||||
case '--tool=*'
|
||||
set tool (string replace -- "--tool=" "" $tokens[$idx])
|
||||
case '-t*'
|
||||
set tool (string replace -r "^-t" "" $tokens[$idx])
|
||||
end
|
||||
set idx (math $idx + 1)
|
||||
end
|
||||
|
||||
for row in (__jobrunner_sessions $tool)
|
||||
set -l f (string split \t -- $row)
|
||||
printf '%s\t%s job (PID %s)\n' $f[1] $f[3] $f[2]
|
||||
end
|
||||
end
|
||||
|
||||
set -l subcmds run list attach kill logs help
|
||||
set -l needs_job "__fish_seen_subcommand_from attach kill logs -a --attach -k --kill -o --output"
|
||||
|
||||
# No file completions; jobs are named, not paths.
|
||||
complete -c jobrunner -f
|
||||
|
||||
# Backend tool selection flag.
|
||||
complete -c jobrunner -n "not __fish_seen_subcommand_from $subcmds" \
|
||||
-s t -l tool -x -a "tmux screen" -d 'Force specific backend'
|
||||
|
||||
# Subcommands (only as the first argument).
|
||||
complete -c jobrunner -n "not __fish_seen_subcommand_from $subcmds" \
|
||||
-a run -d 'Start a named job in the background'
|
||||
complete -c jobrunner -n "not __fish_seen_subcommand_from $subcmds" \
|
||||
-a list -d 'List all managed background jobs'
|
||||
complete -c jobrunner -n "not __fish_seen_subcommand_from $subcmds" \
|
||||
-a attach -d 'Re-attach interactively to a job'
|
||||
complete -c jobrunner -n "not __fish_seen_subcommand_from $subcmds" \
|
||||
-a kill -d 'Terminate a running background job'
|
||||
complete -c jobrunner -n "not __fish_seen_subcommand_from $subcmds" \
|
||||
-a logs -d "Print a job's output without attaching"
|
||||
complete -c jobrunner -n "not __fish_seen_subcommand_from $subcmds" \
|
||||
-a help -d 'Show usage help'
|
||||
|
||||
# Flag forms.
|
||||
complete -c jobrunner -n "not __fish_seen_subcommand_from $subcmds" \
|
||||
-s r -l run -d 'Start a named job in the background'
|
||||
complete -c jobrunner -n "not __fish_seen_subcommand_from $subcmds" \
|
||||
-s l -l list -d 'List all managed background jobs'
|
||||
complete -c jobrunner -n "not __fish_seen_subcommand_from $subcmds" \
|
||||
-s a -l attach -d 'Re-attach interactively to a job'
|
||||
complete -c jobrunner -n "not __fish_seen_subcommand_from $subcmds" \
|
||||
-s k -l kill -d 'Terminate a running background job'
|
||||
complete -c jobrunner -n "not __fish_seen_subcommand_from $subcmds" \
|
||||
-s o -l output -d "Print a job's output without attaching"
|
||||
complete -c jobrunner -s h -l help -d 'Show usage help'
|
||||
|
||||
# Running jobs, for the subcommands that take one.
|
||||
complete -c jobrunner -n "$needs_job" -a '(__jobrunner_complete_jobs)'
|
||||
|
||||
# A bare job name attaches to it, so offer jobs in first position too.
|
||||
complete -c jobrunner -n "not __fish_seen_subcommand_from $subcmds" \
|
||||
-a '(__jobrunner_complete_jobs)'
|
||||
|
||||
# After `run <name>`, complete the command to execute.
|
||||
complete -c jobrunner -n "__fish_seen_subcommand_from run -r --run; and test (count (commandline -opc)) -ge 3" \
|
||||
-a '(__fish_complete_subcommand)'
|
||||
@@ -0,0 +1,21 @@
|
||||
# Copyright (C) 2026 Rootiest
|
||||
# SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
complete -c rand_string -f
|
||||
|
||||
complete -c rand_string -s s -l separator -x -a 'dash underscore dot none' -d 'Set separator for following words'
|
||||
complete -c rand_string -s c -l case -x -a 'lower upper title' -d 'Set casing for following words'
|
||||
complete -c rand_string -s h -l help -d 'Show usage help'
|
||||
|
||||
# List of all available lists in data/words
|
||||
set -l categories
|
||||
if set -q __fish_config_dir
|
||||
set categories (string replace -r '\.txt$' '' (command ls $__fish_config_dir/data/words/*.txt 2>/dev/null | command xargs -n 1 basename 2>/dev/null))
|
||||
end
|
||||
|
||||
for cat in $categories
|
||||
complete -c rand_string -a "$cat" -d "Pick a random word from the $cat list"
|
||||
end
|
||||
|
||||
complete -c rand_string -a 'digits=' -d 'Generate N random digits (e.g. digits=3)'
|
||||
complete -c rand_string -a 'literal=' -d 'Insert a literal string exactly as provided'
|
||||
@@ -0,0 +1,146 @@
|
||||
# Copyright (C) 2026 Rootiest
|
||||
# SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
#
|
||||
# GENERATED FILE --- do not edit by hand.
|
||||
# Regenerate with __fish_config_op_registry_rebuild after editing a
|
||||
# # COMPONENT header, or automatically via docs/build-manual.py.
|
||||
# Source: docs/generate_component_registry.py
|
||||
#
|
||||
# This file must be sourced before any other conf.d/*.fish file that
|
||||
# calls the opinionated guard. That currently holds only because fish's
|
||||
# glob-based conf.d loading happens to sort this filename first
|
||||
# alphabetically among the guard-calling files -- do not rename it
|
||||
# without preserving that ordering.
|
||||
|
||||
set -g __fish_config_op_registry_keys \
|
||||
"__auto_source_fallback_venv:" \
|
||||
"__fish_config_sync_logging:" \
|
||||
"__fish_user_dots_link:" \
|
||||
"_zellij_dump_log:" \
|
||||
"abbr:abbr-integrations" \
|
||||
"abbr:abbr-overrides" \
|
||||
"agy:" \
|
||||
"auto-pull:" \
|
||||
"autopair:" \
|
||||
"bash:" \
|
||||
"bash_expands:" \
|
||||
"cat:" \
|
||||
"claude:" \
|
||||
"config:cachyos-strip-aliases" \
|
||||
"config:cachyos-strip-overrides" \
|
||||
"config:cachyos-tricks" \
|
||||
"config:cdpath" \
|
||||
"config:exit-wiring" \
|
||||
"config:greeting-stamp" \
|
||||
"config:pager-editor-gpg" \
|
||||
"config:path-setup" \
|
||||
"config:vi-mode" \
|
||||
"done:" \
|
||||
"du:" \
|
||||
"edit:" \
|
||||
"first_run:first-run-bootstrap" \
|
||||
"first_run:first-run-greeting" \
|
||||
"fish_right_prompt:" \
|
||||
"help:" \
|
||||
"hist:" \
|
||||
"key_bindings:" \
|
||||
"kitty-logging:" \
|
||||
"kitty-watcher-reminder:" \
|
||||
"less:" \
|
||||
"logs:" \
|
||||
"ls:" \
|
||||
"mkdir:" \
|
||||
"mv:" \
|
||||
"paru-wrapper:paru-autoexec" \
|
||||
"paru-wrapper:paru-logging" \
|
||||
"ping:" \
|
||||
"puffer:" \
|
||||
"rg:" \
|
||||
"rm:" \
|
||||
"smart_exit:exit-plain" \
|
||||
"smart_exit:logging-guard" \
|
||||
"split:" \
|
||||
"spwin:" \
|
||||
"ssh:" \
|
||||
"starship:" \
|
||||
"tab:" \
|
||||
"theme:" \
|
||||
"tmux-logging:" \
|
||||
"top:" \
|
||||
"tricks:aliases-tricks" \
|
||||
"tricks:tricks-bang" \
|
||||
"tricks:tricks-manpager" \
|
||||
"upgrade:" \
|
||||
"wakatime:wakatime-autoexec" \
|
||||
"wakatime:wakatime-hook" \
|
||||
"yay-wrapper:yay-autoexec" \
|
||||
"yay-wrapper:yay-logging" \
|
||||
"yt-dlp:" \
|
||||
"zoxide:"
|
||||
|
||||
set -g __fish_config_op_registry_values \
|
||||
"autoexec/venv" \
|
||||
"logging/terminal-capture" \
|
||||
"autoexec/sync" \
|
||||
"logging/multiplexer-capture" \
|
||||
"integrations/terminal-abbrs" \
|
||||
"overrides/key-bindings" \
|
||||
"aliases/dev-tools" \
|
||||
"autoexec/sync" \
|
||||
"overrides/key-bindings" \
|
||||
"aliases/shell-tools" \
|
||||
"overrides/key-bindings" \
|
||||
"aliases/filesystem" \
|
||||
"aliases/dev-tools" \
|
||||
"aliases/filesystem" \
|
||||
"overrides/key-bindings" \
|
||||
"overrides/environment" \
|
||||
"overrides/environment" \
|
||||
"overrides/key-bindings" \
|
||||
"greeting/greeting-message" \
|
||||
"overrides/environment" \
|
||||
"overrides/environment" \
|
||||
"overrides/key-bindings" \
|
||||
"integrations/notifications" \
|
||||
"aliases/filesystem" \
|
||||
"aliases/dev-tools" \
|
||||
"autoexec/plugin-management" \
|
||||
"greeting/first-run" \
|
||||
"overrides/prompt" \
|
||||
"aliases/shell-tools" \
|
||||
"integrations/history-logs" \
|
||||
"overrides/key-bindings" \
|
||||
"logging/terminal-capture" \
|
||||
"logging/terminal-capture" \
|
||||
"aliases/shell-tools" \
|
||||
"integrations/history-logs" \
|
||||
"aliases/filesystem" \
|
||||
"aliases/filesystem" \
|
||||
"aliases/filesystem" \
|
||||
"autoexec/pkg-wrappers" \
|
||||
"logging/pkg-logs" \
|
||||
"aliases/network" \
|
||||
"overrides/key-bindings" \
|
||||
"aliases/search" \
|
||||
"aliases/filesystem" \
|
||||
"overrides/key-bindings" \
|
||||
"logging/terminal-capture" \
|
||||
"integrations/window-mgmt" \
|
||||
"integrations/window-mgmt" \
|
||||
"aliases/network" \
|
||||
"overrides/prompt" \
|
||||
"integrations/window-mgmt" \
|
||||
"overrides/prompt" \
|
||||
"logging/multiplexer-capture" \
|
||||
"aliases/monitor" \
|
||||
"aliases/filesystem" \
|
||||
"overrides/key-bindings" \
|
||||
"overrides/environment" \
|
||||
"integrations/pkg-upgrade" \
|
||||
"autoexec/telemetry" \
|
||||
"integrations/notifications" \
|
||||
"autoexec/pkg-wrappers" \
|
||||
"logging/pkg-logs" \
|
||||
"aliases/network" \
|
||||
"aliases/filesystem"
|
||||
|
||||
+377
-5
@@ -8,82 +8,172 @@
|
||||
# This file contains all the abbreviations for the terminal.
|
||||
# It is sourced by Fish on startup.
|
||||
|
||||
# COMPONENT
|
||||
# site abbr-integrations: integrations/terminal-abbrs
|
||||
# site abbr-overrides: overrides/key-bindings
|
||||
|
||||
# Neovim
|
||||
# @category Editors
|
||||
# @desc nvim
|
||||
abbr -a n nvim
|
||||
# @category Editors
|
||||
# @desc nvim
|
||||
abbr -a nv nvim
|
||||
# @category Editors
|
||||
# @desc nvim
|
||||
abbr -a neovim nvim
|
||||
# @category Editors
|
||||
# @desc cd ~/.config/nvim
|
||||
abbr -a cdnv 'cd ~/.config/nvim # Neovim Config'
|
||||
# @category Editors
|
||||
# @desc cd ~/.config/nvim; nvim
|
||||
abbr -a cdnvn 'cd ~/.config/nvim;nvim'
|
||||
# VSCode
|
||||
# @category AI Assistants
|
||||
# @desc antigravity-ide
|
||||
abbr -a v antigravity-ide
|
||||
# Kate
|
||||
# @category Editors
|
||||
# @desc kate
|
||||
abbr -a k kate
|
||||
# WezTerm SSH
|
||||
if test "$TERM_PROGRAM" = WezTerm
|
||||
# @category AI Assistants
|
||||
# @desc wezterm ssh (WezTerm only)
|
||||
abbr -a s wezterm ssh
|
||||
end
|
||||
# Neovim in a new tab
|
||||
if test "$TERM" = xterm-kitty
|
||||
# @category Terminal Windows, Tabs, and Panes
|
||||
# @desc Open new tab with nvim (terminal-aware)
|
||||
abbr -a editt kitty @ launch --type=tab --cwd=current nvim # Kitty
|
||||
end
|
||||
if test "$TERM_PROGRAM" = WezTerm
|
||||
# @category Terminal Windows, Tabs, and Panes
|
||||
# @desc Open new tab with nvim (terminal-aware)
|
||||
abbr -a editt wezterm cli spawn nvim # WezTerm
|
||||
end
|
||||
# LazyGit
|
||||
# @category Git
|
||||
# @desc lazygit
|
||||
abbr -a lg lazygit
|
||||
# Sudo shell
|
||||
# @category Miscellaneous
|
||||
# @desc sudo -s
|
||||
abbr -a sudu sudo -s
|
||||
# Kitty
|
||||
if test "$TERM" = xterm-kitty
|
||||
# @category Miscellaneous
|
||||
# @desc kitty (Kitty only)
|
||||
abbr -a kt kitty
|
||||
end
|
||||
# cat
|
||||
# @category Miscellaneous
|
||||
# @desc cat
|
||||
abbr -a c cat
|
||||
# chezmoi
|
||||
# @category Chezmoi
|
||||
# @desc chezmoi
|
||||
abbr -a cm chezmoi
|
||||
# chezmoi cd
|
||||
# @category Chezmoi
|
||||
# @desc chezmoi cd
|
||||
abbr -a cmcd chezmoi cd
|
||||
# @category Chezmoi
|
||||
# @desc chezmoi cd
|
||||
abbr -a czcd chezmoi cd
|
||||
# @category Chezmoi
|
||||
# @desc chezmoi cd
|
||||
abbr -a cdcm chezmoi cd
|
||||
# @category Chezmoi
|
||||
# @desc chezmoi cd
|
||||
abbr -a cdcz chezmoi cd
|
||||
# chezmoi edit
|
||||
# @category Chezmoi
|
||||
# @desc chezmoi edit
|
||||
abbr -a cme chezmoi edit
|
||||
# @category Chezmoi
|
||||
# @desc chezmoi edit
|
||||
abbr -a cze chezmoi edit
|
||||
# chezmoi add
|
||||
# @category Chezmoi
|
||||
# @desc chezmoi add
|
||||
abbr -a cmad chezmoi add
|
||||
# @category Chezmoi
|
||||
# @desc chezmoi add
|
||||
abbr -a czad chezmoi add
|
||||
# chezmoi apply
|
||||
# @category Chezmoi
|
||||
# @desc chezmoi apply
|
||||
abbr -a cmap chezmoi apply
|
||||
# @category Chezmoi
|
||||
# @desc chezmoi apply
|
||||
abbr -a czap chezmoi apply
|
||||
# chezmoi rm
|
||||
# @category Chezmoi
|
||||
# @desc chezmoi forget
|
||||
abbr -a cmrm chezmoi forget
|
||||
# @category Chezmoi
|
||||
# @desc chezmoi forget
|
||||
abbr -a cmf chezmoi forget
|
||||
# @category Chezmoi
|
||||
# @desc chezmoi forget
|
||||
abbr -a czrm chezmoi forget
|
||||
# @category Chezmoi
|
||||
# @desc chezmoi forget
|
||||
abbr -a czf chezmoi forget
|
||||
# chezmoi init
|
||||
# @category Chezmoi
|
||||
# @desc chezmoi init
|
||||
abbr -a cmi chezmoi init
|
||||
# @category Chezmoi
|
||||
# @desc chezmoi init
|
||||
abbr -a czi chezmoi init
|
||||
# Edit
|
||||
# @category Editors
|
||||
# @desc edit
|
||||
abbr -a e edit
|
||||
# Sudoedit
|
||||
# @category Editors
|
||||
# @desc sudoedit
|
||||
abbr -a se sudoedit
|
||||
# Git
|
||||
# @category Git
|
||||
# @desc git
|
||||
abbr -a g git
|
||||
# @category Git
|
||||
# @desc generate .gitignore
|
||||
abbr -a gitig gi
|
||||
# @category Git
|
||||
# @desc generate .gitignore
|
||||
abbr -a git-ignore gi
|
||||
# Antigravity
|
||||
abbr -a ag antigravity
|
||||
abbr -a ag. antigravity .
|
||||
# @category AI Assistants
|
||||
# @desc agy
|
||||
abbr -a ag agy
|
||||
# @category AI Assistants
|
||||
# @desc agy .
|
||||
abbr -a ag. agy .
|
||||
# Quit
|
||||
# @category Miscellaneous
|
||||
# @desc exit
|
||||
abbr -a /exit exit
|
||||
# Window-management abbreviations are opinionated (C4 integrations)
|
||||
if __fish_config_op_enabled __fish_config_op_integrations
|
||||
if __fish_config_op_enabled (status basename) abbr-integrations
|
||||
if test "$TERM" = xterm-kitty
|
||||
# @category Terminal Windows, Tabs, and Panes
|
||||
# @desc Close current pane/window
|
||||
abbr -a :q kitty @ close-window # Kitty (Closes the active split/pane)
|
||||
# @category Terminal Windows, Tabs, and Panes
|
||||
# @desc Close current tab
|
||||
abbr -a :Q kitty @ close-tab # Kitty (Closes the whole tab)
|
||||
end
|
||||
if test "$TERM_PROGRAM" = WezTerm
|
||||
# @category Terminal Windows, Tabs, and Panes
|
||||
# @desc Close current pane/window
|
||||
abbr -a :q wezterm cli kill-pane # WezTerm
|
||||
# @category Terminal Windows, Tabs, and Panes
|
||||
# @desc Close current tab
|
||||
abbr -a :Q wezterm cli kill-pane # WezTerm
|
||||
end
|
||||
end
|
||||
@@ -91,236 +181,518 @@ end
|
||||
######### Alternates ##########
|
||||
### ls alternates
|
||||
# List all files
|
||||
# @category Navigation and Listing
|
||||
# @desc ls
|
||||
abbr -a l ls
|
||||
# List all files by size
|
||||
# @category Navigation and Listing
|
||||
# @desc lss (sort by size)
|
||||
abbr -a lS lss
|
||||
# List all files by reverse modified time
|
||||
# @category Navigation and Listing
|
||||
# @desc lsr (sort by time, oldest first)
|
||||
abbr -a lsR lsr
|
||||
# List by extension
|
||||
# @category Navigation and Listing
|
||||
# @desc lx (sort by extension)
|
||||
abbr -a lX lx
|
||||
# Tree listing (depth 2)
|
||||
# @category Navigation and Listing
|
||||
# @desc lt (tree, depth 2)
|
||||
abbr -a lT lt
|
||||
# Full tree listing
|
||||
# @category Navigation and Listing
|
||||
# @desc lstree (full recursive tree)
|
||||
abbr -a lsT lstree
|
||||
### speed-test alternates
|
||||
# Speedtest using fast.com
|
||||
# @category Miscellaneous
|
||||
# @desc fast-cli
|
||||
abbr -a speedtest-fast fast-cli
|
||||
|
||||
# Kitty/WezTerm window-management abbreviations are opinionated (C4
|
||||
# integrations): they assume an active Kitty or WezTerm session.
|
||||
if __fish_config_op_enabled __fish_config_op_integrations
|
||||
if __fish_config_op_enabled (status basename) abbr-integrations
|
||||
# Window Creation (OS Windows)
|
||||
if test "$TERM" = xterm-kitty
|
||||
# @category Terminal Windows, Tabs, and Panes
|
||||
# @desc New OS window
|
||||
abbr -a :w kitty @ launch --type=os-window # Kitty
|
||||
end
|
||||
if test "$TERM_PROGRAM" = WezTerm
|
||||
# @category Terminal Windows, Tabs, and Panes
|
||||
# @desc New OS window
|
||||
abbr -a :w wezterm cli spawn --new-window # WezTerm
|
||||
end
|
||||
|
||||
# Window Splits (Panes)
|
||||
if test "$TERM" = xterm-kitty
|
||||
# @category Terminal Windows, Tabs, and Panes
|
||||
# @desc Split pane horizontally (new pane below)
|
||||
abbr -a :wv kitty @ launch --location=hsplit # Kitty (Horizontal split)
|
||||
# @category Terminal Windows, Tabs, and Panes
|
||||
# @desc Split pane vertically (new pane to the right)
|
||||
abbr -a :wh kitty @ launch --location=vsplit # Kitty (Vertical split)
|
||||
end
|
||||
if test "$TERM_PROGRAM" = WezTerm
|
||||
# @category Terminal Windows, Tabs, and Panes
|
||||
# @desc Split pane horizontally (new pane below)
|
||||
abbr -a :wv wezterm cli split-pane --bottom # WezTerm
|
||||
# @category Terminal Windows, Tabs, and Panes
|
||||
# @desc Split pane vertically (new pane to the right)
|
||||
abbr -a :wh wezterm cli split-pane --right # WezTerm
|
||||
end
|
||||
|
||||
# Window Detach (Move Pane)
|
||||
if test "$TERM" = xterm-kitty
|
||||
# @category Terminal Windows, Tabs, and Panes
|
||||
# @desc Detach current window to its own OS window
|
||||
abbr -a :wo kitty @ detach-window --target-tab=new # Kitty (Moves pane to new tab)
|
||||
# @category Terminal Windows, Tabs, and Panes
|
||||
# @desc Move current pane to a new tab
|
||||
abbr -a :wot kitty @ detach-window # Kitty (Same as above, default behavior)
|
||||
end
|
||||
if test "$TERM_PROGRAM" = WezTerm
|
||||
# @category Terminal Windows, Tabs, and Panes
|
||||
# @desc Detach current window to its own OS window
|
||||
abbr -a :wo wezterm cli move-pane-to-new-tab --new-window # WezTerm
|
||||
# @category Terminal Windows, Tabs, and Panes
|
||||
# @desc Move current pane to a new tab
|
||||
abbr -a :wot wezterm cli move-pane-to-new-tab # WezTerm
|
||||
end
|
||||
|
||||
# Tab Creation
|
||||
if test "$TERM" = xterm-kitty
|
||||
# @category Terminal Windows, Tabs, and Panes
|
||||
# @desc New tab
|
||||
abbr -a :t kitty @ launch --type=tab # Kitty
|
||||
end
|
||||
if test "$TERM_PROGRAM" = WezTerm
|
||||
# @category Terminal Windows, Tabs, and Panes
|
||||
# @desc New tab
|
||||
abbr -a :t wezterm cli spawn # WezTerm
|
||||
end
|
||||
|
||||
# Rename Tab
|
||||
if test "$TERM" = xterm-kitty
|
||||
# @category Terminal Windows, Tabs, and Panes
|
||||
# @desc Set tab title
|
||||
abbr -a :tl "kitty @ set-tab-title" # Kitty -> Usage: :tl "New Title"
|
||||
end
|
||||
if test "$TERM_PROGRAM" = WezTerm
|
||||
# @category Terminal Windows, Tabs, and Panes
|
||||
# @desc Set tab title
|
||||
abbr -a :tl wezterm cli set-tab-title # WezTerm
|
||||
end
|
||||
|
||||
# Rename Window
|
||||
if test "$TERM" = xterm-kitty
|
||||
# @category Terminal Windows, Tabs, and Panes
|
||||
# @desc Set window title
|
||||
abbr -a :tw "kitty @ set-window-title" # Kitty
|
||||
end
|
||||
if test "$TERM_PROGRAM" = WezTerm
|
||||
# @category Terminal Windows, Tabs, and Panes
|
||||
# @desc Set window title
|
||||
abbr -a :tw wezterm cli set-window-title # WezTerm
|
||||
end
|
||||
|
||||
# Rename Workspace
|
||||
if test "$TERM_PROGRAM" = WezTerm
|
||||
# @category Terminal Windows, Tabs, and Panes
|
||||
# @desc Rename workspace (WezTerm only)
|
||||
abbr -a :twk wezterm cli rename-workspace # WezTerm
|
||||
end
|
||||
# Kitty does not have a direct CLI equivalent for renaming a dynamic "workspace" session.
|
||||
|
||||
# Tab Navigation
|
||||
if test "$TERM" = xterm-kitty
|
||||
# @category Terminal Windows, Tabs, and Panes
|
||||
# @desc Focus previous tab
|
||||
abbr -a :tp "kitty @ focus-tab --match neighbor:left" # Kitty
|
||||
# @category Terminal Windows, Tabs, and Panes
|
||||
# @desc Focus next tab
|
||||
abbr -a :tn "kitty @ focus-tab --match neighbor:right" # Kitty
|
||||
end
|
||||
if test "$TERM_PROGRAM" = WezTerm
|
||||
# @category Terminal Windows, Tabs, and Panes
|
||||
# @desc Focus previous tab
|
||||
abbr -a :tp wezterm cli activate-tab --tab-relative -1 # WezTerm
|
||||
# @category Terminal Windows, Tabs, and Panes
|
||||
# @desc Focus next tab
|
||||
abbr -a :tn wezterm cli activate-tab --tab-relative 1 # WezTerm
|
||||
end
|
||||
|
||||
# Specialty Tab Shortcuts (New Tab in specific dir)
|
||||
if test "$TERM" = xterm-kitty
|
||||
# @category Terminal Windows, Tabs, and Panes
|
||||
# @desc New tab at ~/.config/kitty
|
||||
abbr -a :tgk kitty @ launch --type=tab --cwd ~/.config/kitty # Kitty
|
||||
# @category Terminal Windows, Tabs, and Panes
|
||||
# @desc New tab at ~/.config/nvim
|
||||
abbr -a :tgn kitty @ launch --type=tab --cwd ~/.config/nvim # Kitty
|
||||
# @category Terminal Windows, Tabs, and Panes
|
||||
# @desc New tab at ~/.config/fish
|
||||
abbr -a :tgf kitty @ launch --type=tab --cwd ~/.config/fish # Kitty
|
||||
# @category Terminal Windows, Tabs, and Panes
|
||||
# @desc New tab at ~
|
||||
abbr -a :tgh kitty @ launch --type=tab --cwd ~
|
||||
# @category Terminal Windows, Tabs, and Panes
|
||||
# @desc New tab at ~/.local/share/chezmoi
|
||||
abbr -a :tgcz kitty @ launch --type=tab --cwd ~/.local/share/chezmoi # Kitty
|
||||
# @category Terminal Windows, Tabs, and Panes
|
||||
# @desc New tab at ~/.config/chezmoi
|
||||
abbr -a :tgcm kitty @ launch --type=tab --cwd ~/.config/chezmoi # Kitty
|
||||
# @category Terminal Windows, Tabs, and Panes
|
||||
# @desc New tab at ~/projects
|
||||
abbr -a :tgp kitty @ launch --type=tab --cwd ~/projects # Kitty
|
||||
# @category Terminal Windows, Tabs, and Panes
|
||||
# @desc New tab at / (root)
|
||||
abbr -a :tgr kitty @ launch --type=tab -- sudo -i
|
||||
end
|
||||
if test "$TERM_PROGRAM" = WezTerm
|
||||
# @category Terminal Windows, Tabs, and Panes
|
||||
# @desc New tab at ~/.config/kitty
|
||||
abbr -a :tgk wezterm cli spawn --cwd ~/.config/kitty # WezTerm
|
||||
# @category Terminal Windows, Tabs, and Panes
|
||||
# @desc New tab at ~/.config/nvim
|
||||
abbr -a :tgn wezterm cli spawn --cwd ~/.config/nvim # WezTerm
|
||||
# @category Terminal Windows, Tabs, and Panes
|
||||
# @desc New tab at ~/.config/fish
|
||||
abbr -a :tgf wezterm cli spawn --cwd ~/.config/fish # WezTerm
|
||||
# @category Terminal Windows, Tabs, and Panes
|
||||
# @desc New tab at ~
|
||||
abbr -a :tgh wezterm cli spawn --cwd ~ # WezTerm
|
||||
# @category Terminal Windows, Tabs, and Panes
|
||||
# @desc New tab at ~/.local/share/chezmoi
|
||||
abbr -a :tgcz wezterm cli spawn --cwd ~/.local/share/chezmoi # WezTerm
|
||||
# @category Terminal Windows, Tabs, and Panes
|
||||
# @desc New tab at ~/.config/chezmoi
|
||||
abbr -a :tgcm wezterm cli spawn --cwd ~/.config/chezmoi # WezTerm
|
||||
# @category Terminal Windows, Tabs, and Panes
|
||||
# @desc New tab at ~/projects
|
||||
abbr -a :tgp wezterm cli spawn --cwd ~/projects # WezTerm
|
||||
# @category Terminal Windows, Tabs, and Panes
|
||||
# @desc New tab at / (root)
|
||||
abbr -a :tgr wezterm cli spawn -- sudo -i # WezTerm
|
||||
end
|
||||
|
||||
# Specialty Window Shortcuts (New OS Window in specific dir)
|
||||
if test "$TERM" = xterm-kitty
|
||||
# @category Terminal Windows, Tabs, and Panes
|
||||
# @desc New OS window at ~/.config/kitty
|
||||
abbr -a :wgk kitty @ launch --type=os-window --cwd ~/.config/kitty # Kitty
|
||||
# @category Terminal Windows, Tabs, and Panes
|
||||
# @desc New OS window at ~/.config/nvim
|
||||
abbr -a :wgn kitty @ launch --type=os-window --cwd ~/.config/nvim # Kitty
|
||||
# @category Terminal Windows, Tabs, and Panes
|
||||
# @desc New OS window at ~/.config/fish
|
||||
abbr -a :wgf kitty @ launch --type=os-window --cwd ~/.config/fish # Kitty
|
||||
# @category Terminal Windows, Tabs, and Panes
|
||||
# @desc New OS window at ~
|
||||
abbr -a :wgh kitty @ launch --type=os-window --cwd ~
|
||||
# @category Terminal Windows, Tabs, and Panes
|
||||
# @desc New OS window at ~/.local/share/chezmoi
|
||||
abbr -a :wgzd kitty @ launch --type=os-window --cwd ~/.local/share/chezmoi # Kitty
|
||||
# @category Terminal Windows, Tabs, and Panes
|
||||
# @desc New OS window at ~/.config/chezmoi
|
||||
abbr -a :wgcz kitty @ launch --type=os-window --cwd ~/.config/chezmoi # Kitty
|
||||
# @category Terminal Windows, Tabs, and Panes
|
||||
# @desc New OS window at ~/projects
|
||||
abbr -a :wgp kitty @ launch --type=os-window --cwd ~/projects # Kitty
|
||||
# @category Terminal Windows, Tabs, and Panes
|
||||
# @desc New OS window at / (root)
|
||||
abbr -a :wgr kitty @ launch --type=os-window -- sudo -i # Kitty
|
||||
end
|
||||
if test "$TERM_PROGRAM" = WezTerm
|
||||
# @category Terminal Windows, Tabs, and Panes
|
||||
# @desc New OS window at ~/.config/kitty
|
||||
abbr -a :wgk wezterm cli spawn --new-window --cwd ~/.config/kitty # WezTerm
|
||||
# @category Terminal Windows, Tabs, and Panes
|
||||
# @desc New OS window at ~/.config/nvim
|
||||
abbr -a :wgn wezterm cli spawn --new-window --cwd ~/.config/nvim # WezTerm
|
||||
# @category Terminal Windows, Tabs, and Panes
|
||||
# @desc New OS window at ~/.config/fish
|
||||
abbr -a :wgf wezterm cli spawn --new-window --cwd ~/.config/fish # WezTerm
|
||||
# @category Terminal Windows, Tabs, and Panes
|
||||
# @desc New OS window at ~
|
||||
abbr -a :wgh wezterm cli spawn --new-window --cwd ~ # WezTerm
|
||||
# @category Terminal Windows, Tabs, and Panes
|
||||
# @desc New OS window at ~/.local/share/chezmoi
|
||||
abbr -a :wgzd wezterm cli spawn --new-window --cwd ~/.local/share/chezmoi # WezTerm
|
||||
# @category Terminal Windows, Tabs, and Panes
|
||||
# @desc New OS window at ~/.config/chezmoi
|
||||
abbr -a :wgcz wezterm cli spawn --new-window --cwd ~/.config/chezmoi # WezTerm
|
||||
# @category Terminal Windows, Tabs, and Panes
|
||||
# @desc New OS window at ~/projects
|
||||
abbr -a :wgp wezterm cli spawn --new-window --cwd ~/projects # WezTerm
|
||||
# @category Terminal Windows, Tabs, and Panes
|
||||
# @desc New OS window at / (root)
|
||||
abbr -a :wgr wezterm cli spawn --new-window -- sudo -i # WezTerm
|
||||
end
|
||||
|
||||
# Specialty Window Vertical Shortcuts (Split Bottom)
|
||||
if test "$TERM" = xterm-kitty
|
||||
# @category Terminal Windows, Tabs, and Panes
|
||||
# @desc Split bottom at ~/.config/kitty
|
||||
abbr -a :wvgk kitty @ launch --location=hsplit --cwd ~/.config/kitty # Kitty
|
||||
# @category Terminal Windows, Tabs, and Panes
|
||||
# @desc Split bottom at ~/.config/nvim
|
||||
abbr -a :wvgn kitty @ launch --location=hsplit --cwd ~/.config/nvim # Kitty
|
||||
# @category Terminal Windows, Tabs, and Panes
|
||||
# @desc Split bottom at ~/.config/fish
|
||||
abbr -a :wvgf kitty @ launch --location=hsplit --cwd ~/.config/fish # Kitty
|
||||
# @category Terminal Windows, Tabs, and Panes
|
||||
# @desc Split bottom at ~
|
||||
abbr -a :wvgh kitty @ launch --location=hsplit --cwd ~ # Kitty
|
||||
# @category Terminal Windows, Tabs, and Panes
|
||||
# @desc Split bottom at ~/.local/share/chezmoi
|
||||
abbr -a :wvgcz kitty @ launch --location=hsplit --cwd ~/.local/share/chezmoi # Kitty
|
||||
# @category Terminal Windows, Tabs, and Panes
|
||||
# @desc Split bottom at ~/.config/chezmoi
|
||||
abbr -a :wvgcm kitty @ launch --location=hsplit --cwd ~/.config/chezmoi # Kitty
|
||||
# @category Terminal Windows, Tabs, and Panes
|
||||
# @desc Split bottom at ~/projects
|
||||
abbr -a :wvgp kitty @ launch --location=hsplit --cwd ~/projects # Kitty
|
||||
# @category Terminal Windows, Tabs, and Panes
|
||||
# @desc Split bottom at / (root)
|
||||
abbr -a :wvgr kitty @ launch --location=hsplit -- sudo -i # Kitty
|
||||
end
|
||||
if test "$TERM_PROGRAM" = WezTerm
|
||||
# @category Terminal Windows, Tabs, and Panes
|
||||
# @desc Split bottom at ~/.config/kitty
|
||||
abbr -a :wvgk wezterm cli split-pane --bottom --cwd ~/.config/kitty # WezTerm
|
||||
# @category Terminal Windows, Tabs, and Panes
|
||||
# @desc Split bottom at ~/.config/nvim
|
||||
abbr -a :wvgn wezterm cli split-pane --bottom --cwd ~/.config/nvim # WezTerm
|
||||
# @category Terminal Windows, Tabs, and Panes
|
||||
# @desc Split bottom at ~/.config/fish
|
||||
abbr -a :wvgf wezterm cli split-pane --bottom --cwd ~/.config/fish # WezTerm
|
||||
# @category Terminal Windows, Tabs, and Panes
|
||||
# @desc Split bottom at ~
|
||||
abbr -a :wvgh wezterm cli split-pane --bottom --cwd ~ # WezTerm
|
||||
# @category Terminal Windows, Tabs, and Panes
|
||||
# @desc Split bottom at ~/.local/share/chezmoi
|
||||
abbr -a :wvgcz wezterm cli split-pane --bottom --cwd ~/.local/share/chezmoi # WezTerm
|
||||
# @category Terminal Windows, Tabs, and Panes
|
||||
# @desc Split bottom at ~/.config/chezmoi
|
||||
abbr -a :wvgcm wezterm cli split-pane --bottom --cwd ~/.config/chezmoi # WezTerm
|
||||
# @category Terminal Windows, Tabs, and Panes
|
||||
# @desc Split bottom at ~/projects
|
||||
abbr -a :wvgp wezterm cli split-pane --bottom --cwd ~/projects # WezTerm
|
||||
# @category Terminal Windows, Tabs, and Panes
|
||||
# @desc Split bottom at / (root)
|
||||
abbr -a :wvgr wezterm cli split-pane --bottom -- sudo -i # WezTerm
|
||||
end
|
||||
|
||||
# Specialty Window Horizontal Shortcuts (Split Right)
|
||||
if test "$TERM" = xterm-kitty
|
||||
# @category Terminal Windows, Tabs, and Panes
|
||||
# @desc Split right at ~/.config/kitty
|
||||
abbr -a :whgk kitty @ launch --location=vsplit --cwd ~/.config/kitty # Kitty
|
||||
# @category Terminal Windows, Tabs, and Panes
|
||||
# @desc Split right at ~/.config/nvim
|
||||
abbr -a :whgn kitty @ launch --location=vsplit --cwd ~/.config/nvim # Kitty
|
||||
# @category Terminal Windows, Tabs, and Panes
|
||||
# @desc Split right at ~/.config/fish
|
||||
abbr -a :whgf kitty @ launch --location=vsplit --cwd ~/.config/fish # Kitty
|
||||
# @category Terminal Windows, Tabs, and Panes
|
||||
# @desc Split right at ~
|
||||
abbr -a :whgh kitty @ launch --location=vsplit --cwd ~ # Kitty
|
||||
# @category Terminal Windows, Tabs, and Panes
|
||||
# @desc Split right at ~/.local/share/chezmoi
|
||||
abbr -a :whgcz kitty @ launch --location=vsplit --cwd ~/.local/share/chezmoi # Kitty
|
||||
# @category Terminal Windows, Tabs, and Panes
|
||||
# @desc Split right at ~/.config/chezmoi
|
||||
abbr -a :whgcm kitty @ launch --location=vsplit --cwd ~/.config/chezmoi # Kitty
|
||||
# @category Terminal Windows, Tabs, and Panes
|
||||
# @desc Split right at ~/projects
|
||||
abbr -a :whgp kitty @ launch --location=vsplit --cwd ~/projects # Kitty
|
||||
# @category Terminal Windows, Tabs, and Panes
|
||||
# @desc Split right at / (root)
|
||||
abbr -a :whgr kitty @ launch --location=vsplit --cwd current sudo -i # Kitty -> Specialty cd Shortcuts
|
||||
# @category Terminal Windows, Tabs, and Panes
|
||||
# @desc cd ~/.config/kitty
|
||||
abbr -a :cdk 'cd ~/.config/kitty/ # Kitty Config'
|
||||
# @category Terminal Windows, Tabs, and Panes
|
||||
# @desc cd ~/.config/kitty; nvim
|
||||
abbr -a :cdkn 'cd ~/.config/kitty;nvim'
|
||||
end
|
||||
if test "$TERM_PROGRAM" = WezTerm
|
||||
# @category Terminal Windows, Tabs, and Panes
|
||||
# @desc Split right at ~/.config/kitty
|
||||
abbr -a :whgk wezterm cli split-pane --bottom --cwd ~/.config/kitty # WezTerm
|
||||
# @category Terminal Windows, Tabs, and Panes
|
||||
# @desc Split right at ~/.config/nvim
|
||||
abbr -a :whgn wezterm cli split-pane --bottom --cwd ~/.config/nvim # WezTerm
|
||||
# @category Terminal Windows, Tabs, and Panes
|
||||
# @desc Split right at ~/.config/fish
|
||||
abbr -a :whgf wezterm cli split-pane --bottom --cwd ~/.config/fish # WezTerm
|
||||
# @category Terminal Windows, Tabs, and Panes
|
||||
# @desc Split right at ~
|
||||
abbr -a :whgh wezterm cli split-pane --bottom --cwd ~ # WezTerm
|
||||
# @category Terminal Windows, Tabs, and Panes
|
||||
# @desc Split right at ~/.local/share/chezmoi
|
||||
abbr -a :whgcz wezterm cli split-pane --bottom --cwd ~/.local/share/chezmoi # WezTerm
|
||||
# @category Terminal Windows, Tabs, and Panes
|
||||
# @desc Split right at ~/.config/chezmoi
|
||||
abbr -a :whgcm wezterm cli split-pane --bottom --cwd ~/.config/chezmoi # WezTerm
|
||||
# @category Terminal Windows, Tabs, and Panes
|
||||
# @desc Split right at ~/projects
|
||||
abbr -a :whgp wezterm cli split-pane --bottom --cwd ~/projects # WezTerm
|
||||
# @category Terminal Windows, Tabs, and Panes
|
||||
# @desc Split right at / (root)
|
||||
abbr -a :whgr wezterm cli split-pane --bottom -- sudo -i # WezTerm
|
||||
end
|
||||
# @category Terminal Windows, Tabs, and Panes
|
||||
# @desc cd ~/.config/nvim
|
||||
abbr -a :cdn cd '~/.config/nvim/ # Neovim Config'
|
||||
# @category Terminal Windows, Tabs, and Panes
|
||||
# @desc cd ~/.config/nvim; nvim
|
||||
abbr -a :cdnn 'cd ~/.config/nvim;nvim'
|
||||
# @category Terminal Windows, Tabs, and Panes
|
||||
# @desc cd ~/.config/fish
|
||||
abbr -a :cdf 'cd ~/.config/fish/ # Fish Config'
|
||||
# @category Terminal Windows, Tabs, and Panes
|
||||
# @desc cd ~/.config/fish; nvim
|
||||
abbr -a :cdfn 'cd ~/.config/fish;nvim'
|
||||
# @category Terminal Windows, Tabs, and Panes
|
||||
# @desc cd ~
|
||||
abbr -a :cdh 'cd ~ # Home Directory'
|
||||
# @category Terminal Windows, Tabs, and Panes
|
||||
# @desc cd ~; nvim
|
||||
abbr -a :cdhn 'cd ~;nvim'
|
||||
# @category Terminal Windows, Tabs, and Panes
|
||||
# @desc cd ~/.local/share/chezmoi
|
||||
abbr -a :cdcz cd '~/.local/share/chezmoi/ # Chezmoi Source'
|
||||
# @category Terminal Windows, Tabs, and Panes
|
||||
# @desc cd ~/.local/share/chezmoi; nvim
|
||||
abbr -a :cdczn 'cd ~/.local/share/chezmoi;nvim'
|
||||
# @category Terminal Windows, Tabs, and Panes
|
||||
# @desc cd ~/.config/chezmoi
|
||||
abbr -a :cdcm 'cd ~/.config/chezmoi/ # Chezmoi Config'
|
||||
# @category Terminal Windows, Tabs, and Panes
|
||||
# @desc cd ~/.config/chezmoi; nvim
|
||||
abbr -a :cdcmn 'cd ~/.config/chezmoi;nvim'
|
||||
# @category Terminal Windows, Tabs, and Panes
|
||||
# @desc cd ~/projects/...
|
||||
abbr -a :cdp --regex ':cdp' --set-cursor 'cd ~/projects/%'
|
||||
# abbr -a cdp_slash --position anywhere --regex ':cdp/' --set-cursor 'cd ~/projects/%'
|
||||
# @category Terminal Windows, Tabs, and Panes
|
||||
# @desc cd ~/projects; nvim
|
||||
abbr -a :cdpn 'cd ~/projects;nvim'
|
||||
# @category Terminal Windows, Tabs, and Panes
|
||||
# @desc cd ~/.config/wezterm
|
||||
abbr -a :cdw 'cd ~/.config/wezterm/ # WezTerm Config'
|
||||
# @category Terminal Windows, Tabs, and Panes
|
||||
# @desc cd ~/.config/wezterm; nvim
|
||||
abbr -a :cdwn 'cd ~/.config/wezterm;nvim'
|
||||
if test "$TERM" = xterm-kitty
|
||||
# @category Terminal Windows, Tabs, and Panes
|
||||
# @desc Open new tab with nvim (terminal-aware)
|
||||
abbr -a editt kitty @ launch --type tab nvim
|
||||
end
|
||||
# Spawn window
|
||||
if test "$TERM" = xterm-kitty
|
||||
# @category Terminal Windows, Tabs, and Panes
|
||||
# @desc spwin (spawn new OS window)
|
||||
abbr -a :sw spwin
|
||||
end
|
||||
end
|
||||
|
||||
### Docker ###
|
||||
# @category Docker
|
||||
# @desc docker context use default
|
||||
abbr -a dcl 'docker context use default # Local Host'
|
||||
# @category Docker
|
||||
# @desc ld (lazydocker)
|
||||
abbr -a lzd ld
|
||||
# @category Docker
|
||||
# @desc docker context ls
|
||||
abbr -a dcls 'docker context ls'
|
||||
|
||||
### Beads ###
|
||||
# @category Miscellaneous
|
||||
# @desc bd list
|
||||
abbr -a bl 'bd list'
|
||||
# @category Miscellaneous
|
||||
# @desc bd sync
|
||||
abbr -a bs 'bd sync'
|
||||
# @category Miscellaneous
|
||||
# @desc bd create --title
|
||||
abbr -a bC 'bd create --title'
|
||||
# @category Miscellaneous
|
||||
# @desc bd show
|
||||
abbr -a bsh 'bd show'
|
||||
# @category Miscellaneous
|
||||
# @desc lazybeads
|
||||
abbr -a lb lazybeads
|
||||
|
||||
### Systemctl ###
|
||||
# @category Systemctl
|
||||
# @desc systemctl
|
||||
abbr -a sc systemctl
|
||||
# @category Systemctl
|
||||
# @desc sudo systemctl
|
||||
abbr -a ssc 'sudo systemctl'
|
||||
# @category Systemctl
|
||||
# @desc systemctl --user
|
||||
abbr -a scu 'systemctl --user'
|
||||
# @category Systemctl
|
||||
# @desc systemctl status
|
||||
abbr -a st 'systemctl status'
|
||||
# @category Systemctl
|
||||
# @desc systemctl start
|
||||
abbr -a scs 'systemctl start'
|
||||
# @category Systemctl
|
||||
# @desc systemctl restart
|
||||
abbr -a scr 'systemctl restart'
|
||||
# @category Systemctl
|
||||
# @desc sudo systemctl status
|
||||
abbr -a ssct 'sudo systemctl status'
|
||||
# @category Systemctl
|
||||
# @desc sudo systemctl start
|
||||
abbr -a sscs 'sudo systemctl start'
|
||||
# @category Systemctl
|
||||
# @desc sudo systemctl restart
|
||||
abbr -a sscr 'sudo systemctl restart'
|
||||
|
||||
### Alternate command names ###
|
||||
# Expand to the canonical function name so muscle-memory typos still work,
|
||||
# while surfacing the real command instead of silently forwarding to it.
|
||||
# @category Miscellaneous
|
||||
# @desc repo-open
|
||||
abbr -a open-repo repo-open
|
||||
# @category Miscellaneous
|
||||
# @desc open-url
|
||||
abbr -a url-open open-url
|
||||
|
||||
### History Expansions and Substitutions ###
|
||||
# Bash-style history expansion is opinionated (C3 overrides), gated atomically
|
||||
# with conf.d/tricks.fish, conf.d/puffer.fish, and functions/expand_*.fish.
|
||||
if __fish_config_op_enabled __fish_config_op_overrides
|
||||
if __fish_config_op_enabled (status basename) abbr-overrides
|
||||
# @category History Expansion
|
||||
# @name !^
|
||||
# @desc Expand to the first argument of the previous command
|
||||
abbr -a !^ --position anywhere --function expand_bang_caret
|
||||
# @category History Expansion
|
||||
# @name !*
|
||||
# @desc Expand to all arguments of the previous command
|
||||
abbr -a '!*' --position anywhere --function expand_bang_all
|
||||
# @category History Expansion
|
||||
# @name ^old^new^
|
||||
# @desc Interactive typo substitution (replace 'old' with 'new' in previous command)
|
||||
abbr -a typo_sub --position anywhere --regex '\^([^^]+)\^([^^]*)' --function expand_typo_sub
|
||||
# @category History Expansion
|
||||
# @name !string
|
||||
# @desc Expand to the most recent command starting with 'string'
|
||||
abbr -a bang_string --position anywhere --regex '![\w.-]+' --function expand_bang_string
|
||||
# @category History Expansion
|
||||
# @name !?string?
|
||||
# @desc Expand to the most recent command containing 'string'
|
||||
abbr -a bang_search --position anywhere --regex '!\?[\w.-]+\??' --function expand_bang_search
|
||||
# @category History Expansion
|
||||
# @name !-n
|
||||
# @desc Expand to the nth-previous command
|
||||
abbr -a bang_minus_n --position anywhere --regex '!-(\d+)' --function expand_bang_minus_n
|
||||
end
|
||||
|
||||
@@ -0,0 +1,65 @@
|
||||
# Copyright (C) 2026 Rootiest
|
||||
# SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
# ╭──────────────────────────────────────────────────────────╮
|
||||
# │ Auto-Pull (C2 — Autoexec) │
|
||||
# ╰──────────────────────────────────────────────────────────╯
|
||||
#
|
||||
# Background, fast-forward-only `git pull` for opted-in repositories. Fires
|
||||
# when the working directory enters the fish-config repo (always covered as a
|
||||
# baseline) or any repository registered via the `auto-pull` command. The
|
||||
# actual sync is delegated to `_auto_pull_sync`, which only ever fast-forwards
|
||||
# a clean repo — see that function for the full safety contract.
|
||||
#
|
||||
# Manage the registry with: auto-pull add / remove / list / status
|
||||
|
||||
# C2 guard: when auto-execution is disabled, do not register the handler.
|
||||
__fish_config_op_enabled (status basename); or exit
|
||||
|
||||
# COMPONENT
|
||||
# autoexec/sync
|
||||
#
|
||||
# SYNOPSIS
|
||||
# __auto_pull_on_pwd (event handler, --on-variable PWD)
|
||||
#
|
||||
# DESCRIPTION
|
||||
# On every directory change, checks whether the new $PWD is inside a
|
||||
# registered repository (or the fish-config baseline) and, if so, kicks a
|
||||
# background fast-forward. A throttle global ensures it fires once per
|
||||
# repository entry rather than on every sub-directory change.
|
||||
function __auto_pull_on_pwd --on-variable PWD
|
||||
set -q __fish_config_dir; or set -g __fish_config_dir $XDG_CONFIG_HOME/fish
|
||||
set -q __fish_user_dots_path; or set -l __fish_user_dots_path "$XDG_CONFIG_HOME/.user-dots/fish"
|
||||
set -l list "$__fish_user_dots_path/auto-pull.list"
|
||||
|
||||
# Candidate roots: the fish-config repo plus the user's registry.
|
||||
set -l roots $__fish_config_dir
|
||||
test -r "$list"; and set -a roots (command cat "$list" 2>/dev/null)
|
||||
|
||||
# Find the registered root containing $PWD (exact match or a sub-directory).
|
||||
set -l hit
|
||||
for r in $roots
|
||||
test -n "$r"; or continue
|
||||
if test "$PWD" = "$r"; or string match -q -- "$r/*" "$PWD"
|
||||
set hit "$r"
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
# Outside every registered repo: clear the throttle so re-entry re-syncs.
|
||||
if test -z "$hit"
|
||||
set -e __auto_pull_last
|
||||
return
|
||||
end
|
||||
|
||||
# Already synced for this repo entry — skip until we leave and return.
|
||||
test "$hit" = "$__auto_pull_last"; and return
|
||||
set -g __auto_pull_last "$hit"
|
||||
|
||||
# Background fast-forward. A --no-config child sources just the worker so
|
||||
# it stays fast and free of shell side-effects; real `git`, no shadows.
|
||||
set -l worker "$__fish_config_dir/functions/_auto_pull_sync.fish"
|
||||
test -r "$worker"; or return
|
||||
fish --no-config -c 'source $argv[1]; _auto_pull_sync $argv[2]' -- "$worker" "$hit" &
|
||||
disown 2>/dev/null
|
||||
end
|
||||
@@ -1,8 +1,11 @@
|
||||
status is-interactive || exit
|
||||
|
||||
# COMPONENT
|
||||
# overrides/key-bindings
|
||||
|
||||
# Local modification: opinionated guard (AGENTS.md Task #3). Bracket
|
||||
# auto-pairing intercepts single-character input, classified as C3 overrides.
|
||||
__fish_config_op_enabled __fish_config_op_overrides || exit
|
||||
__fish_config_op_enabled (status basename) || exit
|
||||
|
||||
set --global autopair_left "(" "[" "{" '"' "'"
|
||||
set --global autopair_right ")" "]" "}" '"' "'"
|
||||
|
||||
@@ -0,0 +1,141 @@
|
||||
# Copyright (C) 2026 Rootiest
|
||||
# SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
# COMPONENT
|
||||
# overrides/key-bindings
|
||||
|
||||
# Provides bash-style history expansion functions for abbreviations.
|
||||
# These functions are gated by the C3 overrides switch.
|
||||
|
||||
# Execute expand_bang_all
|
||||
function expand_bang_all --description 'Execute expand_bang_all'
|
||||
# Opinionated guard (C3): no expansion when overrides are disabled.
|
||||
__fish_config_op_enabled (status basename); or return 1
|
||||
|
||||
set -l token $argv[1]
|
||||
if test -z "$token"; set token (commandline -t); end
|
||||
|
||||
set -l tokens (string split -n " " -- $history[1])
|
||||
if test (count $tokens) -gt 1
|
||||
echo -- (string join " " -- $tokens[2..-1])
|
||||
else
|
||||
echo -- $token
|
||||
end
|
||||
end
|
||||
|
||||
# Execute expand_bang_caret
|
||||
function expand_bang_caret --description 'Execute expand_bang_caret'
|
||||
# Opinionated guard (C3): no expansion when overrides are disabled.
|
||||
__fish_config_op_enabled (status basename); or return 1
|
||||
|
||||
# Split the last history item into a list
|
||||
set -l tokens (string split -n ' ' -- $history[1])
|
||||
# tokens[1] is the command, tokens[2] is the first argument
|
||||
if set -q tokens[2]
|
||||
echo -- $tokens[2]
|
||||
end
|
||||
end
|
||||
|
||||
# Execute expand_bang_minus_n
|
||||
function expand_bang_minus_n --description 'Execute expand_bang_minus_n'
|
||||
# Opinionated guard (C3): no expansion when overrides are disabled.
|
||||
__fish_config_op_enabled (status basename); or return 1
|
||||
|
||||
set -l token $argv[1]
|
||||
if test -z "$token"; set token (commandline -t); end
|
||||
|
||||
# Extract the number from the regex match
|
||||
if string match -qr '!-(\d+)' -- "$token"
|
||||
set -l n (string match -r '!-(\d+)' -- "$token")[2]
|
||||
|
||||
if test (count $history) -ge $n
|
||||
echo -- $history[$n]
|
||||
else
|
||||
echo -- $token
|
||||
end
|
||||
else
|
||||
echo -- $token
|
||||
end
|
||||
end
|
||||
|
||||
# Execute expand_bang_search
|
||||
function expand_bang_search --description 'Execute expand_bang_search'
|
||||
# Opinionated guard (C3): no expansion when overrides are disabled.
|
||||
__fish_config_op_enabled (status basename); or return 1
|
||||
|
||||
set -l token $argv[1]
|
||||
if test -z "$token"
|
||||
set token (commandline -t)
|
||||
end
|
||||
|
||||
# Extract query: looks for text after !? and before an optional ?
|
||||
set -l query (string match -r '!\?([^?]+)' -- $token)[2]
|
||||
|
||||
if test -n "$query"
|
||||
# Search history for a match anywhere in the command
|
||||
set -l match (builtin history search --contains --max=1 -- $query)
|
||||
|
||||
if test -n "$match"
|
||||
echo -- $match
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
echo -- $token
|
||||
end
|
||||
|
||||
# Execute expand_bang_string
|
||||
function expand_bang_string --description 'Execute expand_bang_string'
|
||||
# Opinionated guard (C3): no expansion when overrides are disabled.
|
||||
__fish_config_op_enabled (status basename); or return 1
|
||||
|
||||
# Fish 4.x passes the matched token as argv[1]
|
||||
set -l token $argv[1]
|
||||
if test -z "$token"
|
||||
set token (commandline -t)
|
||||
end
|
||||
|
||||
# Remove the '!' to get the search query
|
||||
set -l query (string sub -s 2 -- $token)
|
||||
|
||||
if test -n "$query"
|
||||
# Search history for a prefix match
|
||||
set -l match (builtin history search --prefix --max=1 -- $query)
|
||||
|
||||
if test -n "$match"
|
||||
echo -- $match
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
# If no match or empty query, return the token so it doesn't vanish
|
||||
echo -- $token
|
||||
end
|
||||
|
||||
# Execute expand_typo_sub
|
||||
function expand_typo_sub --description 'Execute expand_typo_sub'
|
||||
# Opinionated guard (C3): no expansion when overrides are disabled.
|
||||
__fish_config_op_enabled (status basename); or return 1
|
||||
|
||||
# In newer Fish, the matched token is often passed as $argv[1]
|
||||
# if the abbr is set up correctly. We'll fallback to commandline just in case.
|
||||
set -l last_cmd $history[1]
|
||||
set -l current_token $argv[1]
|
||||
if test -z "$current_token"
|
||||
set current_token (commandline -t)
|
||||
end
|
||||
|
||||
if string match -qr '\^([^^]+)\^([^^]*)' -- "$current_token"
|
||||
set -l captured (string match -r '\^([^^]+)\^([^^]*)' -- "$current_token")
|
||||
set -l old $captured[2]
|
||||
set -l new $captured[3]
|
||||
|
||||
if test -n "$old"
|
||||
# Using -- to ensure strings starting with '-' aren't treated as flags
|
||||
echo -- (string replace -a -- "$old" "$new" "$last_cmd")
|
||||
end
|
||||
else
|
||||
# Return the token itself so it doesn't vanish
|
||||
echo -- "$current_token"
|
||||
end
|
||||
end
|
||||
+4
-1
@@ -19,6 +19,9 @@
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
# SOFTWARE.
|
||||
#
|
||||
# COMPONENT
|
||||
# integrations/notifications
|
||||
|
||||
if not status is-interactive
|
||||
exit
|
||||
@@ -26,7 +29,7 @@ end
|
||||
|
||||
# Local modification: opinionated guard (AGENTS.md Task #3). Desktop
|
||||
# notifications assume a graphical session, classified as C4 integrations.
|
||||
__fish_config_op_enabled __fish_config_op_integrations; or exit
|
||||
__fish_config_op_enabled (status basename); or exit
|
||||
|
||||
set -g __done_version 1.19.1
|
||||
|
||||
|
||||
+16
-2
@@ -7,6 +7,10 @@
|
||||
#
|
||||
# Runs exactly once on the first interactive fish session after install.
|
||||
# To reset for testing, run: set -Ue __fish_config_first_run_complete
|
||||
#
|
||||
# COMPONENT
|
||||
# site first-run-greeting: greeting/first-run
|
||||
# site first-run-bootstrap: autoexec/plugin-management
|
||||
|
||||
# Exit early in non-interactive shells (scripts, completions, subshells)
|
||||
if not status is-interactive
|
||||
@@ -22,11 +26,21 @@ end
|
||||
# leave the shell in a state that re-triggers everything next session.
|
||||
set -U __fish_config_first_run_complete 1
|
||||
|
||||
# ──────────────────────────── Man page symlink ──────────────────────────
|
||||
# Install fish-config.1 into the user man database once, like an install step.
|
||||
# Unconditional: standard enough that no category gate is warranted.
|
||||
set -l _man1 ~/.local/share/man/man1
|
||||
set -l _src ~/.config/fish/docs/fish-config.1
|
||||
if test -f $_src; and not test -L $_man1/fish-config.1
|
||||
mkdir -p $_man1
|
||||
ln -sf $_src $_man1/fish-config.1
|
||||
end
|
||||
|
||||
# ──────────────────────────── Welcome message ───────────────────────────
|
||||
# Printing a first-run welcome banner is opinionated (C6 greeting). The
|
||||
# first-run state variable is already set unconditionally above, so
|
||||
# disabling the greeting never re-triggers this file.
|
||||
if __fish_config_op_enabled __fish_config_op_greeting
|
||||
if __fish_config_op_enabled (status basename) first-run-greeting
|
||||
echo ""
|
||||
echo " Welcome to your fish shell configuration!"
|
||||
echo " Run 'help config' for offline documentation."
|
||||
@@ -38,7 +52,7 @@ end
|
||||
# Startup side-effects below (Fisher curl, fisher update, theme apply) are
|
||||
# opinionated (C2 auto-execution). The first-run state variable is already
|
||||
# set above either way, so disabling auto-exec never re-triggers this file.
|
||||
if not __fish_config_op_enabled __fish_config_op_autoexec
|
||||
if not __fish_config_op_enabled (status basename) first-run-bootstrap
|
||||
return
|
||||
end
|
||||
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
# Copyright (C) 2026 Rootiest
|
||||
# SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
#
|
||||
# ╭──────────────────────────────────────────────────────────╮
|
||||
# │ help config wrapper │
|
||||
# ╰──────────────────────────────────────────────────────────╯
|
||||
#
|
||||
# COMPONENT
|
||||
# aliases/shell-tools
|
||||
#
|
||||
# SYNOPSIS
|
||||
# help [topic] [sub-topic...]
|
||||
# help config [section] [-w|--html] [-m|--man] [-h|--help]
|
||||
#
|
||||
# DESCRIPTION
|
||||
# Wraps the built-in Fish help command. Intercepts the specific topic
|
||||
# "config" and forwards any subsequent sub-topics/arguments straight to the
|
||||
# custom 'config-help' utility. For all other topics, it forwards the
|
||||
# arguments intact to the original, built-in system help utility.
|
||||
#
|
||||
# When the first argument is "config", the following flags are recognized
|
||||
# and delegated to 'config-help':
|
||||
# -w, --html Open the offline HTML docs in the default browser
|
||||
# -m, --man Open the compiled man page via man -l
|
||||
# -h, --help Print config-help usage reference
|
||||
#
|
||||
# Flags that appear WITHOUT a leading "config" argument — including
|
||||
# -h/--help — are forwarded unchanged to the native Fish help command, so
|
||||
# built-in behavior is never overridden for non-config topics.
|
||||
#
|
||||
# NOTES
|
||||
# To prevent infinite recursion, the wrapper backs up the native help
|
||||
# function as '__original_help' before shadowing it. This MUST happen from
|
||||
# conf.d, not functions/help.fish: as of Fish 4.x the native help is
|
||||
# embedded in the binary (embedded:functions/help.fish) with no on-disk
|
||||
# file to source, and a functions/help.fish autoload shadow makes the name
|
||||
# 'help' resolve to our own wrapper (or nothing, mid-autoload) — so the
|
||||
# backup could never capture the real help. Sourced here at startup, before
|
||||
# any shadow exists, `functions -c help` copies the embedded original.
|
||||
#
|
||||
# EXAMPLE
|
||||
# help config keys # → config-help keys
|
||||
# help config --html # opens the offline HTML docs in the browser
|
||||
# help config keys --man # opens the compiled man page via man -l
|
||||
# help string # forwards to native fish docs for 'string'
|
||||
|
||||
# --- Initialization & Backup ---
|
||||
# Copy the native (embedded) help to __original_help before we shadow it.
|
||||
if not functions -q __original_help
|
||||
functions -c help __original_help
|
||||
end
|
||||
|
||||
# --- Wrapper Definition ---
|
||||
function help --wraps help --description "Custom wrapper to intercept 'help config'"
|
||||
# Opinionated guard (C1): fall back to the native fish help when disabled.
|
||||
if not __fish_config_op_enabled (status current-function)
|
||||
__original_help $argv
|
||||
return $status
|
||||
end
|
||||
|
||||
if test "$argv[1]" = config
|
||||
# All arguments after 'config' — including flags (-w/--html, -m/--man,
|
||||
# -h/--help) and section keywords — are forwarded to config-help.
|
||||
# Flags are only intercepted here when 'config' is the first argument,
|
||||
# so native fish help flags are never shadowed for other topics.
|
||||
config-help $argv[2..]
|
||||
else
|
||||
__original_help $argv
|
||||
end
|
||||
end
|
||||
@@ -8,6 +8,9 @@
|
||||
# This file defines custom key bindings for the Fish shell.
|
||||
# It is sourced by Fish on startup.
|
||||
|
||||
# COMPONENT
|
||||
# overrides/key-bindings
|
||||
|
||||
# ────────────────── Bind Prewious Path Head to Ctrl+G ─────────────────
|
||||
# Bindings to insert the previous path head into the command line
|
||||
# Behaves like `!$:h` does in bash
|
||||
@@ -48,7 +51,11 @@ function fish_user_key_bindings
|
||||
|
||||
# Custom key chords are opinionated (C3 overrides); skip them entirely
|
||||
# when overrides are disabled so stock bindings remain untouched.
|
||||
__fish_config_op_enabled __fish_config_op_overrides; or return
|
||||
# NOTE: (status basename), not (status current-function) -- this guard
|
||||
# lives inside fish's own reserved fish_user_key_bindings function, whose
|
||||
# name is not this file's identity; the registry key is this file's
|
||||
# bare basename, key_bindings.
|
||||
__fish_config_op_enabled (status basename); or return
|
||||
|
||||
# ───────────────────────────── Set Bindings ─────────────────────────────
|
||||
#
|
||||
@@ -59,6 +66,8 @@ function fish_user_key_bindings
|
||||
type -q qalc && bind ctrl-alt-= _qalc_eval
|
||||
bind ctrl-enter _smart_execute
|
||||
bind @@ __fzf_inline_picker
|
||||
bind ctrl-right nextd-or-forward-word
|
||||
bind \e\[1\;5C nextd-or-forward-word
|
||||
|
||||
# Set bindings for all Vi modes:
|
||||
# 'default' is Vi-Command, 'insert' is Vi-Insert, 'visual' is Vi-Visual
|
||||
@@ -69,5 +78,7 @@ function fish_user_key_bindings
|
||||
type -q qalc && bind --mode $mode ctrl-alt-= _qalc_eval
|
||||
bind --mode $mode ctrl-enter _smart_execute
|
||||
bind --mode $mode @@ __fzf_inline_picker
|
||||
bind --mode $mode ctrl-right nextd-or-forward-word
|
||||
bind --mode $mode \e\[1\;5C nextd-or-forward-word
|
||||
end
|
||||
end
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
# Copyright (C) 2026 Rootiest
|
||||
# SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
# COMPONENT
|
||||
# logging/terminal-capture
|
||||
|
||||
#
|
||||
# C5 — Logging & Capture: a non-blocking, per-session reminder shown inside Kitty
|
||||
# when the fish-config scrollback watcher is not yet set up. It never blocks the
|
||||
# shell; it simply prints how to enable or silence it. The notice stops once the
|
||||
# user runs `kitty-logging install` (a watcher line then exists in kitty.conf) or
|
||||
# `kitty-logging dismiss` (sets the universal variable below).
|
||||
|
||||
status is-interactive; or exit
|
||||
type -q kitty; or exit
|
||||
set -q KITTY_WINDOW_ID; or exit
|
||||
__fish_config_op_enabled (status basename); or exit
|
||||
__fish_variable_check __fish_config_kitty_watcher_dismissed; and exit
|
||||
__kitty_logging_has_watcher; and exit
|
||||
|
||||
set_color --bold yellow
|
||||
echo "Kitty session logging is available but not set up."
|
||||
set_color normal
|
||||
echo " Enable: kitty-logging install"
|
||||
echo " Silence: kitty-logging dismiss"
|
||||
@@ -2,16 +2,20 @@
|
||||
# SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
#
|
||||
# Generates ~/.local/bin/paru on first run (and on version bump) when
|
||||
# /usr/bin/paru is installed. The wrapper runs paru in a PTY so progress
|
||||
# paru is installed. The wrapper runs paru in a PTY so progress
|
||||
# bars are preserved, renders the captured animation to a clean static log
|
||||
# (via scripts/clean_progress_log.py), and prunes old logs.
|
||||
|
||||
# COMPONENT
|
||||
# site paru-autoexec: autoexec/pkg-wrappers
|
||||
# site paru-logging: logging/pkg-logs
|
||||
|
||||
# Auto-generating a wrapper in ~/.local/bin is opinionated (C2 auto-exec).
|
||||
# Wrapper generation is also gated by C5 (Logging & Capture).
|
||||
__fish_config_op_enabled __fish_config_op_autoexec; or return
|
||||
__fish_config_op_enabled (status basename) paru-autoexec; or return
|
||||
|
||||
# C5 — Logging & Capture: remove generated wrapper and skip when logging is off
|
||||
if not __fish_config_op_enabled __fish_config_op_logging
|
||||
if not __fish_config_op_enabled (status basename) paru-logging
|
||||
if test -f "$HOME/.local/bin/paru"
|
||||
and grep -q "# paru-wrapper-version:" "$HOME/.local/bin/paru" 2>/dev/null
|
||||
rm -f "$HOME/.local/bin/paru"
|
||||
@@ -19,12 +23,13 @@ if not __fish_config_op_enabled __fish_config_op_logging
|
||||
return
|
||||
end
|
||||
|
||||
set -l _paru_real /usr/bin/paru
|
||||
# Resolve the real paru binary, skipping our own shim (never /usr/bin-assumed).
|
||||
set -l _paru_real (__fish_real_command paru)
|
||||
set -l _paru_wrapper "$HOME/.local/bin/paru"
|
||||
set -l _paru_wrapper_version 5
|
||||
set -l _paru_wrapper_version 6
|
||||
|
||||
# Skip entirely if the real paru binary isn't present
|
||||
test -x $_paru_real; or return
|
||||
test -x "$_paru_real"; or return
|
||||
|
||||
# Check if wrapper already exists at the expected version
|
||||
if test -f $_paru_wrapper
|
||||
@@ -48,7 +53,7 @@ printf '%s\n' \
|
||||
'' \
|
||||
'# Build a safely-quoted command string for script(1).' \
|
||||
'# script(1) allocates a PTY so paru detects a real terminal and shows progress.' \
|
||||
'cmd_str="/usr/bin/paru"' \
|
||||
"cmd_str=\"$_paru_real\"" \
|
||||
'for arg in "$@"; do' \
|
||||
' cmd_str+=" $(printf '"'"'%q'"'"' "$arg")"' \
|
||||
'done' \
|
||||
|
||||
+16
-1
@@ -1,9 +1,12 @@
|
||||
status is-interactive || exit
|
||||
|
||||
# COMPONENT
|
||||
# overrides/key-bindings
|
||||
|
||||
# Local modification: opinionated guard (AGENTS.md Task #3). Puffer's key
|
||||
# intercepts are part of the bang-bang system, gated atomically under C3
|
||||
# overrides with conf.d/tricks.fish, conf.d/abbr.fish, and expand_*.fish.
|
||||
__fish_config_op_enabled __fish_config_op_overrides || exit
|
||||
__fish_config_op_enabled (status basename) || exit
|
||||
|
||||
function _puffer_fish_key_bindings --on-variable fish_key_bindings
|
||||
set -l modes
|
||||
@@ -13,9 +16,21 @@ function _puffer_fish_key_bindings --on-variable fish_key_bindings
|
||||
set modes insert default
|
||||
end
|
||||
|
||||
# @category History Expansion
|
||||
# @name !.
|
||||
# @desc Expand .. to ../.. and so on
|
||||
bind --mode $modes[1] '.' _puffer_fish_expand_dot
|
||||
# @category History Expansion
|
||||
# @name !!
|
||||
# @desc Expand to the previous command
|
||||
bind --mode $modes[1] '!' _puffer_fish_expand_bang
|
||||
# @category History Expansion
|
||||
# @name !$
|
||||
# @desc Expand to the last argument of the previous command
|
||||
bind --mode $modes[1] '$' _puffer_fish_expand_buck
|
||||
# @category History Expansion
|
||||
# @name !*
|
||||
# @desc Expand to all arguments of the previous command
|
||||
bind --mode $modes[1] '*' _puffer_fish_expand_star
|
||||
bind --mode $modes[2] --erase '.' '!' '$' '*'
|
||||
end
|
||||
|
||||
@@ -95,8 +95,19 @@ function __sponge_register_secret_values --on-event fish_prompt
|
||||
|
||||
set -l secret_values
|
||||
|
||||
set -l sensitive_vars (set --names --export | string match --regex -- \
|
||||
'(?i)(?:TOKEN|PASSWORD|PASSWD|SECRET|API[_-]KEY|PRIVATE[_-]KEY|ACCESS[_-]KEY|AUTH[_-]KEY|CREDENTIAL|KOPIA_PASSWORD)')
|
||||
# Base credential-name tokens, plus any user-supplied extras from
|
||||
# __fish_sponge_extra_sensitive (set via config-settings → Sponge page).
|
||||
set -l _sensitive_names \
|
||||
TOKEN PASSWORD PASSWD SECRET 'API[_-]KEY' 'PRIVATE[_-]KEY' \
|
||||
'ACCESS[_-]KEY' 'AUTH[_-]KEY' CREDENTIAL KOPIA_PASSWORD \
|
||||
$__fish_sponge_extra_sensitive
|
||||
set -l _sensitive_alt (string join '|' $_sensitive_names)
|
||||
|
||||
# --entire returns the full matching variable NAME (e.g. GITHUB_TOKEN), not
|
||||
# just the matched token substring (TOKEN) — required so $$var below
|
||||
# dereferences the real variable instead of an unset partial name.
|
||||
set -l sensitive_vars (set --names --export | string match --regex --entire -- \
|
||||
"(?i)(?:$_sensitive_alt)")
|
||||
|
||||
for var in $sensitive_vars
|
||||
# Take only the first element — array vars yield multiple values.
|
||||
|
||||
@@ -1,12 +1,16 @@
|
||||
# Copyright (C) 2026 Rootiest
|
||||
# SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
# COMPONENT
|
||||
# overrides/prompt
|
||||
|
||||
#
|
||||
# Defines fish_prompt only when starship is installed.
|
||||
# Without starship, fish's built-in prompt already emits OSC 133;A
|
||||
# on the prompt line itself, so no wrapper is needed.
|
||||
|
||||
# Replacing the prompt is opinionated (C3 overrides)
|
||||
__fish_config_op_enabled __fish_config_op_overrides; or return
|
||||
__fish_config_op_enabled (status basename); or return
|
||||
|
||||
type -q starship; or return
|
||||
|
||||
|
||||
+5
-1
@@ -1,5 +1,9 @@
|
||||
# Copyright (C) 2026 Rootiest
|
||||
# SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
# COMPONENT
|
||||
# overrides/prompt
|
||||
|
||||
#
|
||||
# ╭──────────────────────────────────────────────────────────╮
|
||||
# │ Fish Theme │
|
||||
@@ -9,7 +13,7 @@
|
||||
# Forcing theme colors and $FZF_DEFAULT_OPTS is opinionated (C3 overrides).
|
||||
# The FZF variable is universal, so clean up our Catppuccin value if it
|
||||
# lingers from a session where overrides were still enabled.
|
||||
if not __fish_config_op_enabled __fish_config_op_overrides
|
||||
if not __fish_config_op_enabled (status basename)
|
||||
if set -q FZF_DEFAULT_OPTS; and string match -q '*#1E1E2E*' -- "$FZF_DEFAULT_OPTS"
|
||||
set --erase FZF_DEFAULT_OPTS
|
||||
end
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
# Copyright (C) 2026 Rootiest
|
||||
# SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
# COMPONENT
|
||||
# logging/multiplexer-capture
|
||||
|
||||
#
|
||||
# C5 — Logging & Capture: starts a pipe-pane log for the current tmux pane
|
||||
# when fish launches inside a tmux session. Each fish shell gets its own
|
||||
# timestamped log file in SCROLLBACK_HISTORY_DIR (default: ~/.terminal_history).
|
||||
# Naming: tmux_<session>-w<window>-p<pane>_YYYY-MM-DD_HH-MM-SS.log
|
||||
|
||||
__fish_config_op_enabled (status basename); or exit
|
||||
status is-interactive; or exit
|
||||
type -q tmux; or exit
|
||||
set -q TMUX; or exit
|
||||
|
||||
_tmux_pipe_log
|
||||
+54
-11
@@ -7,6 +7,11 @@
|
||||
# │ system aliases, and history/backup utilities │
|
||||
# ╰──────────────────────────────────────────────────────────╯
|
||||
|
||||
# COMPONENT
|
||||
# site aliases-tricks: aliases/filesystem
|
||||
# site tricks-manpager: overrides/environment
|
||||
# site tricks-bang: overrides/key-bindings
|
||||
|
||||
## Environment setup
|
||||
# Apply .profile: use this to put fish compatible .profile stuff in
|
||||
if test -f ~/.fish_profile
|
||||
@@ -17,20 +22,14 @@ end
|
||||
fish_add_path ~/.local/bin
|
||||
fish_add_path ~/Applications/depot_tools
|
||||
|
||||
# Expose user-local man pages and keep fish-config.1 symlink current
|
||||
# Expose user-local man pages
|
||||
if not contains ~/.local/share/man $MANPATH
|
||||
set -gx MANPATH ~/.local/share/man $MANPATH
|
||||
end
|
||||
set -l _man1 ~/.local/share/man/man1
|
||||
set -l _src ~/.config/fish/docs/fish-config.1
|
||||
if test -f $_src; and not test -L $_man1/fish-config.1
|
||||
mkdir -p $_man1
|
||||
ln -sf $_src $_man1/fish-config.1
|
||||
end
|
||||
|
||||
# Format man pages using bat (only if bat is installed)
|
||||
# Overriding $MANPAGER is opinionated (C3 overrides)
|
||||
if type -q bat; and __fish_config_op_enabled __fish_config_op_overrides
|
||||
if type -q bat; and __fish_config_op_enabled (status basename) tricks-manpager
|
||||
set -gx MANROFFOPT -c
|
||||
set -gx MANPAGER "sh -c 'col -bx | bat -l man -p'"
|
||||
end
|
||||
@@ -43,7 +42,7 @@ set -gx __done_notification_urgency_level low
|
||||
# Functions needed for !! and !$ https://github.com/oh-my-fish/plugin-bang-bang
|
||||
# The bang-bang system is opinionated (C3 overrides) and is gated atomically
|
||||
# here, in conf.d/abbr.fish, conf.d/puffer.fish, and functions/expand_*.fish.
|
||||
if __fish_config_op_enabled __fish_config_op_overrides
|
||||
if __fish_config_op_enabled (status basename) tricks-bang
|
||||
function __history_previous_command
|
||||
switch (commandline -t)
|
||||
case "!"
|
||||
@@ -66,10 +65,22 @@ if __fish_config_op_enabled __fish_config_op_overrides
|
||||
|
||||
# Apply bang-bang key bindings based on current key binding mode
|
||||
if [ "$fish_key_bindings" = fish_vi_key_bindings ]
|
||||
# @category History Expansion
|
||||
# @name !!
|
||||
# @desc Expand to the previous command
|
||||
bind -Minsert ! __history_previous_command
|
||||
# @category History Expansion
|
||||
# @name !$
|
||||
# @desc Expand to the last argument of the previous command
|
||||
bind -Minsert '$' __history_previous_command_arguments
|
||||
else
|
||||
# @category History Expansion
|
||||
# @name !!
|
||||
# @desc Expand to the previous command
|
||||
bind ! __history_previous_command
|
||||
# @category History Expansion
|
||||
# @name !$
|
||||
# @desc Expand to the last argument of the previous command
|
||||
bind '$' __history_previous_command_arguments
|
||||
end
|
||||
end
|
||||
@@ -77,7 +88,7 @@ end
|
||||
# Fish command history override to show timestamps
|
||||
# Shadowing the history command is opinionated (C1 aliasing); when disabled,
|
||||
# the function is never defined and fish's stock history behavior applies.
|
||||
if __fish_config_op_enabled __fish_config_op_aliases
|
||||
if __fish_config_op_enabled (status basename) aliases-tricks
|
||||
function history
|
||||
builtin history --show-time='%F %T '
|
||||
end
|
||||
@@ -100,23 +111,47 @@ end
|
||||
## Useful aliases
|
||||
|
||||
# Navigation short-cuts
|
||||
# @category Shell Aliases
|
||||
# @desc cd ..
|
||||
alias ..='cd ..'
|
||||
# @category Shell Aliases
|
||||
# @desc cd ../..
|
||||
alias ...='cd ../..'
|
||||
# @category Shell Aliases
|
||||
# @desc cd ../../..
|
||||
alias ....='cd ../../..'
|
||||
# @category Shell Aliases
|
||||
# @desc cd ../../../..
|
||||
alias .....='cd ../../../..'
|
||||
# @category Shell Aliases
|
||||
# @desc cd ../../../../..
|
||||
alias ......='cd ../../../../..'
|
||||
|
||||
# Silent flag injection into POSIX tools is opinionated (C1 aliasing)
|
||||
if __fish_config_op_enabled __fish_config_op_aliases
|
||||
if __fish_config_op_enabled (status basename) aliases-tricks
|
||||
# Tools & Core command color overrides
|
||||
# @category Shell Aliases
|
||||
# @desc dir --color=auto
|
||||
alias dir='dir --color=auto'
|
||||
# @category Shell Aliases
|
||||
# @desc vdir --color=auto
|
||||
alias vdir='vdir --color=auto'
|
||||
# @category Shell Aliases
|
||||
# @desc grep --color=auto
|
||||
alias grep='grep --color=auto'
|
||||
# @category Shell Aliases
|
||||
# @desc fgrep --color=auto
|
||||
alias fgrep='fgrep --color=auto'
|
||||
# @category Shell Aliases
|
||||
# @desc egrep --color=auto
|
||||
alias egrep='egrep --color=auto'
|
||||
|
||||
# Safety aliases (Confirmation before overwriting/deleting)
|
||||
# @category Shell Aliases
|
||||
# @desc cp -i
|
||||
alias cp="cp -i"
|
||||
# @category Shell Aliases
|
||||
# @desc mv -i
|
||||
alias mv="mv -i"
|
||||
|
||||
# Force wget to resume partial downloads
|
||||
@@ -124,9 +159,17 @@ if __fish_config_op_enabled __fish_config_op_aliases
|
||||
end
|
||||
|
||||
# Archives and networking short-hands
|
||||
# @category Shell Aliases
|
||||
# @desc tar -acf
|
||||
alias tarnow='tar -acf '
|
||||
# @category Shell Aliases
|
||||
# @desc tar -zxvf
|
||||
alias untar='tar -zxvf '
|
||||
# @category Shell Aliases
|
||||
# @desc nc termbin.com 9999
|
||||
alias tb='nc termbin.com 9999'
|
||||
|
||||
# System Logs
|
||||
# @category Shell Aliases
|
||||
# @desc journalctl -p 3 -xb
|
||||
alias jctl="journalctl -p 3 -xb"
|
||||
|
||||
@@ -5,11 +5,15 @@
|
||||
# see: https://github.com/ik11235/wakatime.fish
|
||||
###
|
||||
|
||||
# COMPONENT
|
||||
# site wakatime-autoexec: autoexec/telemetry
|
||||
# site wakatime-hook: integrations/notifications
|
||||
|
||||
# Local modification: opinionated guard (AGENTS.md Task #3). WakaTime
|
||||
# reporting is classified under both C2 auto-execution and C4 integrations;
|
||||
# disabling either category skips registering the hook.
|
||||
__fish_config_op_enabled __fish_config_op_autoexec; or exit
|
||||
__fish_config_op_enabled __fish_config_op_integrations; or exit
|
||||
__fish_config_op_enabled (status basename) wakatime-autoexec; or exit
|
||||
__fish_config_op_enabled (status basename) wakatime-hook; or exit
|
||||
|
||||
function __register_wakatime_fish_before_exec -e fish_postexec
|
||||
if set -q FISH_WAKATIME_DISABLED
|
||||
|
||||
+12
-7
@@ -2,16 +2,20 @@
|
||||
# SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
#
|
||||
# Generates ~/.local/bin/yay on first run (and on version bump) when
|
||||
# /usr/bin/yay is installed. The wrapper runs yay in a PTY so progress
|
||||
# yay is installed. The wrapper runs yay in a PTY so progress
|
||||
# bars are preserved, renders the captured animation to a clean static log
|
||||
# (via scripts/clean_progress_log.py), and prunes old logs.
|
||||
|
||||
# COMPONENT
|
||||
# site yay-autoexec: autoexec/pkg-wrappers
|
||||
# site yay-logging: logging/pkg-logs
|
||||
|
||||
# Auto-generating a wrapper in ~/.local/bin is opinionated (C2 auto-exec).
|
||||
# Wrapper generation is also gated by C5 (Logging & Capture).
|
||||
__fish_config_op_enabled __fish_config_op_autoexec; or return
|
||||
__fish_config_op_enabled (status basename) yay-autoexec; or return
|
||||
|
||||
# C5 — Logging & Capture: remove generated wrapper and skip when logging is off
|
||||
if not __fish_config_op_enabled __fish_config_op_logging
|
||||
if not __fish_config_op_enabled (status basename) yay-logging
|
||||
if test -f "$HOME/.local/bin/yay"
|
||||
and grep -q "# yay-wrapper-version:" "$HOME/.local/bin/yay" 2>/dev/null
|
||||
rm -f "$HOME/.local/bin/yay"
|
||||
@@ -19,12 +23,13 @@ if not __fish_config_op_enabled __fish_config_op_logging
|
||||
return
|
||||
end
|
||||
|
||||
set -l _yay_real /usr/bin/yay
|
||||
# Resolve the real yay binary, skipping our own shim (never /usr/bin-assumed).
|
||||
set -l _yay_real (__fish_real_command yay)
|
||||
set -l _yay_wrapper "$HOME/.local/bin/yay"
|
||||
set -l _yay_wrapper_version 5
|
||||
set -l _yay_wrapper_version 6
|
||||
|
||||
# Skip entirely if the real yay binary isn't present
|
||||
test -x $_yay_real; or return
|
||||
test -x "$_yay_real"; or return
|
||||
|
||||
# Check if wrapper already exists at the expected version
|
||||
if test -f $_yay_wrapper
|
||||
@@ -48,7 +53,7 @@ printf '%s\n' \
|
||||
'' \
|
||||
'# Build a safely-quoted command string for script(1).' \
|
||||
'# script(1) allocates a PTY so yay detects a real terminal and shows progress.' \
|
||||
'cmd_str="/usr/bin/yay"' \
|
||||
"cmd_str=\"$_yay_real\"" \
|
||||
'for arg in "$@"; do' \
|
||||
' cmd_str+=" $(printf '"'"'%q'"'"' "$arg")"' \
|
||||
'done' \
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
# Copyright (C) 2026 Rootiest
|
||||
# SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
#
|
||||
# C5 — Logging & Capture: registers a fish_exit handler that dumps the current
|
||||
# Zellij pane's scrollback to a log file when the shell exits. Unlike tmux
|
||||
# (streamed live via pipe-pane), Zellij has no continuous-capture facility, so
|
||||
# we snapshot once on exit via `zellij action dump-screen --full`.
|
||||
#
|
||||
# The handler is registered whenever fish runs inside Zellij; the C5 logging
|
||||
# guard is evaluated inside _zellij_dump_log at exit time, so toggling
|
||||
# __fish_config_op_logging takes effect on the next exit without a restart
|
||||
# (no sync_logging coordination needed, since there is no live stream to stop).
|
||||
#
|
||||
# Event-handler functions must be defined at startup (conf.d) so the --on-event
|
||||
# binding is registered; autoloaded functions in functions/ never register.
|
||||
|
||||
status is-interactive; or exit
|
||||
type -q zellij; or exit
|
||||
set -q ZELLIJ; or exit
|
||||
|
||||
function __zellij_dump_on_exit --on-event fish_exit \
|
||||
--description 'C5 event handler: dump Zellij pane scrollback on shell exit'
|
||||
_zellij_dump_log
|
||||
end
|
||||
+4
-1
@@ -3,6 +3,9 @@
|
||||
# Adapted from icezyclon/zoxide.fish (MIT)
|
||||
# Heavily customized for Fish 4.x compatibility and performance
|
||||
|
||||
# COMPONENT
|
||||
# aliases/filesystem
|
||||
|
||||
if status is-interactive
|
||||
|
||||
if type -q zoxide
|
||||
@@ -65,7 +68,7 @@ if status is-interactive
|
||||
|
||||
# Shadowing cd with zoxide is opinionated (C1 aliasing); z and zi
|
||||
# remain available either way.
|
||||
if __fish_config_op_enabled __fish_config_op_aliases
|
||||
if __fish_config_op_enabled (status basename)
|
||||
alias cd=z
|
||||
end
|
||||
|
||||
|
||||
+98
-74
@@ -7,7 +7,7 @@
|
||||
|
||||
# ───────────────────── Opinionated component guards ─────────────────────
|
||||
# Opinionated components (AGENTS.md Task #3) are wrapped in
|
||||
# __fish_config_op_enabled <category> guards throughout this file and conf.d/.
|
||||
# __fish_config_op_enabled <identity> [<site>] guards throughout this file and conf.d/.
|
||||
# The helper always evaluates the master switch __fish_config_opinionated
|
||||
# first (falsy disables everything), then the per-category opt-out variable:
|
||||
# __fish_config_op_aliases C1 — command shadows / flag injection
|
||||
@@ -15,15 +15,29 @@
|
||||
# __fish_config_op_overrides C3 — key bindings, env, prompt overrides
|
||||
# __fish_config_op_integrations C4 — terminal/tool coupling
|
||||
# __fish_config_op_logging C5 — scrollback capture / AUR log wrappers
|
||||
# (opt-in: unset means OFF)
|
||||
# __fish_config_op_greeting C6 — per-session greeting / first-run welcome
|
||||
# Example: set -U __fish_config_op_aliases off (erase to re-enable)
|
||||
# C5 is the one exception: it defaults to disabled and needs an explicit
|
||||
# truthy value — set -U __fish_config_op_logging on
|
||||
|
||||
# COMPONENT
|
||||
# site cachyos-tricks: overrides/environment
|
||||
# site cachyos-strip-aliases: aliases/filesystem
|
||||
# site cachyos-strip-overrides: overrides/key-bindings
|
||||
# site pager-editor-gpg: overrides/environment
|
||||
# site exit-wiring: overrides/key-bindings
|
||||
# site path-setup: overrides/environment
|
||||
# site cdpath: overrides/environment
|
||||
# site vi-mode: overrides/key-bindings
|
||||
# site greeting-stamp: greeting/greeting-message
|
||||
|
||||
# ──────────────────────── Source CachyOS configs ────────────────────────
|
||||
if test -f /usr/share/cachyos-fish-config/cachyos-config.fish
|
||||
source /usr/share/cachyos-fish-config/cachyos-config.fish
|
||||
# Surgically overriding the distro config is opinionated (C3 overrides):
|
||||
# skip it entirely when overrides are disabled, keeping CachyOS defaults.
|
||||
if __fish_config_op_enabled __fish_config_op_overrides
|
||||
if __fish_config_op_enabled (status basename) cachyos-tricks
|
||||
# Source our tricks over the cachyOS config
|
||||
test -f "$__fish_config_dir/conf.d/tricks.fish"
|
||||
and source "$__fish_config_dir/conf.d/tricks.fish"
|
||||
@@ -38,7 +52,7 @@ if test -f /usr/share/cachyos-fish-config/cachyos-config.fish
|
||||
# The distro config ships opinionated pieces of its own (it is the origin
|
||||
# of tricks.fish); strip them when the matching category is disabled so
|
||||
# the guards hold on CachyOS systems too.
|
||||
if not __fish_config_op_enabled __fish_config_op_aliases
|
||||
if not __fish_config_op_enabled (status basename) cachyos-strip-aliases
|
||||
for _fname in grep fgrep egrep dir vdir wget
|
||||
functions -q $_fname; and functions --erase $_fname
|
||||
end
|
||||
@@ -50,7 +64,7 @@ if test -f /usr/share/cachyos-fish-config/cachyos-config.fish
|
||||
and source $__fish_data_dir/functions/$_fname.fish
|
||||
end
|
||||
end
|
||||
if not __fish_config_op_enabled __fish_config_op_overrides
|
||||
if not __fish_config_op_enabled (status basename) cachyos-strip-overrides
|
||||
for _fname in __history_previous_command __history_previous_command_arguments
|
||||
functions -q $_fname; and functions --erase $_fname
|
||||
end
|
||||
@@ -64,66 +78,76 @@ set --erase _fname
|
||||
|
||||
# ───────────────────────────── XDG variables ────────────────────────────
|
||||
# XDG Base Directory variables (standard practice)
|
||||
set -gx XDG_CONFIG_HOME $HOME/.config # Sets default config dir to ~/.config
|
||||
set -gx XDG_CACHE_HOME $HOME/.cache # Sets default cache dir to ~/.cache
|
||||
set -gx XDG_DATA_HOME $HOME/.local/share # Sets default data dir to ~/.local/share
|
||||
set -gx XDG_STATE_HOME $HOME/.local/state # Sets default state dir to ~/.local/state
|
||||
# We set these unconditionally to ensure a consistent baseline, but only if
|
||||
# they are not already defined by the system/user.
|
||||
set -q XDG_CONFIG_HOME; or set -gx XDG_CONFIG_HOME $HOME/.config # Sets default config dir to ~/.config
|
||||
set -q XDG_CACHE_HOME; or set -gx XDG_CACHE_HOME $HOME/.cache # Sets default cache dir to ~/.cache
|
||||
set -q XDG_DATA_HOME; or set -gx XDG_DATA_HOME $HOME/.local/share # Sets default data dir to ~/.local/share
|
||||
set -q XDG_STATE_HOME; or set -gx XDG_STATE_HOME $HOME/.local/state # Sets default state dir to ~/.local/state
|
||||
|
||||
# Attempt to keep various config/cache files out of the home directory root
|
||||
set -gx RANDFILE "$XDG_STATE_HOME/rnd"
|
||||
set -gx WGETRC "$XDG_CONFIG_HOME/wget/wgetrc"
|
||||
set -gx WGET_HSTS_FILE "$XDG_CACHE_HOME/wget-hsts"
|
||||
set -gx NPM_CONFIG_PREFIX "$XDG_DATA_HOME/npm-global"
|
||||
set -gx NPM_CONFIG_USERCONFIG "$XDG_CONFIG_HOME/npm/npmrc"
|
||||
set -gx ANDROID_USER_HOME "$XDG_DATA_HOME/android"
|
||||
set -gx CARGO_HOME "$XDG_DATA_HOME/cargo"
|
||||
set -gx RUSTUP_HOME "$XDG_DATA_HOME/rustup"
|
||||
set -gx GOPATH "$XDG_DATA_HOME/go"
|
||||
set -gx BUN_INSTALL "$XDG_DATA_HOME/bun"
|
||||
set -gx GNUPGHOME "$XDG_CONFIG_HOME/gnupg"
|
||||
set -gx WAKATIME_HOME "$XDG_CONFIG_HOME/wakatime"
|
||||
set -gx HISTFILE "$XDG_STATE_HOME/bash_history"
|
||||
set -gx EXINIT "set viminfofile=$XDG_STATE_HOME/vim/viminfo | source $MYVIMRC"
|
||||
set -gx NVIDIA_SETTINGS_RW_CONFIG_FILE "$XDG_CONFIG_HOME/nvidia/settings"
|
||||
set -gx CODEIUM_HOME "$XDG_CONFIG_HOME/codeium"
|
||||
set -gx WORDLIST "$XDG_CONFIG_HOME/hunspell_en_US"
|
||||
set -q RANDFILE; or set -gx RANDFILE "$XDG_STATE_HOME/rnd"
|
||||
set -q WGETRC; or set -gx WGETRC "$XDG_CONFIG_HOME/wget/wgetrc"
|
||||
set -q WGET_HSTS_FILE; or set -gx WGET_HSTS_FILE "$XDG_CACHE_HOME/wget-hsts"
|
||||
set -q NPM_CONFIG_PREFIX; or set -gx NPM_CONFIG_PREFIX "$XDG_DATA_HOME/npm-global"
|
||||
set -q NPM_CONFIG_USERCONFIG; or set -gx NPM_CONFIG_USERCONFIG "$XDG_CONFIG_HOME/npm/npmrc"
|
||||
set -q ANDROID_USER_HOME; or set -gx ANDROID_USER_HOME "$XDG_DATA_HOME/android"
|
||||
set -q CARGO_HOME; or set -gx CARGO_HOME "$XDG_DATA_HOME/cargo"
|
||||
set -q RUSTUP_HOME; or set -gx RUSTUP_HOME "$XDG_DATA_HOME/rustup"
|
||||
set -q GOPATH; or set -gx GOPATH "$XDG_DATA_HOME/go"
|
||||
set -q BUN_INSTALL; or set -gx BUN_INSTALL "$XDG_DATA_HOME/bun"
|
||||
set -q GNUPGHOME; or set -gx GNUPGHOME "$XDG_CONFIG_HOME/gnupg"
|
||||
set -q WAKATIME_HOME; or set -gx WAKATIME_HOME "$XDG_CONFIG_HOME/wakatime"
|
||||
set -q HISTFILE; or set -gx HISTFILE "$XDG_STATE_HOME/bash_history"
|
||||
set -q EXINIT; or set -gx EXINIT "set viminfofile=$XDG_STATE_HOME/vim/viminfo | source $MYVIMRC"
|
||||
set -q NVIDIA_SETTINGS_RW_CONFIG_FILE; or set -gx NVIDIA_SETTINGS_RW_CONFIG_FILE "$XDG_CONFIG_HOME/nvidia/settings"
|
||||
set -q CODEIUM_HOME; or set -gx CODEIUM_HOME "$XDG_CONFIG_HOME/codeium"
|
||||
set -q WORDLIST; or set -gx WORDLIST "$XDG_CONFIG_HOME/hunspell_en_US"
|
||||
|
||||
# ─────────────────────────── Pager variables ────────────────────────────
|
||||
# Overriding $PAGER is opinionated (C3 overrides)
|
||||
if __fish_config_op_enabled __fish_config_op_overrides
|
||||
# Overriding $PAGER, $EDITOR, and $GPG_TTY is opinionated (C3 overrides)
|
||||
if __fish_config_op_enabled (status basename) pager-editor-gpg
|
||||
if type -q ov
|
||||
set -gx PAGER ov
|
||||
else if type -q less
|
||||
set -gx PAGER less
|
||||
end
|
||||
end
|
||||
|
||||
# ─────────────────────────── Editor variables ───────────────────────────
|
||||
# Set Editor variables with fallback to vi if nvim isn't available. This ensures that
|
||||
# tools that rely on these variables (like git commit messages) will work out of the box,
|
||||
# while still preferring nvim if it's installed.
|
||||
if type -q nvim
|
||||
set -gx NVIM_APPNAME nvim
|
||||
set -gx EDITOR (command -s nvim)
|
||||
else
|
||||
set -gx EDITOR (command -s vi)
|
||||
end
|
||||
set -gx VISUAL $EDITOR
|
||||
set -gx SUDO_EDITOR $EDITOR
|
||||
# ─────────────────────────── Editor variables ───────────────────────────
|
||||
# Set Editor variables with fallback to vi if nvim isn't available. This ensures that
|
||||
# tools that rely on these variables (like git commit messages) will work out of the box,
|
||||
# while still preferring nvim if it's installed.
|
||||
if type -q nvim
|
||||
set -gx NVIM_APPNAME nvim
|
||||
set -gx EDITOR (command -s nvim)
|
||||
else
|
||||
set -gx EDITOR (command -s vi)
|
||||
end
|
||||
# set -gx VISUAL $EDITOR # <- Use local.fish to set your preferred GUI editor.
|
||||
set -gx SUDO_EDITOR $EDITOR
|
||||
|
||||
# ──────────────────────────── GPG variables ─────────────────────────────
|
||||
# Helps ensure that GPG can prompt for passphrases correctly when invoked from the terminal.
|
||||
set -gx GPG_TTY (tty)
|
||||
# ──────────────────────────── GPG variables ─────────────────────────────
|
||||
# Helps ensure that GPG can prompt for passphrases correctly when invoked from the terminal.
|
||||
set -gx GPG_TTY (tty)
|
||||
end
|
||||
|
||||
# ────────────────────────── Scrollback History ──────────────────────────
|
||||
# Directory where scrollback history is saved into log files.
|
||||
# Optional fish-style source of truth (set -U via config-settings); exported
|
||||
# for the POSIX wrappers (paru/yay/tmux/zellij/_prune_terminal_logs) that read
|
||||
# them. We export the default unconditionally, then override from the universal
|
||||
# var only if set — deliberately NOT creating a global, which would shadow the
|
||||
# universal and stop live edits (config-settings → Paths) from taking effect.
|
||||
set -gx SCROLLBACK_HISTORY_DIR "$HOME/.terminal_history"
|
||||
# Maximum number of scrollback history files to keep
|
||||
set -q __fish_scrollback_history_dir
|
||||
and set -gx SCROLLBACK_HISTORY_DIR $__fish_scrollback_history_dir
|
||||
|
||||
set -gx SCROLLBACK_HISTORY_MAX_FILES 100
|
||||
set -q __fish_scrollback_history_max_files
|
||||
and set -gx SCROLLBACK_HISTORY_MAX_FILES $__fish_scrollback_history_max_files
|
||||
# Wire up a clean exit function that won't fire on background subshells
|
||||
# Replacing the exit builtin is opinionated (C3 overrides); smart_exit also
|
||||
# guards itself so a live toggle takes effect without restarting the shell.
|
||||
if status is-interactive; and __fish_config_op_enabled __fish_config_op_overrides
|
||||
if status is-interactive; and __fish_config_op_enabled (status basename) exit-wiring
|
||||
function exit --description 'Safe interactive exit'
|
||||
# If the smart_exit file exists in our function path, invoke it explicitly
|
||||
if functions -q smart_exit
|
||||
@@ -139,16 +163,19 @@ end
|
||||
# Adds common user bin directories to the PATH. The -mg --move option for cargo ensures that
|
||||
# the cargo bin directory is moved to the end of the PATH, which can help avoid conflicts
|
||||
# with system-installed Rust tools while still allowing user-installed cargo binaries to be found.
|
||||
fish_add_path $HOME/.local/bin # Standard user-local executables (XDG spec)
|
||||
fish_add_path $HOME/.local/share/../bin # Alternative/legacy path for local user binaries
|
||||
fish_add_path $HOME/Applications # User-installed applications and standalone apps
|
||||
fish_add_path $HOME/scripts # Custom personal shell scripts and automation
|
||||
fish_add_path -mga $CARGO_HOME/bin # Rust binaries and tools installed via Cargo
|
||||
fish_add_path $BUN_INSTALL/bin # Bun runtime executables and globally installed packages
|
||||
fish_add_path $XDG_DATA_HOME/npm-global/bin # Global Node.js/npm packages (XDG compliant location)
|
||||
fish_add_path $HOME/.lmstudio/bin # LM Studio CLI tools for local LLM management
|
||||
fish_add_path $HOME/.resend/bin # Resend email service CLI tools
|
||||
fish_add_path $HOME/.fzf/bin # Fuzzy Finder (fzf) core binary and helper scripts
|
||||
# PATH setup is opinionated (C3 overrides)
|
||||
if __fish_config_op_enabled (status basename) path-setup
|
||||
fish_add_path $HOME/.local/bin # Standard user-local executables (XDG spec)
|
||||
fish_add_path $HOME/.local/share/../bin # Alternative/legacy path for local user binaries
|
||||
fish_add_path $HOME/Applications # User-installed applications and standalone apps
|
||||
fish_add_path $HOME/scripts # Custom personal shell scripts and automation
|
||||
fish_add_path -mga $CARGO_HOME/bin # Rust binaries and tools installed via Cargo
|
||||
fish_add_path $BUN_INSTALL/bin # Bun runtime executables and globally installed packages
|
||||
fish_add_path $XDG_DATA_HOME/npm-global/bin # Global Node.js/npm packages (XDG compliant location)
|
||||
fish_add_path $HOME/.lmstudio/bin # LM Studio CLI tools for local LLM management
|
||||
fish_add_path $HOME/.resend/bin # Resend email service CLI tools
|
||||
fish_add_path $HOME/.fzf/bin # Fuzzy Finder (fzf) core binary and helper scripts
|
||||
end
|
||||
|
||||
# ───────────────────────── CDPATH projects dir ──────────────────────────
|
||||
# Allows cd-ing to directories within $HOME/projects or $HOME without needing to specify the full path.
|
||||
@@ -160,7 +187,7 @@ fish_add_path $HOME/.fzf/bin # Fuzzy Finder (fzf) core binary an
|
||||
# so if you have a directory named 'myproject' in the current directory,
|
||||
# running 'cd myproject' will take you there instead of $HOME/projects/myproject.
|
||||
# CDPATH injection is opinionated (C3 overrides)
|
||||
if __fish_config_op_enabled __fish_config_op_overrides
|
||||
if __fish_config_op_enabled (status basename) cdpath
|
||||
set -gx CDPATH . $HOME/projects $HOME
|
||||
end
|
||||
|
||||
@@ -175,7 +202,7 @@ if status is-interactive
|
||||
# This is optional but can improve the user experience for those who prefer Vi-style key bindings.
|
||||
# Global Vi mode is opinionated (C3 overrides); without it fish keeps its
|
||||
# default Emacs-style bindings.
|
||||
if __fish_config_op_enabled __fish_config_op_overrides
|
||||
if __fish_config_op_enabled (status basename) vi-mode
|
||||
set -g fish_key_bindings fish_vi_key_bindings
|
||||
end
|
||||
|
||||
@@ -215,30 +242,27 @@ if status is-interactive
|
||||
# │ This is useful for machine-specific behavior or configurations. │
|
||||
# ╰────────────────────────────── OVERRIDES ─────────────────────────────╯
|
||||
#
|
||||
# Define user-dots path variable for a more legible secrets/local config.
|
||||
set -l dot_fish "$XDG_CONFIG_HOME/.user-dots/fish"
|
||||
# ───────────────────────── Source user secrets ──────────────────────────
|
||||
# Sources a secrets.fish file if it exists, which can be used to store
|
||||
# sensitive environment variables and configurations that shouldn't be
|
||||
# committed to version control.
|
||||
# This allows you to keep things like API keys, database credentials,
|
||||
# and other secrets out of your main config files and safely ignored by git.
|
||||
test -f "$dot_fish/secrets.fish"; and source "$dot_fish/secrets.fish"
|
||||
# Resolve user-dots path. Customize via: set -U __fish_user_dots_path /your/path
|
||||
set -q __fish_user_dots_path
|
||||
or set -l __fish_user_dots_path "$XDG_CONFIG_HOME/.user-dots/fish"
|
||||
# ────────────────────── user-dots convenience symlink ───────────────────
|
||||
# Keep $__fish_config_dir/user-dots tracking the resolved path so it can be
|
||||
# browsed from the fish config dir. Git-ignored. Controlled by the
|
||||
# __fish_user_dots_symlink toggle (config-settings → Paths); creation is a
|
||||
# C2 side-effect, removal-on-opt-out is honoured regardless. See the helper.
|
||||
__fish_user_dots_link
|
||||
|
||||
# ─────────────────────── Source machine-local config ────────────────────
|
||||
# Sources a local.fish file if it exists, which can be used for machine-specific
|
||||
# variables and configurations that shouldn't be shared across machines.
|
||||
# This allows you to have different settings on different machines without affecting
|
||||
# your main config or secrets files. For example, you might want different PATH additions,
|
||||
# aliases, or environment variables on your work laptop vs. your home desktop.
|
||||
test -f "$dot_fish/local.fish"; and source "$dot_fish/local.fish"
|
||||
# Sources local.fish if it exists. That file handles sourcing its own
|
||||
# secrets.fish companion when needed.
|
||||
test -f "$__fish_user_dots_path/local.fish"; and source "$__fish_user_dots_path/local.fish"
|
||||
|
||||
# ─────────────────── C6: Greeting & First-Run UI override ───────────────
|
||||
# When the greeting category is disabled, stamp out any fish_greeting
|
||||
# function that distro configs set (e.g., CachyOS defines it as fastfetch).
|
||||
# This runs last inside the interactive block so our empty definition wins
|
||||
# over whatever cachyos-config.fish or vendor conf.d installed.
|
||||
if not __fish_config_op_enabled __fish_config_op_greeting
|
||||
if not __fish_config_op_enabled (status basename) greeting-stamp
|
||||
function fish_greeting
|
||||
end
|
||||
end
|
||||
|
||||
@@ -0,0 +1,108 @@
|
||||
admiring
|
||||
adoring
|
||||
affectionate
|
||||
agitated
|
||||
amazing
|
||||
angry
|
||||
awesome
|
||||
beautiful
|
||||
blissful
|
||||
bold
|
||||
boring
|
||||
brave
|
||||
busy
|
||||
charming
|
||||
clever
|
||||
compassionate
|
||||
competent
|
||||
condescending
|
||||
confident
|
||||
cool
|
||||
cranky
|
||||
crazy
|
||||
dazzling
|
||||
determined
|
||||
distracted
|
||||
dreamy
|
||||
eager
|
||||
ecstatic
|
||||
elastic
|
||||
elated
|
||||
elegant
|
||||
eloquent
|
||||
epic
|
||||
exciting
|
||||
fervent
|
||||
festive
|
||||
flamboyant
|
||||
focused
|
||||
friendly
|
||||
frosty
|
||||
funny
|
||||
gallant
|
||||
gifted
|
||||
goofy
|
||||
gracious
|
||||
great
|
||||
happy
|
||||
hardcore
|
||||
heuristic
|
||||
hopeful
|
||||
hungry
|
||||
infallible
|
||||
inspiring
|
||||
intelligent
|
||||
interesting
|
||||
jolly
|
||||
jovial
|
||||
keen
|
||||
kind
|
||||
laughing
|
||||
loving
|
||||
lucid
|
||||
magical
|
||||
modest
|
||||
musing
|
||||
mystifying
|
||||
naughty
|
||||
nervous
|
||||
nice
|
||||
nifty
|
||||
nostalgic
|
||||
objective
|
||||
optimistic
|
||||
peaceful
|
||||
pedantic
|
||||
pensive
|
||||
practical
|
||||
priceless
|
||||
quirky
|
||||
quizzical
|
||||
recursing
|
||||
relaxed
|
||||
reverent
|
||||
romantic
|
||||
sad
|
||||
serene
|
||||
sharp
|
||||
silly
|
||||
sleepy
|
||||
stoic
|
||||
strange
|
||||
stupefied
|
||||
suspicious
|
||||
sweet
|
||||
tender
|
||||
thirsty
|
||||
trusting
|
||||
unruffled
|
||||
upbeat
|
||||
vibrant
|
||||
vigilant
|
||||
vigorous
|
||||
wizardly
|
||||
wonderful
|
||||
xenodochial
|
||||
youthful
|
||||
zealous
|
||||
zen
|
||||
@@ -0,0 +1,223 @@
|
||||
aardvark
|
||||
albatross
|
||||
alligator
|
||||
alpaca
|
||||
ant
|
||||
anteater
|
||||
antelope
|
||||
ape
|
||||
armadillo
|
||||
baboon
|
||||
badger
|
||||
barracuda
|
||||
bat
|
||||
bear
|
||||
beaver
|
||||
bee
|
||||
bison
|
||||
boar
|
||||
buffalo
|
||||
butterfly
|
||||
camel
|
||||
capybara
|
||||
caribou
|
||||
cat
|
||||
caterpillar
|
||||
cattle
|
||||
chamois
|
||||
cheetah
|
||||
chicken
|
||||
chimpanzee
|
||||
chinchilla
|
||||
chough
|
||||
clam
|
||||
cobra
|
||||
cockroach
|
||||
cod
|
||||
cormorant
|
||||
coyote
|
||||
crab
|
||||
crane
|
||||
crocodile
|
||||
crow
|
||||
curlew
|
||||
deer
|
||||
dinosaur
|
||||
dog
|
||||
dogfish
|
||||
dolphin
|
||||
donkey
|
||||
dotterel
|
||||
dove
|
||||
dragonfly
|
||||
duck
|
||||
dugong
|
||||
dunlin
|
||||
eagle
|
||||
echidna
|
||||
eel
|
||||
eland
|
||||
elephant
|
||||
elk
|
||||
emu
|
||||
falcon
|
||||
ferret
|
||||
finch
|
||||
fish
|
||||
flamingo
|
||||
fly
|
||||
fox
|
||||
frog
|
||||
gaur
|
||||
gazelle
|
||||
gerbil
|
||||
giraffe
|
||||
gnat
|
||||
gnu
|
||||
goat
|
||||
goldfinch
|
||||
goldfish
|
||||
goose
|
||||
gorilla
|
||||
goshawk
|
||||
grasshopper
|
||||
grouse
|
||||
guanaco
|
||||
gull
|
||||
hamster
|
||||
hare
|
||||
hawk
|
||||
hedgehog
|
||||
heron
|
||||
herring
|
||||
hippopotamus
|
||||
hornet
|
||||
horse
|
||||
human
|
||||
hummingbird
|
||||
hyena
|
||||
ibex
|
||||
ibis
|
||||
jackal
|
||||
jaguar
|
||||
jay
|
||||
jellyfish
|
||||
kangaroo
|
||||
kingfisher
|
||||
koala
|
||||
kookabura
|
||||
kouprey
|
||||
kudu
|
||||
lapwing
|
||||
lark
|
||||
lemur
|
||||
leopard
|
||||
lion
|
||||
llama
|
||||
lobster
|
||||
locust
|
||||
loris
|
||||
louse
|
||||
lyrebird
|
||||
magpie
|
||||
mallard
|
||||
manatee
|
||||
mandrill
|
||||
mantis
|
||||
marten
|
||||
meerkat
|
||||
mink
|
||||
mole
|
||||
mongoose
|
||||
monkey
|
||||
moose
|
||||
mosquito
|
||||
mouse
|
||||
mule
|
||||
narwhal
|
||||
newt
|
||||
nightingale
|
||||
octopus
|
||||
okapi
|
||||
opossum
|
||||
oryx
|
||||
ostrich
|
||||
otter
|
||||
owl
|
||||
oyster
|
||||
panther
|
||||
parrot
|
||||
partridge
|
||||
peafowl
|
||||
pelican
|
||||
penguin
|
||||
pheasant
|
||||
pig
|
||||
pigeon
|
||||
pony
|
||||
porcupine
|
||||
porpoise
|
||||
quail
|
||||
quelea
|
||||
quetzal
|
||||
rabbit
|
||||
raccoon
|
||||
rail
|
||||
ram
|
||||
rat
|
||||
raven
|
||||
red-deer
|
||||
red-panda
|
||||
reindeer
|
||||
rhinoceros
|
||||
rook
|
||||
salamander
|
||||
salmon
|
||||
sand-dollar
|
||||
sandpiper
|
||||
sardine
|
||||
scorpion
|
||||
seahorse
|
||||
seal
|
||||
shark
|
||||
sheep
|
||||
shrew
|
||||
skunk
|
||||
snail
|
||||
snake
|
||||
sparrow
|
||||
spider
|
||||
spoonbill
|
||||
squid
|
||||
squirrel
|
||||
starling
|
||||
stingray
|
||||
stinkbug
|
||||
stork
|
||||
swallow
|
||||
swan
|
||||
tapir
|
||||
tarsier
|
||||
termite
|
||||
tiger
|
||||
toad
|
||||
trout
|
||||
turkey
|
||||
turtle
|
||||
viper
|
||||
vulture
|
||||
wallaby
|
||||
walrus
|
||||
wasp
|
||||
weasel
|
||||
whale
|
||||
wildcat
|
||||
wolf
|
||||
wolverine
|
||||
wombat
|
||||
woodcock
|
||||
woodpecker
|
||||
worm
|
||||
wren
|
||||
yak
|
||||
zebra
|
||||
@@ -0,0 +1,81 @@
|
||||
amber
|
||||
amethyst
|
||||
apricot
|
||||
aqua
|
||||
aquamarine
|
||||
auburn
|
||||
azure
|
||||
beige
|
||||
black
|
||||
blue
|
||||
bronze
|
||||
brown
|
||||
buff
|
||||
carmine
|
||||
celadon
|
||||
cerise
|
||||
cerulean
|
||||
charcoal
|
||||
chartreuse
|
||||
chocolate
|
||||
cinnamon
|
||||
copper
|
||||
coral
|
||||
cream
|
||||
crimson
|
||||
cyan
|
||||
denim
|
||||
emerald
|
||||
fuchsia
|
||||
gold
|
||||
goldenrod
|
||||
gray
|
||||
green
|
||||
grey
|
||||
indigo
|
||||
ivory
|
||||
jade
|
||||
khaki
|
||||
lavender
|
||||
lemon
|
||||
lilac
|
||||
lime
|
||||
magenta
|
||||
mahogany
|
||||
maroon
|
||||
mauve
|
||||
mustard
|
||||
navy
|
||||
ochre
|
||||
olive
|
||||
orange
|
||||
orchid
|
||||
peach
|
||||
pear
|
||||
periwinkle
|
||||
pink
|
||||
plum
|
||||
puce
|
||||
purple
|
||||
quartz
|
||||
red
|
||||
rose
|
||||
ruby
|
||||
rust
|
||||
salmon
|
||||
sapphire
|
||||
scarlet
|
||||
silver
|
||||
slate
|
||||
tan
|
||||
taupe
|
||||
teal
|
||||
tomato
|
||||
topaz
|
||||
turquoise
|
||||
ultramarine
|
||||
umber
|
||||
vanilla
|
||||
violet
|
||||
white
|
||||
yellow
|
||||
@@ -0,0 +1,236 @@
|
||||
agnesi
|
||||
albattani
|
||||
allen
|
||||
almeida
|
||||
antonelli
|
||||
archimedes
|
||||
ardinghelli
|
||||
aryabhata
|
||||
austin
|
||||
babbage
|
||||
banach
|
||||
banzai
|
||||
bardeen
|
||||
bartik
|
||||
bassi
|
||||
beaver
|
||||
bell
|
||||
benz
|
||||
bhabha
|
||||
bhaskara
|
||||
black
|
||||
blackburn
|
||||
blackwell
|
||||
bohr
|
||||
booth
|
||||
borg
|
||||
bose
|
||||
bouman
|
||||
boyd
|
||||
brahmagupta
|
||||
brattain
|
||||
brown
|
||||
buck
|
||||
burnell
|
||||
cannon
|
||||
carson
|
||||
cartwright
|
||||
carver
|
||||
cerf
|
||||
chandrasekhar
|
||||
chaplygin
|
||||
chatelet
|
||||
chatterjee
|
||||
chaum
|
||||
chebyshev
|
||||
clarke
|
||||
cohen
|
||||
colden
|
||||
cori
|
||||
cray
|
||||
curie
|
||||
curran
|
||||
darwin
|
||||
davinci
|
||||
dewdney
|
||||
dhawan
|
||||
diffie
|
||||
dijkstra
|
||||
dirac
|
||||
driscoll
|
||||
dubinsky
|
||||
easley
|
||||
edison
|
||||
einstein
|
||||
elbakyan
|
||||
elgamal
|
||||
elion
|
||||
ellis
|
||||
engelbart
|
||||
euclid
|
||||
euler
|
||||
faraday
|
||||
feistel
|
||||
fermat
|
||||
fermi
|
||||
feynman
|
||||
franklin
|
||||
gagarin
|
||||
galileo
|
||||
galois
|
||||
ganguly
|
||||
gates
|
||||
gauss
|
||||
germain
|
||||
goldberg
|
||||
goldstine
|
||||
goldwasser
|
||||
golick
|
||||
goodall
|
||||
gould
|
||||
greider
|
||||
grothendieck
|
||||
haibt
|
||||
hamilton
|
||||
haslett
|
||||
hawking
|
||||
heisenberg
|
||||
hellman
|
||||
hermann
|
||||
herschel
|
||||
hertz
|
||||
heyrovsky
|
||||
hodgkin
|
||||
hofstadter
|
||||
hoover
|
||||
hopper
|
||||
hugle
|
||||
hypatia
|
||||
ishizaka
|
||||
jackson
|
||||
jang
|
||||
jemison
|
||||
jennings
|
||||
jepsen
|
||||
johnson
|
||||
joliot
|
||||
jones
|
||||
kalam
|
||||
kapitsa
|
||||
kare
|
||||
keldysh
|
||||
keller
|
||||
kepler
|
||||
khayyam
|
||||
khorana
|
||||
kilby
|
||||
kirch
|
||||
knuth
|
||||
kowalevski
|
||||
lalande
|
||||
lamarr
|
||||
lamport
|
||||
leakey
|
||||
leavitt
|
||||
lederberg
|
||||
lehmann
|
||||
lewin
|
||||
lichterman
|
||||
liskov
|
||||
lovelace
|
||||
lumiere
|
||||
mahavira
|
||||
margulis
|
||||
matsumoto
|
||||
maxwell
|
||||
mayer
|
||||
mccarthy
|
||||
mcclintock
|
||||
mclaren
|
||||
mclean
|
||||
mcnulty
|
||||
meitner
|
||||
mendel
|
||||
mendeleev
|
||||
meninsky
|
||||
merkle
|
||||
mestorf
|
||||
mirzakhani
|
||||
montalcini
|
||||
moore
|
||||
morse
|
||||
moser
|
||||
murdock
|
||||
napier
|
||||
nash
|
||||
neumann
|
||||
newton
|
||||
nightingale
|
||||
nobel
|
||||
noether
|
||||
northcutt
|
||||
noyce
|
||||
panini
|
||||
pare
|
||||
pascal
|
||||
pasteur
|
||||
payne
|
||||
perlman
|
||||
pike
|
||||
poincare
|
||||
poitras
|
||||
proskuriakova
|
||||
ptolemy
|
||||
raman
|
||||
ramanujan
|
||||
rhodes
|
||||
ride
|
||||
ritchie
|
||||
robinson
|
||||
roentgen
|
||||
rosalind
|
||||
rubin
|
||||
saha
|
||||
sammet
|
||||
sanderson
|
||||
satoshi
|
||||
shamir
|
||||
shannon
|
||||
shaw
|
||||
shirley
|
||||
shockley
|
||||
shtern
|
||||
sinoussi
|
||||
snyder
|
||||
solomon
|
||||
spence
|
||||
stonebraker
|
||||
sutherland
|
||||
swanson
|
||||
swartz
|
||||
swirles
|
||||
taussig
|
||||
tesla
|
||||
tharp
|
||||
thompson
|
||||
torvalds
|
||||
tu
|
||||
turing
|
||||
varahamihira
|
||||
vaughan
|
||||
villani
|
||||
visvesvaraya
|
||||
volhard
|
||||
wescoff
|
||||
wilbur
|
||||
wiles
|
||||
williams
|
||||
williamson
|
||||
wilson
|
||||
wing
|
||||
wozniak
|
||||
wright
|
||||
wu
|
||||
yalow
|
||||
yonath
|
||||
zhukovsky
|
||||
+1296
File diff suppressed because it is too large
Load Diff
+1000
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,865 @@
|
||||
#!/usr/bin/env python3
|
||||
# Copyright (C) 2026 Rootiest
|
||||
# SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
"""Generate publishable artifacts from the docs/manual SSOT.
|
||||
|
||||
--concat one ordered markdown document for pandoc / config-help
|
||||
--site Starlight content tree + sidebar.json
|
||||
"""
|
||||
|
||||
import argparse
|
||||
import json
|
||||
import re
|
||||
import shutil
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
import manualtools as mt
|
||||
import generate_component_registry
|
||||
|
||||
DOCS = Path(__file__).parent
|
||||
MANUAL = DOCS / "manual"
|
||||
FUNCTIONS = DOCS.parent / "functions"
|
||||
SLUG_DIR = "reference"
|
||||
|
||||
|
||||
def _is_function_page(path: Path, root: Path) -> bool:
|
||||
"""True for a Section 5 category stub (not its index)."""
|
||||
rel = path.relative_to(root)
|
||||
return bool(rel.parts) and rel.parts[0].endswith("-functions") and rel.name != "index.md"
|
||||
|
||||
|
||||
def _entry_slug(title: str) -> str:
|
||||
"""The site's page slug for an entry heading."""
|
||||
return re.sub(r"[^\w-]+", "-", title.strip().lower()).strip("-")
|
||||
|
||||
|
||||
def _entry_link(name: str, functions: dict) -> str:
|
||||
"""Link a dependency name to its entry page; plain code span if unknown."""
|
||||
fn = functions.get(name)
|
||||
if not fn:
|
||||
return f"`{name}`"
|
||||
category = re.sub(r"^\d+-", "", fn["CATEGORY"][0])
|
||||
return f"[`{name}`](/{SLUG_DIR}/{category}/{_entry_slug(name)}/)"
|
||||
|
||||
|
||||
def _with_entries(body: str, path: Path, entries: dict) -> str:
|
||||
"""Append this category's generated `## name` entries to its stub body."""
|
||||
generated = entries.get(path.stem, [])
|
||||
if not generated:
|
||||
return body
|
||||
blocks = [f"## {name}\n\n{entry}" for name, entry in generated]
|
||||
return "\n\n".join(([body] if body.strip() else []) + blocks)
|
||||
|
||||
|
||||
def _with_abbreviations(body: str, abbrs: dict[str, list[dict]]) -> str:
|
||||
"""Inject generated abbreviation tables into the document placeholders."""
|
||||
rendered_abbrs = {}
|
||||
for cat, items in abbrs.items():
|
||||
lines_cat = [" Abbreviation Description", " ───────────────────────────────────────────────────────────────────"]
|
||||
for abbr in items:
|
||||
name = abbr["name"]
|
||||
desc = abbr["desc"]
|
||||
|
||||
# Left-pad description to ensure at least 2 spaces for cell split
|
||||
name_part = name.ljust(16)
|
||||
if len(name_part) < len(name) + 2:
|
||||
name_part = name + " "
|
||||
|
||||
lines_cat.append(f" {name_part}{desc}")
|
||||
rendered_abbrs[cat] = "\n".join(lines_cat)
|
||||
|
||||
for cat, table in rendered_abbrs.items():
|
||||
placeholder = f"<!-- GENERATED: {cat} -->"
|
||||
body = body.replace(placeholder, table)
|
||||
|
||||
return body
|
||||
|
||||
|
||||
def build_concat(root: Path) -> str:
|
||||
"""Concatenate the manual into one ordered markdown document.
|
||||
|
||||
Each file contributes `# {manTitle or title}` at a level matching its
|
||||
depth, and its body headings are demoted by the same amount.
|
||||
|
||||
`root / "_pandoc.yml"` (if present) holds the original document's
|
||||
pandoc metadata block (title/section/header/date/author) as raw text,
|
||||
with no frontmatter fences and no Astro-visible frontmatter key. When
|
||||
present, its contents are re-emitted byte-for-byte as the leading
|
||||
`---`-fenced block, ahead of every heading.
|
||||
"""
|
||||
entries = build_entries(mt.parse_functions(FUNCTIONS))
|
||||
chunks: list[str] = []
|
||||
pandoc_path = root / "_pandoc.yml"
|
||||
if pandoc_path.exists():
|
||||
raw = pandoc_path.read_text().rstrip("\n")
|
||||
chunks.append(f"---\n{raw}\n---")
|
||||
for path, depth in mt.walk(root):
|
||||
fm, body = mt.parse(path)
|
||||
if not fm.get("man", True):
|
||||
continue
|
||||
heading = fm.get("manTitle") or fm.get("title", path.stem)
|
||||
chunks.append("#" * (depth + 1) + " " + heading)
|
||||
if _is_function_page(path, root):
|
||||
body = _with_entries(body, path, entries)
|
||||
elif "04-abbreviations" in path.parts:
|
||||
abbrs = mt.parse_abbreviations(DOCS.parent / "conf.d")
|
||||
body = _with_abbreviations(body, abbrs)
|
||||
if body:
|
||||
body = re.sub(r"<LinkButton.*?</LinkButton>\n*", "", body, flags=re.DOTALL)
|
||||
body = re.sub(r"<CardGrid.*?</CardGrid>\n*", "", body, flags=re.DOTALL)
|
||||
body = re.sub(r"\[([^\]]+)\]\(/[^)]+\)", r"\1", body)
|
||||
chunks.append(mt.shift_headings(body, depth))
|
||||
return "\n\n".join(chunks) + "\n"
|
||||
|
||||
|
||||
SENTENCE_RE = re.compile(r"^(.+?[.!?])(\s|$)", re.S)
|
||||
PIPELINE_KEYS = ("man", "site", "manTitle", "helpKeywords")
|
||||
JSX_ATTR_ESCAPES = (
|
||||
("&", "&"),
|
||||
('"', """),
|
||||
("<", "<"),
|
||||
("{", "{"),
|
||||
)
|
||||
|
||||
|
||||
def _jsx_attr_escape(value: str) -> str:
|
||||
"""Escape a string for safe use inside a quoted JSX attribute value.
|
||||
|
||||
`&` must go first so escaping later characters doesn't double-escape
|
||||
the ampersands it introduces. `"` closes the attribute early; `<` and
|
||||
`{` are otherwise-live MDX/JSX syntax that must not be interpreted.
|
||||
"""
|
||||
for char, escape in JSX_ATTR_ESCAPES:
|
||||
value = value.replace(char, escape)
|
||||
return value
|
||||
|
||||
|
||||
def _first_sentence(body: str) -> str:
|
||||
"""Extract a one-line description from the start of an entry body.
|
||||
|
||||
The `Synopsis:` block is skipped whole — label line plus its
|
||||
deeper-indented continuation lines. It restates the calling convention,
|
||||
which the card already shows as its title, so using one as the card
|
||||
description wastes the line.
|
||||
|
||||
Source prose is hard-wrapped, so the leading paragraph is unwrapped
|
||||
before the sentence match — otherwise a card truncates at the first
|
||||
line break, mid-clause.
|
||||
"""
|
||||
para: list[str] = []
|
||||
in_fence = False
|
||||
syn_indent: int | None = None
|
||||
for raw in body.split("\n"):
|
||||
line = raw.strip()
|
||||
indent = len(raw) - len(raw.lstrip())
|
||||
if syn_indent is not None:
|
||||
if line and indent <= syn_indent:
|
||||
syn_indent = None
|
||||
else:
|
||||
continue
|
||||
if line.startswith("```"):
|
||||
in_fence = not in_fence
|
||||
if para:
|
||||
break
|
||||
continue
|
||||
if in_fence:
|
||||
continue
|
||||
if not line or line.startswith(("#", "|", "-", "*", ">")):
|
||||
if para:
|
||||
break
|
||||
continue
|
||||
if line.startswith("Synopsis:"):
|
||||
syn_indent = indent
|
||||
continue
|
||||
para.append(line)
|
||||
if not para:
|
||||
return ""
|
||||
text = " ".join(para)
|
||||
m = SENTENCE_RE.match(text)
|
||||
return (m.group(1) if m else text)[:160]
|
||||
|
||||
|
||||
# Commands common enough in this manual that a block whose every line starts
|
||||
# with one is certainly shell, not prose or a two-column reference table.
|
||||
SHELL_HEADS = frozenset(
|
||||
"""
|
||||
abbr alias apt bg bind brew builtin cargo cat cd chmod code command cp curl
|
||||
dnf docker echo end env exec export fg fish fisher for funcsave function git help
|
||||
if jobs kitty ls man math mkdir mv nvim npm pacman paru pip pip3 pkg printf
|
||||
python python3 rm set shutdown source string sudo switch systemctl test time
|
||||
tmux touch trash type wget wezterm while yay zellij zypper
|
||||
fish_default_key_bindings fish_vi_key_bindings
|
||||
""".split()
|
||||
)
|
||||
|
||||
SYNOPSIS_PREFIX = "Synopsis:"
|
||||
EXAMPLE_PREFIX = "Example:"
|
||||
INDENT = " "
|
||||
|
||||
|
||||
def _is_prose(para: list[str]) -> bool:
|
||||
"""True when a paragraph reads as sentences rather than as code or a table.
|
||||
|
||||
Column-aligned reference tables are the main thing to keep out of a
|
||||
syntax-highlighted fence, and internal runs of two-or-more spaces are
|
||||
what distinguishes them from prose. `<` and `{` are excluded because
|
||||
the emitted paragraph is live markdown, where both would be parsed.
|
||||
"""
|
||||
text = " ".join(para)
|
||||
if "<" in text or "{" in text:
|
||||
return False
|
||||
if not para or para[-1].rstrip()[-1:] not in ".:":
|
||||
return False
|
||||
return all(
|
||||
len(line.split()) >= 3 and " " not in line.strip() for line in para
|
||||
)
|
||||
|
||||
|
||||
def _is_shell(para: list[str], entry_name: str | None) -> bool:
|
||||
"""True when every line of a paragraph looks like a shell command."""
|
||||
name_re = (
|
||||
re.compile(rf"(?<![\w-]){re.escape(entry_name)}(?![\w-])")
|
||||
if entry_name
|
||||
else None
|
||||
)
|
||||
for line in para:
|
||||
stripped = line.strip()
|
||||
if not stripped or stripped.startswith("#"):
|
||||
continue
|
||||
if name_re and name_re.search(stripped):
|
||||
continue
|
||||
if stripped.split()[0].lstrip("$").rstrip(";") not in SHELL_HEADS:
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
# A lone indented line that's just a path ending in a known extension —
|
||||
# e.g. pointing at where a file lives — reads better as a titled snippet
|
||||
# than an unhighlighted grey slab.
|
||||
PATH_LINE_RE = re.compile(r"^[~$][\w./{}-]*\.\w+$")
|
||||
|
||||
# A leading "# in local.fish" / "# local.fish" comment names the file an
|
||||
# example belongs to; promote it to the fence title instead of leaving it
|
||||
# as a literal comment inside the code.
|
||||
FILENAME_COMMENT_RE = re.compile(r"^#\s*(?:in\s+)?([$~\w./-]+\.\w+)\s*$")
|
||||
|
||||
CELL_SPLIT = re.compile(r"\s{2,}")
|
||||
|
||||
# A rule line under a header row — the "Component Reference" tables'
|
||||
# authoring convention (header, dashes, data rows all at the same indent,
|
||||
# no ":"-terminated label). Either one solid run of dashes, or (RST-style)
|
||||
# one dash run per column, gapped the same way CELL_SPLIT splits cells.
|
||||
RULE_CELL_RE = re.compile(r"^[─\-]{3,}$")
|
||||
|
||||
|
||||
def _cell(text: str, code: bool) -> str:
|
||||
"""Render one table cell. `|` must be escaped even inside a code span."""
|
||||
text = text.strip().replace("|", r"\|")
|
||||
return f"`{text}`" if code and text else text
|
||||
|
||||
|
||||
def _as_table(para: list[str]) -> str | None:
|
||||
"""Render an aligned two-column block as a markdown table, else None.
|
||||
|
||||
Option and subcommand tables are the one thing in this manual that is
|
||||
genuinely tabular, and the indented-code fallback renders them as a grey
|
||||
slab. Everything else stays in that fallback: returning None is always
|
||||
safe, so every check here is free to be conservative.
|
||||
|
||||
The rows must form one contiguous indented run, optionally introduced by
|
||||
a label line (`Options:`) and closed by a sentence. Lines indented deeper
|
||||
than the run are wrapped descriptions and fold into the row above.
|
||||
"""
|
||||
starts = [i for i, ln in enumerate(para) if ln.startswith(" ")]
|
||||
if len(starts) < 2 or starts != list(range(starts[0], starts[-1] + 1)):
|
||||
return None
|
||||
head = para[: starts[0]]
|
||||
body = para[starts[0] : starts[-1] + 1]
|
||||
tail = para[starts[-1] + 1 :]
|
||||
if head and not head[-1].rstrip().endswith(":"):
|
||||
return None # a head that isn't a label means mixed content
|
||||
|
||||
indent = min(len(ln) - len(ln.lstrip()) for ln in body)
|
||||
rows: list[list[str]] = []
|
||||
for line in body:
|
||||
if len(line) - len(line.lstrip()) > indent and rows:
|
||||
rows[-1][1] += " " + line.strip()
|
||||
continue
|
||||
parts = CELL_SPLIT.split(line.strip(), 1)
|
||||
if len(parts) != 2 or not parts[1].strip():
|
||||
return None # not column-aligned; a numbered list, or prose
|
||||
rows.append([parts[0], parts[1].strip()])
|
||||
if len(rows) < 2:
|
||||
return None
|
||||
if any("<" in value or "{" in value for _, value in rows):
|
||||
return None # live markdown in the prose column
|
||||
|
||||
out = [line.strip() for line in head]
|
||||
out += ["| | |", "|---|---|"]
|
||||
out += [f"| {_cell(k, True)} | {_cell(v, False)} |" for k, v in rows]
|
||||
out += [line.strip() for line in tail]
|
||||
return "\n".join(out)
|
||||
|
||||
|
||||
def _as_ruled_table(para: list[str]) -> str | None:
|
||||
"""Render a header + solid-rule + rows block as an N-column table, else None.
|
||||
|
||||
This is the "Component Reference" tables' convention: header row, a
|
||||
dashed rule, then data rows at the same indent (no ":"-label, no extra
|
||||
nesting — the two things _as_table looks for). A row that splits into
|
||||
just one cell is a word-wrapped continuation of the row above; anything
|
||||
else that doesn't match the header's column count is a source alignment
|
||||
bug, so bail out to the code-block fallback rather than guess.
|
||||
"""
|
||||
if len(para) < 4:
|
||||
return None
|
||||
rule_cells = CELL_SPLIT.split(para[1].strip())
|
||||
if not all(RULE_CELL_RE.match(cell) for cell in rule_cells):
|
||||
return None
|
||||
header = CELL_SPLIT.split(para[0].strip())
|
||||
n = len(header)
|
||||
if n < 2:
|
||||
return None
|
||||
rows: list[list[str]] = []
|
||||
for line in para[2:]:
|
||||
parts = CELL_SPLIT.split(line.strip(), n - 1)
|
||||
if len(parts) == n:
|
||||
rows.append(parts)
|
||||
elif len(parts) == 1 and rows:
|
||||
rows[-1][-1] += " " + parts[0].strip()
|
||||
else:
|
||||
return None
|
||||
if len(rows) < 2:
|
||||
return None
|
||||
|
||||
# Unlike _as_table's prose column, these tables legitimately contain
|
||||
# placeholders like <session> or brace globs — code-span protects them
|
||||
# instead of rejecting the whole table.
|
||||
def cell(text: str, code: bool) -> str:
|
||||
needs_protection = ("<" in text or "{" in text) and "`" not in text
|
||||
return _cell(text, code or needs_protection)
|
||||
|
||||
out = [f"| {' | '.join(header)} |", "|" + "|".join(["---"] * n) + "|"]
|
||||
for row in rows:
|
||||
cells = [cell(row[0], True)] + [cell(c, False) for c in row[1:]]
|
||||
out.append(f"| {' | '.join(cells)} |")
|
||||
return "\n".join(out)
|
||||
|
||||
|
||||
TREE_ROOT_RE = re.compile(r"^[~$][\w./{}-]*/$")
|
||||
TREE_BRANCH_RE = re.compile(r"^([│ \t]*)[├└]──\s*(\S+)\s*(.*)$")
|
||||
|
||||
|
||||
def _as_file_tree(para: list[str]) -> str | None:
|
||||
"""Render a hand-drawn box-drawing tree as a Starlight <FileTree>, else None."""
|
||||
if len(para) < 2 or not TREE_ROOT_RE.match(para[0].strip()):
|
||||
return None
|
||||
branches = []
|
||||
for line in para[1:]:
|
||||
m = TREE_BRANCH_RE.match(line)
|
||||
if not m:
|
||||
return None
|
||||
branches.append(m.groups())
|
||||
out = ["<FileTree>", f"- {para[0].strip()}"]
|
||||
for prefix, name, desc in branches:
|
||||
depth = len(prefix.replace('\t', ' ')) // 4
|
||||
indent = " " * (depth + 1)
|
||||
out.append(f"{indent}- {name} {desc}".rstrip())
|
||||
out.append("</FileTree>")
|
||||
return "\n".join(out)
|
||||
|
||||
|
||||
def _render_para(para: list[str], entry_name: str | None, deeper: bool) -> str:
|
||||
"""Render one paragraph of a former indented block.
|
||||
|
||||
`deeper` marks paragraphs carrying their own extra indentation — nested
|
||||
option tables, whose alignment only survives inside a code block.
|
||||
"""
|
||||
if not deeper:
|
||||
if _is_prose(para):
|
||||
return "\n".join(line.strip() for line in para)
|
||||
if len(para) == 1 and PATH_LINE_RE.match(para[0].strip()):
|
||||
path = para[0].strip()
|
||||
name = path.rsplit("/", 1)[-1]
|
||||
return f'```fish title="{name}"\n{path}\n```'
|
||||
if _is_shell(para, entry_name):
|
||||
body = para
|
||||
title = None
|
||||
m = FILENAME_COMMENT_RE.match(para[0].strip())
|
||||
if m:
|
||||
title, body = m.group(1), para[1:]
|
||||
info = f'fish title="{title}"' if title else "fish"
|
||||
return f"```{info}\n" + "\n".join(body) + "\n```"
|
||||
table = _as_ruled_table(para) or _as_table(para) or _as_file_tree(para)
|
||||
if table is not None:
|
||||
return table
|
||||
return "\n".join(INDENT + line for line in para)
|
||||
|
||||
|
||||
def _prettify_block(block: list[str], entry_name: str | None) -> str:
|
||||
"""Convert one indented block into fenced code, prose, and tables.
|
||||
|
||||
The manual is authored man-page style: every example, table, and
|
||||
description sits in a single 4-space-indented block, which renders on
|
||||
the site as one unhighlighted grey slab. Splitting a block into its
|
||||
paragraphs recovers the structure the indentation flattened.
|
||||
"""
|
||||
lines = [line[len(INDENT) :] if line.startswith(INDENT) else line for line in block]
|
||||
|
||||
out: list[str] = []
|
||||
if lines and lines[0].startswith(SYNOPSIS_PREFIX):
|
||||
synopsis = [lines.pop(0)[len(SYNOPSIS_PREFIX) :].strip()]
|
||||
# A multi-line synopsis is authored aligned under the first line;
|
||||
# keep the whole thing in one fence rather than orphaning the rest.
|
||||
while lines and lines[0].startswith(" "):
|
||||
synopsis.append(lines.pop(0).strip())
|
||||
# A "Usage" title (Starlight's filename-title convention, repurposed
|
||||
# as a label) makes the synopsis read as a snippet of the function
|
||||
# it documents rather than a bare command example.
|
||||
info = 'fish title="Usage"' if entry_name else "fish"
|
||||
out.append(f"```{info}\n" + "\n".join(synopsis) + "\n```")
|
||||
|
||||
para: list[str] = []
|
||||
for line in lines + [""]:
|
||||
if line.strip():
|
||||
para.append(line)
|
||||
continue
|
||||
if para:
|
||||
if para[0].strip() == EXAMPLE_PREFIX:
|
||||
example = para[1:]
|
||||
if example and _is_shell(example, entry_name):
|
||||
body = "\n".join(example)
|
||||
out.append(f'```fish title="Examples"\n{body}\n```')
|
||||
else:
|
||||
deeper = any(line.startswith(" ") for line in example)
|
||||
out.append(_render_para(example, entry_name, deeper))
|
||||
else:
|
||||
deeper = any(line.startswith(" ") for line in para)
|
||||
out.append(_render_para(para, entry_name, deeper))
|
||||
para = []
|
||||
return "\n\n".join(chunk for chunk in out if chunk.strip())
|
||||
|
||||
|
||||
ASIDE_LABELS: dict[str, tuple[str, str, str | None]] = {
|
||||
"NOTE": ("note", "Note", None),
|
||||
"IMPORTANT": ("note", "Important", "star"),
|
||||
"TIP": ("tip", "Tip", None),
|
||||
"HINT": ("tip", "Hint", "question-circle"),
|
||||
"WARNING": ("caution", "Warning", "warning"),
|
||||
"CAUTION": ("caution", "Caution", None),
|
||||
"DANGER": ("danger", "Danger", None),
|
||||
}
|
||||
ASIDE_RE = re.compile(rf"^({'|'.join(ASIDE_LABELS)}):\s*(.*)$")
|
||||
|
||||
|
||||
def _as_aside(para: list[str]) -> str | None:
|
||||
"""Render a `LABEL: ...` flat paragraph as a Starlight <Aside>, else None."""
|
||||
m = ASIDE_RE.match(para[0])
|
||||
if not m:
|
||||
return None
|
||||
label, rest = m.groups()
|
||||
aside_type, title, icon = ASIDE_LABELS[label]
|
||||
body = "\n".join(([rest] if rest else []) + para[1:])
|
||||
attrs = f'type="{aside_type}" title="{title}"'
|
||||
if icon:
|
||||
attrs += f' icon="{icon}"'
|
||||
return f"<Aside {attrs}>\n{body}\n</Aside>"
|
||||
|
||||
|
||||
def prettify(body: str, entry_name: str | None = None) -> str:
|
||||
"""Rewrite a body's indented code blocks and labeled asides for the website.
|
||||
|
||||
Site-only: the man page and `config-help` keep reading the untouched
|
||||
SSOT, where the indented form and the `LABEL:` text are exactly what
|
||||
pandoc/`config-help` want.
|
||||
"""
|
||||
out: list[str] = []
|
||||
block: list[str] = []
|
||||
flat: list[str] = []
|
||||
in_fence = False
|
||||
|
||||
def flush_flat() -> None:
|
||||
out.append(_as_aside(flat) or "\n".join(flat))
|
||||
|
||||
for line in body.split("\n"):
|
||||
if mt.FENCE_RE.match(line):
|
||||
in_fence = not in_fence
|
||||
if not in_fence and (line.startswith(INDENT) or (not line.strip() and block)):
|
||||
if flat:
|
||||
flush_flat()
|
||||
flat.clear()
|
||||
block.append(line)
|
||||
continue
|
||||
if block:
|
||||
while block and not block[-1].strip():
|
||||
block.pop()
|
||||
out.append(_prettify_block(block, entry_name))
|
||||
out.append("")
|
||||
block = []
|
||||
if in_fence or not line.strip():
|
||||
if flat:
|
||||
flush_flat()
|
||||
flat.clear()
|
||||
out.append(line)
|
||||
else:
|
||||
flat.append(line)
|
||||
|
||||
if flat:
|
||||
flush_flat()
|
||||
if block:
|
||||
while block and not block[-1].strip():
|
||||
block.pop()
|
||||
out.append(_prettify_block(block, entry_name))
|
||||
return "\n".join(out)
|
||||
|
||||
|
||||
ENTRY_HEADS = {
|
||||
"ARGUMENTS": "Arguments:",
|
||||
"EXIT STATUS": "Exit Status:",
|
||||
"RETURNS": "Returns:",
|
||||
"NOTES": "Notes:",
|
||||
}
|
||||
|
||||
|
||||
def render_entry(fn: dict[str, list[str]], used_by: list[str], link=None) -> str:
|
||||
"""Render one parsed function header as a manual entry body.
|
||||
|
||||
Emits the same man-page shape Section 5 was authored in — one 4-space
|
||||
indented block opening with `Synopsis:` — so `prettify` keeps handling it
|
||||
for the site and pandoc keeps handling it for the man page, with no
|
||||
special case on either side.
|
||||
|
||||
`link` maps a function name to its markdown link, or is None for the man
|
||||
page, where a URL in the middle of a sentence is noise.
|
||||
"""
|
||||
out: list[str] = []
|
||||
syn = fn.get("SYNOPSIS", [])
|
||||
if syn:
|
||||
pad = " " * len(SYNOPSIS_PREFIX + " ")
|
||||
out.append(f"{SYNOPSIS_PREFIX} {syn[0]}")
|
||||
out += [pad + line for line in syn[1:]]
|
||||
out.append("")
|
||||
for line in fn.get("DESCRIPTION", []):
|
||||
out.append(line)
|
||||
for label, head in ENTRY_HEADS.items():
|
||||
body = fn.get(label)
|
||||
if not body:
|
||||
continue
|
||||
out += ["", head] + [" " + line for line in body]
|
||||
if fn.get("EXAMPLE"):
|
||||
out += ["", EXAMPLE_PREFIX] + fn["EXAMPLE"]
|
||||
|
||||
block = "\n".join((INDENT + line).rstrip() for line in out)
|
||||
|
||||
def names(raw: list[str]) -> list[str]:
|
||||
return [n for n in re.split(r"[,\s]+", " ".join(raw)) if n]
|
||||
|
||||
refs = []
|
||||
for label, values in (
|
||||
("Dependencies", names(fn.get("DEPENDENCIES", []))),
|
||||
("Used by", sorted(used_by)),
|
||||
):
|
||||
if values:
|
||||
rendered = ", ".join(link(v) if link else f"`{v}`" for v in values)
|
||||
refs.append(f"**{label}:** {rendered}")
|
||||
if refs:
|
||||
block += "\n\n" + "\n\n".join(refs)
|
||||
return block
|
||||
|
||||
|
||||
def build_entries(functions: dict[str, dict], link=None) -> dict[str, list[tuple[str, str]]]:
|
||||
"""Group rendered entries by category stem, ordered by function name.
|
||||
|
||||
The `Used by` reverse index is computed here in one pass rather than
|
||||
authored: a bidirectional link maintained by hand drifts the moment one
|
||||
side is edited.
|
||||
"""
|
||||
used_by: dict[str, list[str]] = {}
|
||||
for name, fn in functions.items():
|
||||
for dep in re.split(r"[,\s]+", " ".join(fn.get("DEPENDENCIES", []))):
|
||||
if dep in functions:
|
||||
used_by.setdefault(dep, []).append(name)
|
||||
|
||||
out: dict[str, list[tuple[str, str]]] = {}
|
||||
for name in sorted(functions):
|
||||
fn = functions[name]
|
||||
body = render_entry(fn, used_by.get(name, []), link)
|
||||
out.setdefault(fn["CATEGORY"][0], []).append((name, body))
|
||||
return out
|
||||
|
||||
|
||||
def _page_fm(fm: dict) -> dict:
|
||||
"""Strip pipeline-only keys from frontmatter destined for the site."""
|
||||
return {k: v for k, v in fm.items() if k not in PIPELINE_KEYS}
|
||||
|
||||
|
||||
def _split_entries(body: str) -> tuple[str, list[tuple[str, str]]]:
|
||||
"""Split a category body into (intro, [(entry title, entry body)]).
|
||||
|
||||
Fence-aware: an H2-looking line (`## ...`) inside a fenced code block
|
||||
(tracked the same way as `manualtools.shift_headings`) is treated as
|
||||
ordinary body text, not an entry boundary.
|
||||
"""
|
||||
lines = body.split("\n")
|
||||
heading_re = re.compile(r"^## (.+)$")
|
||||
boundaries: list[tuple[int, str]] = []
|
||||
in_fence = False
|
||||
for i, line in enumerate(lines):
|
||||
if mt.FENCE_RE.match(line):
|
||||
in_fence = not in_fence
|
||||
continue
|
||||
if not in_fence:
|
||||
m = heading_re.match(line)
|
||||
if m:
|
||||
boundaries.append((i, m.group(1)))
|
||||
|
||||
if not boundaries:
|
||||
return body.strip(), []
|
||||
|
||||
intro = "\n".join(lines[: boundaries[0][0]]).strip()
|
||||
entries = []
|
||||
for idx, (line_no, title) in enumerate(boundaries):
|
||||
start = line_no + 1
|
||||
end = boundaries[idx + 1][0] if idx + 1 < len(boundaries) else len(lines)
|
||||
# Strip newlines only: a bare .strip() would eat the leading
|
||||
# indentation of the entry's first line, detaching the `Synopsis:`
|
||||
# line from the indented block it opens.
|
||||
entry_body = "\n".join(lines[start:end]).strip("\n")
|
||||
entries.append((title.strip(), entry_body))
|
||||
return intro, entries
|
||||
|
||||
|
||||
|
||||
def _inject_subheading_cards(body: str) -> str:
|
||||
"""Extract `## Heading`s and inject a CardGrid after the intro."""
|
||||
headings = []
|
||||
for line in body.splitlines():
|
||||
m = re.match(r"^##\s+(.+)$", line)
|
||||
if m:
|
||||
headings.append(m.group(1).strip())
|
||||
|
||||
if len(headings) < 2:
|
||||
return body
|
||||
|
||||
parts = body.split("\n## ", 1)
|
||||
if len(parts) != 2:
|
||||
return body
|
||||
|
||||
intro = parts[0].strip()
|
||||
rest = "## " + parts[1]
|
||||
|
||||
cards = []
|
||||
for title in headings:
|
||||
safe_title = _jsx_attr_escape(title)
|
||||
slug = re.sub(r"[^\w\s-]", "", title.lower())
|
||||
slug = re.sub(r"[-\s]+", "-", slug).strip("-")
|
||||
cards.append(f' <LinkCard title="{safe_title}" href="#{slug}" />')
|
||||
|
||||
cardgrid = "<CardGrid>\n" + "\n".join(cards) + "\n</CardGrid>\n\n"
|
||||
|
||||
return f"{intro}\n\n{cardgrid}{rest}"
|
||||
|
||||
ASTRO_ASIDE_COMPONENTS = {"<Aside": "Aside", "<FileTree": "FileTree", "<LinkButton": "LinkButton", "<CardGrid": "CardGrid", "<LinkCard": "LinkCard"}
|
||||
|
||||
|
||||
def _write_prettified(target: Path, fm: dict, content: str) -> None:
|
||||
"""Write a prettified page, promoting to .mdx when it needs a component import.
|
||||
|
||||
A page stays .md (prettify()'s default, no imports) unless its rendered
|
||||
content actually contains an <Aside> or <FileTree> — the only two
|
||||
components a prettified (non-hand-built) page can contain.
|
||||
"""
|
||||
needed = [name for marker, name in ASTRO_ASIDE_COMPONENTS.items() if marker in content]
|
||||
if needed:
|
||||
imports = f"import {{ {', '.join(needed)} }} from '@astrojs/starlight/components';\n\n"
|
||||
target = target.with_suffix(".mdx")
|
||||
content = imports + content
|
||||
target.write_text(mt.serialize(fm, content))
|
||||
|
||||
|
||||
def build_site(root: Path, out: Path) -> list[dict]:
|
||||
"""Write the Starlight content tree. Returns the sidebar structure."""
|
||||
if out.exists():
|
||||
shutil.rmtree(out)
|
||||
out.mkdir(parents=True)
|
||||
|
||||
functions = mt.parse_functions(FUNCTIONS)
|
||||
entries = build_entries(functions, link=lambda n: _entry_link(n, functions))
|
||||
|
||||
sidebar: list[dict] = [{"label": "Home", "link": "/"}]
|
||||
standard_groups: dict = {}
|
||||
functions_group: dict = {}
|
||||
functions_index_target = None
|
||||
functions_index_fm = None
|
||||
functions_index_body = None
|
||||
functions_cards = []
|
||||
for path, _depth in mt.walk(root):
|
||||
fm, body = mt.parse(path)
|
||||
if not fm.get("site", True):
|
||||
continue
|
||||
|
||||
rel = path.relative_to(root)
|
||||
is_function_dir = rel.parts and rel.parts[0].endswith("-functions")
|
||||
|
||||
if not is_function_dir:
|
||||
target = out / rel
|
||||
if "04-abbreviations" in path.parts:
|
||||
abbrs = mt.parse_abbreviations(DOCS.parent / "conf.d")
|
||||
body = _with_abbreviations(body, abbrs)
|
||||
target.parent.mkdir(parents=True, exist_ok=True)
|
||||
body = _inject_subheading_cards(body)
|
||||
_write_prettified(target, _page_fm(fm), prettify(body))
|
||||
|
||||
if len(rel.parts) > 1:
|
||||
group_dir = rel.parts[0]
|
||||
if rel.name == "index.md":
|
||||
group = {
|
||||
"label": fm["title"],
|
||||
"collapsed": True,
|
||||
"items": [{"label": "Categories", "link": f"/{group_dir}/"}]
|
||||
}
|
||||
standard_groups[group_dir] = group
|
||||
sidebar.append(group)
|
||||
elif rel.name != "404.md":
|
||||
if group_dir in standard_groups:
|
||||
standard_groups[group_dir]["items"].append({
|
||||
"label": fm["title"],
|
||||
"link": f"/{group_dir}/{rel.stem}/"
|
||||
})
|
||||
else:
|
||||
sidebar.append({"label": fm["title"], "link": f"/{group_dir}/{rel.stem}/"})
|
||||
else:
|
||||
if rel.name not in ("index.md", "404.md"):
|
||||
sidebar.append({"label": fm["title"], "link": "/" + rel.stem + "/"})
|
||||
continue
|
||||
|
||||
# Section 5: category index page keeps its slot; entries explode.
|
||||
#
|
||||
# Deliberately NOT "functions": Cloudflare Pages reserves a top-level
|
||||
# `functions/` directory in the deploy output for Pages Functions
|
||||
# (server-side handlers) and silently drops it from the static-asset
|
||||
# upload. The pages build fine and never arrive — every entry 404s in
|
||||
# production while working locally. test_site_avoids_reserved_dir
|
||||
# guards this.
|
||||
slug_dir = SLUG_DIR
|
||||
if rel.name == "index.md":
|
||||
functions_index_target = out / slug_dir / "index.md"
|
||||
functions_index_fm = fm
|
||||
functions_index_body = body
|
||||
functions_cards = []
|
||||
|
||||
# Built explicitly rather than by `autogenerate`, which labels
|
||||
# each group with its raw directory slug and republishes this
|
||||
# index as a child of the group it already titles.
|
||||
functions_group = {
|
||||
"label": fm["title"],
|
||||
"collapsed": True,
|
||||
"items": [{"label": "Categories", "link": f"/{slug_dir}/"}],
|
||||
}
|
||||
sidebar.append(functions_group)
|
||||
continue
|
||||
|
||||
category = re.sub(r"^\d+-", "", rel.stem)
|
||||
cat_dir = out / slug_dir / category
|
||||
cat_dir.mkdir(parents=True, exist_ok=True)
|
||||
intro, page_entries = _split_entries(_with_entries(body, path, entries))
|
||||
|
||||
cat_title = fm["title"]
|
||||
cat_desc = fm.get("description", "")
|
||||
safe_title = _jsx_attr_escape(cat_title)
|
||||
safe_desc = _jsx_attr_escape(cat_desc)
|
||||
href = f"/{slug_dir}/{category}/"
|
||||
functions_cards.append(
|
||||
f' <LinkCard title="{safe_title}" href="{href}"'
|
||||
+ (f' description="{safe_desc}"' if cat_desc else "")
|
||||
+ " />"
|
||||
)
|
||||
|
||||
cards = []
|
||||
links = []
|
||||
for title, entry_body in page_entries:
|
||||
entry_slug = _entry_slug(title)
|
||||
desc = _first_sentence(entry_body)
|
||||
entry_fm = {"title": title}
|
||||
if desc:
|
||||
entry_fm["description"] = desc
|
||||
_write_prettified(
|
||||
cat_dir / f"{entry_slug}.md",
|
||||
entry_fm,
|
||||
prettify(entry_body, title.split()[0]),
|
||||
)
|
||||
href = f"/{slug_dir}/{category}/{entry_slug}/"
|
||||
links.append({"label": title, "link": href})
|
||||
safe_title = _jsx_attr_escape(title)
|
||||
safe_desc = _jsx_attr_escape(desc)
|
||||
cards.append(
|
||||
f' <LinkCard title="{safe_title}" href="{href}"'
|
||||
+ (f' description="{safe_desc}"' if desc else "")
|
||||
+ " />"
|
||||
)
|
||||
|
||||
overview = (
|
||||
"import { CardGrid, LinkCard } from '@astrojs/starlight/components';\n\n"
|
||||
+ (f"{intro}\n\n" if intro else "")
|
||||
+ "<CardGrid>\n"
|
||||
+ "\n".join(cards)
|
||||
+ "\n</CardGrid>\n"
|
||||
)
|
||||
(cat_dir / "index.mdx").write_text(mt.serialize(_page_fm(fm), overview))
|
||||
|
||||
functions_group.setdefault("items", []).append(
|
||||
{
|
||||
"label": fm["title"],
|
||||
"collapsed": True,
|
||||
"items": [
|
||||
{"label": f"{fm['title']} Overview", "link": f"/{slug_dir}/{category}/"},
|
||||
*links,
|
||||
],
|
||||
}
|
||||
)
|
||||
|
||||
if functions_index_target:
|
||||
overview_content = (
|
||||
(f"{functions_index_body}\n\n" if functions_index_body.strip() else "")
|
||||
+ "<CardGrid>\n"
|
||||
+ "\n".join(functions_cards)
|
||||
+ "\n</CardGrid>\n"
|
||||
)
|
||||
_write_prettified(functions_index_target, _page_fm(functions_index_fm), prettify(overview_content))
|
||||
|
||||
return sidebar
|
||||
|
||||
|
||||
def main() -> int:
|
||||
ap = argparse.ArgumentParser(description=__doc__)
|
||||
ap.add_argument("--concat", action="store_true", help="emit the pandoc document")
|
||||
ap.add_argument("--site", action="store_true", help="emit the Starlight content tree")
|
||||
ap.add_argument("-o", "--output", type=Path, help="write to PATH instead of stdout")
|
||||
args = ap.parse_args()
|
||||
|
||||
if not (args.concat or args.site):
|
||||
ap.error("nothing to do: pass --concat and/or --site")
|
||||
|
||||
generate_component_registry.main()
|
||||
|
||||
if args.site:
|
||||
src = DOCS / "site" / "src"
|
||||
out = src / "content" / "docs"
|
||||
sidebar = build_site(MANUAL, out)
|
||||
(src / "sidebar.json").write_text(json.dumps(sidebar, indent=2) + "\n")
|
||||
print(f"wrote site content to {out} ({len(sidebar)} sidebar entries)")
|
||||
|
||||
if args.concat:
|
||||
text = build_concat(MANUAL)
|
||||
if args.output:
|
||||
args.output.write_text(text)
|
||||
print(f"wrote {args.output}")
|
||||
else:
|
||||
sys.stdout.write(text)
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.path.insert(0, str(Path(__file__).parent))
|
||||
raise SystemExit(main())
|
||||
+3869
-1169
File diff suppressed because it is too large
Load Diff
+144
-41
@@ -11,6 +11,10 @@ synopsis=# SYNOPSIS
|
||||
description=# DESCRIPTION
|
||||
toc=# TABLE OF CONTENTS
|
||||
contents=# TABLE OF CONTENTS
|
||||
autopair=# DESCRIPTION
|
||||
puffer=# DESCRIPTION
|
||||
puffer-fish=# DESCRIPTION
|
||||
logging-events=# DESCRIPTION
|
||||
|
||||
# ── Section 1: Configuration Variables ───────────────────────
|
||||
variables=# 1. CONFIGURATION VARIABLES
|
||||
@@ -20,6 +24,9 @@ toolhomes=## Tool Homes (XDG-compliant)
|
||||
editor=## Editor and Pager
|
||||
pager=## Editor and Pager
|
||||
scrollback=## Scrollback History
|
||||
__fish_scrollback_history_dir=## Scrollback History
|
||||
__fish_scrollback_history_max_files=## Scrollback History
|
||||
scrollback-dir=## Scrollback History
|
||||
|
||||
# ── Section 2: PATH ───────────────────────────────────────────
|
||||
path=# 2. PATH SETUP
|
||||
@@ -84,6 +91,7 @@ less=### less
|
||||
rawfish=### rawfish
|
||||
view=### view
|
||||
git=## 5.4 Git and Version Control
|
||||
auto-pull=### auto-pull
|
||||
branch=### branch
|
||||
gi=### gi
|
||||
gitignore=### gi
|
||||
@@ -117,6 +125,8 @@ split=### split
|
||||
spwin=### spwin
|
||||
detach=### detach
|
||||
bkg=### bkg
|
||||
jobrunner=### jobrunner
|
||||
jr=### jr
|
||||
ssh=### ssh
|
||||
clipboard=## 5.9 Clipboard
|
||||
copy-fn=### y
|
||||
@@ -129,20 +139,37 @@ logging=## 5.11 Pager and Logging
|
||||
logs=### logs
|
||||
smart-exit=### smart_exit
|
||||
ai=## 5.12 AI and Developer Tools
|
||||
antigravity=### antigravity
|
||||
claude=### claude-resume
|
||||
antigravity-ide=### antigravity-ide
|
||||
agy=### agy
|
||||
agents-init=### agents-init
|
||||
agents=### agents-init
|
||||
agents-tools=### agents-init
|
||||
version-bump=### agents-init
|
||||
.version=### agents-init
|
||||
structure-version=### agents-init
|
||||
core.hooksPath=### agents-init
|
||||
devlogs=### agents-init
|
||||
claude-cli=### claude
|
||||
claude-docs=### claude-docs
|
||||
claude-pr=### claude-pr
|
||||
code-resume=### code-resume
|
||||
qc=### qc
|
||||
quick-chat=### qc
|
||||
aichat=### qc
|
||||
superpowers=### superpowers
|
||||
media=## 5.13 Media and Utilities
|
||||
dng2avif=### dng2avif
|
||||
spark=### spark
|
||||
yt-dlp=### yt-dlp
|
||||
miscfns=## 5.14 Miscellaneous
|
||||
config-help=### config-help
|
||||
open-url=### open-url
|
||||
url-open=### open-url
|
||||
repo-open=### repo-open
|
||||
open-repo=### repo-open
|
||||
config-update=### config-update
|
||||
config-toggle=### config-toggle
|
||||
toggle=### config-toggle
|
||||
config-settings=### config-settings
|
||||
config-toggle=### config-settings
|
||||
toggle=### config-settings
|
||||
bash=### bash
|
||||
cheat=### cheat
|
||||
dockup=### dockup
|
||||
@@ -150,7 +177,37 @@ joplin=### joplin
|
||||
replay=### replay
|
||||
tmux=### tmux-clean
|
||||
wake-lock=### wake-lock
|
||||
zellij=### zellij
|
||||
|
||||
# ── Tool-name synonyms (replacement → shadowed command) ──────
|
||||
# These tools don't appear in any heading, so the fallback scan can't
|
||||
# find them; map each to the function that wraps it.
|
||||
eza=### ls
|
||||
exa=### ls
|
||||
lsd=### ls
|
||||
trash=### rm
|
||||
btop=### top
|
||||
prettyping=### ping
|
||||
duf=### du
|
||||
dust=### du
|
||||
kitten=### ssh
|
||||
bat=### cat
|
||||
|
||||
# ── Tool integrations (Section: Integrations) ────────────────
|
||||
zoxide=### Zoxide
|
||||
z=### Zoxide
|
||||
direnv=### DirEnv
|
||||
venv=### Auto Python Venv
|
||||
virtualenv=### Auto Python Venv
|
||||
python=### Auto Python Venv
|
||||
wakatime=### WakaTime
|
||||
tailscale=### Tailscale
|
||||
done=### Done Notifications
|
||||
notifications=### Done Notifications
|
||||
notify=### Done Notifications
|
||||
pager-hierarchy=## Pager Hierarchy
|
||||
shell-aliases=## 4.11 Shell Aliases
|
||||
kitty-logging=### kitty-logging
|
||||
watcher=### kitty-logging
|
||||
|
||||
# ── Section 6: Dependency Catalog ────────────────────────────
|
||||
catalog=# 6. DEPENDENCY CATALOG
|
||||
@@ -164,6 +221,8 @@ install-methods=## Install Methods
|
||||
customization=# 7. CUSTOMIZATION
|
||||
customize=# 7. CUSTOMIZATION
|
||||
local=## Machine-local Configuration
|
||||
user-dots=## Machine-local Configuration
|
||||
dots-link=## Machine-local Configuration
|
||||
secrets=## Secrets and API Keys
|
||||
overrides=## Overriding Configuration Variables
|
||||
universal=## Fish Universal Variables
|
||||
@@ -172,52 +231,96 @@ minimal=## Opinionated Components (Minimal Mode)
|
||||
minimal-mode=## Opinionated Components (Minimal Mode)
|
||||
opt-out=## Opinionated Components (Minimal Mode)
|
||||
toggles=## Opinionated Components (Minimal Mode)
|
||||
component-reference=### Component Reference
|
||||
components=### Component Reference
|
||||
c1=#### C1 — Command Shadows
|
||||
command-shadows=#### C1 — Command Shadows
|
||||
aliases-detail=#### C1 — Command Shadows
|
||||
c2=#### C2 — Startup Side-Effects
|
||||
autoexec=#### C2 — Startup Side-Effects
|
||||
startup=#### C2 — Startup Side-Effects
|
||||
c3=#### C3 — Key and Environment Overrides
|
||||
overrides-detail=#### C3 — Key and Environment Overrides
|
||||
bang-bang=#### C3 — Key and Environment Overrides
|
||||
c4=#### C4 — Terminal and Tool Integration
|
||||
integrations-detail=#### C4 — Terminal and Tool Integration
|
||||
c5=#### C5 — Logging and Capture
|
||||
logging-detail=#### C5 — Logging and Capture
|
||||
logging-sentinel=#### C5 — Logging and Capture
|
||||
c6=#### C6 — Greeting and First-Run UI
|
||||
greeting=#### C6 — Greeting and First-Run UI
|
||||
component-reference=# 8. COMPONENTS REFERENCE
|
||||
components=# 8. COMPONENTS REFERENCE
|
||||
c1=## C1 — Command Shadows
|
||||
command-shadows=## C1 — Command Shadows
|
||||
aliases-detail=## C1 — Command Shadows
|
||||
c2=## C2 — Startup Side-Effects
|
||||
autoexec=## C2 — Startup Side-Effects
|
||||
startup=## C2 — Startup Side-Effects
|
||||
c3=## C3 — Key and Environment Overrides
|
||||
overrides-detail=## C3 — Key and Environment Overrides
|
||||
bang-bang=## C3 — Key and Environment Overrides
|
||||
c4=## C4 — Terminal and Tool Integration
|
||||
integrations-detail=## C4 — Terminal and Tool Integration
|
||||
c5=## C5 — Logging and Capture
|
||||
logging-detail=## C5 — Logging and Capture
|
||||
logging-sentinel=## C5 — Logging and Capture
|
||||
zellij=## C5 — Logging and Capture
|
||||
zellij-logging=## C5 — Logging and Capture
|
||||
tmux-logging=## C5 — Logging and Capture
|
||||
pipe-pane=## C5 — Logging and Capture
|
||||
dump-screen=## C5 — Logging and Capture
|
||||
c6=## C6 — Greeting and First-Run UI
|
||||
greeting=## C6 — Greeting and First-Run UI
|
||||
|
||||
# ── Section 8: Fisher Plugins ─────────────────────────────────
|
||||
plugins=# 8. FISHER PLUGINS
|
||||
fisher=# 8. FISHER PLUGINS
|
||||
# ── Prompt and Theme ──────────────────────────────────────────
|
||||
prompt-theme=## Prompt and Theme
|
||||
starship=### Starship
|
||||
fallback-prompt=### Catppuccin Fallback Prompt
|
||||
catppuccin-prompt=### Catppuccin Fallback Prompt
|
||||
nim-prompt=### Catppuccin Fallback Prompt
|
||||
fzf-theme=### FZF
|
||||
catppuccin-theme=### Catppuccin Mocha Syntax Highlighting
|
||||
|
||||
# ── Section 9: Fisher Plugins ─────────────────────────────────
|
||||
plugins=# 9. FISHER PLUGINS
|
||||
fisher=# 9. FISHER PLUGINS
|
||||
fisher-managed=## Fisher-Managed Plugins
|
||||
sponge=## Fisher-Managed Plugins
|
||||
sponge-filtering=## Sponge History Filtering
|
||||
history-filtering=## Sponge History Filtering
|
||||
privacy=## Sponge History Filtering
|
||||
__fish_sponge_extra_sensitive=## Sponge History Filtering
|
||||
extra-sensitive=## Sponge History Filtering
|
||||
sponge-settings=### config-settings
|
||||
bundled-plugins=## Bundled Plugin Functionality
|
||||
fish-plugins-manifest=## fish_plugins Manifest
|
||||
|
||||
# ── Section 9: Installation ────────────────────────────────────
|
||||
installation=# 9. INSTALLATION
|
||||
install=# 9. INSTALLATION
|
||||
# ── Section 10: Installation ────────────────────────────────────
|
||||
installation=# 10. INSTALLATION
|
||||
install=# 10. INSTALLATION
|
||||
sentinel=## Return Sentinel
|
||||
updating=## Updating
|
||||
|
||||
# ── Section 10: Personalization ───────────────────────────────
|
||||
personalization=# 10. PERSONALIZATION
|
||||
personalize=# 10. PERSONALIZATION
|
||||
secrets=## secrets.fish
|
||||
# ── Section 11: Personalization ───────────────────────────────
|
||||
personalization=# 11. PERSONALIZATION
|
||||
personalize=# 11. PERSONALIZATION
|
||||
secrets-file=## secrets.fish
|
||||
local-config=## local.fish
|
||||
|
||||
# ── Section 11: Viewing This Manual ──────────────────────────
|
||||
viewing=# 11. VIEWING THIS MANUAL
|
||||
manual=# 11. VIEWING THIS MANUAL
|
||||
ov=## With ov (recommended)
|
||||
man-page=## As a man page (if compiled)
|
||||
manpage=## As a man page (if compiled)
|
||||
jump=## Jumping to a section
|
||||
# ── Section 12: Troubleshooting ──────────────────────────────
|
||||
troubleshooting=# 12. TROUBLESHOOTING
|
||||
troubleshoot=# 12. TROUBLESHOOTING
|
||||
faq=# 12. TROUBLESHOOTING
|
||||
uninstall=## Uninstalling and Reverting to Backup
|
||||
revert=## Uninstalling and Reverting to Backup
|
||||
fish-version=## Fish Version Requirement
|
||||
version-req=## Fish Version Requirement
|
||||
disable-logging=## Enable or Disable Session Logging
|
||||
enable-logging=## Enable or Disable Session Logging
|
||||
disable-greeting=## Change or Disable the Greeting
|
||||
change-greeting=## Change or Disable the Greeting
|
||||
secrets-trouble=## Secrets and Machine-Local Configuration
|
||||
local-trouble=## Secrets and Machine-Local Configuration
|
||||
return-sentinel=## Tool Init Does Nothing (Return Sentinel)
|
||||
tool-init=## Tool Init Does Nothing (Return Sentinel)
|
||||
missing-deps=## Missing Dependencies
|
||||
vi-mode=## Vi Mode Keybindings
|
||||
vi-trouble=## Vi Mode Keybindings
|
||||
emacs-mode=## Vi Mode Keybindings
|
||||
minimal-trouble=## What's with the C1-C6 stuff?
|
||||
|
||||
# ── Section 13: Viewing This Manual ──────────────────────────
|
||||
viewing=# 13. VIEWING THIS MANUAL
|
||||
manual=# 13. VIEWING THIS MANUAL
|
||||
ov=## In the terminal
|
||||
man-page=## As a man page
|
||||
manpage=## As a man page
|
||||
jump=## In the terminal
|
||||
html=## The documentation website
|
||||
browser=## The documentation website
|
||||
site=## The documentation website
|
||||
|
||||
|
||||
|
||||
+3018
-964
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,121 @@
|
||||
#!/usr/bin/env python3
|
||||
# Copyright (C) 2026 Rootiest
|
||||
# SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
"""Generate the committed opinionated-component registry.
|
||||
|
||||
Walks every `# COMPONENT` header in functions/*.fish, conf.d/*.fish, and
|
||||
config.fish and writes conf.d/__fish_config_op_registry.fish, the fish
|
||||
data file __fish_config_op_registry_lookup reads at shell startup.
|
||||
|
||||
Run manually (via __fish_config_op_registry_rebuild) after editing a
|
||||
# COMPONENT header, and automatically as a pre-step in build-manual.py
|
||||
before the manual is built.
|
||||
"""
|
||||
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
import manualtools as mt
|
||||
|
||||
DOCS = Path(__file__).parent
|
||||
REPO = DOCS.parent
|
||||
OUTPUT = REPO / "conf.d" / "__fish_config_op_registry.fish"
|
||||
|
||||
|
||||
def collect_components() -> dict[str, list[str]]:
|
||||
"""Gather every `# COMPONENT` header across the whole repo.
|
||||
|
||||
Concatenates raw component lines when the same identity appears in
|
||||
more than one source (e.g. functions/auto-pull.fish and
|
||||
conf.d/auto-pull.fish both self-identify as "auto-pull" at runtime,
|
||||
since the guard can only ever look up the bare status
|
||||
current-function/basename string) rather than letting one silently
|
||||
overwrite the other.
|
||||
"""
|
||||
out: dict[str, list[str]] = {}
|
||||
for source in (
|
||||
mt.parse_components(REPO / "functions"),
|
||||
mt.parse_components(REPO / "conf.d"),
|
||||
mt.parse_component_file(REPO / "config.fish"),
|
||||
):
|
||||
for identity, lines in source.items():
|
||||
out.setdefault(identity, []).extend(lines)
|
||||
return out
|
||||
|
||||
|
||||
def build_registry(components: dict[str, list[str]]) -> tuple[dict[str, list[str]], list[str]]:
|
||||
"""Turn {identity: [raw COMPONENT lines]} into ({"identity:site": [tags]}, warnings).
|
||||
|
||||
A site with both always/on and always/off tagged is a contradiction:
|
||||
both are stripped and a warning is emitted, but generation continues
|
||||
-- any other real tag on that same site survives. A site whose
|
||||
effective tag set is empty after stripping produces no registry entry
|
||||
at all, which __fish_config_op_enabled already treats as always/on
|
||||
(fail-open) at guard time -- see spec §4.5.
|
||||
"""
|
||||
registry: dict[str, list[str]] = {}
|
||||
warnings: list[str] = []
|
||||
for identity, raw_lines in components.items():
|
||||
by_site: dict[str, list[str]] = {}
|
||||
for site, tag in mt.parse_component_lines(raw_lines):
|
||||
by_site.setdefault(site, []).append(tag)
|
||||
for site, tags in by_site.items():
|
||||
if "always/on" in tags and "always/off" in tags:
|
||||
label = identity if not site else f"{identity}:{site}"
|
||||
warnings.append(
|
||||
f"{label}: both always/on and always/off tagged; ignoring both"
|
||||
)
|
||||
tags = [t for t in tags if t not in ("always/on", "always/off")]
|
||||
if tags:
|
||||
registry[f"{identity}:{site}"] = list(dict.fromkeys(tags))
|
||||
return registry, warnings
|
||||
|
||||
|
||||
def render(registry: dict[str, list[str]]) -> str:
|
||||
keys = sorted(registry)
|
||||
lines = [
|
||||
"# Copyright (C) 2026 Rootiest",
|
||||
"# SPDX-License-Identifier: AGPL-3.0-or-later",
|
||||
"#",
|
||||
"# GENERATED FILE --- do not edit by hand.",
|
||||
"# Regenerate with __fish_config_op_registry_rebuild after editing a",
|
||||
"# # COMPONENT header, or automatically via docs/build-manual.py.",
|
||||
"# Source: docs/generate_component_registry.py",
|
||||
"#",
|
||||
"# This file must be sourced before any other conf.d/*.fish file that",
|
||||
"# calls the opinionated guard. That currently holds only because fish's",
|
||||
"# glob-based conf.d loading happens to sort this filename first",
|
||||
"# alphabetically among the guard-calling files -- do not rename it",
|
||||
"# without preserving that ordering.",
|
||||
"",
|
||||
]
|
||||
if not keys:
|
||||
lines.append("set -g __fish_config_op_registry_keys")
|
||||
lines.append("set -g __fish_config_op_registry_values")
|
||||
return "\n".join(lines) + "\n"
|
||||
|
||||
quoted_keys = [f'"{k}"' for k in keys]
|
||||
lines.append("set -g __fish_config_op_registry_keys \\")
|
||||
lines += [f" {k} \\" for k in quoted_keys[:-1]] + [f" {quoted_keys[-1]}"]
|
||||
lines.append("")
|
||||
|
||||
values = ['"' + " ".join(registry[k]) + '"' for k in keys]
|
||||
lines.append("set -g __fish_config_op_registry_values \\")
|
||||
lines += [f" {v} \\" for v in values[:-1]] + [f" {values[-1]}"]
|
||||
lines.append("")
|
||||
return "\n".join(lines) + "\n"
|
||||
|
||||
|
||||
def main() -> int:
|
||||
components = collect_components()
|
||||
registry, warnings = build_registry(components)
|
||||
for w in warnings:
|
||||
print(f" WARN {w}", file=sys.stderr)
|
||||
OUTPUT.write_text(render(registry))
|
||||
print(f"wrote {OUTPUT} ({len(registry)} entries)", file=sys.stderr)
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.path.insert(0, str(Path(__file__).parent))
|
||||
raise SystemExit(main())
|
||||
@@ -1,301 +0,0 @@
|
||||
<style>
|
||||
/* ── Catppuccin Latte (light) / Mocha (dark) ─────────────────── */
|
||||
:root {
|
||||
color-scheme: light dark;
|
||||
--bg: #eff1f5;
|
||||
--surface: #e6e9ef;
|
||||
--overlay: #ccd0da;
|
||||
--text: #4c4f69;
|
||||
--sub1: #6c6f85;
|
||||
--sub0: #8c8fa1;
|
||||
--blue: #1e66f5;
|
||||
--lavender: #7287fd;
|
||||
--sapphire: #209fb5;
|
||||
--green: #40a02b;
|
||||
--yellow: #df8e1d;
|
||||
--peach: #fe640b;
|
||||
--mauve: #8839ef;
|
||||
--code-bg: #dce0e8;
|
||||
--border: #bcc0cc;
|
||||
--glow1: rgba(30, 102, 245, 0.05);
|
||||
--glow2: rgba(136, 57, 239, 0.04);
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
:root {
|
||||
--bg: #1e1e2e;
|
||||
--surface: #313244;
|
||||
--overlay: #45475a;
|
||||
--text: #cdd6f4;
|
||||
--sub1: #bac2de;
|
||||
--sub0: #a6adc8;
|
||||
--blue: #89b4fa;
|
||||
--lavender: #b4befe;
|
||||
--sapphire: #74c7ec;
|
||||
--green: #a6e3a1;
|
||||
--yellow: #f9e2af;
|
||||
--peach: #fab387;
|
||||
--mauve: #cba6f7;
|
||||
--code-bg: #181825;
|
||||
--border: #45475a;
|
||||
--glow1: rgba(137, 180, 250, 0.06);
|
||||
--glow2: rgba(203, 166, 247, 0.05);
|
||||
}
|
||||
}
|
||||
|
||||
*, *::before, *::after { box-sizing: border-box; }
|
||||
|
||||
html {
|
||||
background-color: var(--bg);
|
||||
background-image:
|
||||
radial-gradient(ellipse 55% 40% at 10% 5%, var(--glow1) 0%, transparent 100%),
|
||||
radial-gradient(ellipse 45% 45% at 90% 95%, var(--glow2) 0%, transparent 100%);
|
||||
min-height: 100%;
|
||||
}
|
||||
|
||||
body {
|
||||
color: var(--text);
|
||||
font-family: system-ui, -apple-system, "Segoe UI", Helvetica, sans-serif;
|
||||
font-size: 16px;
|
||||
line-height: 1.75;
|
||||
max-width: 880px;
|
||||
margin: 0 auto;
|
||||
padding: 2rem 2.5rem 5rem;
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
/* ── Links ─────────────────────────────────────────────────── */
|
||||
a { color: var(--blue); text-decoration: none; }
|
||||
a:hover { color: var(--lavender); text-decoration: underline; }
|
||||
a:visited { color: var(--lavender); }
|
||||
|
||||
/* ── Headings ──────────────────────────────────────────────── */
|
||||
h1, h2, h3, h4, h5, h6 {
|
||||
font-family: "JetBrains Mono", "Fira Code", ui-monospace, monospace;
|
||||
color: var(--lavender);
|
||||
line-height: 1.3;
|
||||
margin-top: 2em;
|
||||
margin-bottom: 0.5em;
|
||||
}
|
||||
h1 {
|
||||
font-size: 1.9rem;
|
||||
color: var(--text);
|
||||
border-bottom: 1px solid var(--border);
|
||||
padding-bottom: 0.4em;
|
||||
margin-top: 1.2em;
|
||||
}
|
||||
h2 {
|
||||
font-size: 1.35rem;
|
||||
border-bottom: 1px solid var(--border);
|
||||
padding-bottom: 0.2em;
|
||||
}
|
||||
h3 { font-size: 1.1rem; color: var(--sapphire); }
|
||||
h4 { font-size: 0.95rem; color: var(--sub1); }
|
||||
|
||||
p { margin: 0.8em 0; }
|
||||
|
||||
/* ── Title block (pandoc-generated cover) ──────────────────── */
|
||||
#title-block-header {
|
||||
text-align: center;
|
||||
padding: 2.5rem 0 2rem;
|
||||
margin-bottom: 1.5rem;
|
||||
border-bottom: 1px solid var(--border);
|
||||
}
|
||||
#title-block-header .title {
|
||||
font-family: "JetBrains Mono", "Fira Code", ui-monospace, monospace;
|
||||
font-size: 2.6rem;
|
||||
letter-spacing: 0.12em;
|
||||
color: var(--lavender);
|
||||
border: none;
|
||||
margin: 0 0 0.75rem;
|
||||
}
|
||||
#title-block-header .author,
|
||||
#title-block-header .date {
|
||||
color: var(--sub0);
|
||||
font-size: 0.875rem;
|
||||
margin: 0.2rem 0;
|
||||
}
|
||||
|
||||
/* ── Inline code ───────────────────────────────────────────── */
|
||||
code {
|
||||
font-family: "JetBrains Mono", "Fira Code", ui-monospace, monospace;
|
||||
background: var(--code-bg);
|
||||
color: var(--peach);
|
||||
padding: 0.15em 0.4em;
|
||||
border-radius: 4px;
|
||||
font-size: 0.875em;
|
||||
}
|
||||
|
||||
/* ── Code blocks ───────────────────────────────────────────── */
|
||||
pre {
|
||||
background: var(--code-bg);
|
||||
border: 1px solid var(--border);
|
||||
border-left: 3px solid var(--sapphire);
|
||||
border-radius: 0 8px 8px 0;
|
||||
padding: 1.1em 1.4em;
|
||||
overflow-x: auto;
|
||||
line-height: 1.55;
|
||||
margin: 1.2em 0;
|
||||
}
|
||||
pre code {
|
||||
background: none;
|
||||
color: var(--text);
|
||||
padding: 0;
|
||||
font-size: 0.88em;
|
||||
}
|
||||
|
||||
/* ── Blockquotes ───────────────────────────────────────────── */
|
||||
blockquote {
|
||||
border-left: 3px solid var(--yellow);
|
||||
margin: 1.5em 0;
|
||||
padding: 0.75em 1.25em;
|
||||
background: var(--surface);
|
||||
color: var(--sub1);
|
||||
border-radius: 0 6px 6px 0;
|
||||
}
|
||||
blockquote p { margin: 0.3em 0; }
|
||||
|
||||
/* ── Tables ────────────────────────────────────────────────── */
|
||||
table {
|
||||
border-collapse: collapse;
|
||||
width: 100%;
|
||||
margin: 1.4em 0;
|
||||
font-size: 0.93em;
|
||||
}
|
||||
th, td {
|
||||
border: 1px solid var(--border);
|
||||
padding: 0.55em 0.9em;
|
||||
text-align: left;
|
||||
}
|
||||
th {
|
||||
background: var(--surface);
|
||||
color: var(--lavender);
|
||||
font-weight: 600;
|
||||
font-family: "JetBrains Mono", "Fira Code", ui-monospace, monospace;
|
||||
font-size: 0.82em;
|
||||
letter-spacing: 0.06em;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
tr:nth-child(even) { background: var(--surface); }
|
||||
tr:hover { background: var(--overlay); }
|
||||
|
||||
/* ── HR ────────────────────────────────────────────────────── */
|
||||
hr { border: none; border-top: 1px solid var(--border); margin: 2.5em 0; }
|
||||
|
||||
/* ── Lists ─────────────────────────────────────────────────── */
|
||||
ul, ol { padding-left: 1.6em; }
|
||||
li { margin: 0.35em 0; }
|
||||
|
||||
/* ── Chunk navigation bar (prev / up / next) ───────────────── */
|
||||
nav:not(#TOC):not([role="doc-toc"]) {
|
||||
background: var(--surface);
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 8px;
|
||||
margin: 1.5em 0;
|
||||
font-size: 0.875em;
|
||||
overflow: hidden;
|
||||
}
|
||||
nav:not(#TOC):not([role="doc-toc"]) p {
|
||||
margin: 0;
|
||||
padding: 0.65em 1.2em;
|
||||
display: flex;
|
||||
gap: 0.4em 1.75em;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
}
|
||||
/* JS wraps each "Label: <a>" pair in .nav-item so they flex as a unit */
|
||||
.nav-item {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 0.3em;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.nav-item a { color: var(--blue); }
|
||||
.nav-item a:hover { color: var(--lavender); }
|
||||
|
||||
/* ── Table of contents panel ───────────────────────────────── */
|
||||
nav#TOC, nav[role="doc-toc"] {
|
||||
display: block;
|
||||
background: var(--surface);
|
||||
border: 1px solid var(--border);
|
||||
border-left: 3px solid var(--lavender);
|
||||
border-radius: 0 8px 8px 0;
|
||||
padding: 1.2em 1.5em;
|
||||
margin: 1.5em 0;
|
||||
}
|
||||
nav#TOC > h2,
|
||||
nav[role="doc-toc"] > h2 {
|
||||
font-size: 0.7rem;
|
||||
letter-spacing: 0.14em;
|
||||
text-transform: uppercase;
|
||||
color: var(--sub0);
|
||||
border: none;
|
||||
margin: 0 0 0.9em;
|
||||
padding: 0;
|
||||
}
|
||||
nav#TOC ul, nav[role="doc-toc"] ul {
|
||||
list-style: none;
|
||||
padding-left: 1em;
|
||||
margin: 0.25em 0;
|
||||
}
|
||||
nav#TOC > ul, nav[role="doc-toc"] > ul { padding-left: 0; }
|
||||
nav#TOC li, nav[role="doc-toc"] li {
|
||||
margin: 0.3em 0;
|
||||
padding-left: 0.75em;
|
||||
border-left: 1px solid transparent;
|
||||
transition: border-color 0.12s;
|
||||
}
|
||||
nav#TOC li:hover, nav[role="doc-toc"] li:hover {
|
||||
border-left-color: var(--lavender);
|
||||
}
|
||||
nav#TOC a, nav[role="doc-toc"] a {
|
||||
color: var(--sub1);
|
||||
font-size: 0.9em;
|
||||
}
|
||||
nav#TOC a:hover, nav[role="doc-toc"] a:hover {
|
||||
color: var(--lavender);
|
||||
text-decoration: none;
|
||||
}
|
||||
</style>
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
/* ── Hide ToC on every page except index.html ───────────── */
|
||||
var path = location.pathname;
|
||||
var onIndex = path === '/' || path === '' || /\/index\.html(\?.*)?$/.test(path);
|
||||
if (!onIndex) {
|
||||
var toc = document.getElementById('TOC') ||
|
||||
document.querySelector('[role="doc-toc"]');
|
||||
if (toc) toc.remove();
|
||||
}
|
||||
|
||||
/* ── Wrap each "Label: <a>" pair in a .nav-item span ───────
|
||||
Pandoc emits label text nodes and anchors as siblings;
|
||||
flex sees them as separate items, causing labels to split
|
||||
from their links when wrapping. Grouping them in a span
|
||||
keeps each label+link as a single flex unit. */
|
||||
document.querySelectorAll('nav:not(#TOC):not([role="doc-toc"])').forEach(function (nav) {
|
||||
var p = nav.querySelector('p');
|
||||
if (!p) return;
|
||||
var children = Array.from(p.childNodes);
|
||||
var pairs = [];
|
||||
for (var i = 0; i + 1 < children.length; i++) {
|
||||
var cur = children[i];
|
||||
var nxt = children[i + 1];
|
||||
if (cur.nodeType === Node.TEXT_NODE &&
|
||||
/[A-Z][a-z]*:\s*/.test(cur.textContent) &&
|
||||
nxt.nodeType === Node.ELEMENT_NODE &&
|
||||
nxt.tagName === 'A') {
|
||||
pairs.push([cur, nxt]);
|
||||
i++; // skip the anchor on the next iteration
|
||||
}
|
||||
}
|
||||
pairs.forEach(function (pair) {
|
||||
var span = document.createElement('span');
|
||||
span.className = 'nav-item';
|
||||
p.insertBefore(span, pair[0]);
|
||||
span.appendChild(pair[0]);
|
||||
span.appendChild(pair[1]);
|
||||
});
|
||||
});
|
||||
});
|
||||
</script>
|
||||
@@ -1,495 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" lang="" xml:lang="">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="generator" content="pandoc" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" />
|
||||
<meta name="author" content="Rootiest" />
|
||||
<title>NAME</title>
|
||||
<style>
|
||||
div.sitenav { display: flex; flex-direction: row; flex-wrap: wrap; }
|
||||
span.navlink { flex: 1; }
|
||||
span.navlink-label { display: inline-block; min-width: 4em; }
|
||||
html {
|
||||
color: #1a1a1a;
|
||||
background-color: #fdfdfd;
|
||||
}
|
||||
body {
|
||||
margin: 0 auto;
|
||||
max-width: 36em;
|
||||
padding-left: 50px;
|
||||
padding-right: 50px;
|
||||
padding-top: 50px;
|
||||
padding-bottom: 50px;
|
||||
hyphens: auto;
|
||||
overflow-wrap: break-word;
|
||||
text-rendering: optimizeLegibility;
|
||||
font-kerning: normal;
|
||||
}
|
||||
@media (max-width: 600px) {
|
||||
body {
|
||||
font-size: 0.9em;
|
||||
padding: 12px;
|
||||
}
|
||||
h1 {
|
||||
font-size: 1.8em;
|
||||
}
|
||||
}
|
||||
@media print {
|
||||
html {
|
||||
background-color: white;
|
||||
}
|
||||
body {
|
||||
background-color: transparent;
|
||||
color: black;
|
||||
font-size: 12pt;
|
||||
}
|
||||
p, h2, h3 {
|
||||
orphans: 3;
|
||||
widows: 3;
|
||||
}
|
||||
h2, h3, h4 {
|
||||
page-break-after: avoid;
|
||||
}
|
||||
}
|
||||
p {
|
||||
margin: 1em 0;
|
||||
}
|
||||
a {
|
||||
color: #1a1a1a;
|
||||
}
|
||||
a:visited {
|
||||
color: #1a1a1a;
|
||||
}
|
||||
img {
|
||||
max-width: 100%;
|
||||
}
|
||||
h1, h2, h3, h4, h5, h6 {
|
||||
margin-top: 1.4em;
|
||||
}
|
||||
h5, h6 {
|
||||
font-size: 1em;
|
||||
font-style: italic;
|
||||
}
|
||||
h6 {
|
||||
font-weight: normal;
|
||||
}
|
||||
ol, ul {
|
||||
padding-left: 1.7em;
|
||||
margin-top: 1em;
|
||||
}
|
||||
li > ol, li > ul {
|
||||
margin-top: 0;
|
||||
}
|
||||
blockquote {
|
||||
margin: 1em 0 1em 1.7em;
|
||||
padding-left: 1em;
|
||||
border-left: 2px solid #e6e6e6;
|
||||
color: #606060;
|
||||
}
|
||||
code {
|
||||
font-family: Menlo, Monaco, Consolas, 'Lucida Console', monospace;
|
||||
font-size: 85%;
|
||||
margin: 0;
|
||||
hyphens: manual;
|
||||
}
|
||||
pre {
|
||||
margin: 1em 0;
|
||||
overflow: auto;
|
||||
}
|
||||
pre code {
|
||||
padding: 0;
|
||||
overflow: visible;
|
||||
overflow-wrap: normal;
|
||||
}
|
||||
.sourceCode {
|
||||
background-color: transparent;
|
||||
overflow: visible;
|
||||
}
|
||||
hr {
|
||||
background-color: #1a1a1a;
|
||||
border: none;
|
||||
height: 1px;
|
||||
margin: 1em 0;
|
||||
}
|
||||
table {
|
||||
margin: 1em 0;
|
||||
border-collapse: collapse;
|
||||
width: 100%;
|
||||
overflow-x: auto;
|
||||
display: block;
|
||||
font-variant-numeric: lining-nums tabular-nums;
|
||||
}
|
||||
table caption {
|
||||
margin-bottom: 0.75em;
|
||||
}
|
||||
tbody {
|
||||
margin-top: 0.5em;
|
||||
border-top: 1px solid #1a1a1a;
|
||||
border-bottom: 1px solid #1a1a1a;
|
||||
}
|
||||
th {
|
||||
border-top: 1px solid #1a1a1a;
|
||||
padding: 0.25em 0.5em 0.25em 0.5em;
|
||||
}
|
||||
td {
|
||||
padding: 0.125em 0.5em 0.25em 0.5em;
|
||||
}
|
||||
header {
|
||||
margin-bottom: 4em;
|
||||
text-align: center;
|
||||
}
|
||||
#TOC li {
|
||||
list-style: none;
|
||||
}
|
||||
#TOC ul {
|
||||
padding-left: 1.3em;
|
||||
}
|
||||
#TOC > ul {
|
||||
padding-left: 0;
|
||||
}
|
||||
#TOC a:not(:hover) {
|
||||
text-decoration: none;
|
||||
}
|
||||
code{white-space: pre-wrap;}
|
||||
span.smallcaps{font-variant: small-caps;}
|
||||
div.columns{display: flex; gap: min(4vw, 1.5em);}
|
||||
div.column{flex: auto; overflow-x: auto;}
|
||||
div.hanging-indent{margin-left: 1.5em; text-indent: -1.5em;}
|
||||
/* The extra [class] is a hack that increases specificity enough to
|
||||
override a similar rule in reveal.js */
|
||||
ul.task-list[class]{list-style: none;}
|
||||
ul.task-list li input[type="checkbox"] {
|
||||
font-size: inherit;
|
||||
width: 0.8em;
|
||||
margin: 0 0.8em 0.2em -1.6em;
|
||||
vertical-align: middle;
|
||||
}
|
||||
.display.math{display: block; text-align: center; margin: 0.5rem auto;}
|
||||
</style>
|
||||
<style>
|
||||
/* ── Catppuccin Latte (light) / Mocha (dark) ─────────────────── */
|
||||
:root {
|
||||
color-scheme: light dark;
|
||||
--bg: #eff1f5;
|
||||
--surface: #e6e9ef;
|
||||
--overlay: #ccd0da;
|
||||
--text: #4c4f69;
|
||||
--sub1: #6c6f85;
|
||||
--sub0: #8c8fa1;
|
||||
--blue: #1e66f5;
|
||||
--lavender: #7287fd;
|
||||
--sapphire: #209fb5;
|
||||
--green: #40a02b;
|
||||
--yellow: #df8e1d;
|
||||
--peach: #fe640b;
|
||||
--mauve: #8839ef;
|
||||
--code-bg: #dce0e8;
|
||||
--border: #bcc0cc;
|
||||
--glow1: rgba(30, 102, 245, 0.05);
|
||||
--glow2: rgba(136, 57, 239, 0.04);
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
:root {
|
||||
--bg: #1e1e2e;
|
||||
--surface: #313244;
|
||||
--overlay: #45475a;
|
||||
--text: #cdd6f4;
|
||||
--sub1: #bac2de;
|
||||
--sub0: #a6adc8;
|
||||
--blue: #89b4fa;
|
||||
--lavender: #b4befe;
|
||||
--sapphire: #74c7ec;
|
||||
--green: #a6e3a1;
|
||||
--yellow: #f9e2af;
|
||||
--peach: #fab387;
|
||||
--mauve: #cba6f7;
|
||||
--code-bg: #181825;
|
||||
--border: #45475a;
|
||||
--glow1: rgba(137, 180, 250, 0.06);
|
||||
--glow2: rgba(203, 166, 247, 0.05);
|
||||
}
|
||||
}
|
||||
|
||||
*, *::before, *::after { box-sizing: border-box; }
|
||||
|
||||
html {
|
||||
background-color: var(--bg);
|
||||
background-image:
|
||||
radial-gradient(ellipse 55% 40% at 10% 5%, var(--glow1) 0%, transparent 100%),
|
||||
radial-gradient(ellipse 45% 45% at 90% 95%, var(--glow2) 0%, transparent 100%);
|
||||
min-height: 100%;
|
||||
}
|
||||
|
||||
body {
|
||||
color: var(--text);
|
||||
font-family: system-ui, -apple-system, "Segoe UI", Helvetica, sans-serif;
|
||||
font-size: 16px;
|
||||
line-height: 1.75;
|
||||
max-width: 880px;
|
||||
margin: 0 auto;
|
||||
padding: 2rem 2.5rem 5rem;
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
/* ── Links ─────────────────────────────────────────────────── */
|
||||
a { color: var(--blue); text-decoration: none; }
|
||||
a:hover { color: var(--lavender); text-decoration: underline; }
|
||||
a:visited { color: var(--lavender); }
|
||||
|
||||
/* ── Headings ──────────────────────────────────────────────── */
|
||||
h1, h2, h3, h4, h5, h6 {
|
||||
font-family: "JetBrains Mono", "Fira Code", ui-monospace, monospace;
|
||||
color: var(--lavender);
|
||||
line-height: 1.3;
|
||||
margin-top: 2em;
|
||||
margin-bottom: 0.5em;
|
||||
}
|
||||
h1 {
|
||||
font-size: 1.9rem;
|
||||
color: var(--text);
|
||||
border-bottom: 1px solid var(--border);
|
||||
padding-bottom: 0.4em;
|
||||
margin-top: 1.2em;
|
||||
}
|
||||
h2 {
|
||||
font-size: 1.35rem;
|
||||
border-bottom: 1px solid var(--border);
|
||||
padding-bottom: 0.2em;
|
||||
}
|
||||
h3 { font-size: 1.1rem; color: var(--sapphire); }
|
||||
h4 { font-size: 0.95rem; color: var(--sub1); }
|
||||
|
||||
p { margin: 0.8em 0; }
|
||||
|
||||
/* ── Title block (pandoc-generated cover) ──────────────────── */
|
||||
#title-block-header {
|
||||
text-align: center;
|
||||
padding: 2.5rem 0 2rem;
|
||||
margin-bottom: 1.5rem;
|
||||
border-bottom: 1px solid var(--border);
|
||||
}
|
||||
#title-block-header .title {
|
||||
font-family: "JetBrains Mono", "Fira Code", ui-monospace, monospace;
|
||||
font-size: 2.6rem;
|
||||
letter-spacing: 0.12em;
|
||||
color: var(--lavender);
|
||||
border: none;
|
||||
margin: 0 0 0.75rem;
|
||||
}
|
||||
#title-block-header .author,
|
||||
#title-block-header .date {
|
||||
color: var(--sub0);
|
||||
font-size: 0.875rem;
|
||||
margin: 0.2rem 0;
|
||||
}
|
||||
|
||||
/* ── Inline code ───────────────────────────────────────────── */
|
||||
code {
|
||||
font-family: "JetBrains Mono", "Fira Code", ui-monospace, monospace;
|
||||
background: var(--code-bg);
|
||||
color: var(--peach);
|
||||
padding: 0.15em 0.4em;
|
||||
border-radius: 4px;
|
||||
font-size: 0.875em;
|
||||
}
|
||||
|
||||
/* ── Code blocks ───────────────────────────────────────────── */
|
||||
pre {
|
||||
background: var(--code-bg);
|
||||
border: 1px solid var(--border);
|
||||
border-left: 3px solid var(--sapphire);
|
||||
border-radius: 0 8px 8px 0;
|
||||
padding: 1.1em 1.4em;
|
||||
overflow-x: auto;
|
||||
line-height: 1.55;
|
||||
margin: 1.2em 0;
|
||||
}
|
||||
pre code {
|
||||
background: none;
|
||||
color: var(--text);
|
||||
padding: 0;
|
||||
font-size: 0.88em;
|
||||
}
|
||||
|
||||
/* ── Blockquotes ───────────────────────────────────────────── */
|
||||
blockquote {
|
||||
border-left: 3px solid var(--yellow);
|
||||
margin: 1.5em 0;
|
||||
padding: 0.75em 1.25em;
|
||||
background: var(--surface);
|
||||
color: var(--sub1);
|
||||
border-radius: 0 6px 6px 0;
|
||||
}
|
||||
blockquote p { margin: 0.3em 0; }
|
||||
|
||||
/* ── Tables ────────────────────────────────────────────────── */
|
||||
table {
|
||||
border-collapse: collapse;
|
||||
width: 100%;
|
||||
margin: 1.4em 0;
|
||||
font-size: 0.93em;
|
||||
}
|
||||
th, td {
|
||||
border: 1px solid var(--border);
|
||||
padding: 0.55em 0.9em;
|
||||
text-align: left;
|
||||
}
|
||||
th {
|
||||
background: var(--surface);
|
||||
color: var(--lavender);
|
||||
font-weight: 600;
|
||||
font-family: "JetBrains Mono", "Fira Code", ui-monospace, monospace;
|
||||
font-size: 0.82em;
|
||||
letter-spacing: 0.06em;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
tr:nth-child(even) { background: var(--surface); }
|
||||
tr:hover { background: var(--overlay); }
|
||||
|
||||
/* ── HR ────────────────────────────────────────────────────── */
|
||||
hr { border: none; border-top: 1px solid var(--border); margin: 2.5em 0; }
|
||||
|
||||
/* ── Lists ─────────────────────────────────────────────────── */
|
||||
ul, ol { padding-left: 1.6em; }
|
||||
li { margin: 0.35em 0; }
|
||||
|
||||
/* ── Chunk navigation bar (prev / up / next) ───────────────── */
|
||||
nav:not(#TOC):not([role="doc-toc"]) {
|
||||
background: var(--surface);
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 8px;
|
||||
margin: 1.5em 0;
|
||||
font-size: 0.875em;
|
||||
overflow: hidden;
|
||||
}
|
||||
nav:not(#TOC):not([role="doc-toc"]) p {
|
||||
margin: 0;
|
||||
padding: 0.65em 1.2em;
|
||||
display: flex;
|
||||
gap: 0.4em 1.75em;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
}
|
||||
/* JS wraps each "Label: <a>" pair in .nav-item so they flex as a unit */
|
||||
.nav-item {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 0.3em;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.nav-item a { color: var(--blue); }
|
||||
.nav-item a:hover { color: var(--lavender); }
|
||||
|
||||
/* ── Table of contents panel ───────────────────────────────── */
|
||||
nav#TOC, nav[role="doc-toc"] {
|
||||
display: block;
|
||||
background: var(--surface);
|
||||
border: 1px solid var(--border);
|
||||
border-left: 3px solid var(--lavender);
|
||||
border-radius: 0 8px 8px 0;
|
||||
padding: 1.2em 1.5em;
|
||||
margin: 1.5em 0;
|
||||
}
|
||||
nav#TOC > h2,
|
||||
nav[role="doc-toc"] > h2 {
|
||||
font-size: 0.7rem;
|
||||
letter-spacing: 0.14em;
|
||||
text-transform: uppercase;
|
||||
color: var(--sub0);
|
||||
border: none;
|
||||
margin: 0 0 0.9em;
|
||||
padding: 0;
|
||||
}
|
||||
nav#TOC ul, nav[role="doc-toc"] ul {
|
||||
list-style: none;
|
||||
padding-left: 1em;
|
||||
margin: 0.25em 0;
|
||||
}
|
||||
nav#TOC > ul, nav[role="doc-toc"] > ul { padding-left: 0; }
|
||||
nav#TOC li, nav[role="doc-toc"] li {
|
||||
margin: 0.3em 0;
|
||||
padding-left: 0.75em;
|
||||
border-left: 1px solid transparent;
|
||||
transition: border-color 0.12s;
|
||||
}
|
||||
nav#TOC li:hover, nav[role="doc-toc"] li:hover {
|
||||
border-left-color: var(--lavender);
|
||||
}
|
||||
nav#TOC a, nav[role="doc-toc"] a {
|
||||
color: var(--sub1);
|
||||
font-size: 0.9em;
|
||||
}
|
||||
nav#TOC a:hover, nav[role="doc-toc"] a:hover {
|
||||
color: var(--lavender);
|
||||
text-decoration: none;
|
||||
}
|
||||
</style>
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
/* ── Hide ToC on every page except index.html ───────────── */
|
||||
var path = location.pathname;
|
||||
var onIndex = path === '/' || path === '' || /\/index\.html(\?.*)?$/.test(path);
|
||||
if (!onIndex) {
|
||||
var toc = document.getElementById('TOC') ||
|
||||
document.querySelector('[role="doc-toc"]');
|
||||
if (toc) toc.remove();
|
||||
}
|
||||
|
||||
/* ── Wrap each "Label: <a>" pair in a .nav-item span ───────
|
||||
Pandoc emits label text nodes and anchors as siblings;
|
||||
flex sees them as separate items, causing labels to split
|
||||
from their links when wrapping. Grouping them in a span
|
||||
keeps each label+link as a single flex unit. */
|
||||
document.querySelectorAll('nav:not(#TOC):not([role="doc-toc"])').forEach(function (nav) {
|
||||
var p = nav.querySelector('p');
|
||||
if (!p) return;
|
||||
var children = Array.from(p.childNodes);
|
||||
var pairs = [];
|
||||
for (var i = 0; i + 1 < children.length; i++) {
|
||||
var cur = children[i];
|
||||
var nxt = children[i + 1];
|
||||
if (cur.nodeType === Node.TEXT_NODE &&
|
||||
/[A-Z][a-z]*:\s*/.test(cur.textContent) &&
|
||||
nxt.nodeType === Node.ELEMENT_NODE &&
|
||||
nxt.tagName === 'A') {
|
||||
pairs.push([cur, nxt]);
|
||||
i++; // skip the anchor on the next iteration
|
||||
}
|
||||
}
|
||||
pairs.forEach(function (pair) {
|
||||
var span = document.createElement('span');
|
||||
span.className = 'nav-item';
|
||||
p.insertBefore(span, pair[0]);
|
||||
span.appendChild(pair[0]);
|
||||
span.appendChild(pair[1]);
|
||||
});
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<nav id="sitenav">
|
||||
<div class="sitenav">
|
||||
<span class="navlink">
|
||||
<span class="navlink-label">Up:</span> <a href="index.html" accesskey="u" rel="up">FISH-CONFIG</a>
|
||||
</span>
|
||||
<span class="navlink">
|
||||
<span class="navlink-label">Top:</span> <a href="index.html" accesskey="t" rel="top">FISH-CONFIG</a>
|
||||
</span>
|
||||
</div>
|
||||
<div class="sitenav">
|
||||
<span class="navlink">
|
||||
<span class="navlink-label">Next:</span> <a href="2-synopsis.html" accesskey="n" rel="next">SYNOPSIS</a>
|
||||
</span>
|
||||
<span class="navlink">
|
||||
<span class="navlink-label">Previous:</span> <a href="index.html" accesskey="p" rel="previous">FISH-CONFIG</a>
|
||||
</span>
|
||||
</div>
|
||||
</nav>
|
||||
<h1 data-number="1" id="name">NAME</h1>
|
||||
<p>fish-config - personal fish shell configuration for Fish 4.x with
|
||||
modern CLI tool integration</p>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,534 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" lang="" xml:lang="">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="generator" content="pandoc" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" />
|
||||
<meta name="author" content="Rootiest" />
|
||||
<title>6. DEPENDENCY CATALOG</title>
|
||||
<style>
|
||||
div.sitenav { display: flex; flex-direction: row; flex-wrap: wrap; }
|
||||
span.navlink { flex: 1; }
|
||||
span.navlink-label { display: inline-block; min-width: 4em; }
|
||||
html {
|
||||
color: #1a1a1a;
|
||||
background-color: #fdfdfd;
|
||||
}
|
||||
body {
|
||||
margin: 0 auto;
|
||||
max-width: 36em;
|
||||
padding-left: 50px;
|
||||
padding-right: 50px;
|
||||
padding-top: 50px;
|
||||
padding-bottom: 50px;
|
||||
hyphens: auto;
|
||||
overflow-wrap: break-word;
|
||||
text-rendering: optimizeLegibility;
|
||||
font-kerning: normal;
|
||||
}
|
||||
@media (max-width: 600px) {
|
||||
body {
|
||||
font-size: 0.9em;
|
||||
padding: 12px;
|
||||
}
|
||||
h1 {
|
||||
font-size: 1.8em;
|
||||
}
|
||||
}
|
||||
@media print {
|
||||
html {
|
||||
background-color: white;
|
||||
}
|
||||
body {
|
||||
background-color: transparent;
|
||||
color: black;
|
||||
font-size: 12pt;
|
||||
}
|
||||
p, h2, h3 {
|
||||
orphans: 3;
|
||||
widows: 3;
|
||||
}
|
||||
h2, h3, h4 {
|
||||
page-break-after: avoid;
|
||||
}
|
||||
}
|
||||
p {
|
||||
margin: 1em 0;
|
||||
}
|
||||
a {
|
||||
color: #1a1a1a;
|
||||
}
|
||||
a:visited {
|
||||
color: #1a1a1a;
|
||||
}
|
||||
img {
|
||||
max-width: 100%;
|
||||
}
|
||||
h1, h2, h3, h4, h5, h6 {
|
||||
margin-top: 1.4em;
|
||||
}
|
||||
h5, h6 {
|
||||
font-size: 1em;
|
||||
font-style: italic;
|
||||
}
|
||||
h6 {
|
||||
font-weight: normal;
|
||||
}
|
||||
ol, ul {
|
||||
padding-left: 1.7em;
|
||||
margin-top: 1em;
|
||||
}
|
||||
li > ol, li > ul {
|
||||
margin-top: 0;
|
||||
}
|
||||
blockquote {
|
||||
margin: 1em 0 1em 1.7em;
|
||||
padding-left: 1em;
|
||||
border-left: 2px solid #e6e6e6;
|
||||
color: #606060;
|
||||
}
|
||||
code {
|
||||
font-family: Menlo, Monaco, Consolas, 'Lucida Console', monospace;
|
||||
font-size: 85%;
|
||||
margin: 0;
|
||||
hyphens: manual;
|
||||
}
|
||||
pre {
|
||||
margin: 1em 0;
|
||||
overflow: auto;
|
||||
}
|
||||
pre code {
|
||||
padding: 0;
|
||||
overflow: visible;
|
||||
overflow-wrap: normal;
|
||||
}
|
||||
.sourceCode {
|
||||
background-color: transparent;
|
||||
overflow: visible;
|
||||
}
|
||||
hr {
|
||||
background-color: #1a1a1a;
|
||||
border: none;
|
||||
height: 1px;
|
||||
margin: 1em 0;
|
||||
}
|
||||
table {
|
||||
margin: 1em 0;
|
||||
border-collapse: collapse;
|
||||
width: 100%;
|
||||
overflow-x: auto;
|
||||
display: block;
|
||||
font-variant-numeric: lining-nums tabular-nums;
|
||||
}
|
||||
table caption {
|
||||
margin-bottom: 0.75em;
|
||||
}
|
||||
tbody {
|
||||
margin-top: 0.5em;
|
||||
border-top: 1px solid #1a1a1a;
|
||||
border-bottom: 1px solid #1a1a1a;
|
||||
}
|
||||
th {
|
||||
border-top: 1px solid #1a1a1a;
|
||||
padding: 0.25em 0.5em 0.25em 0.5em;
|
||||
}
|
||||
td {
|
||||
padding: 0.125em 0.5em 0.25em 0.5em;
|
||||
}
|
||||
header {
|
||||
margin-bottom: 4em;
|
||||
text-align: center;
|
||||
}
|
||||
#TOC li {
|
||||
list-style: none;
|
||||
}
|
||||
#TOC ul {
|
||||
padding-left: 1.3em;
|
||||
}
|
||||
#TOC > ul {
|
||||
padding-left: 0;
|
||||
}
|
||||
#TOC a:not(:hover) {
|
||||
text-decoration: none;
|
||||
}
|
||||
code{white-space: pre-wrap;}
|
||||
span.smallcaps{font-variant: small-caps;}
|
||||
div.columns{display: flex; gap: min(4vw, 1.5em);}
|
||||
div.column{flex: auto; overflow-x: auto;}
|
||||
div.hanging-indent{margin-left: 1.5em; text-indent: -1.5em;}
|
||||
/* The extra [class] is a hack that increases specificity enough to
|
||||
override a similar rule in reveal.js */
|
||||
ul.task-list[class]{list-style: none;}
|
||||
ul.task-list li input[type="checkbox"] {
|
||||
font-size: inherit;
|
||||
width: 0.8em;
|
||||
margin: 0 0.8em 0.2em -1.6em;
|
||||
vertical-align: middle;
|
||||
}
|
||||
.display.math{display: block; text-align: center; margin: 0.5rem auto;}
|
||||
</style>
|
||||
<style>
|
||||
/* ── Catppuccin Latte (light) / Mocha (dark) ─────────────────── */
|
||||
:root {
|
||||
color-scheme: light dark;
|
||||
--bg: #eff1f5;
|
||||
--surface: #e6e9ef;
|
||||
--overlay: #ccd0da;
|
||||
--text: #4c4f69;
|
||||
--sub1: #6c6f85;
|
||||
--sub0: #8c8fa1;
|
||||
--blue: #1e66f5;
|
||||
--lavender: #7287fd;
|
||||
--sapphire: #209fb5;
|
||||
--green: #40a02b;
|
||||
--yellow: #df8e1d;
|
||||
--peach: #fe640b;
|
||||
--mauve: #8839ef;
|
||||
--code-bg: #dce0e8;
|
||||
--border: #bcc0cc;
|
||||
--glow1: rgba(30, 102, 245, 0.05);
|
||||
--glow2: rgba(136, 57, 239, 0.04);
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
:root {
|
||||
--bg: #1e1e2e;
|
||||
--surface: #313244;
|
||||
--overlay: #45475a;
|
||||
--text: #cdd6f4;
|
||||
--sub1: #bac2de;
|
||||
--sub0: #a6adc8;
|
||||
--blue: #89b4fa;
|
||||
--lavender: #b4befe;
|
||||
--sapphire: #74c7ec;
|
||||
--green: #a6e3a1;
|
||||
--yellow: #f9e2af;
|
||||
--peach: #fab387;
|
||||
--mauve: #cba6f7;
|
||||
--code-bg: #181825;
|
||||
--border: #45475a;
|
||||
--glow1: rgba(137, 180, 250, 0.06);
|
||||
--glow2: rgba(203, 166, 247, 0.05);
|
||||
}
|
||||
}
|
||||
|
||||
*, *::before, *::after { box-sizing: border-box; }
|
||||
|
||||
html {
|
||||
background-color: var(--bg);
|
||||
background-image:
|
||||
radial-gradient(ellipse 55% 40% at 10% 5%, var(--glow1) 0%, transparent 100%),
|
||||
radial-gradient(ellipse 45% 45% at 90% 95%, var(--glow2) 0%, transparent 100%);
|
||||
min-height: 100%;
|
||||
}
|
||||
|
||||
body {
|
||||
color: var(--text);
|
||||
font-family: system-ui, -apple-system, "Segoe UI", Helvetica, sans-serif;
|
||||
font-size: 16px;
|
||||
line-height: 1.75;
|
||||
max-width: 880px;
|
||||
margin: 0 auto;
|
||||
padding: 2rem 2.5rem 5rem;
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
/* ── Links ─────────────────────────────────────────────────── */
|
||||
a { color: var(--blue); text-decoration: none; }
|
||||
a:hover { color: var(--lavender); text-decoration: underline; }
|
||||
a:visited { color: var(--lavender); }
|
||||
|
||||
/* ── Headings ──────────────────────────────────────────────── */
|
||||
h1, h2, h3, h4, h5, h6 {
|
||||
font-family: "JetBrains Mono", "Fira Code", ui-monospace, monospace;
|
||||
color: var(--lavender);
|
||||
line-height: 1.3;
|
||||
margin-top: 2em;
|
||||
margin-bottom: 0.5em;
|
||||
}
|
||||
h1 {
|
||||
font-size: 1.9rem;
|
||||
color: var(--text);
|
||||
border-bottom: 1px solid var(--border);
|
||||
padding-bottom: 0.4em;
|
||||
margin-top: 1.2em;
|
||||
}
|
||||
h2 {
|
||||
font-size: 1.35rem;
|
||||
border-bottom: 1px solid var(--border);
|
||||
padding-bottom: 0.2em;
|
||||
}
|
||||
h3 { font-size: 1.1rem; color: var(--sapphire); }
|
||||
h4 { font-size: 0.95rem; color: var(--sub1); }
|
||||
|
||||
p { margin: 0.8em 0; }
|
||||
|
||||
/* ── Title block (pandoc-generated cover) ──────────────────── */
|
||||
#title-block-header {
|
||||
text-align: center;
|
||||
padding: 2.5rem 0 2rem;
|
||||
margin-bottom: 1.5rem;
|
||||
border-bottom: 1px solid var(--border);
|
||||
}
|
||||
#title-block-header .title {
|
||||
font-family: "JetBrains Mono", "Fira Code", ui-monospace, monospace;
|
||||
font-size: 2.6rem;
|
||||
letter-spacing: 0.12em;
|
||||
color: var(--lavender);
|
||||
border: none;
|
||||
margin: 0 0 0.75rem;
|
||||
}
|
||||
#title-block-header .author,
|
||||
#title-block-header .date {
|
||||
color: var(--sub0);
|
||||
font-size: 0.875rem;
|
||||
margin: 0.2rem 0;
|
||||
}
|
||||
|
||||
/* ── Inline code ───────────────────────────────────────────── */
|
||||
code {
|
||||
font-family: "JetBrains Mono", "Fira Code", ui-monospace, monospace;
|
||||
background: var(--code-bg);
|
||||
color: var(--peach);
|
||||
padding: 0.15em 0.4em;
|
||||
border-radius: 4px;
|
||||
font-size: 0.875em;
|
||||
}
|
||||
|
||||
/* ── Code blocks ───────────────────────────────────────────── */
|
||||
pre {
|
||||
background: var(--code-bg);
|
||||
border: 1px solid var(--border);
|
||||
border-left: 3px solid var(--sapphire);
|
||||
border-radius: 0 8px 8px 0;
|
||||
padding: 1.1em 1.4em;
|
||||
overflow-x: auto;
|
||||
line-height: 1.55;
|
||||
margin: 1.2em 0;
|
||||
}
|
||||
pre code {
|
||||
background: none;
|
||||
color: var(--text);
|
||||
padding: 0;
|
||||
font-size: 0.88em;
|
||||
}
|
||||
|
||||
/* ── Blockquotes ───────────────────────────────────────────── */
|
||||
blockquote {
|
||||
border-left: 3px solid var(--yellow);
|
||||
margin: 1.5em 0;
|
||||
padding: 0.75em 1.25em;
|
||||
background: var(--surface);
|
||||
color: var(--sub1);
|
||||
border-radius: 0 6px 6px 0;
|
||||
}
|
||||
blockquote p { margin: 0.3em 0; }
|
||||
|
||||
/* ── Tables ────────────────────────────────────────────────── */
|
||||
table {
|
||||
border-collapse: collapse;
|
||||
width: 100%;
|
||||
margin: 1.4em 0;
|
||||
font-size: 0.93em;
|
||||
}
|
||||
th, td {
|
||||
border: 1px solid var(--border);
|
||||
padding: 0.55em 0.9em;
|
||||
text-align: left;
|
||||
}
|
||||
th {
|
||||
background: var(--surface);
|
||||
color: var(--lavender);
|
||||
font-weight: 600;
|
||||
font-family: "JetBrains Mono", "Fira Code", ui-monospace, monospace;
|
||||
font-size: 0.82em;
|
||||
letter-spacing: 0.06em;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
tr:nth-child(even) { background: var(--surface); }
|
||||
tr:hover { background: var(--overlay); }
|
||||
|
||||
/* ── HR ────────────────────────────────────────────────────── */
|
||||
hr { border: none; border-top: 1px solid var(--border); margin: 2.5em 0; }
|
||||
|
||||
/* ── Lists ─────────────────────────────────────────────────── */
|
||||
ul, ol { padding-left: 1.6em; }
|
||||
li { margin: 0.35em 0; }
|
||||
|
||||
/* ── Chunk navigation bar (prev / up / next) ───────────────── */
|
||||
nav:not(#TOC):not([role="doc-toc"]) {
|
||||
background: var(--surface);
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 8px;
|
||||
margin: 1.5em 0;
|
||||
font-size: 0.875em;
|
||||
overflow: hidden;
|
||||
}
|
||||
nav:not(#TOC):not([role="doc-toc"]) p {
|
||||
margin: 0;
|
||||
padding: 0.65em 1.2em;
|
||||
display: flex;
|
||||
gap: 0.4em 1.75em;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
}
|
||||
/* JS wraps each "Label: <a>" pair in .nav-item so they flex as a unit */
|
||||
.nav-item {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 0.3em;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.nav-item a { color: var(--blue); }
|
||||
.nav-item a:hover { color: var(--lavender); }
|
||||
|
||||
/* ── Table of contents panel ───────────────────────────────── */
|
||||
nav#TOC, nav[role="doc-toc"] {
|
||||
display: block;
|
||||
background: var(--surface);
|
||||
border: 1px solid var(--border);
|
||||
border-left: 3px solid var(--lavender);
|
||||
border-radius: 0 8px 8px 0;
|
||||
padding: 1.2em 1.5em;
|
||||
margin: 1.5em 0;
|
||||
}
|
||||
nav#TOC > h2,
|
||||
nav[role="doc-toc"] > h2 {
|
||||
font-size: 0.7rem;
|
||||
letter-spacing: 0.14em;
|
||||
text-transform: uppercase;
|
||||
color: var(--sub0);
|
||||
border: none;
|
||||
margin: 0 0 0.9em;
|
||||
padding: 0;
|
||||
}
|
||||
nav#TOC ul, nav[role="doc-toc"] ul {
|
||||
list-style: none;
|
||||
padding-left: 1em;
|
||||
margin: 0.25em 0;
|
||||
}
|
||||
nav#TOC > ul, nav[role="doc-toc"] > ul { padding-left: 0; }
|
||||
nav#TOC li, nav[role="doc-toc"] li {
|
||||
margin: 0.3em 0;
|
||||
padding-left: 0.75em;
|
||||
border-left: 1px solid transparent;
|
||||
transition: border-color 0.12s;
|
||||
}
|
||||
nav#TOC li:hover, nav[role="doc-toc"] li:hover {
|
||||
border-left-color: var(--lavender);
|
||||
}
|
||||
nav#TOC a, nav[role="doc-toc"] a {
|
||||
color: var(--sub1);
|
||||
font-size: 0.9em;
|
||||
}
|
||||
nav#TOC a:hover, nav[role="doc-toc"] a:hover {
|
||||
color: var(--lavender);
|
||||
text-decoration: none;
|
||||
}
|
||||
</style>
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
/* ── Hide ToC on every page except index.html ───────────── */
|
||||
var path = location.pathname;
|
||||
var onIndex = path === '/' || path === '' || /\/index\.html(\?.*)?$/.test(path);
|
||||
if (!onIndex) {
|
||||
var toc = document.getElementById('TOC') ||
|
||||
document.querySelector('[role="doc-toc"]');
|
||||
if (toc) toc.remove();
|
||||
}
|
||||
|
||||
/* ── Wrap each "Label: <a>" pair in a .nav-item span ───────
|
||||
Pandoc emits label text nodes and anchors as siblings;
|
||||
flex sees them as separate items, causing labels to split
|
||||
from their links when wrapping. Grouping them in a span
|
||||
keeps each label+link as a single flex unit. */
|
||||
document.querySelectorAll('nav:not(#TOC):not([role="doc-toc"])').forEach(function (nav) {
|
||||
var p = nav.querySelector('p');
|
||||
if (!p) return;
|
||||
var children = Array.from(p.childNodes);
|
||||
var pairs = [];
|
||||
for (var i = 0; i + 1 < children.length; i++) {
|
||||
var cur = children[i];
|
||||
var nxt = children[i + 1];
|
||||
if (cur.nodeType === Node.TEXT_NODE &&
|
||||
/[A-Z][a-z]*:\s*/.test(cur.textContent) &&
|
||||
nxt.nodeType === Node.ELEMENT_NODE &&
|
||||
nxt.tagName === 'A') {
|
||||
pairs.push([cur, nxt]);
|
||||
i++; // skip the anchor on the next iteration
|
||||
}
|
||||
}
|
||||
pairs.forEach(function (pair) {
|
||||
var span = document.createElement('span');
|
||||
span.className = 'nav-item';
|
||||
p.insertBefore(span, pair[0]);
|
||||
span.appendChild(pair[0]);
|
||||
span.appendChild(pair[1]);
|
||||
});
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<nav id="sitenav">
|
||||
<div class="sitenav">
|
||||
<span class="navlink">
|
||||
<span class="navlink-label">Up:</span> <a href="index.html" accesskey="u" rel="up">FISH-CONFIG</a>
|
||||
</span>
|
||||
<span class="navlink">
|
||||
<span class="navlink-label">Top:</span> <a href="index.html" accesskey="t" rel="top">FISH-CONFIG</a>
|
||||
</span>
|
||||
</div>
|
||||
<div class="sitenav">
|
||||
<span class="navlink">
|
||||
<span class="navlink-label">Next:</span> <a href="11-7-customization.html" accesskey="n" rel="next">7. CUSTOMIZATION</a>
|
||||
</span>
|
||||
<span class="navlink">
|
||||
<span class="navlink-label">Previous:</span> <a href="9-5-functions-reference.html" accesskey="p" rel="previous">5. FUNCTIONS REFERENCE</a>
|
||||
</span>
|
||||
</div>
|
||||
</nav>
|
||||
<h1 data-number="10" id="6-dependency-catalog">6. DEPENDENCY
|
||||
CATALOG</h1>
|
||||
<p>fish-deps manages these tools. Run <code>fish-deps</code> to check
|
||||
status, or <code>fish-deps install</code> to install missing ones.</p>
|
||||
<h2 data-number="10.1" id="required">Required</h2>
|
||||
<pre><code>uv Python package manager (Astral)
|
||||
cargo Rust toolchain (via rustup)
|
||||
fish Fish shell >= 4.0
|
||||
fisher Fish plugin manager
|
||||
starship Cross-shell prompt
|
||||
fzf Fuzzy finder
|
||||
zoxide Smart cd with frecency
|
||||
direnv Per-directory environment loading
|
||||
paru AUR helper (Arch only; preferred)
|
||||
yay AUR helper (Arch only; fallback)</code></pre>
|
||||
<h2 data-number="10.2" id="integrations-1">Integrations</h2>
|
||||
<pre><code>wakatime Developer time tracking
|
||||
tailscale Mesh VPN client</code></pre>
|
||||
<h2 data-number="10.3" id="recommended">Recommended</h2>
|
||||
<pre><code>eza Modern ls replacement
|
||||
lsd ls replacement (fallback to eza)
|
||||
bat Syntax-highlighted cat
|
||||
btop Modern resource monitor
|
||||
dust Disk usage tree (Rust)
|
||||
duf Disk usage/free overview
|
||||
prettyping Colorized ping wrapper
|
||||
ov Modern pager (replaces less)
|
||||
ripgrep Fast line search
|
||||
lazygit Terminal git UI
|
||||
lazydocker Terminal docker UI
|
||||
trash Safe delete (trash-cli)
|
||||
kitty GPU-accelerated terminal (primary)
|
||||
wezterm GPU-accelerated terminal (alternative)</code></pre>
|
||||
<h2 data-number="10.4" id="install-methods">Install Methods</h2>
|
||||
<p>The install priority for each tool:</p>
|
||||
<pre><code>cargo Rust tools (eza, lsd, bat, dust, ov, ripgrep, trashy, zoxide,
|
||||
starship) — always gets the latest crate version
|
||||
system PM paru / apt / brew / dnf / etc. — for tools without a crate
|
||||
git clone fzf — installed from GitHub to ~/.fzf/
|
||||
curl starship installer, fisher bootstrap, uv installer
|
||||
pipx Python-based tools</code></pre>
|
||||
<hr />
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,769 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" lang="" xml:lang="">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="generator" content="pandoc" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" />
|
||||
<meta name="author" content="Rootiest" />
|
||||
<title>7. CUSTOMIZATION</title>
|
||||
<style>
|
||||
div.sitenav { display: flex; flex-direction: row; flex-wrap: wrap; }
|
||||
span.navlink { flex: 1; }
|
||||
span.navlink-label { display: inline-block; min-width: 4em; }
|
||||
html {
|
||||
color: #1a1a1a;
|
||||
background-color: #fdfdfd;
|
||||
}
|
||||
body {
|
||||
margin: 0 auto;
|
||||
max-width: 36em;
|
||||
padding-left: 50px;
|
||||
padding-right: 50px;
|
||||
padding-top: 50px;
|
||||
padding-bottom: 50px;
|
||||
hyphens: auto;
|
||||
overflow-wrap: break-word;
|
||||
text-rendering: optimizeLegibility;
|
||||
font-kerning: normal;
|
||||
}
|
||||
@media (max-width: 600px) {
|
||||
body {
|
||||
font-size: 0.9em;
|
||||
padding: 12px;
|
||||
}
|
||||
h1 {
|
||||
font-size: 1.8em;
|
||||
}
|
||||
}
|
||||
@media print {
|
||||
html {
|
||||
background-color: white;
|
||||
}
|
||||
body {
|
||||
background-color: transparent;
|
||||
color: black;
|
||||
font-size: 12pt;
|
||||
}
|
||||
p, h2, h3 {
|
||||
orphans: 3;
|
||||
widows: 3;
|
||||
}
|
||||
h2, h3, h4 {
|
||||
page-break-after: avoid;
|
||||
}
|
||||
}
|
||||
p {
|
||||
margin: 1em 0;
|
||||
}
|
||||
a {
|
||||
color: #1a1a1a;
|
||||
}
|
||||
a:visited {
|
||||
color: #1a1a1a;
|
||||
}
|
||||
img {
|
||||
max-width: 100%;
|
||||
}
|
||||
h1, h2, h3, h4, h5, h6 {
|
||||
margin-top: 1.4em;
|
||||
}
|
||||
h5, h6 {
|
||||
font-size: 1em;
|
||||
font-style: italic;
|
||||
}
|
||||
h6 {
|
||||
font-weight: normal;
|
||||
}
|
||||
ol, ul {
|
||||
padding-left: 1.7em;
|
||||
margin-top: 1em;
|
||||
}
|
||||
li > ol, li > ul {
|
||||
margin-top: 0;
|
||||
}
|
||||
blockquote {
|
||||
margin: 1em 0 1em 1.7em;
|
||||
padding-left: 1em;
|
||||
border-left: 2px solid #e6e6e6;
|
||||
color: #606060;
|
||||
}
|
||||
code {
|
||||
font-family: Menlo, Monaco, Consolas, 'Lucida Console', monospace;
|
||||
font-size: 85%;
|
||||
margin: 0;
|
||||
hyphens: manual;
|
||||
}
|
||||
pre {
|
||||
margin: 1em 0;
|
||||
overflow: auto;
|
||||
}
|
||||
pre code {
|
||||
padding: 0;
|
||||
overflow: visible;
|
||||
overflow-wrap: normal;
|
||||
}
|
||||
.sourceCode {
|
||||
background-color: transparent;
|
||||
overflow: visible;
|
||||
}
|
||||
hr {
|
||||
background-color: #1a1a1a;
|
||||
border: none;
|
||||
height: 1px;
|
||||
margin: 1em 0;
|
||||
}
|
||||
table {
|
||||
margin: 1em 0;
|
||||
border-collapse: collapse;
|
||||
width: 100%;
|
||||
overflow-x: auto;
|
||||
display: block;
|
||||
font-variant-numeric: lining-nums tabular-nums;
|
||||
}
|
||||
table caption {
|
||||
margin-bottom: 0.75em;
|
||||
}
|
||||
tbody {
|
||||
margin-top: 0.5em;
|
||||
border-top: 1px solid #1a1a1a;
|
||||
border-bottom: 1px solid #1a1a1a;
|
||||
}
|
||||
th {
|
||||
border-top: 1px solid #1a1a1a;
|
||||
padding: 0.25em 0.5em 0.25em 0.5em;
|
||||
}
|
||||
td {
|
||||
padding: 0.125em 0.5em 0.25em 0.5em;
|
||||
}
|
||||
header {
|
||||
margin-bottom: 4em;
|
||||
text-align: center;
|
||||
}
|
||||
#TOC li {
|
||||
list-style: none;
|
||||
}
|
||||
#TOC ul {
|
||||
padding-left: 1.3em;
|
||||
}
|
||||
#TOC > ul {
|
||||
padding-left: 0;
|
||||
}
|
||||
#TOC a:not(:hover) {
|
||||
text-decoration: none;
|
||||
}
|
||||
code{white-space: pre-wrap;}
|
||||
span.smallcaps{font-variant: small-caps;}
|
||||
div.columns{display: flex; gap: min(4vw, 1.5em);}
|
||||
div.column{flex: auto; overflow-x: auto;}
|
||||
div.hanging-indent{margin-left: 1.5em; text-indent: -1.5em;}
|
||||
/* The extra [class] is a hack that increases specificity enough to
|
||||
override a similar rule in reveal.js */
|
||||
ul.task-list[class]{list-style: none;}
|
||||
ul.task-list li input[type="checkbox"] {
|
||||
font-size: inherit;
|
||||
width: 0.8em;
|
||||
margin: 0 0.8em 0.2em -1.6em;
|
||||
vertical-align: middle;
|
||||
}
|
||||
.display.math{display: block; text-align: center; margin: 0.5rem auto;}
|
||||
</style>
|
||||
<style>
|
||||
/* ── Catppuccin Latte (light) / Mocha (dark) ─────────────────── */
|
||||
:root {
|
||||
color-scheme: light dark;
|
||||
--bg: #eff1f5;
|
||||
--surface: #e6e9ef;
|
||||
--overlay: #ccd0da;
|
||||
--text: #4c4f69;
|
||||
--sub1: #6c6f85;
|
||||
--sub0: #8c8fa1;
|
||||
--blue: #1e66f5;
|
||||
--lavender: #7287fd;
|
||||
--sapphire: #209fb5;
|
||||
--green: #40a02b;
|
||||
--yellow: #df8e1d;
|
||||
--peach: #fe640b;
|
||||
--mauve: #8839ef;
|
||||
--code-bg: #dce0e8;
|
||||
--border: #bcc0cc;
|
||||
--glow1: rgba(30, 102, 245, 0.05);
|
||||
--glow2: rgba(136, 57, 239, 0.04);
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
:root {
|
||||
--bg: #1e1e2e;
|
||||
--surface: #313244;
|
||||
--overlay: #45475a;
|
||||
--text: #cdd6f4;
|
||||
--sub1: #bac2de;
|
||||
--sub0: #a6adc8;
|
||||
--blue: #89b4fa;
|
||||
--lavender: #b4befe;
|
||||
--sapphire: #74c7ec;
|
||||
--green: #a6e3a1;
|
||||
--yellow: #f9e2af;
|
||||
--peach: #fab387;
|
||||
--mauve: #cba6f7;
|
||||
--code-bg: #181825;
|
||||
--border: #45475a;
|
||||
--glow1: rgba(137, 180, 250, 0.06);
|
||||
--glow2: rgba(203, 166, 247, 0.05);
|
||||
}
|
||||
}
|
||||
|
||||
*, *::before, *::after { box-sizing: border-box; }
|
||||
|
||||
html {
|
||||
background-color: var(--bg);
|
||||
background-image:
|
||||
radial-gradient(ellipse 55% 40% at 10% 5%, var(--glow1) 0%, transparent 100%),
|
||||
radial-gradient(ellipse 45% 45% at 90% 95%, var(--glow2) 0%, transparent 100%);
|
||||
min-height: 100%;
|
||||
}
|
||||
|
||||
body {
|
||||
color: var(--text);
|
||||
font-family: system-ui, -apple-system, "Segoe UI", Helvetica, sans-serif;
|
||||
font-size: 16px;
|
||||
line-height: 1.75;
|
||||
max-width: 880px;
|
||||
margin: 0 auto;
|
||||
padding: 2rem 2.5rem 5rem;
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
/* ── Links ─────────────────────────────────────────────────── */
|
||||
a { color: var(--blue); text-decoration: none; }
|
||||
a:hover { color: var(--lavender); text-decoration: underline; }
|
||||
a:visited { color: var(--lavender); }
|
||||
|
||||
/* ── Headings ──────────────────────────────────────────────── */
|
||||
h1, h2, h3, h4, h5, h6 {
|
||||
font-family: "JetBrains Mono", "Fira Code", ui-monospace, monospace;
|
||||
color: var(--lavender);
|
||||
line-height: 1.3;
|
||||
margin-top: 2em;
|
||||
margin-bottom: 0.5em;
|
||||
}
|
||||
h1 {
|
||||
font-size: 1.9rem;
|
||||
color: var(--text);
|
||||
border-bottom: 1px solid var(--border);
|
||||
padding-bottom: 0.4em;
|
||||
margin-top: 1.2em;
|
||||
}
|
||||
h2 {
|
||||
font-size: 1.35rem;
|
||||
border-bottom: 1px solid var(--border);
|
||||
padding-bottom: 0.2em;
|
||||
}
|
||||
h3 { font-size: 1.1rem; color: var(--sapphire); }
|
||||
h4 { font-size: 0.95rem; color: var(--sub1); }
|
||||
|
||||
p { margin: 0.8em 0; }
|
||||
|
||||
/* ── Title block (pandoc-generated cover) ──────────────────── */
|
||||
#title-block-header {
|
||||
text-align: center;
|
||||
padding: 2.5rem 0 2rem;
|
||||
margin-bottom: 1.5rem;
|
||||
border-bottom: 1px solid var(--border);
|
||||
}
|
||||
#title-block-header .title {
|
||||
font-family: "JetBrains Mono", "Fira Code", ui-monospace, monospace;
|
||||
font-size: 2.6rem;
|
||||
letter-spacing: 0.12em;
|
||||
color: var(--lavender);
|
||||
border: none;
|
||||
margin: 0 0 0.75rem;
|
||||
}
|
||||
#title-block-header .author,
|
||||
#title-block-header .date {
|
||||
color: var(--sub0);
|
||||
font-size: 0.875rem;
|
||||
margin: 0.2rem 0;
|
||||
}
|
||||
|
||||
/* ── Inline code ───────────────────────────────────────────── */
|
||||
code {
|
||||
font-family: "JetBrains Mono", "Fira Code", ui-monospace, monospace;
|
||||
background: var(--code-bg);
|
||||
color: var(--peach);
|
||||
padding: 0.15em 0.4em;
|
||||
border-radius: 4px;
|
||||
font-size: 0.875em;
|
||||
}
|
||||
|
||||
/* ── Code blocks ───────────────────────────────────────────── */
|
||||
pre {
|
||||
background: var(--code-bg);
|
||||
border: 1px solid var(--border);
|
||||
border-left: 3px solid var(--sapphire);
|
||||
border-radius: 0 8px 8px 0;
|
||||
padding: 1.1em 1.4em;
|
||||
overflow-x: auto;
|
||||
line-height: 1.55;
|
||||
margin: 1.2em 0;
|
||||
}
|
||||
pre code {
|
||||
background: none;
|
||||
color: var(--text);
|
||||
padding: 0;
|
||||
font-size: 0.88em;
|
||||
}
|
||||
|
||||
/* ── Blockquotes ───────────────────────────────────────────── */
|
||||
blockquote {
|
||||
border-left: 3px solid var(--yellow);
|
||||
margin: 1.5em 0;
|
||||
padding: 0.75em 1.25em;
|
||||
background: var(--surface);
|
||||
color: var(--sub1);
|
||||
border-radius: 0 6px 6px 0;
|
||||
}
|
||||
blockquote p { margin: 0.3em 0; }
|
||||
|
||||
/* ── Tables ────────────────────────────────────────────────── */
|
||||
table {
|
||||
border-collapse: collapse;
|
||||
width: 100%;
|
||||
margin: 1.4em 0;
|
||||
font-size: 0.93em;
|
||||
}
|
||||
th, td {
|
||||
border: 1px solid var(--border);
|
||||
padding: 0.55em 0.9em;
|
||||
text-align: left;
|
||||
}
|
||||
th {
|
||||
background: var(--surface);
|
||||
color: var(--lavender);
|
||||
font-weight: 600;
|
||||
font-family: "JetBrains Mono", "Fira Code", ui-monospace, monospace;
|
||||
font-size: 0.82em;
|
||||
letter-spacing: 0.06em;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
tr:nth-child(even) { background: var(--surface); }
|
||||
tr:hover { background: var(--overlay); }
|
||||
|
||||
/* ── HR ────────────────────────────────────────────────────── */
|
||||
hr { border: none; border-top: 1px solid var(--border); margin: 2.5em 0; }
|
||||
|
||||
/* ── Lists ─────────────────────────────────────────────────── */
|
||||
ul, ol { padding-left: 1.6em; }
|
||||
li { margin: 0.35em 0; }
|
||||
|
||||
/* ── Chunk navigation bar (prev / up / next) ───────────────── */
|
||||
nav:not(#TOC):not([role="doc-toc"]) {
|
||||
background: var(--surface);
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 8px;
|
||||
margin: 1.5em 0;
|
||||
font-size: 0.875em;
|
||||
overflow: hidden;
|
||||
}
|
||||
nav:not(#TOC):not([role="doc-toc"]) p {
|
||||
margin: 0;
|
||||
padding: 0.65em 1.2em;
|
||||
display: flex;
|
||||
gap: 0.4em 1.75em;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
}
|
||||
/* JS wraps each "Label: <a>" pair in .nav-item so they flex as a unit */
|
||||
.nav-item {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 0.3em;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.nav-item a { color: var(--blue); }
|
||||
.nav-item a:hover { color: var(--lavender); }
|
||||
|
||||
/* ── Table of contents panel ───────────────────────────────── */
|
||||
nav#TOC, nav[role="doc-toc"] {
|
||||
display: block;
|
||||
background: var(--surface);
|
||||
border: 1px solid var(--border);
|
||||
border-left: 3px solid var(--lavender);
|
||||
border-radius: 0 8px 8px 0;
|
||||
padding: 1.2em 1.5em;
|
||||
margin: 1.5em 0;
|
||||
}
|
||||
nav#TOC > h2,
|
||||
nav[role="doc-toc"] > h2 {
|
||||
font-size: 0.7rem;
|
||||
letter-spacing: 0.14em;
|
||||
text-transform: uppercase;
|
||||
color: var(--sub0);
|
||||
border: none;
|
||||
margin: 0 0 0.9em;
|
||||
padding: 0;
|
||||
}
|
||||
nav#TOC ul, nav[role="doc-toc"] ul {
|
||||
list-style: none;
|
||||
padding-left: 1em;
|
||||
margin: 0.25em 0;
|
||||
}
|
||||
nav#TOC > ul, nav[role="doc-toc"] > ul { padding-left: 0; }
|
||||
nav#TOC li, nav[role="doc-toc"] li {
|
||||
margin: 0.3em 0;
|
||||
padding-left: 0.75em;
|
||||
border-left: 1px solid transparent;
|
||||
transition: border-color 0.12s;
|
||||
}
|
||||
nav#TOC li:hover, nav[role="doc-toc"] li:hover {
|
||||
border-left-color: var(--lavender);
|
||||
}
|
||||
nav#TOC a, nav[role="doc-toc"] a {
|
||||
color: var(--sub1);
|
||||
font-size: 0.9em;
|
||||
}
|
||||
nav#TOC a:hover, nav[role="doc-toc"] a:hover {
|
||||
color: var(--lavender);
|
||||
text-decoration: none;
|
||||
}
|
||||
</style>
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
/* ── Hide ToC on every page except index.html ───────────── */
|
||||
var path = location.pathname;
|
||||
var onIndex = path === '/' || path === '' || /\/index\.html(\?.*)?$/.test(path);
|
||||
if (!onIndex) {
|
||||
var toc = document.getElementById('TOC') ||
|
||||
document.querySelector('[role="doc-toc"]');
|
||||
if (toc) toc.remove();
|
||||
}
|
||||
|
||||
/* ── Wrap each "Label: <a>" pair in a .nav-item span ───────
|
||||
Pandoc emits label text nodes and anchors as siblings;
|
||||
flex sees them as separate items, causing labels to split
|
||||
from their links when wrapping. Grouping them in a span
|
||||
keeps each label+link as a single flex unit. */
|
||||
document.querySelectorAll('nav:not(#TOC):not([role="doc-toc"])').forEach(function (nav) {
|
||||
var p = nav.querySelector('p');
|
||||
if (!p) return;
|
||||
var children = Array.from(p.childNodes);
|
||||
var pairs = [];
|
||||
for (var i = 0; i + 1 < children.length; i++) {
|
||||
var cur = children[i];
|
||||
var nxt = children[i + 1];
|
||||
if (cur.nodeType === Node.TEXT_NODE &&
|
||||
/[A-Z][a-z]*:\s*/.test(cur.textContent) &&
|
||||
nxt.nodeType === Node.ELEMENT_NODE &&
|
||||
nxt.tagName === 'A') {
|
||||
pairs.push([cur, nxt]);
|
||||
i++; // skip the anchor on the next iteration
|
||||
}
|
||||
}
|
||||
pairs.forEach(function (pair) {
|
||||
var span = document.createElement('span');
|
||||
span.className = 'nav-item';
|
||||
p.insertBefore(span, pair[0]);
|
||||
span.appendChild(pair[0]);
|
||||
span.appendChild(pair[1]);
|
||||
});
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<nav id="sitenav">
|
||||
<div class="sitenav">
|
||||
<span class="navlink">
|
||||
<span class="navlink-label">Up:</span> <a href="index.html" accesskey="u" rel="up">FISH-CONFIG</a>
|
||||
</span>
|
||||
<span class="navlink">
|
||||
<span class="navlink-label">Top:</span> <a href="index.html" accesskey="t" rel="top">FISH-CONFIG</a>
|
||||
</span>
|
||||
</div>
|
||||
<div class="sitenav">
|
||||
<span class="navlink">
|
||||
<span class="navlink-label">Next:</span> <a href="12-8-fisher-plugins.html" accesskey="n" rel="next">8. FISHER PLUGINS</a>
|
||||
</span>
|
||||
<span class="navlink">
|
||||
<span class="navlink-label">Previous:</span> <a href="10-6-dependency-catalog.html" accesskey="p" rel="previous">6. DEPENDENCY CATALOG</a>
|
||||
</span>
|
||||
</div>
|
||||
</nav>
|
||||
<h1 data-number="11" id="7-customization">7. CUSTOMIZATION</h1>
|
||||
<h2 data-number="11.1" id="machine-local-configuration">Machine-local
|
||||
Configuration</h2>
|
||||
<p>Place machine-specific settings that should not be committed to git
|
||||
in:</p>
|
||||
<pre><code>~/.config/.user-dots/fish/local.fish</code></pre>
|
||||
<p>Typical uses: additional PATH entries, local aliases,
|
||||
hostname-specific env vars, work-specific tool configs.</p>
|
||||
<h2 data-number="11.2" id="secrets-and-api-keys">Secrets and API
|
||||
Keys</h2>
|
||||
<pre><code>~/.config/.user-dots/fish/secrets.fish</code></pre>
|
||||
<p>Store API tokens, GPG keys, private credentials here. This file is
|
||||
never committed.</p>
|
||||
<p>Both files are sourced at the end of config.fish on every interactive
|
||||
session, so they can override anything set earlier.</p>
|
||||
<h2 data-number="11.3"
|
||||
id="overriding-configuration-variables">Overriding Configuration
|
||||
Variables</h2>
|
||||
<p>Any variable set in local.fish after the main config loads takes
|
||||
effect. Example: to increase the scrollback history limit:</p>
|
||||
<pre><code># in local.fish
|
||||
set -gx SCROLLBACK_HISTORY_MAX_FILES 200</code></pre>
|
||||
<h2 data-number="11.4" id="fish-universal-variables">Fish Universal
|
||||
Variables</h2>
|
||||
<p>Some settings (fzf colors, theme) are stored in fish_variables via
|
||||
<code>set -U</code>. These are machine-local and git-ignored. Do not
|
||||
commit fish_variables.</p>
|
||||
<h2 data-number="11.5"
|
||||
id="opinionated-components-minimal-mode">Opinionated Components (Minimal
|
||||
Mode)</h2>
|
||||
<p>Every opinionated piece of this config is active by default but can
|
||||
be switched off through six category opt-out variables, each evaluated
|
||||
via __fish_variable_check. Set a variable to any falsy value (0, false,
|
||||
no, off, n) to disable its category; erase it or set a truthy value (1,
|
||||
true, yes, on, y) to re-enable. Unset means enabled.</p>
|
||||
<p>An explicit per-category truthy value takes precedence over the
|
||||
master switch: setting __fish_config_opinionated=0 disables all unset
|
||||
categories, but a category with an explicit truthy value remains enabled
|
||||
regardless.</p>
|
||||
<pre><code>Variable Disables
|
||||
------------------------------ ------------------------------------
|
||||
__fish_config_op_aliases Command shadows and flag injection:
|
||||
ls->eza, cat->bat, cd->zoxide,
|
||||
rm->trash, less->ov, top->btop,
|
||||
ping->prettyping, ssh->kitten,
|
||||
du->duf/dust, mkdir/bash wrappers,
|
||||
history timestamps, grep/cp/mv/wget
|
||||
flag injection, help intercept
|
||||
__fish_config_op_autoexec Startup side-effects: Fisher
|
||||
bootstrap, theme apply, paru/yay
|
||||
wrapper generation, auto venv
|
||||
activation, WakaTime hook
|
||||
__fish_config_op_overrides Key and env overrides: Vi mode,
|
||||
exit->smart_exit, PAGER/MANPAGER,
|
||||
CDPATH, bang-bang system, autopair,
|
||||
puffer, starship prompt, theme
|
||||
colors, FZF_DEFAULT_OPTS, right
|
||||
prompt
|
||||
__fish_config_op_integrations Terminal/tool coupling: Kitty/
|
||||
WezTerm window abbreviations, done
|
||||
notifications, spwin/tab/split,
|
||||
hist, logs, upgrade, WakaTime
|
||||
__fish_config_op_logging Logging & capture: scrollback
|
||||
capture on exit, paru/yay AUR log
|
||||
wrappers, Kitty watcher capture;
|
||||
sentinel file coordinates
|
||||
cross-process state
|
||||
__fish_config_op_greeting Greeting & first-run UI: per-session
|
||||
fish_greeting override (defines empty
|
||||
function late in config.fish to
|
||||
suppress distro greetings such as
|
||||
CachyOS fastfetch); first-run welcome
|
||||
banner in conf.d/first_run.fish</code></pre>
|
||||
<p>Examples:</p>
|
||||
<pre><code># Disable command shadows only (rm becomes plain rm again):
|
||||
set -U __fish_config_op_aliases off
|
||||
|
||||
# Full minimal mode — disable all six categories at once:
|
||||
set -U __fish_config_opinionated 0
|
||||
|
||||
# Re-enable everything:
|
||||
set -Ue __fish_config_opinionated
|
||||
|
||||
# Minimal mode but keep the greeting:
|
||||
set -U __fish_config_opinionated 0
|
||||
set -U __fish_config_op_greeting 1
|
||||
# (erase both to go back to full-flavor defaults)</code></pre>
|
||||
<p>Notes:</p>
|
||||
<ul>
|
||||
<li>Command shadows (rm, cat, ls, ...) react immediately; conf.d-level
|
||||
components (bindings, prompt, abbreviations, hooks) take effect in new
|
||||
shells.</li>
|
||||
<li>With aliases disabled, rm falls back to bare <code>command rm</code>
|
||||
— files are deleted permanently, not trashed.</li>
|
||||
<li>Disabled integration commands (spwin, tab, split, hist, logs,
|
||||
upgrade) print an error naming the variable that disabled them.</li>
|
||||
<li>On CachyOS, the distro fish config's own aliases, history override,
|
||||
and bang-bang bindings are stripped per category as well.</li>
|
||||
</ul>
|
||||
<h3 data-number="11.5.1" id="component-reference">Component
|
||||
Reference</h3>
|
||||
<p>The following tables detail every component in each category. Use
|
||||
this reference to understand exactly which behaviors change when you
|
||||
toggle a category variable.</p>
|
||||
<h4 data-number="11.5.1.1" id="c1--command-shadows">C1 — Command
|
||||
Shadows</h4>
|
||||
<p>Disabling __fish_config_op_aliases restores standard system behavior
|
||||
for all of these commands.</p>
|
||||
<pre><code>Command / Alias Active behavior Disabled fallback
|
||||
───────────────────────────────────────────────────────────────────────────
|
||||
ls eza -l -a --icons --hyperlink system ls
|
||||
cat bat syntax-highlighted; dirs → ls /usr/bin/cat
|
||||
cd zoxide frecency-based navigation fish builtin cd
|
||||
rm moves files to trash (recoverable) command rm (permanent)
|
||||
less $PAGER → ov → less → more → cat system less
|
||||
du duf (disk overview) or dust (dir tree) system du
|
||||
top btop resource monitor system top
|
||||
ping prettyping --nolegend animation system ping
|
||||
ssh kitten ssh in Kitty terminal system ssh
|
||||
rg rg --hyperlink-format=kitty system rg
|
||||
mkdir verbose path-tree display on creation mkdir -p silently
|
||||
bash XDG bashrc + $SHELL reset on exit system bash
|
||||
history timestamps prepended to every entry fish builtin history
|
||||
cp / mv forced -i confirmation prompt cp / mv unmodified
|
||||
wget forced --continue (resume downloads) system wget
|
||||
grep/fgrep/egrep forced --color=auto system grep variants
|
||||
dir / vdir forced --color=auto system dir / vdir
|
||||
help config intercepts "help config" → config-help fish builtin help</code></pre>
|
||||
<p>When C1 is disabled, <code>rm</code> uses bare
|
||||
<code>command rm</code> with no wrapper — files are permanently deleted,
|
||||
not trashed. There is no intermediate safety net.</p>
|
||||
<h4 data-number="11.5.1.2" id="c2--startup-side-effects">C2 — Startup
|
||||
Side-Effects</h4>
|
||||
<p>These run automatically without any user action. Disabling
|
||||
__fish_config_op_autoexec prevents all of them.</p>
|
||||
<pre><code>Component Trigger What it does
|
||||
───────────────────────────────────────────────────────────────────────────
|
||||
Fisher bootstrap First shell only Downloads and installs fisher
|
||||
Fisher update After bootstrap Installs all fish_plugins entries
|
||||
Catppuccin Mocha theme First shell only Applies theme via fish_config
|
||||
paru wrapper Every startup Writes ~/.local/bin/paru wrapper
|
||||
yay wrapper Every startup Writes ~/.local/bin/yay wrapper
|
||||
Python venv activation On every cd Sources .venv/bin/activate.fish
|
||||
WakaTime command hook On every command Reports to WakaTime API</code></pre>
|
||||
<p>When C2 is disabled: no Fisher install, no theme application, no
|
||||
paru/yay wrapper generation, no automatic venv activation, and no
|
||||
WakaTime reporting. The first-run completion marker
|
||||
(__fish_config_first_run_complete) is still set so the init does not
|
||||
re-run on subsequent shells.</p>
|
||||
<p>Python venv activation fires on every directory change. If a
|
||||
directory uses direnv (.envrc present), direnv takes priority and
|
||||
auto-venv is skipped for that directory.</p>
|
||||
<h4 data-number="11.5.1.3" id="c3--key-and-environment-overrides">C3 —
|
||||
Key and Environment Overrides</h4>
|
||||
<p>These change fundamental shell behavior: how keys work, which pager
|
||||
opens, and what the prompt looks like. Disabling
|
||||
__fish_config_op_overrides removes all of them.</p>
|
||||
<pre><code>Override What it replaces or sets
|
||||
───────────────────────────────────────────────────────────────────────────
|
||||
Vi mode fish_vi_key_bindings replaces default Emacs mode
|
||||
exit → smart_exit exit wrapper that captures scrollback before closing
|
||||
PAGER=ov ov used by git, man, and all $PAGER-aware tools
|
||||
MANPAGER=bat pipeline man pages rendered with syntax highlighting
|
||||
CDPATH=. ~/projects ~ bare dir names resolve against ~/projects and ~
|
||||
Bang-bang system ! and $ keys expand history; !^, !*, !-N, !?str?,
|
||||
^old^new abbreviations; six expand_bang_* helpers
|
||||
Autopair ( [ { " ' auto-close to (), [], {}, "", ''
|
||||
Puffer key intercepts . ! $ * keys intercepted for smart expansion
|
||||
Starship prompt fish_prompt replaced by Starship + OSC 133 markers
|
||||
Catppuccin colors 30+ fish_color_* variables set to Mocha palette
|
||||
FZF_DEFAULT_OPTS FZF themed to Catppuccin Mocha colors
|
||||
Right prompt fish_right_prompt: Docker context + timestamp</code></pre>
|
||||
<p>The bang-bang system spans key_bindings.fish, abbr.fish, puffer.fish,
|
||||
and six expand_bang_*.fish functions. All are gated together — disabling
|
||||
C3 removes the entire bang-expansion system at once.</p>
|
||||
<p>When C3 is disabled, <code>exit</code> falls back to
|
||||
<code>builtin exit</code> with no scrollback capture, no Kitty IPC, and
|
||||
no file I/O on exit. The scrollback capture block is independently
|
||||
controlled by C5 (see below).</p>
|
||||
<h4 data-number="11.5.1.4" id="c4--terminal-and-tool-integration">C4 —
|
||||
Terminal and Tool Integration</h4>
|
||||
<p>These features couple the shell to specific external tools. Disabling
|
||||
__fish_config_op_integrations disables all of them.</p>
|
||||
<pre><code>Component Requires
|
||||
───────────────────────────────────────────────────────────────────────────
|
||||
~60 Kitty/WezTerm abbrs Active Kitty or WezTerm session
|
||||
(:w, :wv, :wh, :t, etc.)
|
||||
Done desktop notifications Graphical desktop with a notification daemon
|
||||
spwin Kitty or WezTerm
|
||||
tab Kitty, WezTerm, or Konsole
|
||||
split Kitty or WezTerm
|
||||
hist fzf + wl-copy (Wayland clipboard)
|
||||
logs fzf + ov; reads from ~/.terminal_history/
|
||||
upgrade paru or yay (Arch Linux only)
|
||||
WakaTime hook wakatime CLI and a configured API key</code></pre>
|
||||
<p>Disabled integration commands (spwin, tab, split, hist, logs,
|
||||
upgrade) print a colored error to stderr naming the variable that
|
||||
disabled them rather than silently failing.</p>
|
||||
<h4 data-number="11.5.1.5" id="c5--logging-and-capture">C5 — Logging and
|
||||
Capture</h4>
|
||||
<p>Three components capture shell output to disk. Disabling
|
||||
__fish_config_op_logging skips all capture and removes the logging
|
||||
wrappers.</p>
|
||||
<pre><code>Component What it captures
|
||||
───────────────────────────────────────────────────────────────────────────
|
||||
Scrollback capture Terminal session output saved to:
|
||||
~/.terminal_history/scrollback_YYYY-MM-DD_HH-MM-SS.log
|
||||
paru wrapper All paru/AUR output captured to:
|
||||
~/.terminal_history/paru_YYYY-MM-DD_HH-MM-SS.log
|
||||
yay wrapper All yay/AUR output captured to:
|
||||
~/.terminal_history/yay_YYYY-MM-DD_HH-MM-SS.log
|
||||
Kitty watcher watcher.py captures scrollback when Kitty closes</code></pre>
|
||||
<p>Logging coordination via sentinel file</p>
|
||||
<p>C5 uses a sentinel file to synchronize state between the shell and
|
||||
out-of-process components (the Kitty watcher and all running
|
||||
shells):</p>
|
||||
<pre><code>~/.config/fish/.logging_disabled</code></pre>
|
||||
<p>Disabling __fish_config_op_logging:</p>
|
||||
<ol type="1">
|
||||
<li>Creates the sentinel immediately in every open shell.</li>
|
||||
<li>Removes ~/.local/bin/paru and ~/.local/bin/yay logging wrappers;
|
||||
bare /usr/bin/paru and /usr/bin/yay are used instead.</li>
|
||||
<li>Kitty's watcher.py reads the sentinel on each save attempt and skips
|
||||
capture — no Kitty restart required.</li>
|
||||
<li>smart_exit stops saving scrollback logs.</li>
|
||||
</ol>
|
||||
<p>Re-enabling __fish_config_op_logging:</p>
|
||||
<ol type="1">
|
||||
<li>Removes the sentinel in every open shell.</li>
|
||||
<li>Regenerates paru/yay logging wrappers in ~/.local/bin/.</li>
|
||||
<li>Kitty watcher resumes capture on the next session exit.</li>
|
||||
</ol>
|
||||
<p>Changes propagate to all running shells through an event handler that
|
||||
fires whenever __fish_config_op_logging changes — no shell restart
|
||||
needed.</p>
|
||||
<p>Note: C3 and C5 compose independently. C3 controls whether the
|
||||
smart_exit wrapper is active at all; C5 controls only the
|
||||
scrollback-capture block inside it. With C3 disabled, exit is plain
|
||||
builtin exit regardless of C5.</p>
|
||||
<h4 data-number="11.5.1.6" id="c6--greeting-and-first-run-ui">C6 —
|
||||
Greeting and First-Run UI</h4>
|
||||
<pre><code>Component What it shows
|
||||
───────────────────────────────────────────────────────────────────────────
|
||||
First-run welcome banner One-time message on first interactive session
|
||||
fish_greeting override Empty function defined late in config.fish to
|
||||
suppress distro greetings (e.g. CachyOS sets
|
||||
fish_greeting to fastfetch by default)</code></pre>
|
||||
<p>When C6 is disabled, no greeting is printed by this config. Any
|
||||
greeting set by the distro or other configs runs normally — this config
|
||||
simply does not override it.</p>
|
||||
<h2 data-number="11.6" id="prompt-and-theme">Prompt and Theme</h2>
|
||||
<h3 data-number="11.6.1" id="starship">Starship</h3>
|
||||
<p>The primary prompt is Starship, initialized by conf.d/starship.fish.
|
||||
Configure it via ~/.config/starship.toml.</p>
|
||||
<p>conf.d/starship.fish defines a fish_prompt wrapper that only
|
||||
activates when starship is in PATH. It emits OSC 133;A (prompt start)
|
||||
immediately before Starship renders and OSC 133;B (input start)
|
||||
immediately after, placing both markers on the prompt line itself. This
|
||||
allows ov to use them as sticky section headers when browsing scrollback
|
||||
logs. Without Starship, fish's built-in prompt handles these markers
|
||||
automatically.</p>
|
||||
<h3 data-number="11.6.2" id="fzf">FZF</h3>
|
||||
<p>FZF is themed to Catppuccin Mocha via FZF_DEFAULT_OPTS set in
|
||||
integrations/fzf.fish. The colors applied:</p>
|
||||
<pre><code>Background: #1E1E2E (base) #313244 (surface0)
|
||||
Foreground: #CDD6F4 (text)
|
||||
Highlights: #F38BA8 (red) #CBA6F7 (mauve) #B4BEFE (lavender)</code></pre>
|
||||
<p>To customize, override FZF_DEFAULT_OPTS in local.fish.</p>
|
||||
<h3 data-number="11.6.3"
|
||||
id="catppuccin-mocha-syntax-highlighting">Catppuccin Mocha Syntax
|
||||
Highlighting</h3>
|
||||
<p>The Catppuccin Mocha theme ships with this config in themes/ and is
|
||||
applied on first run via <code>conf.d/first_run.fish</code>. Colors are
|
||||
stored in fish_variables (universal). To switch variants, install a
|
||||
different theme from themes/:</p>
|
||||
<pre><code>fish_config theme save "Catppuccin Latte"</code></pre>
|
||||
<hr />
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,561 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" lang="" xml:lang="">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="generator" content="pandoc" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" />
|
||||
<meta name="author" content="Rootiest" />
|
||||
<title>8. FISHER PLUGINS</title>
|
||||
<style>
|
||||
div.sitenav { display: flex; flex-direction: row; flex-wrap: wrap; }
|
||||
span.navlink { flex: 1; }
|
||||
span.navlink-label { display: inline-block; min-width: 4em; }
|
||||
html {
|
||||
color: #1a1a1a;
|
||||
background-color: #fdfdfd;
|
||||
}
|
||||
body {
|
||||
margin: 0 auto;
|
||||
max-width: 36em;
|
||||
padding-left: 50px;
|
||||
padding-right: 50px;
|
||||
padding-top: 50px;
|
||||
padding-bottom: 50px;
|
||||
hyphens: auto;
|
||||
overflow-wrap: break-word;
|
||||
text-rendering: optimizeLegibility;
|
||||
font-kerning: normal;
|
||||
}
|
||||
@media (max-width: 600px) {
|
||||
body {
|
||||
font-size: 0.9em;
|
||||
padding: 12px;
|
||||
}
|
||||
h1 {
|
||||
font-size: 1.8em;
|
||||
}
|
||||
}
|
||||
@media print {
|
||||
html {
|
||||
background-color: white;
|
||||
}
|
||||
body {
|
||||
background-color: transparent;
|
||||
color: black;
|
||||
font-size: 12pt;
|
||||
}
|
||||
p, h2, h3 {
|
||||
orphans: 3;
|
||||
widows: 3;
|
||||
}
|
||||
h2, h3, h4 {
|
||||
page-break-after: avoid;
|
||||
}
|
||||
}
|
||||
p {
|
||||
margin: 1em 0;
|
||||
}
|
||||
a {
|
||||
color: #1a1a1a;
|
||||
}
|
||||
a:visited {
|
||||
color: #1a1a1a;
|
||||
}
|
||||
img {
|
||||
max-width: 100%;
|
||||
}
|
||||
h1, h2, h3, h4, h5, h6 {
|
||||
margin-top: 1.4em;
|
||||
}
|
||||
h5, h6 {
|
||||
font-size: 1em;
|
||||
font-style: italic;
|
||||
}
|
||||
h6 {
|
||||
font-weight: normal;
|
||||
}
|
||||
ol, ul {
|
||||
padding-left: 1.7em;
|
||||
margin-top: 1em;
|
||||
}
|
||||
li > ol, li > ul {
|
||||
margin-top: 0;
|
||||
}
|
||||
blockquote {
|
||||
margin: 1em 0 1em 1.7em;
|
||||
padding-left: 1em;
|
||||
border-left: 2px solid #e6e6e6;
|
||||
color: #606060;
|
||||
}
|
||||
code {
|
||||
font-family: Menlo, Monaco, Consolas, 'Lucida Console', monospace;
|
||||
font-size: 85%;
|
||||
margin: 0;
|
||||
hyphens: manual;
|
||||
}
|
||||
pre {
|
||||
margin: 1em 0;
|
||||
overflow: auto;
|
||||
}
|
||||
pre code {
|
||||
padding: 0;
|
||||
overflow: visible;
|
||||
overflow-wrap: normal;
|
||||
}
|
||||
.sourceCode {
|
||||
background-color: transparent;
|
||||
overflow: visible;
|
||||
}
|
||||
hr {
|
||||
background-color: #1a1a1a;
|
||||
border: none;
|
||||
height: 1px;
|
||||
margin: 1em 0;
|
||||
}
|
||||
table {
|
||||
margin: 1em 0;
|
||||
border-collapse: collapse;
|
||||
width: 100%;
|
||||
overflow-x: auto;
|
||||
display: block;
|
||||
font-variant-numeric: lining-nums tabular-nums;
|
||||
}
|
||||
table caption {
|
||||
margin-bottom: 0.75em;
|
||||
}
|
||||
tbody {
|
||||
margin-top: 0.5em;
|
||||
border-top: 1px solid #1a1a1a;
|
||||
border-bottom: 1px solid #1a1a1a;
|
||||
}
|
||||
th {
|
||||
border-top: 1px solid #1a1a1a;
|
||||
padding: 0.25em 0.5em 0.25em 0.5em;
|
||||
}
|
||||
td {
|
||||
padding: 0.125em 0.5em 0.25em 0.5em;
|
||||
}
|
||||
header {
|
||||
margin-bottom: 4em;
|
||||
text-align: center;
|
||||
}
|
||||
#TOC li {
|
||||
list-style: none;
|
||||
}
|
||||
#TOC ul {
|
||||
padding-left: 1.3em;
|
||||
}
|
||||
#TOC > ul {
|
||||
padding-left: 0;
|
||||
}
|
||||
#TOC a:not(:hover) {
|
||||
text-decoration: none;
|
||||
}
|
||||
code{white-space: pre-wrap;}
|
||||
span.smallcaps{font-variant: small-caps;}
|
||||
div.columns{display: flex; gap: min(4vw, 1.5em);}
|
||||
div.column{flex: auto; overflow-x: auto;}
|
||||
div.hanging-indent{margin-left: 1.5em; text-indent: -1.5em;}
|
||||
/* The extra [class] is a hack that increases specificity enough to
|
||||
override a similar rule in reveal.js */
|
||||
ul.task-list[class]{list-style: none;}
|
||||
ul.task-list li input[type="checkbox"] {
|
||||
font-size: inherit;
|
||||
width: 0.8em;
|
||||
margin: 0 0.8em 0.2em -1.6em;
|
||||
vertical-align: middle;
|
||||
}
|
||||
.display.math{display: block; text-align: center; margin: 0.5rem auto;}
|
||||
</style>
|
||||
<style>
|
||||
/* ── Catppuccin Latte (light) / Mocha (dark) ─────────────────── */
|
||||
:root {
|
||||
color-scheme: light dark;
|
||||
--bg: #eff1f5;
|
||||
--surface: #e6e9ef;
|
||||
--overlay: #ccd0da;
|
||||
--text: #4c4f69;
|
||||
--sub1: #6c6f85;
|
||||
--sub0: #8c8fa1;
|
||||
--blue: #1e66f5;
|
||||
--lavender: #7287fd;
|
||||
--sapphire: #209fb5;
|
||||
--green: #40a02b;
|
||||
--yellow: #df8e1d;
|
||||
--peach: #fe640b;
|
||||
--mauve: #8839ef;
|
||||
--code-bg: #dce0e8;
|
||||
--border: #bcc0cc;
|
||||
--glow1: rgba(30, 102, 245, 0.05);
|
||||
--glow2: rgba(136, 57, 239, 0.04);
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
:root {
|
||||
--bg: #1e1e2e;
|
||||
--surface: #313244;
|
||||
--overlay: #45475a;
|
||||
--text: #cdd6f4;
|
||||
--sub1: #bac2de;
|
||||
--sub0: #a6adc8;
|
||||
--blue: #89b4fa;
|
||||
--lavender: #b4befe;
|
||||
--sapphire: #74c7ec;
|
||||
--green: #a6e3a1;
|
||||
--yellow: #f9e2af;
|
||||
--peach: #fab387;
|
||||
--mauve: #cba6f7;
|
||||
--code-bg: #181825;
|
||||
--border: #45475a;
|
||||
--glow1: rgba(137, 180, 250, 0.06);
|
||||
--glow2: rgba(203, 166, 247, 0.05);
|
||||
}
|
||||
}
|
||||
|
||||
*, *::before, *::after { box-sizing: border-box; }
|
||||
|
||||
html {
|
||||
background-color: var(--bg);
|
||||
background-image:
|
||||
radial-gradient(ellipse 55% 40% at 10% 5%, var(--glow1) 0%, transparent 100%),
|
||||
radial-gradient(ellipse 45% 45% at 90% 95%, var(--glow2) 0%, transparent 100%);
|
||||
min-height: 100%;
|
||||
}
|
||||
|
||||
body {
|
||||
color: var(--text);
|
||||
font-family: system-ui, -apple-system, "Segoe UI", Helvetica, sans-serif;
|
||||
font-size: 16px;
|
||||
line-height: 1.75;
|
||||
max-width: 880px;
|
||||
margin: 0 auto;
|
||||
padding: 2rem 2.5rem 5rem;
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
/* ── Links ─────────────────────────────────────────────────── */
|
||||
a { color: var(--blue); text-decoration: none; }
|
||||
a:hover { color: var(--lavender); text-decoration: underline; }
|
||||
a:visited { color: var(--lavender); }
|
||||
|
||||
/* ── Headings ──────────────────────────────────────────────── */
|
||||
h1, h2, h3, h4, h5, h6 {
|
||||
font-family: "JetBrains Mono", "Fira Code", ui-monospace, monospace;
|
||||
color: var(--lavender);
|
||||
line-height: 1.3;
|
||||
margin-top: 2em;
|
||||
margin-bottom: 0.5em;
|
||||
}
|
||||
h1 {
|
||||
font-size: 1.9rem;
|
||||
color: var(--text);
|
||||
border-bottom: 1px solid var(--border);
|
||||
padding-bottom: 0.4em;
|
||||
margin-top: 1.2em;
|
||||
}
|
||||
h2 {
|
||||
font-size: 1.35rem;
|
||||
border-bottom: 1px solid var(--border);
|
||||
padding-bottom: 0.2em;
|
||||
}
|
||||
h3 { font-size: 1.1rem; color: var(--sapphire); }
|
||||
h4 { font-size: 0.95rem; color: var(--sub1); }
|
||||
|
||||
p { margin: 0.8em 0; }
|
||||
|
||||
/* ── Title block (pandoc-generated cover) ──────────────────── */
|
||||
#title-block-header {
|
||||
text-align: center;
|
||||
padding: 2.5rem 0 2rem;
|
||||
margin-bottom: 1.5rem;
|
||||
border-bottom: 1px solid var(--border);
|
||||
}
|
||||
#title-block-header .title {
|
||||
font-family: "JetBrains Mono", "Fira Code", ui-monospace, monospace;
|
||||
font-size: 2.6rem;
|
||||
letter-spacing: 0.12em;
|
||||
color: var(--lavender);
|
||||
border: none;
|
||||
margin: 0 0 0.75rem;
|
||||
}
|
||||
#title-block-header .author,
|
||||
#title-block-header .date {
|
||||
color: var(--sub0);
|
||||
font-size: 0.875rem;
|
||||
margin: 0.2rem 0;
|
||||
}
|
||||
|
||||
/* ── Inline code ───────────────────────────────────────────── */
|
||||
code {
|
||||
font-family: "JetBrains Mono", "Fira Code", ui-monospace, monospace;
|
||||
background: var(--code-bg);
|
||||
color: var(--peach);
|
||||
padding: 0.15em 0.4em;
|
||||
border-radius: 4px;
|
||||
font-size: 0.875em;
|
||||
}
|
||||
|
||||
/* ── Code blocks ───────────────────────────────────────────── */
|
||||
pre {
|
||||
background: var(--code-bg);
|
||||
border: 1px solid var(--border);
|
||||
border-left: 3px solid var(--sapphire);
|
||||
border-radius: 0 8px 8px 0;
|
||||
padding: 1.1em 1.4em;
|
||||
overflow-x: auto;
|
||||
line-height: 1.55;
|
||||
margin: 1.2em 0;
|
||||
}
|
||||
pre code {
|
||||
background: none;
|
||||
color: var(--text);
|
||||
padding: 0;
|
||||
font-size: 0.88em;
|
||||
}
|
||||
|
||||
/* ── Blockquotes ───────────────────────────────────────────── */
|
||||
blockquote {
|
||||
border-left: 3px solid var(--yellow);
|
||||
margin: 1.5em 0;
|
||||
padding: 0.75em 1.25em;
|
||||
background: var(--surface);
|
||||
color: var(--sub1);
|
||||
border-radius: 0 6px 6px 0;
|
||||
}
|
||||
blockquote p { margin: 0.3em 0; }
|
||||
|
||||
/* ── Tables ────────────────────────────────────────────────── */
|
||||
table {
|
||||
border-collapse: collapse;
|
||||
width: 100%;
|
||||
margin: 1.4em 0;
|
||||
font-size: 0.93em;
|
||||
}
|
||||
th, td {
|
||||
border: 1px solid var(--border);
|
||||
padding: 0.55em 0.9em;
|
||||
text-align: left;
|
||||
}
|
||||
th {
|
||||
background: var(--surface);
|
||||
color: var(--lavender);
|
||||
font-weight: 600;
|
||||
font-family: "JetBrains Mono", "Fira Code", ui-monospace, monospace;
|
||||
font-size: 0.82em;
|
||||
letter-spacing: 0.06em;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
tr:nth-child(even) { background: var(--surface); }
|
||||
tr:hover { background: var(--overlay); }
|
||||
|
||||
/* ── HR ────────────────────────────────────────────────────── */
|
||||
hr { border: none; border-top: 1px solid var(--border); margin: 2.5em 0; }
|
||||
|
||||
/* ── Lists ─────────────────────────────────────────────────── */
|
||||
ul, ol { padding-left: 1.6em; }
|
||||
li { margin: 0.35em 0; }
|
||||
|
||||
/* ── Chunk navigation bar (prev / up / next) ───────────────── */
|
||||
nav:not(#TOC):not([role="doc-toc"]) {
|
||||
background: var(--surface);
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 8px;
|
||||
margin: 1.5em 0;
|
||||
font-size: 0.875em;
|
||||
overflow: hidden;
|
||||
}
|
||||
nav:not(#TOC):not([role="doc-toc"]) p {
|
||||
margin: 0;
|
||||
padding: 0.65em 1.2em;
|
||||
display: flex;
|
||||
gap: 0.4em 1.75em;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
}
|
||||
/* JS wraps each "Label: <a>" pair in .nav-item so they flex as a unit */
|
||||
.nav-item {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 0.3em;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.nav-item a { color: var(--blue); }
|
||||
.nav-item a:hover { color: var(--lavender); }
|
||||
|
||||
/* ── Table of contents panel ───────────────────────────────── */
|
||||
nav#TOC, nav[role="doc-toc"] {
|
||||
display: block;
|
||||
background: var(--surface);
|
||||
border: 1px solid var(--border);
|
||||
border-left: 3px solid var(--lavender);
|
||||
border-radius: 0 8px 8px 0;
|
||||
padding: 1.2em 1.5em;
|
||||
margin: 1.5em 0;
|
||||
}
|
||||
nav#TOC > h2,
|
||||
nav[role="doc-toc"] > h2 {
|
||||
font-size: 0.7rem;
|
||||
letter-spacing: 0.14em;
|
||||
text-transform: uppercase;
|
||||
color: var(--sub0);
|
||||
border: none;
|
||||
margin: 0 0 0.9em;
|
||||
padding: 0;
|
||||
}
|
||||
nav#TOC ul, nav[role="doc-toc"] ul {
|
||||
list-style: none;
|
||||
padding-left: 1em;
|
||||
margin: 0.25em 0;
|
||||
}
|
||||
nav#TOC > ul, nav[role="doc-toc"] > ul { padding-left: 0; }
|
||||
nav#TOC li, nav[role="doc-toc"] li {
|
||||
margin: 0.3em 0;
|
||||
padding-left: 0.75em;
|
||||
border-left: 1px solid transparent;
|
||||
transition: border-color 0.12s;
|
||||
}
|
||||
nav#TOC li:hover, nav[role="doc-toc"] li:hover {
|
||||
border-left-color: var(--lavender);
|
||||
}
|
||||
nav#TOC a, nav[role="doc-toc"] a {
|
||||
color: var(--sub1);
|
||||
font-size: 0.9em;
|
||||
}
|
||||
nav#TOC a:hover, nav[role="doc-toc"] a:hover {
|
||||
color: var(--lavender);
|
||||
text-decoration: none;
|
||||
}
|
||||
</style>
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
/* ── Hide ToC on every page except index.html ───────────── */
|
||||
var path = location.pathname;
|
||||
var onIndex = path === '/' || path === '' || /\/index\.html(\?.*)?$/.test(path);
|
||||
if (!onIndex) {
|
||||
var toc = document.getElementById('TOC') ||
|
||||
document.querySelector('[role="doc-toc"]');
|
||||
if (toc) toc.remove();
|
||||
}
|
||||
|
||||
/* ── Wrap each "Label: <a>" pair in a .nav-item span ───────
|
||||
Pandoc emits label text nodes and anchors as siblings;
|
||||
flex sees them as separate items, causing labels to split
|
||||
from their links when wrapping. Grouping them in a span
|
||||
keeps each label+link as a single flex unit. */
|
||||
document.querySelectorAll('nav:not(#TOC):not([role="doc-toc"])').forEach(function (nav) {
|
||||
var p = nav.querySelector('p');
|
||||
if (!p) return;
|
||||
var children = Array.from(p.childNodes);
|
||||
var pairs = [];
|
||||
for (var i = 0; i + 1 < children.length; i++) {
|
||||
var cur = children[i];
|
||||
var nxt = children[i + 1];
|
||||
if (cur.nodeType === Node.TEXT_NODE &&
|
||||
/[A-Z][a-z]*:\s*/.test(cur.textContent) &&
|
||||
nxt.nodeType === Node.ELEMENT_NODE &&
|
||||
nxt.tagName === 'A') {
|
||||
pairs.push([cur, nxt]);
|
||||
i++; // skip the anchor on the next iteration
|
||||
}
|
||||
}
|
||||
pairs.forEach(function (pair) {
|
||||
var span = document.createElement('span');
|
||||
span.className = 'nav-item';
|
||||
p.insertBefore(span, pair[0]);
|
||||
span.appendChild(pair[0]);
|
||||
span.appendChild(pair[1]);
|
||||
});
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<nav id="sitenav">
|
||||
<div class="sitenav">
|
||||
<span class="navlink">
|
||||
<span class="navlink-label">Up:</span> <a href="index.html" accesskey="u" rel="up">FISH-CONFIG</a>
|
||||
</span>
|
||||
<span class="navlink">
|
||||
<span class="navlink-label">Top:</span> <a href="index.html" accesskey="t" rel="top">FISH-CONFIG</a>
|
||||
</span>
|
||||
</div>
|
||||
<div class="sitenav">
|
||||
<span class="navlink">
|
||||
<span class="navlink-label">Next:</span> <a href="13-9-installation.html" accesskey="n" rel="next">9. INSTALLATION</a>
|
||||
</span>
|
||||
<span class="navlink">
|
||||
<span class="navlink-label">Previous:</span> <a href="11-7-customization.html" accesskey="p" rel="previous">7. CUSTOMIZATION</a>
|
||||
</span>
|
||||
</div>
|
||||
</nav>
|
||||
<h1 data-number="12" id="8-fisher-plugins">8. FISHER PLUGINS</h1>
|
||||
<p>Fisher is bootstrapped automatically on the <strong>first interactive
|
||||
session</strong> via <code>conf.d/first_run.fish</code>. This also
|
||||
applies the Catppuccin Mocha theme and prints a one-time welcome message
|
||||
(gated by __fish_config_op_greeting; set it to 0 to suppress).
|
||||
Subsequent sessions skip all first-run logic with zero overhead.</p>
|
||||
<p>To re-trigger first-run initialization (e.g., after a fresh install
|
||||
or for testing), run:</p>
|
||||
<pre><code>set -Ue __fish_config_first_run_complete</code></pre>
|
||||
<p>Then open a new shell.</p>
|
||||
<h2 data-number="12.1" id="fisher-managed-plugins">Fisher-Managed
|
||||
Plugins</h2>
|
||||
<p>The following plugins are fully managed by Fisher. Their files are
|
||||
installed into the repo directory by Fisher and are listed in
|
||||
<code>.gitignore</code> — do not commit them. Fisher installs and
|
||||
updates them automatically.</p>
|
||||
<pre><code>jorgebucaran/fisher Plugin manager itself
|
||||
meaningful-ooo/sponge Remove failed commands from history</code></pre>
|
||||
<h2 data-number="12.2" id="sponge-history-filtering">Sponge History
|
||||
Filtering</h2>
|
||||
<p>Sponge removes failed commands from history and, via
|
||||
conf.d/sponge_privacy.fish, also filters privacy-sensitive commands
|
||||
through three layers:</p>
|
||||
<p>Layer 1 — Static patterns (universal, persistent across sessions):
|
||||
Commands matching any of these structural signatures are never
|
||||
recorded:</p>
|
||||
<pre><code>--password / --token / --passphrase / --api-key flags with values
|
||||
Inline env assignments: GITHUB_TOKEN=xxx, MY_API_KEY=abc
|
||||
Fish set with sensitive names: set -gx GITHUB_TOKEN xxx
|
||||
URLs with embedded credentials: https://user:pass@host
|
||||
HTTP Authorization headers: curl -H "Authorization: ..."
|
||||
Basic auth flags: curl -u user:pass
|
||||
sshpass, docker login -p, openssl -passin/-passout</code></pre>
|
||||
<p>Layer 2 — Dynamic secret values (session globals, refreshed each
|
||||
login): On the first prompt, after secrets.fish has loaded, the literal
|
||||
values of all exported variables whose names suggest credentials (TOKEN,
|
||||
PASSWORD, SECRET, API_KEY, etc.) are collected, regex-escaped, and added
|
||||
as a session-scoped overlay. Because globals shadow universals in Fish,
|
||||
the combined list is what sponge sees. Rotating a token takes effect on
|
||||
the next login automatically.</p>
|
||||
<p>Layer 3 — Per-command filter (sponge_filter_secrets): Catches
|
||||
credentials in variables exported after login, such as tokens sourced
|
||||
from a project .env file mid-session.</p>
|
||||
<p>To add your own persistent patterns:</p>
|
||||
<pre><code>set -U -a sponge_regex_patterns 'your-regex-here'</code></pre>
|
||||
<h2 data-number="12.3" id="bundled-plugin-functionality">Bundled Plugin
|
||||
Functionality</h2>
|
||||
<p>The remaining plugin functionality is bundled directly with this
|
||||
config rather than managed through Fisher. The bundled versions include
|
||||
customizations for Fish 4.x compatibility and improved behavior that
|
||||
differ from their upstream releases. Installing them through Fisher
|
||||
would overwrite these customizations.</p>
|
||||
<p>Bundled components and their upstream origins:</p>
|
||||
<pre><code>catppuccin/fish → themes/ + conf.d/theme.fish
|
||||
PatrickF1/fzf.fish → functions/_fzf_*.fish + conf.d/fzf.fish
|
||||
franciscolourenco/done → conf.d/done.fish
|
||||
jorgebucaran/autopair.fish → functions/_autopair_*.fish + conf.d/autopair.fish
|
||||
nickeb96/puffer-fish → functions/_puffer_fish_*.fish + conf.d/puffer.fish</code></pre>
|
||||
<p>Do not run <code>fisher install</code> for these — it will overwrite
|
||||
the customized versions. To update their behavior, edit the relevant
|
||||
bundled files directly.</p>
|
||||
<h2 data-number="12.4" id="fish_plugins-manifest">fish_plugins
|
||||
Manifest</h2>
|
||||
<p>The <code>fish_plugins</code> file at the config root:</p>
|
||||
<pre><code>jorgebucaran/fisher Plugin manager itself
|
||||
meaningful-ooo/sponge Remove failed commands from history</code></pre>
|
||||
<p>To update all Fisher-managed plugins, run <code>fisher update</code>
|
||||
or <code>fish-deps update</code> which calls it as its first step.</p>
|
||||
<hr />
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,521 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" lang="" xml:lang="">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="generator" content="pandoc" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" />
|
||||
<meta name="author" content="Rootiest" />
|
||||
<title>9. INSTALLATION</title>
|
||||
<style>
|
||||
div.sitenav { display: flex; flex-direction: row; flex-wrap: wrap; }
|
||||
span.navlink { flex: 1; }
|
||||
span.navlink-label { display: inline-block; min-width: 4em; }
|
||||
html {
|
||||
color: #1a1a1a;
|
||||
background-color: #fdfdfd;
|
||||
}
|
||||
body {
|
||||
margin: 0 auto;
|
||||
max-width: 36em;
|
||||
padding-left: 50px;
|
||||
padding-right: 50px;
|
||||
padding-top: 50px;
|
||||
padding-bottom: 50px;
|
||||
hyphens: auto;
|
||||
overflow-wrap: break-word;
|
||||
text-rendering: optimizeLegibility;
|
||||
font-kerning: normal;
|
||||
}
|
||||
@media (max-width: 600px) {
|
||||
body {
|
||||
font-size: 0.9em;
|
||||
padding: 12px;
|
||||
}
|
||||
h1 {
|
||||
font-size: 1.8em;
|
||||
}
|
||||
}
|
||||
@media print {
|
||||
html {
|
||||
background-color: white;
|
||||
}
|
||||
body {
|
||||
background-color: transparent;
|
||||
color: black;
|
||||
font-size: 12pt;
|
||||
}
|
||||
p, h2, h3 {
|
||||
orphans: 3;
|
||||
widows: 3;
|
||||
}
|
||||
h2, h3, h4 {
|
||||
page-break-after: avoid;
|
||||
}
|
||||
}
|
||||
p {
|
||||
margin: 1em 0;
|
||||
}
|
||||
a {
|
||||
color: #1a1a1a;
|
||||
}
|
||||
a:visited {
|
||||
color: #1a1a1a;
|
||||
}
|
||||
img {
|
||||
max-width: 100%;
|
||||
}
|
||||
h1, h2, h3, h4, h5, h6 {
|
||||
margin-top: 1.4em;
|
||||
}
|
||||
h5, h6 {
|
||||
font-size: 1em;
|
||||
font-style: italic;
|
||||
}
|
||||
h6 {
|
||||
font-weight: normal;
|
||||
}
|
||||
ol, ul {
|
||||
padding-left: 1.7em;
|
||||
margin-top: 1em;
|
||||
}
|
||||
li > ol, li > ul {
|
||||
margin-top: 0;
|
||||
}
|
||||
blockquote {
|
||||
margin: 1em 0 1em 1.7em;
|
||||
padding-left: 1em;
|
||||
border-left: 2px solid #e6e6e6;
|
||||
color: #606060;
|
||||
}
|
||||
code {
|
||||
font-family: Menlo, Monaco, Consolas, 'Lucida Console', monospace;
|
||||
font-size: 85%;
|
||||
margin: 0;
|
||||
hyphens: manual;
|
||||
}
|
||||
pre {
|
||||
margin: 1em 0;
|
||||
overflow: auto;
|
||||
}
|
||||
pre code {
|
||||
padding: 0;
|
||||
overflow: visible;
|
||||
overflow-wrap: normal;
|
||||
}
|
||||
.sourceCode {
|
||||
background-color: transparent;
|
||||
overflow: visible;
|
||||
}
|
||||
hr {
|
||||
background-color: #1a1a1a;
|
||||
border: none;
|
||||
height: 1px;
|
||||
margin: 1em 0;
|
||||
}
|
||||
table {
|
||||
margin: 1em 0;
|
||||
border-collapse: collapse;
|
||||
width: 100%;
|
||||
overflow-x: auto;
|
||||
display: block;
|
||||
font-variant-numeric: lining-nums tabular-nums;
|
||||
}
|
||||
table caption {
|
||||
margin-bottom: 0.75em;
|
||||
}
|
||||
tbody {
|
||||
margin-top: 0.5em;
|
||||
border-top: 1px solid #1a1a1a;
|
||||
border-bottom: 1px solid #1a1a1a;
|
||||
}
|
||||
th {
|
||||
border-top: 1px solid #1a1a1a;
|
||||
padding: 0.25em 0.5em 0.25em 0.5em;
|
||||
}
|
||||
td {
|
||||
padding: 0.125em 0.5em 0.25em 0.5em;
|
||||
}
|
||||
header {
|
||||
margin-bottom: 4em;
|
||||
text-align: center;
|
||||
}
|
||||
#TOC li {
|
||||
list-style: none;
|
||||
}
|
||||
#TOC ul {
|
||||
padding-left: 1.3em;
|
||||
}
|
||||
#TOC > ul {
|
||||
padding-left: 0;
|
||||
}
|
||||
#TOC a:not(:hover) {
|
||||
text-decoration: none;
|
||||
}
|
||||
code{white-space: pre-wrap;}
|
||||
span.smallcaps{font-variant: small-caps;}
|
||||
div.columns{display: flex; gap: min(4vw, 1.5em);}
|
||||
div.column{flex: auto; overflow-x: auto;}
|
||||
div.hanging-indent{margin-left: 1.5em; text-indent: -1.5em;}
|
||||
/* The extra [class] is a hack that increases specificity enough to
|
||||
override a similar rule in reveal.js */
|
||||
ul.task-list[class]{list-style: none;}
|
||||
ul.task-list li input[type="checkbox"] {
|
||||
font-size: inherit;
|
||||
width: 0.8em;
|
||||
margin: 0 0.8em 0.2em -1.6em;
|
||||
vertical-align: middle;
|
||||
}
|
||||
.display.math{display: block; text-align: center; margin: 0.5rem auto;}
|
||||
</style>
|
||||
<style>
|
||||
/* ── Catppuccin Latte (light) / Mocha (dark) ─────────────────── */
|
||||
:root {
|
||||
color-scheme: light dark;
|
||||
--bg: #eff1f5;
|
||||
--surface: #e6e9ef;
|
||||
--overlay: #ccd0da;
|
||||
--text: #4c4f69;
|
||||
--sub1: #6c6f85;
|
||||
--sub0: #8c8fa1;
|
||||
--blue: #1e66f5;
|
||||
--lavender: #7287fd;
|
||||
--sapphire: #209fb5;
|
||||
--green: #40a02b;
|
||||
--yellow: #df8e1d;
|
||||
--peach: #fe640b;
|
||||
--mauve: #8839ef;
|
||||
--code-bg: #dce0e8;
|
||||
--border: #bcc0cc;
|
||||
--glow1: rgba(30, 102, 245, 0.05);
|
||||
--glow2: rgba(136, 57, 239, 0.04);
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
:root {
|
||||
--bg: #1e1e2e;
|
||||
--surface: #313244;
|
||||
--overlay: #45475a;
|
||||
--text: #cdd6f4;
|
||||
--sub1: #bac2de;
|
||||
--sub0: #a6adc8;
|
||||
--blue: #89b4fa;
|
||||
--lavender: #b4befe;
|
||||
--sapphire: #74c7ec;
|
||||
--green: #a6e3a1;
|
||||
--yellow: #f9e2af;
|
||||
--peach: #fab387;
|
||||
--mauve: #cba6f7;
|
||||
--code-bg: #181825;
|
||||
--border: #45475a;
|
||||
--glow1: rgba(137, 180, 250, 0.06);
|
||||
--glow2: rgba(203, 166, 247, 0.05);
|
||||
}
|
||||
}
|
||||
|
||||
*, *::before, *::after { box-sizing: border-box; }
|
||||
|
||||
html {
|
||||
background-color: var(--bg);
|
||||
background-image:
|
||||
radial-gradient(ellipse 55% 40% at 10% 5%, var(--glow1) 0%, transparent 100%),
|
||||
radial-gradient(ellipse 45% 45% at 90% 95%, var(--glow2) 0%, transparent 100%);
|
||||
min-height: 100%;
|
||||
}
|
||||
|
||||
body {
|
||||
color: var(--text);
|
||||
font-family: system-ui, -apple-system, "Segoe UI", Helvetica, sans-serif;
|
||||
font-size: 16px;
|
||||
line-height: 1.75;
|
||||
max-width: 880px;
|
||||
margin: 0 auto;
|
||||
padding: 2rem 2.5rem 5rem;
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
/* ── Links ─────────────────────────────────────────────────── */
|
||||
a { color: var(--blue); text-decoration: none; }
|
||||
a:hover { color: var(--lavender); text-decoration: underline; }
|
||||
a:visited { color: var(--lavender); }
|
||||
|
||||
/* ── Headings ──────────────────────────────────────────────── */
|
||||
h1, h2, h3, h4, h5, h6 {
|
||||
font-family: "JetBrains Mono", "Fira Code", ui-monospace, monospace;
|
||||
color: var(--lavender);
|
||||
line-height: 1.3;
|
||||
margin-top: 2em;
|
||||
margin-bottom: 0.5em;
|
||||
}
|
||||
h1 {
|
||||
font-size: 1.9rem;
|
||||
color: var(--text);
|
||||
border-bottom: 1px solid var(--border);
|
||||
padding-bottom: 0.4em;
|
||||
margin-top: 1.2em;
|
||||
}
|
||||
h2 {
|
||||
font-size: 1.35rem;
|
||||
border-bottom: 1px solid var(--border);
|
||||
padding-bottom: 0.2em;
|
||||
}
|
||||
h3 { font-size: 1.1rem; color: var(--sapphire); }
|
||||
h4 { font-size: 0.95rem; color: var(--sub1); }
|
||||
|
||||
p { margin: 0.8em 0; }
|
||||
|
||||
/* ── Title block (pandoc-generated cover) ──────────────────── */
|
||||
#title-block-header {
|
||||
text-align: center;
|
||||
padding: 2.5rem 0 2rem;
|
||||
margin-bottom: 1.5rem;
|
||||
border-bottom: 1px solid var(--border);
|
||||
}
|
||||
#title-block-header .title {
|
||||
font-family: "JetBrains Mono", "Fira Code", ui-monospace, monospace;
|
||||
font-size: 2.6rem;
|
||||
letter-spacing: 0.12em;
|
||||
color: var(--lavender);
|
||||
border: none;
|
||||
margin: 0 0 0.75rem;
|
||||
}
|
||||
#title-block-header .author,
|
||||
#title-block-header .date {
|
||||
color: var(--sub0);
|
||||
font-size: 0.875rem;
|
||||
margin: 0.2rem 0;
|
||||
}
|
||||
|
||||
/* ── Inline code ───────────────────────────────────────────── */
|
||||
code {
|
||||
font-family: "JetBrains Mono", "Fira Code", ui-monospace, monospace;
|
||||
background: var(--code-bg);
|
||||
color: var(--peach);
|
||||
padding: 0.15em 0.4em;
|
||||
border-radius: 4px;
|
||||
font-size: 0.875em;
|
||||
}
|
||||
|
||||
/* ── Code blocks ───────────────────────────────────────────── */
|
||||
pre {
|
||||
background: var(--code-bg);
|
||||
border: 1px solid var(--border);
|
||||
border-left: 3px solid var(--sapphire);
|
||||
border-radius: 0 8px 8px 0;
|
||||
padding: 1.1em 1.4em;
|
||||
overflow-x: auto;
|
||||
line-height: 1.55;
|
||||
margin: 1.2em 0;
|
||||
}
|
||||
pre code {
|
||||
background: none;
|
||||
color: var(--text);
|
||||
padding: 0;
|
||||
font-size: 0.88em;
|
||||
}
|
||||
|
||||
/* ── Blockquotes ───────────────────────────────────────────── */
|
||||
blockquote {
|
||||
border-left: 3px solid var(--yellow);
|
||||
margin: 1.5em 0;
|
||||
padding: 0.75em 1.25em;
|
||||
background: var(--surface);
|
||||
color: var(--sub1);
|
||||
border-radius: 0 6px 6px 0;
|
||||
}
|
||||
blockquote p { margin: 0.3em 0; }
|
||||
|
||||
/* ── Tables ────────────────────────────────────────────────── */
|
||||
table {
|
||||
border-collapse: collapse;
|
||||
width: 100%;
|
||||
margin: 1.4em 0;
|
||||
font-size: 0.93em;
|
||||
}
|
||||
th, td {
|
||||
border: 1px solid var(--border);
|
||||
padding: 0.55em 0.9em;
|
||||
text-align: left;
|
||||
}
|
||||
th {
|
||||
background: var(--surface);
|
||||
color: var(--lavender);
|
||||
font-weight: 600;
|
||||
font-family: "JetBrains Mono", "Fira Code", ui-monospace, monospace;
|
||||
font-size: 0.82em;
|
||||
letter-spacing: 0.06em;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
tr:nth-child(even) { background: var(--surface); }
|
||||
tr:hover { background: var(--overlay); }
|
||||
|
||||
/* ── HR ────────────────────────────────────────────────────── */
|
||||
hr { border: none; border-top: 1px solid var(--border); margin: 2.5em 0; }
|
||||
|
||||
/* ── Lists ─────────────────────────────────────────────────── */
|
||||
ul, ol { padding-left: 1.6em; }
|
||||
li { margin: 0.35em 0; }
|
||||
|
||||
/* ── Chunk navigation bar (prev / up / next) ───────────────── */
|
||||
nav:not(#TOC):not([role="doc-toc"]) {
|
||||
background: var(--surface);
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 8px;
|
||||
margin: 1.5em 0;
|
||||
font-size: 0.875em;
|
||||
overflow: hidden;
|
||||
}
|
||||
nav:not(#TOC):not([role="doc-toc"]) p {
|
||||
margin: 0;
|
||||
padding: 0.65em 1.2em;
|
||||
display: flex;
|
||||
gap: 0.4em 1.75em;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
}
|
||||
/* JS wraps each "Label: <a>" pair in .nav-item so they flex as a unit */
|
||||
.nav-item {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 0.3em;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.nav-item a { color: var(--blue); }
|
||||
.nav-item a:hover { color: var(--lavender); }
|
||||
|
||||
/* ── Table of contents panel ───────────────────────────────── */
|
||||
nav#TOC, nav[role="doc-toc"] {
|
||||
display: block;
|
||||
background: var(--surface);
|
||||
border: 1px solid var(--border);
|
||||
border-left: 3px solid var(--lavender);
|
||||
border-radius: 0 8px 8px 0;
|
||||
padding: 1.2em 1.5em;
|
||||
margin: 1.5em 0;
|
||||
}
|
||||
nav#TOC > h2,
|
||||
nav[role="doc-toc"] > h2 {
|
||||
font-size: 0.7rem;
|
||||
letter-spacing: 0.14em;
|
||||
text-transform: uppercase;
|
||||
color: var(--sub0);
|
||||
border: none;
|
||||
margin: 0 0 0.9em;
|
||||
padding: 0;
|
||||
}
|
||||
nav#TOC ul, nav[role="doc-toc"] ul {
|
||||
list-style: none;
|
||||
padding-left: 1em;
|
||||
margin: 0.25em 0;
|
||||
}
|
||||
nav#TOC > ul, nav[role="doc-toc"] > ul { padding-left: 0; }
|
||||
nav#TOC li, nav[role="doc-toc"] li {
|
||||
margin: 0.3em 0;
|
||||
padding-left: 0.75em;
|
||||
border-left: 1px solid transparent;
|
||||
transition: border-color 0.12s;
|
||||
}
|
||||
nav#TOC li:hover, nav[role="doc-toc"] li:hover {
|
||||
border-left-color: var(--lavender);
|
||||
}
|
||||
nav#TOC a, nav[role="doc-toc"] a {
|
||||
color: var(--sub1);
|
||||
font-size: 0.9em;
|
||||
}
|
||||
nav#TOC a:hover, nav[role="doc-toc"] a:hover {
|
||||
color: var(--lavender);
|
||||
text-decoration: none;
|
||||
}
|
||||
</style>
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
/* ── Hide ToC on every page except index.html ───────────── */
|
||||
var path = location.pathname;
|
||||
var onIndex = path === '/' || path === '' || /\/index\.html(\?.*)?$/.test(path);
|
||||
if (!onIndex) {
|
||||
var toc = document.getElementById('TOC') ||
|
||||
document.querySelector('[role="doc-toc"]');
|
||||
if (toc) toc.remove();
|
||||
}
|
||||
|
||||
/* ── Wrap each "Label: <a>" pair in a .nav-item span ───────
|
||||
Pandoc emits label text nodes and anchors as siblings;
|
||||
flex sees them as separate items, causing labels to split
|
||||
from their links when wrapping. Grouping them in a span
|
||||
keeps each label+link as a single flex unit. */
|
||||
document.querySelectorAll('nav:not(#TOC):not([role="doc-toc"])').forEach(function (nav) {
|
||||
var p = nav.querySelector('p');
|
||||
if (!p) return;
|
||||
var children = Array.from(p.childNodes);
|
||||
var pairs = [];
|
||||
for (var i = 0; i + 1 < children.length; i++) {
|
||||
var cur = children[i];
|
||||
var nxt = children[i + 1];
|
||||
if (cur.nodeType === Node.TEXT_NODE &&
|
||||
/[A-Z][a-z]*:\s*/.test(cur.textContent) &&
|
||||
nxt.nodeType === Node.ELEMENT_NODE &&
|
||||
nxt.tagName === 'A') {
|
||||
pairs.push([cur, nxt]);
|
||||
i++; // skip the anchor on the next iteration
|
||||
}
|
||||
}
|
||||
pairs.forEach(function (pair) {
|
||||
var span = document.createElement('span');
|
||||
span.className = 'nav-item';
|
||||
p.insertBefore(span, pair[0]);
|
||||
span.appendChild(pair[0]);
|
||||
span.appendChild(pair[1]);
|
||||
});
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<nav id="sitenav">
|
||||
<div class="sitenav">
|
||||
<span class="navlink">
|
||||
<span class="navlink-label">Up:</span> <a href="index.html" accesskey="u" rel="up">FISH-CONFIG</a>
|
||||
</span>
|
||||
<span class="navlink">
|
||||
<span class="navlink-label">Top:</span> <a href="index.html" accesskey="t" rel="top">FISH-CONFIG</a>
|
||||
</span>
|
||||
</div>
|
||||
<div class="sitenav">
|
||||
<span class="navlink">
|
||||
<span class="navlink-label">Next:</span> <a href="14-10-personalization.html" accesskey="n" rel="next">10. PERSONALIZATION</a>
|
||||
</span>
|
||||
<span class="navlink">
|
||||
<span class="navlink-label">Previous:</span> <a href="12-8-fisher-plugins.html" accesskey="p" rel="previous">8. FISHER PLUGINS</a>
|
||||
</span>
|
||||
</div>
|
||||
</nav>
|
||||
<h1 data-number="13" id="9-installation">9. INSTALLATION</h1>
|
||||
<p>This configuration is managed as a git repository. To deploy on a new
|
||||
machine:</p>
|
||||
<pre><code>mv ~/.config/fish ~/.config/fish.bak # back up any existing config
|
||||
git clone https://git.rootiest.dev/rootiest/fish-config.git ~/.config/fish</code></pre>
|
||||
<p>Then open a new Fish shell. Fisher installs automatically on first
|
||||
launch and the Catppuccin Mocha theme is applied. All other plugin
|
||||
functionality is bundled directly with this config and requires no
|
||||
additional installation.</p>
|
||||
<h2 data-number="13.1" id="return-sentinel">Return Sentinel</h2>
|
||||
<p>config.fish ends with a return sentinel guard. Any lines appended
|
||||
after it by a tool's setup command (starship init fish | source, zoxide
|
||||
init fish | source, etc.) will have no effect. All integrations are
|
||||
managed via conf.d/ files.</p>
|
||||
<p>If a new tool's shell integration appears to do nothing, check
|
||||
whether its setup command appended an init line below the sentinel and
|
||||
create a dedicated conf.d/<tool>.fish instead.</p>
|
||||
<h2 data-number="13.2" id="updating">Updating</h2>
|
||||
<p>Pull the latest changes from the upstream repository without needing
|
||||
a configured git remote:</p>
|
||||
<pre><code>config-update Fetch and apply the latest commits from upstream
|
||||
config-update --dry-run Preview available changes without applying them
|
||||
config-update --force Stash local changes, pull, then restore the stash</code></pre>
|
||||
<p>The remote URL (<a
|
||||
href="https://git.rootiest.dev/rootiest/fish-config.git">https://git.rootiest.dev/rootiest/fish-config.git</a>)
|
||||
is hard-coded, so this works on a fresh clone with no origin configured.
|
||||
All git output is suppressed. Run exec fish after a successful update to
|
||||
reload.</p>
|
||||
<hr />
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,532 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" lang="" xml:lang="">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="generator" content="pandoc" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" />
|
||||
<meta name="author" content="Rootiest" />
|
||||
<title>10. PERSONALIZATION</title>
|
||||
<style>
|
||||
div.sitenav { display: flex; flex-direction: row; flex-wrap: wrap; }
|
||||
span.navlink { flex: 1; }
|
||||
span.navlink-label { display: inline-block; min-width: 4em; }
|
||||
html {
|
||||
color: #1a1a1a;
|
||||
background-color: #fdfdfd;
|
||||
}
|
||||
body {
|
||||
margin: 0 auto;
|
||||
max-width: 36em;
|
||||
padding-left: 50px;
|
||||
padding-right: 50px;
|
||||
padding-top: 50px;
|
||||
padding-bottom: 50px;
|
||||
hyphens: auto;
|
||||
overflow-wrap: break-word;
|
||||
text-rendering: optimizeLegibility;
|
||||
font-kerning: normal;
|
||||
}
|
||||
@media (max-width: 600px) {
|
||||
body {
|
||||
font-size: 0.9em;
|
||||
padding: 12px;
|
||||
}
|
||||
h1 {
|
||||
font-size: 1.8em;
|
||||
}
|
||||
}
|
||||
@media print {
|
||||
html {
|
||||
background-color: white;
|
||||
}
|
||||
body {
|
||||
background-color: transparent;
|
||||
color: black;
|
||||
font-size: 12pt;
|
||||
}
|
||||
p, h2, h3 {
|
||||
orphans: 3;
|
||||
widows: 3;
|
||||
}
|
||||
h2, h3, h4 {
|
||||
page-break-after: avoid;
|
||||
}
|
||||
}
|
||||
p {
|
||||
margin: 1em 0;
|
||||
}
|
||||
a {
|
||||
color: #1a1a1a;
|
||||
}
|
||||
a:visited {
|
||||
color: #1a1a1a;
|
||||
}
|
||||
img {
|
||||
max-width: 100%;
|
||||
}
|
||||
h1, h2, h3, h4, h5, h6 {
|
||||
margin-top: 1.4em;
|
||||
}
|
||||
h5, h6 {
|
||||
font-size: 1em;
|
||||
font-style: italic;
|
||||
}
|
||||
h6 {
|
||||
font-weight: normal;
|
||||
}
|
||||
ol, ul {
|
||||
padding-left: 1.7em;
|
||||
margin-top: 1em;
|
||||
}
|
||||
li > ol, li > ul {
|
||||
margin-top: 0;
|
||||
}
|
||||
blockquote {
|
||||
margin: 1em 0 1em 1.7em;
|
||||
padding-left: 1em;
|
||||
border-left: 2px solid #e6e6e6;
|
||||
color: #606060;
|
||||
}
|
||||
code {
|
||||
font-family: Menlo, Monaco, Consolas, 'Lucida Console', monospace;
|
||||
font-size: 85%;
|
||||
margin: 0;
|
||||
hyphens: manual;
|
||||
}
|
||||
pre {
|
||||
margin: 1em 0;
|
||||
overflow: auto;
|
||||
}
|
||||
pre code {
|
||||
padding: 0;
|
||||
overflow: visible;
|
||||
overflow-wrap: normal;
|
||||
}
|
||||
.sourceCode {
|
||||
background-color: transparent;
|
||||
overflow: visible;
|
||||
}
|
||||
hr {
|
||||
background-color: #1a1a1a;
|
||||
border: none;
|
||||
height: 1px;
|
||||
margin: 1em 0;
|
||||
}
|
||||
table {
|
||||
margin: 1em 0;
|
||||
border-collapse: collapse;
|
||||
width: 100%;
|
||||
overflow-x: auto;
|
||||
display: block;
|
||||
font-variant-numeric: lining-nums tabular-nums;
|
||||
}
|
||||
table caption {
|
||||
margin-bottom: 0.75em;
|
||||
}
|
||||
tbody {
|
||||
margin-top: 0.5em;
|
||||
border-top: 1px solid #1a1a1a;
|
||||
border-bottom: 1px solid #1a1a1a;
|
||||
}
|
||||
th {
|
||||
border-top: 1px solid #1a1a1a;
|
||||
padding: 0.25em 0.5em 0.25em 0.5em;
|
||||
}
|
||||
td {
|
||||
padding: 0.125em 0.5em 0.25em 0.5em;
|
||||
}
|
||||
header {
|
||||
margin-bottom: 4em;
|
||||
text-align: center;
|
||||
}
|
||||
#TOC li {
|
||||
list-style: none;
|
||||
}
|
||||
#TOC ul {
|
||||
padding-left: 1.3em;
|
||||
}
|
||||
#TOC > ul {
|
||||
padding-left: 0;
|
||||
}
|
||||
#TOC a:not(:hover) {
|
||||
text-decoration: none;
|
||||
}
|
||||
code{white-space: pre-wrap;}
|
||||
span.smallcaps{font-variant: small-caps;}
|
||||
div.columns{display: flex; gap: min(4vw, 1.5em);}
|
||||
div.column{flex: auto; overflow-x: auto;}
|
||||
div.hanging-indent{margin-left: 1.5em; text-indent: -1.5em;}
|
||||
/* The extra [class] is a hack that increases specificity enough to
|
||||
override a similar rule in reveal.js */
|
||||
ul.task-list[class]{list-style: none;}
|
||||
ul.task-list li input[type="checkbox"] {
|
||||
font-size: inherit;
|
||||
width: 0.8em;
|
||||
margin: 0 0.8em 0.2em -1.6em;
|
||||
vertical-align: middle;
|
||||
}
|
||||
.display.math{display: block; text-align: center; margin: 0.5rem auto;}
|
||||
</style>
|
||||
<style>
|
||||
/* ── Catppuccin Latte (light) / Mocha (dark) ─────────────────── */
|
||||
:root {
|
||||
color-scheme: light dark;
|
||||
--bg: #eff1f5;
|
||||
--surface: #e6e9ef;
|
||||
--overlay: #ccd0da;
|
||||
--text: #4c4f69;
|
||||
--sub1: #6c6f85;
|
||||
--sub0: #8c8fa1;
|
||||
--blue: #1e66f5;
|
||||
--lavender: #7287fd;
|
||||
--sapphire: #209fb5;
|
||||
--green: #40a02b;
|
||||
--yellow: #df8e1d;
|
||||
--peach: #fe640b;
|
||||
--mauve: #8839ef;
|
||||
--code-bg: #dce0e8;
|
||||
--border: #bcc0cc;
|
||||
--glow1: rgba(30, 102, 245, 0.05);
|
||||
--glow2: rgba(136, 57, 239, 0.04);
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
:root {
|
||||
--bg: #1e1e2e;
|
||||
--surface: #313244;
|
||||
--overlay: #45475a;
|
||||
--text: #cdd6f4;
|
||||
--sub1: #bac2de;
|
||||
--sub0: #a6adc8;
|
||||
--blue: #89b4fa;
|
||||
--lavender: #b4befe;
|
||||
--sapphire: #74c7ec;
|
||||
--green: #a6e3a1;
|
||||
--yellow: #f9e2af;
|
||||
--peach: #fab387;
|
||||
--mauve: #cba6f7;
|
||||
--code-bg: #181825;
|
||||
--border: #45475a;
|
||||
--glow1: rgba(137, 180, 250, 0.06);
|
||||
--glow2: rgba(203, 166, 247, 0.05);
|
||||
}
|
||||
}
|
||||
|
||||
*, *::before, *::after { box-sizing: border-box; }
|
||||
|
||||
html {
|
||||
background-color: var(--bg);
|
||||
background-image:
|
||||
radial-gradient(ellipse 55% 40% at 10% 5%, var(--glow1) 0%, transparent 100%),
|
||||
radial-gradient(ellipse 45% 45% at 90% 95%, var(--glow2) 0%, transparent 100%);
|
||||
min-height: 100%;
|
||||
}
|
||||
|
||||
body {
|
||||
color: var(--text);
|
||||
font-family: system-ui, -apple-system, "Segoe UI", Helvetica, sans-serif;
|
||||
font-size: 16px;
|
||||
line-height: 1.75;
|
||||
max-width: 880px;
|
||||
margin: 0 auto;
|
||||
padding: 2rem 2.5rem 5rem;
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
/* ── Links ─────────────────────────────────────────────────── */
|
||||
a { color: var(--blue); text-decoration: none; }
|
||||
a:hover { color: var(--lavender); text-decoration: underline; }
|
||||
a:visited { color: var(--lavender); }
|
||||
|
||||
/* ── Headings ──────────────────────────────────────────────── */
|
||||
h1, h2, h3, h4, h5, h6 {
|
||||
font-family: "JetBrains Mono", "Fira Code", ui-monospace, monospace;
|
||||
color: var(--lavender);
|
||||
line-height: 1.3;
|
||||
margin-top: 2em;
|
||||
margin-bottom: 0.5em;
|
||||
}
|
||||
h1 {
|
||||
font-size: 1.9rem;
|
||||
color: var(--text);
|
||||
border-bottom: 1px solid var(--border);
|
||||
padding-bottom: 0.4em;
|
||||
margin-top: 1.2em;
|
||||
}
|
||||
h2 {
|
||||
font-size: 1.35rem;
|
||||
border-bottom: 1px solid var(--border);
|
||||
padding-bottom: 0.2em;
|
||||
}
|
||||
h3 { font-size: 1.1rem; color: var(--sapphire); }
|
||||
h4 { font-size: 0.95rem; color: var(--sub1); }
|
||||
|
||||
p { margin: 0.8em 0; }
|
||||
|
||||
/* ── Title block (pandoc-generated cover) ──────────────────── */
|
||||
#title-block-header {
|
||||
text-align: center;
|
||||
padding: 2.5rem 0 2rem;
|
||||
margin-bottom: 1.5rem;
|
||||
border-bottom: 1px solid var(--border);
|
||||
}
|
||||
#title-block-header .title {
|
||||
font-family: "JetBrains Mono", "Fira Code", ui-monospace, monospace;
|
||||
font-size: 2.6rem;
|
||||
letter-spacing: 0.12em;
|
||||
color: var(--lavender);
|
||||
border: none;
|
||||
margin: 0 0 0.75rem;
|
||||
}
|
||||
#title-block-header .author,
|
||||
#title-block-header .date {
|
||||
color: var(--sub0);
|
||||
font-size: 0.875rem;
|
||||
margin: 0.2rem 0;
|
||||
}
|
||||
|
||||
/* ── Inline code ───────────────────────────────────────────── */
|
||||
code {
|
||||
font-family: "JetBrains Mono", "Fira Code", ui-monospace, monospace;
|
||||
background: var(--code-bg);
|
||||
color: var(--peach);
|
||||
padding: 0.15em 0.4em;
|
||||
border-radius: 4px;
|
||||
font-size: 0.875em;
|
||||
}
|
||||
|
||||
/* ── Code blocks ───────────────────────────────────────────── */
|
||||
pre {
|
||||
background: var(--code-bg);
|
||||
border: 1px solid var(--border);
|
||||
border-left: 3px solid var(--sapphire);
|
||||
border-radius: 0 8px 8px 0;
|
||||
padding: 1.1em 1.4em;
|
||||
overflow-x: auto;
|
||||
line-height: 1.55;
|
||||
margin: 1.2em 0;
|
||||
}
|
||||
pre code {
|
||||
background: none;
|
||||
color: var(--text);
|
||||
padding: 0;
|
||||
font-size: 0.88em;
|
||||
}
|
||||
|
||||
/* ── Blockquotes ───────────────────────────────────────────── */
|
||||
blockquote {
|
||||
border-left: 3px solid var(--yellow);
|
||||
margin: 1.5em 0;
|
||||
padding: 0.75em 1.25em;
|
||||
background: var(--surface);
|
||||
color: var(--sub1);
|
||||
border-radius: 0 6px 6px 0;
|
||||
}
|
||||
blockquote p { margin: 0.3em 0; }
|
||||
|
||||
/* ── Tables ────────────────────────────────────────────────── */
|
||||
table {
|
||||
border-collapse: collapse;
|
||||
width: 100%;
|
||||
margin: 1.4em 0;
|
||||
font-size: 0.93em;
|
||||
}
|
||||
th, td {
|
||||
border: 1px solid var(--border);
|
||||
padding: 0.55em 0.9em;
|
||||
text-align: left;
|
||||
}
|
||||
th {
|
||||
background: var(--surface);
|
||||
color: var(--lavender);
|
||||
font-weight: 600;
|
||||
font-family: "JetBrains Mono", "Fira Code", ui-monospace, monospace;
|
||||
font-size: 0.82em;
|
||||
letter-spacing: 0.06em;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
tr:nth-child(even) { background: var(--surface); }
|
||||
tr:hover { background: var(--overlay); }
|
||||
|
||||
/* ── HR ────────────────────────────────────────────────────── */
|
||||
hr { border: none; border-top: 1px solid var(--border); margin: 2.5em 0; }
|
||||
|
||||
/* ── Lists ─────────────────────────────────────────────────── */
|
||||
ul, ol { padding-left: 1.6em; }
|
||||
li { margin: 0.35em 0; }
|
||||
|
||||
/* ── Chunk navigation bar (prev / up / next) ───────────────── */
|
||||
nav:not(#TOC):not([role="doc-toc"]) {
|
||||
background: var(--surface);
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 8px;
|
||||
margin: 1.5em 0;
|
||||
font-size: 0.875em;
|
||||
overflow: hidden;
|
||||
}
|
||||
nav:not(#TOC):not([role="doc-toc"]) p {
|
||||
margin: 0;
|
||||
padding: 0.65em 1.2em;
|
||||
display: flex;
|
||||
gap: 0.4em 1.75em;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
}
|
||||
/* JS wraps each "Label: <a>" pair in .nav-item so they flex as a unit */
|
||||
.nav-item {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 0.3em;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.nav-item a { color: var(--blue); }
|
||||
.nav-item a:hover { color: var(--lavender); }
|
||||
|
||||
/* ── Table of contents panel ───────────────────────────────── */
|
||||
nav#TOC, nav[role="doc-toc"] {
|
||||
display: block;
|
||||
background: var(--surface);
|
||||
border: 1px solid var(--border);
|
||||
border-left: 3px solid var(--lavender);
|
||||
border-radius: 0 8px 8px 0;
|
||||
padding: 1.2em 1.5em;
|
||||
margin: 1.5em 0;
|
||||
}
|
||||
nav#TOC > h2,
|
||||
nav[role="doc-toc"] > h2 {
|
||||
font-size: 0.7rem;
|
||||
letter-spacing: 0.14em;
|
||||
text-transform: uppercase;
|
||||
color: var(--sub0);
|
||||
border: none;
|
||||
margin: 0 0 0.9em;
|
||||
padding: 0;
|
||||
}
|
||||
nav#TOC ul, nav[role="doc-toc"] ul {
|
||||
list-style: none;
|
||||
padding-left: 1em;
|
||||
margin: 0.25em 0;
|
||||
}
|
||||
nav#TOC > ul, nav[role="doc-toc"] > ul { padding-left: 0; }
|
||||
nav#TOC li, nav[role="doc-toc"] li {
|
||||
margin: 0.3em 0;
|
||||
padding-left: 0.75em;
|
||||
border-left: 1px solid transparent;
|
||||
transition: border-color 0.12s;
|
||||
}
|
||||
nav#TOC li:hover, nav[role="doc-toc"] li:hover {
|
||||
border-left-color: var(--lavender);
|
||||
}
|
||||
nav#TOC a, nav[role="doc-toc"] a {
|
||||
color: var(--sub1);
|
||||
font-size: 0.9em;
|
||||
}
|
||||
nav#TOC a:hover, nav[role="doc-toc"] a:hover {
|
||||
color: var(--lavender);
|
||||
text-decoration: none;
|
||||
}
|
||||
</style>
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
/* ── Hide ToC on every page except index.html ───────────── */
|
||||
var path = location.pathname;
|
||||
var onIndex = path === '/' || path === '' || /\/index\.html(\?.*)?$/.test(path);
|
||||
if (!onIndex) {
|
||||
var toc = document.getElementById('TOC') ||
|
||||
document.querySelector('[role="doc-toc"]');
|
||||
if (toc) toc.remove();
|
||||
}
|
||||
|
||||
/* ── Wrap each "Label: <a>" pair in a .nav-item span ───────
|
||||
Pandoc emits label text nodes and anchors as siblings;
|
||||
flex sees them as separate items, causing labels to split
|
||||
from their links when wrapping. Grouping them in a span
|
||||
keeps each label+link as a single flex unit. */
|
||||
document.querySelectorAll('nav:not(#TOC):not([role="doc-toc"])').forEach(function (nav) {
|
||||
var p = nav.querySelector('p');
|
||||
if (!p) return;
|
||||
var children = Array.from(p.childNodes);
|
||||
var pairs = [];
|
||||
for (var i = 0; i + 1 < children.length; i++) {
|
||||
var cur = children[i];
|
||||
var nxt = children[i + 1];
|
||||
if (cur.nodeType === Node.TEXT_NODE &&
|
||||
/[A-Z][a-z]*:\s*/.test(cur.textContent) &&
|
||||
nxt.nodeType === Node.ELEMENT_NODE &&
|
||||
nxt.tagName === 'A') {
|
||||
pairs.push([cur, nxt]);
|
||||
i++; // skip the anchor on the next iteration
|
||||
}
|
||||
}
|
||||
pairs.forEach(function (pair) {
|
||||
var span = document.createElement('span');
|
||||
span.className = 'nav-item';
|
||||
p.insertBefore(span, pair[0]);
|
||||
span.appendChild(pair[0]);
|
||||
span.appendChild(pair[1]);
|
||||
});
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<nav id="sitenav">
|
||||
<div class="sitenav">
|
||||
<span class="navlink">
|
||||
<span class="navlink-label">Up:</span> <a href="index.html" accesskey="u" rel="up">FISH-CONFIG</a>
|
||||
</span>
|
||||
<span class="navlink">
|
||||
<span class="navlink-label">Top:</span> <a href="index.html" accesskey="t" rel="top">FISH-CONFIG</a>
|
||||
</span>
|
||||
</div>
|
||||
<div class="sitenav">
|
||||
<span class="navlink">
|
||||
<span class="navlink-label">Next:</span> <a href="15-11-viewing-this-manual.html" accesskey="n" rel="next">11. VIEWING THIS MANUAL</a>
|
||||
</span>
|
||||
<span class="navlink">
|
||||
<span class="navlink-label">Previous:</span> <a href="13-9-installation.html" accesskey="p" rel="previous">9. INSTALLATION</a>
|
||||
</span>
|
||||
</div>
|
||||
</nav>
|
||||
<h1 data-number="14" id="10-personalization">10. PERSONALIZATION</h1>
|
||||
<p>Sensitive credentials and machine-specific settings are kept out of
|
||||
version control in a private directory at ~/.config/.user-dots/fish/.
|
||||
Two files are sourced automatically by config.fish if they exist:</p>
|
||||
<pre><code>~/.config/.user-dots/fish/
|
||||
├── secrets.fish API keys, tokens, passwords, personal identifiers
|
||||
└── local.fish Machine-specific paths and environment variables</code></pre>
|
||||
<p>fish_variables (auto-managed by fish) is excluded from this repo via
|
||||
.gitignore. Do not commit it.</p>
|
||||
<h2 data-number="14.1" id="secretsfish">secrets.fish</h2>
|
||||
<p>Store anything you would not commit to a public repo: API keys, auth
|
||||
tokens, passwords, and personal identifiers.</p>
|
||||
<pre><code>set -gx MY_NAME "Your Name"
|
||||
set -gx MY_EMAIL "you@example.com"
|
||||
set -gx GPG_RECIPIENT "you@example.com"
|
||||
set -gx GITHUB_TOKEN ghp_yourTokenHere
|
||||
set -gx OPENAI_API_KEY sk-proj-yourKeyHere
|
||||
set -gx GITEA_TOKEN yourGiteaTokenHere
|
||||
set -gx GITEA_CHOSEN_LOGIN your.gitea.instance
|
||||
set -gx KOPIA_PASSWORD yourKopiaPassword</code></pre>
|
||||
<h2 data-number="14.2" id="localfish">local.fish</h2>
|
||||
<p>Store paths and variables specific to one machine — things that would
|
||||
be wrong on any other system.</p>
|
||||
<pre><code># CDPATH — directories searched by cd
|
||||
set -gx CDPATH . /home/youruser/projects /home/youruser
|
||||
|
||||
# Path to your shared .gitignore boilerplate
|
||||
set -gx GITIGNORE_BOILERPLATE ~/.config/git/gitignore_boilerplate
|
||||
|
||||
# SSH shortcuts
|
||||
abbr -a sshr 'ssh you@your-server.local'
|
||||
abbr -a sshw 'ssh you@work-server.example.com'
|
||||
|
||||
# Docker context shortcuts
|
||||
abbr -a dcr 'docker context use my-remote-server'
|
||||
abbr -a dcw 'docker context use work-server'</code></pre>
|
||||
<p>Both files are sourced at the end of config.fish with an existence
|
||||
check so the public config works cleanly on any machine without the
|
||||
private repo.</p>
|
||||
<hr />
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,545 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" lang="" xml:lang="">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="generator" content="pandoc" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" />
|
||||
<meta name="author" content="Rootiest" />
|
||||
<title>11. VIEWING THIS MANUAL</title>
|
||||
<style>
|
||||
div.sitenav { display: flex; flex-direction: row; flex-wrap: wrap; }
|
||||
span.navlink { flex: 1; }
|
||||
span.navlink-label { display: inline-block; min-width: 4em; }
|
||||
html {
|
||||
color: #1a1a1a;
|
||||
background-color: #fdfdfd;
|
||||
}
|
||||
body {
|
||||
margin: 0 auto;
|
||||
max-width: 36em;
|
||||
padding-left: 50px;
|
||||
padding-right: 50px;
|
||||
padding-top: 50px;
|
||||
padding-bottom: 50px;
|
||||
hyphens: auto;
|
||||
overflow-wrap: break-word;
|
||||
text-rendering: optimizeLegibility;
|
||||
font-kerning: normal;
|
||||
}
|
||||
@media (max-width: 600px) {
|
||||
body {
|
||||
font-size: 0.9em;
|
||||
padding: 12px;
|
||||
}
|
||||
h1 {
|
||||
font-size: 1.8em;
|
||||
}
|
||||
}
|
||||
@media print {
|
||||
html {
|
||||
background-color: white;
|
||||
}
|
||||
body {
|
||||
background-color: transparent;
|
||||
color: black;
|
||||
font-size: 12pt;
|
||||
}
|
||||
p, h2, h3 {
|
||||
orphans: 3;
|
||||
widows: 3;
|
||||
}
|
||||
h2, h3, h4 {
|
||||
page-break-after: avoid;
|
||||
}
|
||||
}
|
||||
p {
|
||||
margin: 1em 0;
|
||||
}
|
||||
a {
|
||||
color: #1a1a1a;
|
||||
}
|
||||
a:visited {
|
||||
color: #1a1a1a;
|
||||
}
|
||||
img {
|
||||
max-width: 100%;
|
||||
}
|
||||
h1, h2, h3, h4, h5, h6 {
|
||||
margin-top: 1.4em;
|
||||
}
|
||||
h5, h6 {
|
||||
font-size: 1em;
|
||||
font-style: italic;
|
||||
}
|
||||
h6 {
|
||||
font-weight: normal;
|
||||
}
|
||||
ol, ul {
|
||||
padding-left: 1.7em;
|
||||
margin-top: 1em;
|
||||
}
|
||||
li > ol, li > ul {
|
||||
margin-top: 0;
|
||||
}
|
||||
blockquote {
|
||||
margin: 1em 0 1em 1.7em;
|
||||
padding-left: 1em;
|
||||
border-left: 2px solid #e6e6e6;
|
||||
color: #606060;
|
||||
}
|
||||
code {
|
||||
font-family: Menlo, Monaco, Consolas, 'Lucida Console', monospace;
|
||||
font-size: 85%;
|
||||
margin: 0;
|
||||
hyphens: manual;
|
||||
}
|
||||
pre {
|
||||
margin: 1em 0;
|
||||
overflow: auto;
|
||||
}
|
||||
pre code {
|
||||
padding: 0;
|
||||
overflow: visible;
|
||||
overflow-wrap: normal;
|
||||
}
|
||||
.sourceCode {
|
||||
background-color: transparent;
|
||||
overflow: visible;
|
||||
}
|
||||
hr {
|
||||
background-color: #1a1a1a;
|
||||
border: none;
|
||||
height: 1px;
|
||||
margin: 1em 0;
|
||||
}
|
||||
table {
|
||||
margin: 1em 0;
|
||||
border-collapse: collapse;
|
||||
width: 100%;
|
||||
overflow-x: auto;
|
||||
display: block;
|
||||
font-variant-numeric: lining-nums tabular-nums;
|
||||
}
|
||||
table caption {
|
||||
margin-bottom: 0.75em;
|
||||
}
|
||||
tbody {
|
||||
margin-top: 0.5em;
|
||||
border-top: 1px solid #1a1a1a;
|
||||
border-bottom: 1px solid #1a1a1a;
|
||||
}
|
||||
th {
|
||||
border-top: 1px solid #1a1a1a;
|
||||
padding: 0.25em 0.5em 0.25em 0.5em;
|
||||
}
|
||||
td {
|
||||
padding: 0.125em 0.5em 0.25em 0.5em;
|
||||
}
|
||||
header {
|
||||
margin-bottom: 4em;
|
||||
text-align: center;
|
||||
}
|
||||
#TOC li {
|
||||
list-style: none;
|
||||
}
|
||||
#TOC ul {
|
||||
padding-left: 1.3em;
|
||||
}
|
||||
#TOC > ul {
|
||||
padding-left: 0;
|
||||
}
|
||||
#TOC a:not(:hover) {
|
||||
text-decoration: none;
|
||||
}
|
||||
code{white-space: pre-wrap;}
|
||||
span.smallcaps{font-variant: small-caps;}
|
||||
div.columns{display: flex; gap: min(4vw, 1.5em);}
|
||||
div.column{flex: auto; overflow-x: auto;}
|
||||
div.hanging-indent{margin-left: 1.5em; text-indent: -1.5em;}
|
||||
/* The extra [class] is a hack that increases specificity enough to
|
||||
override a similar rule in reveal.js */
|
||||
ul.task-list[class]{list-style: none;}
|
||||
ul.task-list li input[type="checkbox"] {
|
||||
font-size: inherit;
|
||||
width: 0.8em;
|
||||
margin: 0 0.8em 0.2em -1.6em;
|
||||
vertical-align: middle;
|
||||
}
|
||||
.display.math{display: block; text-align: center; margin: 0.5rem auto;}
|
||||
</style>
|
||||
<style>
|
||||
/* ── Catppuccin Latte (light) / Mocha (dark) ─────────────────── */
|
||||
:root {
|
||||
color-scheme: light dark;
|
||||
--bg: #eff1f5;
|
||||
--surface: #e6e9ef;
|
||||
--overlay: #ccd0da;
|
||||
--text: #4c4f69;
|
||||
--sub1: #6c6f85;
|
||||
--sub0: #8c8fa1;
|
||||
--blue: #1e66f5;
|
||||
--lavender: #7287fd;
|
||||
--sapphire: #209fb5;
|
||||
--green: #40a02b;
|
||||
--yellow: #df8e1d;
|
||||
--peach: #fe640b;
|
||||
--mauve: #8839ef;
|
||||
--code-bg: #dce0e8;
|
||||
--border: #bcc0cc;
|
||||
--glow1: rgba(30, 102, 245, 0.05);
|
||||
--glow2: rgba(136, 57, 239, 0.04);
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
:root {
|
||||
--bg: #1e1e2e;
|
||||
--surface: #313244;
|
||||
--overlay: #45475a;
|
||||
--text: #cdd6f4;
|
||||
--sub1: #bac2de;
|
||||
--sub0: #a6adc8;
|
||||
--blue: #89b4fa;
|
||||
--lavender: #b4befe;
|
||||
--sapphire: #74c7ec;
|
||||
--green: #a6e3a1;
|
||||
--yellow: #f9e2af;
|
||||
--peach: #fab387;
|
||||
--mauve: #cba6f7;
|
||||
--code-bg: #181825;
|
||||
--border: #45475a;
|
||||
--glow1: rgba(137, 180, 250, 0.06);
|
||||
--glow2: rgba(203, 166, 247, 0.05);
|
||||
}
|
||||
}
|
||||
|
||||
*, *::before, *::after { box-sizing: border-box; }
|
||||
|
||||
html {
|
||||
background-color: var(--bg);
|
||||
background-image:
|
||||
radial-gradient(ellipse 55% 40% at 10% 5%, var(--glow1) 0%, transparent 100%),
|
||||
radial-gradient(ellipse 45% 45% at 90% 95%, var(--glow2) 0%, transparent 100%);
|
||||
min-height: 100%;
|
||||
}
|
||||
|
||||
body {
|
||||
color: var(--text);
|
||||
font-family: system-ui, -apple-system, "Segoe UI", Helvetica, sans-serif;
|
||||
font-size: 16px;
|
||||
line-height: 1.75;
|
||||
max-width: 880px;
|
||||
margin: 0 auto;
|
||||
padding: 2rem 2.5rem 5rem;
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
/* ── Links ─────────────────────────────────────────────────── */
|
||||
a { color: var(--blue); text-decoration: none; }
|
||||
a:hover { color: var(--lavender); text-decoration: underline; }
|
||||
a:visited { color: var(--lavender); }
|
||||
|
||||
/* ── Headings ──────────────────────────────────────────────── */
|
||||
h1, h2, h3, h4, h5, h6 {
|
||||
font-family: "JetBrains Mono", "Fira Code", ui-monospace, monospace;
|
||||
color: var(--lavender);
|
||||
line-height: 1.3;
|
||||
margin-top: 2em;
|
||||
margin-bottom: 0.5em;
|
||||
}
|
||||
h1 {
|
||||
font-size: 1.9rem;
|
||||
color: var(--text);
|
||||
border-bottom: 1px solid var(--border);
|
||||
padding-bottom: 0.4em;
|
||||
margin-top: 1.2em;
|
||||
}
|
||||
h2 {
|
||||
font-size: 1.35rem;
|
||||
border-bottom: 1px solid var(--border);
|
||||
padding-bottom: 0.2em;
|
||||
}
|
||||
h3 { font-size: 1.1rem; color: var(--sapphire); }
|
||||
h4 { font-size: 0.95rem; color: var(--sub1); }
|
||||
|
||||
p { margin: 0.8em 0; }
|
||||
|
||||
/* ── Title block (pandoc-generated cover) ──────────────────── */
|
||||
#title-block-header {
|
||||
text-align: center;
|
||||
padding: 2.5rem 0 2rem;
|
||||
margin-bottom: 1.5rem;
|
||||
border-bottom: 1px solid var(--border);
|
||||
}
|
||||
#title-block-header .title {
|
||||
font-family: "JetBrains Mono", "Fira Code", ui-monospace, monospace;
|
||||
font-size: 2.6rem;
|
||||
letter-spacing: 0.12em;
|
||||
color: var(--lavender);
|
||||
border: none;
|
||||
margin: 0 0 0.75rem;
|
||||
}
|
||||
#title-block-header .author,
|
||||
#title-block-header .date {
|
||||
color: var(--sub0);
|
||||
font-size: 0.875rem;
|
||||
margin: 0.2rem 0;
|
||||
}
|
||||
|
||||
/* ── Inline code ───────────────────────────────────────────── */
|
||||
code {
|
||||
font-family: "JetBrains Mono", "Fira Code", ui-monospace, monospace;
|
||||
background: var(--code-bg);
|
||||
color: var(--peach);
|
||||
padding: 0.15em 0.4em;
|
||||
border-radius: 4px;
|
||||
font-size: 0.875em;
|
||||
}
|
||||
|
||||
/* ── Code blocks ───────────────────────────────────────────── */
|
||||
pre {
|
||||
background: var(--code-bg);
|
||||
border: 1px solid var(--border);
|
||||
border-left: 3px solid var(--sapphire);
|
||||
border-radius: 0 8px 8px 0;
|
||||
padding: 1.1em 1.4em;
|
||||
overflow-x: auto;
|
||||
line-height: 1.55;
|
||||
margin: 1.2em 0;
|
||||
}
|
||||
pre code {
|
||||
background: none;
|
||||
color: var(--text);
|
||||
padding: 0;
|
||||
font-size: 0.88em;
|
||||
}
|
||||
|
||||
/* ── Blockquotes ───────────────────────────────────────────── */
|
||||
blockquote {
|
||||
border-left: 3px solid var(--yellow);
|
||||
margin: 1.5em 0;
|
||||
padding: 0.75em 1.25em;
|
||||
background: var(--surface);
|
||||
color: var(--sub1);
|
||||
border-radius: 0 6px 6px 0;
|
||||
}
|
||||
blockquote p { margin: 0.3em 0; }
|
||||
|
||||
/* ── Tables ────────────────────────────────────────────────── */
|
||||
table {
|
||||
border-collapse: collapse;
|
||||
width: 100%;
|
||||
margin: 1.4em 0;
|
||||
font-size: 0.93em;
|
||||
}
|
||||
th, td {
|
||||
border: 1px solid var(--border);
|
||||
padding: 0.55em 0.9em;
|
||||
text-align: left;
|
||||
}
|
||||
th {
|
||||
background: var(--surface);
|
||||
color: var(--lavender);
|
||||
font-weight: 600;
|
||||
font-family: "JetBrains Mono", "Fira Code", ui-monospace, monospace;
|
||||
font-size: 0.82em;
|
||||
letter-spacing: 0.06em;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
tr:nth-child(even) { background: var(--surface); }
|
||||
tr:hover { background: var(--overlay); }
|
||||
|
||||
/* ── HR ────────────────────────────────────────────────────── */
|
||||
hr { border: none; border-top: 1px solid var(--border); margin: 2.5em 0; }
|
||||
|
||||
/* ── Lists ─────────────────────────────────────────────────── */
|
||||
ul, ol { padding-left: 1.6em; }
|
||||
li { margin: 0.35em 0; }
|
||||
|
||||
/* ── Chunk navigation bar (prev / up / next) ───────────────── */
|
||||
nav:not(#TOC):not([role="doc-toc"]) {
|
||||
background: var(--surface);
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 8px;
|
||||
margin: 1.5em 0;
|
||||
font-size: 0.875em;
|
||||
overflow: hidden;
|
||||
}
|
||||
nav:not(#TOC):not([role="doc-toc"]) p {
|
||||
margin: 0;
|
||||
padding: 0.65em 1.2em;
|
||||
display: flex;
|
||||
gap: 0.4em 1.75em;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
}
|
||||
/* JS wraps each "Label: <a>" pair in .nav-item so they flex as a unit */
|
||||
.nav-item {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 0.3em;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.nav-item a { color: var(--blue); }
|
||||
.nav-item a:hover { color: var(--lavender); }
|
||||
|
||||
/* ── Table of contents panel ───────────────────────────────── */
|
||||
nav#TOC, nav[role="doc-toc"] {
|
||||
display: block;
|
||||
background: var(--surface);
|
||||
border: 1px solid var(--border);
|
||||
border-left: 3px solid var(--lavender);
|
||||
border-radius: 0 8px 8px 0;
|
||||
padding: 1.2em 1.5em;
|
||||
margin: 1.5em 0;
|
||||
}
|
||||
nav#TOC > h2,
|
||||
nav[role="doc-toc"] > h2 {
|
||||
font-size: 0.7rem;
|
||||
letter-spacing: 0.14em;
|
||||
text-transform: uppercase;
|
||||
color: var(--sub0);
|
||||
border: none;
|
||||
margin: 0 0 0.9em;
|
||||
padding: 0;
|
||||
}
|
||||
nav#TOC ul, nav[role="doc-toc"] ul {
|
||||
list-style: none;
|
||||
padding-left: 1em;
|
||||
margin: 0.25em 0;
|
||||
}
|
||||
nav#TOC > ul, nav[role="doc-toc"] > ul { padding-left: 0; }
|
||||
nav#TOC li, nav[role="doc-toc"] li {
|
||||
margin: 0.3em 0;
|
||||
padding-left: 0.75em;
|
||||
border-left: 1px solid transparent;
|
||||
transition: border-color 0.12s;
|
||||
}
|
||||
nav#TOC li:hover, nav[role="doc-toc"] li:hover {
|
||||
border-left-color: var(--lavender);
|
||||
}
|
||||
nav#TOC a, nav[role="doc-toc"] a {
|
||||
color: var(--sub1);
|
||||
font-size: 0.9em;
|
||||
}
|
||||
nav#TOC a:hover, nav[role="doc-toc"] a:hover {
|
||||
color: var(--lavender);
|
||||
text-decoration: none;
|
||||
}
|
||||
</style>
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
/* ── Hide ToC on every page except index.html ───────────── */
|
||||
var path = location.pathname;
|
||||
var onIndex = path === '/' || path === '' || /\/index\.html(\?.*)?$/.test(path);
|
||||
if (!onIndex) {
|
||||
var toc = document.getElementById('TOC') ||
|
||||
document.querySelector('[role="doc-toc"]');
|
||||
if (toc) toc.remove();
|
||||
}
|
||||
|
||||
/* ── Wrap each "Label: <a>" pair in a .nav-item span ───────
|
||||
Pandoc emits label text nodes and anchors as siblings;
|
||||
flex sees them as separate items, causing labels to split
|
||||
from their links when wrapping. Grouping them in a span
|
||||
keeps each label+link as a single flex unit. */
|
||||
document.querySelectorAll('nav:not(#TOC):not([role="doc-toc"])').forEach(function (nav) {
|
||||
var p = nav.querySelector('p');
|
||||
if (!p) return;
|
||||
var children = Array.from(p.childNodes);
|
||||
var pairs = [];
|
||||
for (var i = 0; i + 1 < children.length; i++) {
|
||||
var cur = children[i];
|
||||
var nxt = children[i + 1];
|
||||
if (cur.nodeType === Node.TEXT_NODE &&
|
||||
/[A-Z][a-z]*:\s*/.test(cur.textContent) &&
|
||||
nxt.nodeType === Node.ELEMENT_NODE &&
|
||||
nxt.tagName === 'A') {
|
||||
pairs.push([cur, nxt]);
|
||||
i++; // skip the anchor on the next iteration
|
||||
}
|
||||
}
|
||||
pairs.forEach(function (pair) {
|
||||
var span = document.createElement('span');
|
||||
span.className = 'nav-item';
|
||||
p.insertBefore(span, pair[0]);
|
||||
span.appendChild(pair[0]);
|
||||
span.appendChild(pair[1]);
|
||||
});
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<nav id="sitenav">
|
||||
<div class="sitenav">
|
||||
<span class="navlink">
|
||||
<span class="navlink-label">Up:</span> <a href="index.html" accesskey="u" rel="up">FISH-CONFIG</a>
|
||||
</span>
|
||||
<span class="navlink">
|
||||
<span class="navlink-label">Top:</span> <a href="index.html" accesskey="t" rel="top">FISH-CONFIG</a>
|
||||
</span>
|
||||
</div>
|
||||
<div class="sitenav">
|
||||
<span class="navlink">
|
||||
</span>
|
||||
<span class="navlink">
|
||||
<span class="navlink-label">Previous:</span> <a href="14-10-personalization.html" accesskey="p" rel="previous">10. PERSONALIZATION</a>
|
||||
</span>
|
||||
</div>
|
||||
</nav>
|
||||
<h1 data-number="15" id="11-viewing-this-manual">11. VIEWING THIS
|
||||
MANUAL</h1>
|
||||
<h2 data-number="15.1" id="with-ov-recommended">With ov
|
||||
(recommended)</h2>
|
||||
<pre><code>help config</code></pre>
|
||||
<p>ov renders the Markdown with syntax highlighting and section-based
|
||||
navigation.</p>
|
||||
<pre><code>Space next section
|
||||
^ previous section
|
||||
Alt+u toggle section list sidebar
|
||||
/ search forward
|
||||
n / N next / previous search match
|
||||
g go to line number
|
||||
j interactive jump target (line, %, or 'section')
|
||||
q quit</code></pre>
|
||||
<h2 data-number="15.2" id="with-bat">With bat</h2>
|
||||
<pre><code>bat --language=markdown --paging=always ~/.config/fish/docs/fish-config.md</code></pre>
|
||||
<h2 data-number="15.3" id="as-a-man-page">As a man page</h2>
|
||||
<pre><code>help config --man
|
||||
help config pkg --man</code></pre>
|
||||
<p>Opens the compiled docs/fish-config.1 directly via man -l, bypassing
|
||||
the pager fallback chain. If a section keyword is given, the pager opens
|
||||
at the nearest matching heading. The symlink and MANPATH are also
|
||||
configured automatically on shell start for the standard invocation:</p>
|
||||
<pre><code>man fish-config</code></pre>
|
||||
<p>NOTE: fish-config (hyphen) is this config's man page. fish_config
|
||||
(underscore) is fish's built-in browser-based configuration tool — a
|
||||
completely separate command. Do not mix them up.</p>
|
||||
<h2 data-number="15.4" id="in-the-browser-html">In the browser
|
||||
(HTML)</h2>
|
||||
<pre><code>help config --html
|
||||
help config pkg --html</code></pre>
|
||||
<p>Opens docs/html/index.html in the default web browser. If a section
|
||||
keyword is given, the browser opens directly at the matching anchor
|
||||
(resolved via docs/html/sitemap.json). Browser detection queries the
|
||||
system's x-scheme-handler/https MIME entry (via xdg-mime) to find the
|
||||
real browser binary, then falls back through known browser binaries
|
||||
(firefox, chromium, vivaldi, etc.), and finally xdg-open as a last
|
||||
resort. Set $fish_help_browser or $BROWSER to override.</p>
|
||||
<h2 data-number="15.5" id="as-a-wiki">As a wiki</h2>
|
||||
<p>The generated Markdown wiki lives in docs/wiki/. index.md provides
|
||||
the project overview and a full table of contents. Each section page has
|
||||
a navigation bar at the top linking to every other section.</p>
|
||||
<p>The wiki is auto-generated from this file by the CI pipeline on every
|
||||
push to main that changes docs/fish-config.md.</p>
|
||||
<h2 data-number="15.6" id="jumping-to-a-section">Jumping to a
|
||||
section</h2>
|
||||
<pre><code>help config keybindings
|
||||
help config abbreviations
|
||||
help config pkg
|
||||
help config logs
|
||||
help config fish-deps</code></pre>
|
||||
<p>The keyword is matched case-insensitively against section
|
||||
headings.</p>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,503 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" lang="" xml:lang="">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="generator" content="pandoc" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" />
|
||||
<meta name="author" content="Rootiest" />
|
||||
<title>SYNOPSIS</title>
|
||||
<style>
|
||||
div.sitenav { display: flex; flex-direction: row; flex-wrap: wrap; }
|
||||
span.navlink { flex: 1; }
|
||||
span.navlink-label { display: inline-block; min-width: 4em; }
|
||||
html {
|
||||
color: #1a1a1a;
|
||||
background-color: #fdfdfd;
|
||||
}
|
||||
body {
|
||||
margin: 0 auto;
|
||||
max-width: 36em;
|
||||
padding-left: 50px;
|
||||
padding-right: 50px;
|
||||
padding-top: 50px;
|
||||
padding-bottom: 50px;
|
||||
hyphens: auto;
|
||||
overflow-wrap: break-word;
|
||||
text-rendering: optimizeLegibility;
|
||||
font-kerning: normal;
|
||||
}
|
||||
@media (max-width: 600px) {
|
||||
body {
|
||||
font-size: 0.9em;
|
||||
padding: 12px;
|
||||
}
|
||||
h1 {
|
||||
font-size: 1.8em;
|
||||
}
|
||||
}
|
||||
@media print {
|
||||
html {
|
||||
background-color: white;
|
||||
}
|
||||
body {
|
||||
background-color: transparent;
|
||||
color: black;
|
||||
font-size: 12pt;
|
||||
}
|
||||
p, h2, h3 {
|
||||
orphans: 3;
|
||||
widows: 3;
|
||||
}
|
||||
h2, h3, h4 {
|
||||
page-break-after: avoid;
|
||||
}
|
||||
}
|
||||
p {
|
||||
margin: 1em 0;
|
||||
}
|
||||
a {
|
||||
color: #1a1a1a;
|
||||
}
|
||||
a:visited {
|
||||
color: #1a1a1a;
|
||||
}
|
||||
img {
|
||||
max-width: 100%;
|
||||
}
|
||||
h1, h2, h3, h4, h5, h6 {
|
||||
margin-top: 1.4em;
|
||||
}
|
||||
h5, h6 {
|
||||
font-size: 1em;
|
||||
font-style: italic;
|
||||
}
|
||||
h6 {
|
||||
font-weight: normal;
|
||||
}
|
||||
ol, ul {
|
||||
padding-left: 1.7em;
|
||||
margin-top: 1em;
|
||||
}
|
||||
li > ol, li > ul {
|
||||
margin-top: 0;
|
||||
}
|
||||
blockquote {
|
||||
margin: 1em 0 1em 1.7em;
|
||||
padding-left: 1em;
|
||||
border-left: 2px solid #e6e6e6;
|
||||
color: #606060;
|
||||
}
|
||||
code {
|
||||
font-family: Menlo, Monaco, Consolas, 'Lucida Console', monospace;
|
||||
font-size: 85%;
|
||||
margin: 0;
|
||||
hyphens: manual;
|
||||
}
|
||||
pre {
|
||||
margin: 1em 0;
|
||||
overflow: auto;
|
||||
}
|
||||
pre code {
|
||||
padding: 0;
|
||||
overflow: visible;
|
||||
overflow-wrap: normal;
|
||||
}
|
||||
.sourceCode {
|
||||
background-color: transparent;
|
||||
overflow: visible;
|
||||
}
|
||||
hr {
|
||||
background-color: #1a1a1a;
|
||||
border: none;
|
||||
height: 1px;
|
||||
margin: 1em 0;
|
||||
}
|
||||
table {
|
||||
margin: 1em 0;
|
||||
border-collapse: collapse;
|
||||
width: 100%;
|
||||
overflow-x: auto;
|
||||
display: block;
|
||||
font-variant-numeric: lining-nums tabular-nums;
|
||||
}
|
||||
table caption {
|
||||
margin-bottom: 0.75em;
|
||||
}
|
||||
tbody {
|
||||
margin-top: 0.5em;
|
||||
border-top: 1px solid #1a1a1a;
|
||||
border-bottom: 1px solid #1a1a1a;
|
||||
}
|
||||
th {
|
||||
border-top: 1px solid #1a1a1a;
|
||||
padding: 0.25em 0.5em 0.25em 0.5em;
|
||||
}
|
||||
td {
|
||||
padding: 0.125em 0.5em 0.25em 0.5em;
|
||||
}
|
||||
header {
|
||||
margin-bottom: 4em;
|
||||
text-align: center;
|
||||
}
|
||||
#TOC li {
|
||||
list-style: none;
|
||||
}
|
||||
#TOC ul {
|
||||
padding-left: 1.3em;
|
||||
}
|
||||
#TOC > ul {
|
||||
padding-left: 0;
|
||||
}
|
||||
#TOC a:not(:hover) {
|
||||
text-decoration: none;
|
||||
}
|
||||
code{white-space: pre-wrap;}
|
||||
span.smallcaps{font-variant: small-caps;}
|
||||
div.columns{display: flex; gap: min(4vw, 1.5em);}
|
||||
div.column{flex: auto; overflow-x: auto;}
|
||||
div.hanging-indent{margin-left: 1.5em; text-indent: -1.5em;}
|
||||
/* The extra [class] is a hack that increases specificity enough to
|
||||
override a similar rule in reveal.js */
|
||||
ul.task-list[class]{list-style: none;}
|
||||
ul.task-list li input[type="checkbox"] {
|
||||
font-size: inherit;
|
||||
width: 0.8em;
|
||||
margin: 0 0.8em 0.2em -1.6em;
|
||||
vertical-align: middle;
|
||||
}
|
||||
.display.math{display: block; text-align: center; margin: 0.5rem auto;}
|
||||
</style>
|
||||
<style>
|
||||
/* ── Catppuccin Latte (light) / Mocha (dark) ─────────────────── */
|
||||
:root {
|
||||
color-scheme: light dark;
|
||||
--bg: #eff1f5;
|
||||
--surface: #e6e9ef;
|
||||
--overlay: #ccd0da;
|
||||
--text: #4c4f69;
|
||||
--sub1: #6c6f85;
|
||||
--sub0: #8c8fa1;
|
||||
--blue: #1e66f5;
|
||||
--lavender: #7287fd;
|
||||
--sapphire: #209fb5;
|
||||
--green: #40a02b;
|
||||
--yellow: #df8e1d;
|
||||
--peach: #fe640b;
|
||||
--mauve: #8839ef;
|
||||
--code-bg: #dce0e8;
|
||||
--border: #bcc0cc;
|
||||
--glow1: rgba(30, 102, 245, 0.05);
|
||||
--glow2: rgba(136, 57, 239, 0.04);
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
:root {
|
||||
--bg: #1e1e2e;
|
||||
--surface: #313244;
|
||||
--overlay: #45475a;
|
||||
--text: #cdd6f4;
|
||||
--sub1: #bac2de;
|
||||
--sub0: #a6adc8;
|
||||
--blue: #89b4fa;
|
||||
--lavender: #b4befe;
|
||||
--sapphire: #74c7ec;
|
||||
--green: #a6e3a1;
|
||||
--yellow: #f9e2af;
|
||||
--peach: #fab387;
|
||||
--mauve: #cba6f7;
|
||||
--code-bg: #181825;
|
||||
--border: #45475a;
|
||||
--glow1: rgba(137, 180, 250, 0.06);
|
||||
--glow2: rgba(203, 166, 247, 0.05);
|
||||
}
|
||||
}
|
||||
|
||||
*, *::before, *::after { box-sizing: border-box; }
|
||||
|
||||
html {
|
||||
background-color: var(--bg);
|
||||
background-image:
|
||||
radial-gradient(ellipse 55% 40% at 10% 5%, var(--glow1) 0%, transparent 100%),
|
||||
radial-gradient(ellipse 45% 45% at 90% 95%, var(--glow2) 0%, transparent 100%);
|
||||
min-height: 100%;
|
||||
}
|
||||
|
||||
body {
|
||||
color: var(--text);
|
||||
font-family: system-ui, -apple-system, "Segoe UI", Helvetica, sans-serif;
|
||||
font-size: 16px;
|
||||
line-height: 1.75;
|
||||
max-width: 880px;
|
||||
margin: 0 auto;
|
||||
padding: 2rem 2.5rem 5rem;
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
/* ── Links ─────────────────────────────────────────────────── */
|
||||
a { color: var(--blue); text-decoration: none; }
|
||||
a:hover { color: var(--lavender); text-decoration: underline; }
|
||||
a:visited { color: var(--lavender); }
|
||||
|
||||
/* ── Headings ──────────────────────────────────────────────── */
|
||||
h1, h2, h3, h4, h5, h6 {
|
||||
font-family: "JetBrains Mono", "Fira Code", ui-monospace, monospace;
|
||||
color: var(--lavender);
|
||||
line-height: 1.3;
|
||||
margin-top: 2em;
|
||||
margin-bottom: 0.5em;
|
||||
}
|
||||
h1 {
|
||||
font-size: 1.9rem;
|
||||
color: var(--text);
|
||||
border-bottom: 1px solid var(--border);
|
||||
padding-bottom: 0.4em;
|
||||
margin-top: 1.2em;
|
||||
}
|
||||
h2 {
|
||||
font-size: 1.35rem;
|
||||
border-bottom: 1px solid var(--border);
|
||||
padding-bottom: 0.2em;
|
||||
}
|
||||
h3 { font-size: 1.1rem; color: var(--sapphire); }
|
||||
h4 { font-size: 0.95rem; color: var(--sub1); }
|
||||
|
||||
p { margin: 0.8em 0; }
|
||||
|
||||
/* ── Title block (pandoc-generated cover) ──────────────────── */
|
||||
#title-block-header {
|
||||
text-align: center;
|
||||
padding: 2.5rem 0 2rem;
|
||||
margin-bottom: 1.5rem;
|
||||
border-bottom: 1px solid var(--border);
|
||||
}
|
||||
#title-block-header .title {
|
||||
font-family: "JetBrains Mono", "Fira Code", ui-monospace, monospace;
|
||||
font-size: 2.6rem;
|
||||
letter-spacing: 0.12em;
|
||||
color: var(--lavender);
|
||||
border: none;
|
||||
margin: 0 0 0.75rem;
|
||||
}
|
||||
#title-block-header .author,
|
||||
#title-block-header .date {
|
||||
color: var(--sub0);
|
||||
font-size: 0.875rem;
|
||||
margin: 0.2rem 0;
|
||||
}
|
||||
|
||||
/* ── Inline code ───────────────────────────────────────────── */
|
||||
code {
|
||||
font-family: "JetBrains Mono", "Fira Code", ui-monospace, monospace;
|
||||
background: var(--code-bg);
|
||||
color: var(--peach);
|
||||
padding: 0.15em 0.4em;
|
||||
border-radius: 4px;
|
||||
font-size: 0.875em;
|
||||
}
|
||||
|
||||
/* ── Code blocks ───────────────────────────────────────────── */
|
||||
pre {
|
||||
background: var(--code-bg);
|
||||
border: 1px solid var(--border);
|
||||
border-left: 3px solid var(--sapphire);
|
||||
border-radius: 0 8px 8px 0;
|
||||
padding: 1.1em 1.4em;
|
||||
overflow-x: auto;
|
||||
line-height: 1.55;
|
||||
margin: 1.2em 0;
|
||||
}
|
||||
pre code {
|
||||
background: none;
|
||||
color: var(--text);
|
||||
padding: 0;
|
||||
font-size: 0.88em;
|
||||
}
|
||||
|
||||
/* ── Blockquotes ───────────────────────────────────────────── */
|
||||
blockquote {
|
||||
border-left: 3px solid var(--yellow);
|
||||
margin: 1.5em 0;
|
||||
padding: 0.75em 1.25em;
|
||||
background: var(--surface);
|
||||
color: var(--sub1);
|
||||
border-radius: 0 6px 6px 0;
|
||||
}
|
||||
blockquote p { margin: 0.3em 0; }
|
||||
|
||||
/* ── Tables ────────────────────────────────────────────────── */
|
||||
table {
|
||||
border-collapse: collapse;
|
||||
width: 100%;
|
||||
margin: 1.4em 0;
|
||||
font-size: 0.93em;
|
||||
}
|
||||
th, td {
|
||||
border: 1px solid var(--border);
|
||||
padding: 0.55em 0.9em;
|
||||
text-align: left;
|
||||
}
|
||||
th {
|
||||
background: var(--surface);
|
||||
color: var(--lavender);
|
||||
font-weight: 600;
|
||||
font-family: "JetBrains Mono", "Fira Code", ui-monospace, monospace;
|
||||
font-size: 0.82em;
|
||||
letter-spacing: 0.06em;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
tr:nth-child(even) { background: var(--surface); }
|
||||
tr:hover { background: var(--overlay); }
|
||||
|
||||
/* ── HR ────────────────────────────────────────────────────── */
|
||||
hr { border: none; border-top: 1px solid var(--border); margin: 2.5em 0; }
|
||||
|
||||
/* ── Lists ─────────────────────────────────────────────────── */
|
||||
ul, ol { padding-left: 1.6em; }
|
||||
li { margin: 0.35em 0; }
|
||||
|
||||
/* ── Chunk navigation bar (prev / up / next) ───────────────── */
|
||||
nav:not(#TOC):not([role="doc-toc"]) {
|
||||
background: var(--surface);
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 8px;
|
||||
margin: 1.5em 0;
|
||||
font-size: 0.875em;
|
||||
overflow: hidden;
|
||||
}
|
||||
nav:not(#TOC):not([role="doc-toc"]) p {
|
||||
margin: 0;
|
||||
padding: 0.65em 1.2em;
|
||||
display: flex;
|
||||
gap: 0.4em 1.75em;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
}
|
||||
/* JS wraps each "Label: <a>" pair in .nav-item so they flex as a unit */
|
||||
.nav-item {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 0.3em;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.nav-item a { color: var(--blue); }
|
||||
.nav-item a:hover { color: var(--lavender); }
|
||||
|
||||
/* ── Table of contents panel ───────────────────────────────── */
|
||||
nav#TOC, nav[role="doc-toc"] {
|
||||
display: block;
|
||||
background: var(--surface);
|
||||
border: 1px solid var(--border);
|
||||
border-left: 3px solid var(--lavender);
|
||||
border-radius: 0 8px 8px 0;
|
||||
padding: 1.2em 1.5em;
|
||||
margin: 1.5em 0;
|
||||
}
|
||||
nav#TOC > h2,
|
||||
nav[role="doc-toc"] > h2 {
|
||||
font-size: 0.7rem;
|
||||
letter-spacing: 0.14em;
|
||||
text-transform: uppercase;
|
||||
color: var(--sub0);
|
||||
border: none;
|
||||
margin: 0 0 0.9em;
|
||||
padding: 0;
|
||||
}
|
||||
nav#TOC ul, nav[role="doc-toc"] ul {
|
||||
list-style: none;
|
||||
padding-left: 1em;
|
||||
margin: 0.25em 0;
|
||||
}
|
||||
nav#TOC > ul, nav[role="doc-toc"] > ul { padding-left: 0; }
|
||||
nav#TOC li, nav[role="doc-toc"] li {
|
||||
margin: 0.3em 0;
|
||||
padding-left: 0.75em;
|
||||
border-left: 1px solid transparent;
|
||||
transition: border-color 0.12s;
|
||||
}
|
||||
nav#TOC li:hover, nav[role="doc-toc"] li:hover {
|
||||
border-left-color: var(--lavender);
|
||||
}
|
||||
nav#TOC a, nav[role="doc-toc"] a {
|
||||
color: var(--sub1);
|
||||
font-size: 0.9em;
|
||||
}
|
||||
nav#TOC a:hover, nav[role="doc-toc"] a:hover {
|
||||
color: var(--lavender);
|
||||
text-decoration: none;
|
||||
}
|
||||
</style>
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
/* ── Hide ToC on every page except index.html ───────────── */
|
||||
var path = location.pathname;
|
||||
var onIndex = path === '/' || path === '' || /\/index\.html(\?.*)?$/.test(path);
|
||||
if (!onIndex) {
|
||||
var toc = document.getElementById('TOC') ||
|
||||
document.querySelector('[role="doc-toc"]');
|
||||
if (toc) toc.remove();
|
||||
}
|
||||
|
||||
/* ── Wrap each "Label: <a>" pair in a .nav-item span ───────
|
||||
Pandoc emits label text nodes and anchors as siblings;
|
||||
flex sees them as separate items, causing labels to split
|
||||
from their links when wrapping. Grouping them in a span
|
||||
keeps each label+link as a single flex unit. */
|
||||
document.querySelectorAll('nav:not(#TOC):not([role="doc-toc"])').forEach(function (nav) {
|
||||
var p = nav.querySelector('p');
|
||||
if (!p) return;
|
||||
var children = Array.from(p.childNodes);
|
||||
var pairs = [];
|
||||
for (var i = 0; i + 1 < children.length; i++) {
|
||||
var cur = children[i];
|
||||
var nxt = children[i + 1];
|
||||
if (cur.nodeType === Node.TEXT_NODE &&
|
||||
/[A-Z][a-z]*:\s*/.test(cur.textContent) &&
|
||||
nxt.nodeType === Node.ELEMENT_NODE &&
|
||||
nxt.tagName === 'A') {
|
||||
pairs.push([cur, nxt]);
|
||||
i++; // skip the anchor on the next iteration
|
||||
}
|
||||
}
|
||||
pairs.forEach(function (pair) {
|
||||
var span = document.createElement('span');
|
||||
span.className = 'nav-item';
|
||||
p.insertBefore(span, pair[0]);
|
||||
span.appendChild(pair[0]);
|
||||
span.appendChild(pair[1]);
|
||||
});
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<nav id="sitenav">
|
||||
<div class="sitenav">
|
||||
<span class="navlink">
|
||||
<span class="navlink-label">Up:</span> <a href="index.html" accesskey="u" rel="up">FISH-CONFIG</a>
|
||||
</span>
|
||||
<span class="navlink">
|
||||
<span class="navlink-label">Top:</span> <a href="index.html" accesskey="t" rel="top">FISH-CONFIG</a>
|
||||
</span>
|
||||
</div>
|
||||
<div class="sitenav">
|
||||
<span class="navlink">
|
||||
<span class="navlink-label">Next:</span> <a href="3-description.html" accesskey="n" rel="next">DESCRIPTION</a>
|
||||
</span>
|
||||
<span class="navlink">
|
||||
<span class="navlink-label">Previous:</span> <a href="1-name.html" accesskey="p" rel="previous">NAME</a>
|
||||
</span>
|
||||
</div>
|
||||
</nav>
|
||||
<h1 data-number="2" id="synopsis">SYNOPSIS</h1>
|
||||
<pre><code>help config [SECTION]</code></pre>
|
||||
<p>Open this manual in the best available pager. Optionally jump to a
|
||||
section by keyword:</p>
|
||||
<pre><code>help config keybindings
|
||||
help config pkg
|
||||
help config abbreviations
|
||||
help config logs</code></pre>
|
||||
<p>The <code>help config</code> syntax integrates with fish's built-in
|
||||
help command. The underlying <code>config-help</code> function is also
|
||||
available directly.</p>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,538 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" lang="" xml:lang="">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="generator" content="pandoc" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" />
|
||||
<meta name="author" content="Rootiest" />
|
||||
<title>DESCRIPTION</title>
|
||||
<style>
|
||||
div.sitenav { display: flex; flex-direction: row; flex-wrap: wrap; }
|
||||
span.navlink { flex: 1; }
|
||||
span.navlink-label { display: inline-block; min-width: 4em; }
|
||||
html {
|
||||
color: #1a1a1a;
|
||||
background-color: #fdfdfd;
|
||||
}
|
||||
body {
|
||||
margin: 0 auto;
|
||||
max-width: 36em;
|
||||
padding-left: 50px;
|
||||
padding-right: 50px;
|
||||
padding-top: 50px;
|
||||
padding-bottom: 50px;
|
||||
hyphens: auto;
|
||||
overflow-wrap: break-word;
|
||||
text-rendering: optimizeLegibility;
|
||||
font-kerning: normal;
|
||||
}
|
||||
@media (max-width: 600px) {
|
||||
body {
|
||||
font-size: 0.9em;
|
||||
padding: 12px;
|
||||
}
|
||||
h1 {
|
||||
font-size: 1.8em;
|
||||
}
|
||||
}
|
||||
@media print {
|
||||
html {
|
||||
background-color: white;
|
||||
}
|
||||
body {
|
||||
background-color: transparent;
|
||||
color: black;
|
||||
font-size: 12pt;
|
||||
}
|
||||
p, h2, h3 {
|
||||
orphans: 3;
|
||||
widows: 3;
|
||||
}
|
||||
h2, h3, h4 {
|
||||
page-break-after: avoid;
|
||||
}
|
||||
}
|
||||
p {
|
||||
margin: 1em 0;
|
||||
}
|
||||
a {
|
||||
color: #1a1a1a;
|
||||
}
|
||||
a:visited {
|
||||
color: #1a1a1a;
|
||||
}
|
||||
img {
|
||||
max-width: 100%;
|
||||
}
|
||||
h1, h2, h3, h4, h5, h6 {
|
||||
margin-top: 1.4em;
|
||||
}
|
||||
h5, h6 {
|
||||
font-size: 1em;
|
||||
font-style: italic;
|
||||
}
|
||||
h6 {
|
||||
font-weight: normal;
|
||||
}
|
||||
ol, ul {
|
||||
padding-left: 1.7em;
|
||||
margin-top: 1em;
|
||||
}
|
||||
li > ol, li > ul {
|
||||
margin-top: 0;
|
||||
}
|
||||
blockquote {
|
||||
margin: 1em 0 1em 1.7em;
|
||||
padding-left: 1em;
|
||||
border-left: 2px solid #e6e6e6;
|
||||
color: #606060;
|
||||
}
|
||||
code {
|
||||
font-family: Menlo, Monaco, Consolas, 'Lucida Console', monospace;
|
||||
font-size: 85%;
|
||||
margin: 0;
|
||||
hyphens: manual;
|
||||
}
|
||||
pre {
|
||||
margin: 1em 0;
|
||||
overflow: auto;
|
||||
}
|
||||
pre code {
|
||||
padding: 0;
|
||||
overflow: visible;
|
||||
overflow-wrap: normal;
|
||||
}
|
||||
.sourceCode {
|
||||
background-color: transparent;
|
||||
overflow: visible;
|
||||
}
|
||||
hr {
|
||||
background-color: #1a1a1a;
|
||||
border: none;
|
||||
height: 1px;
|
||||
margin: 1em 0;
|
||||
}
|
||||
table {
|
||||
margin: 1em 0;
|
||||
border-collapse: collapse;
|
||||
width: 100%;
|
||||
overflow-x: auto;
|
||||
display: block;
|
||||
font-variant-numeric: lining-nums tabular-nums;
|
||||
}
|
||||
table caption {
|
||||
margin-bottom: 0.75em;
|
||||
}
|
||||
tbody {
|
||||
margin-top: 0.5em;
|
||||
border-top: 1px solid #1a1a1a;
|
||||
border-bottom: 1px solid #1a1a1a;
|
||||
}
|
||||
th {
|
||||
border-top: 1px solid #1a1a1a;
|
||||
padding: 0.25em 0.5em 0.25em 0.5em;
|
||||
}
|
||||
td {
|
||||
padding: 0.125em 0.5em 0.25em 0.5em;
|
||||
}
|
||||
header {
|
||||
margin-bottom: 4em;
|
||||
text-align: center;
|
||||
}
|
||||
#TOC li {
|
||||
list-style: none;
|
||||
}
|
||||
#TOC ul {
|
||||
padding-left: 1.3em;
|
||||
}
|
||||
#TOC > ul {
|
||||
padding-left: 0;
|
||||
}
|
||||
#TOC a:not(:hover) {
|
||||
text-decoration: none;
|
||||
}
|
||||
code{white-space: pre-wrap;}
|
||||
span.smallcaps{font-variant: small-caps;}
|
||||
div.columns{display: flex; gap: min(4vw, 1.5em);}
|
||||
div.column{flex: auto; overflow-x: auto;}
|
||||
div.hanging-indent{margin-left: 1.5em; text-indent: -1.5em;}
|
||||
/* The extra [class] is a hack that increases specificity enough to
|
||||
override a similar rule in reveal.js */
|
||||
ul.task-list[class]{list-style: none;}
|
||||
ul.task-list li input[type="checkbox"] {
|
||||
font-size: inherit;
|
||||
width: 0.8em;
|
||||
margin: 0 0.8em 0.2em -1.6em;
|
||||
vertical-align: middle;
|
||||
}
|
||||
.display.math{display: block; text-align: center; margin: 0.5rem auto;}
|
||||
</style>
|
||||
<style>
|
||||
/* ── Catppuccin Latte (light) / Mocha (dark) ─────────────────── */
|
||||
:root {
|
||||
color-scheme: light dark;
|
||||
--bg: #eff1f5;
|
||||
--surface: #e6e9ef;
|
||||
--overlay: #ccd0da;
|
||||
--text: #4c4f69;
|
||||
--sub1: #6c6f85;
|
||||
--sub0: #8c8fa1;
|
||||
--blue: #1e66f5;
|
||||
--lavender: #7287fd;
|
||||
--sapphire: #209fb5;
|
||||
--green: #40a02b;
|
||||
--yellow: #df8e1d;
|
||||
--peach: #fe640b;
|
||||
--mauve: #8839ef;
|
||||
--code-bg: #dce0e8;
|
||||
--border: #bcc0cc;
|
||||
--glow1: rgba(30, 102, 245, 0.05);
|
||||
--glow2: rgba(136, 57, 239, 0.04);
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
:root {
|
||||
--bg: #1e1e2e;
|
||||
--surface: #313244;
|
||||
--overlay: #45475a;
|
||||
--text: #cdd6f4;
|
||||
--sub1: #bac2de;
|
||||
--sub0: #a6adc8;
|
||||
--blue: #89b4fa;
|
||||
--lavender: #b4befe;
|
||||
--sapphire: #74c7ec;
|
||||
--green: #a6e3a1;
|
||||
--yellow: #f9e2af;
|
||||
--peach: #fab387;
|
||||
--mauve: #cba6f7;
|
||||
--code-bg: #181825;
|
||||
--border: #45475a;
|
||||
--glow1: rgba(137, 180, 250, 0.06);
|
||||
--glow2: rgba(203, 166, 247, 0.05);
|
||||
}
|
||||
}
|
||||
|
||||
*, *::before, *::after { box-sizing: border-box; }
|
||||
|
||||
html {
|
||||
background-color: var(--bg);
|
||||
background-image:
|
||||
radial-gradient(ellipse 55% 40% at 10% 5%, var(--glow1) 0%, transparent 100%),
|
||||
radial-gradient(ellipse 45% 45% at 90% 95%, var(--glow2) 0%, transparent 100%);
|
||||
min-height: 100%;
|
||||
}
|
||||
|
||||
body {
|
||||
color: var(--text);
|
||||
font-family: system-ui, -apple-system, "Segoe UI", Helvetica, sans-serif;
|
||||
font-size: 16px;
|
||||
line-height: 1.75;
|
||||
max-width: 880px;
|
||||
margin: 0 auto;
|
||||
padding: 2rem 2.5rem 5rem;
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
/* ── Links ─────────────────────────────────────────────────── */
|
||||
a { color: var(--blue); text-decoration: none; }
|
||||
a:hover { color: var(--lavender); text-decoration: underline; }
|
||||
a:visited { color: var(--lavender); }
|
||||
|
||||
/* ── Headings ──────────────────────────────────────────────── */
|
||||
h1, h2, h3, h4, h5, h6 {
|
||||
font-family: "JetBrains Mono", "Fira Code", ui-monospace, monospace;
|
||||
color: var(--lavender);
|
||||
line-height: 1.3;
|
||||
margin-top: 2em;
|
||||
margin-bottom: 0.5em;
|
||||
}
|
||||
h1 {
|
||||
font-size: 1.9rem;
|
||||
color: var(--text);
|
||||
border-bottom: 1px solid var(--border);
|
||||
padding-bottom: 0.4em;
|
||||
margin-top: 1.2em;
|
||||
}
|
||||
h2 {
|
||||
font-size: 1.35rem;
|
||||
border-bottom: 1px solid var(--border);
|
||||
padding-bottom: 0.2em;
|
||||
}
|
||||
h3 { font-size: 1.1rem; color: var(--sapphire); }
|
||||
h4 { font-size: 0.95rem; color: var(--sub1); }
|
||||
|
||||
p { margin: 0.8em 0; }
|
||||
|
||||
/* ── Title block (pandoc-generated cover) ──────────────────── */
|
||||
#title-block-header {
|
||||
text-align: center;
|
||||
padding: 2.5rem 0 2rem;
|
||||
margin-bottom: 1.5rem;
|
||||
border-bottom: 1px solid var(--border);
|
||||
}
|
||||
#title-block-header .title {
|
||||
font-family: "JetBrains Mono", "Fira Code", ui-monospace, monospace;
|
||||
font-size: 2.6rem;
|
||||
letter-spacing: 0.12em;
|
||||
color: var(--lavender);
|
||||
border: none;
|
||||
margin: 0 0 0.75rem;
|
||||
}
|
||||
#title-block-header .author,
|
||||
#title-block-header .date {
|
||||
color: var(--sub0);
|
||||
font-size: 0.875rem;
|
||||
margin: 0.2rem 0;
|
||||
}
|
||||
|
||||
/* ── Inline code ───────────────────────────────────────────── */
|
||||
code {
|
||||
font-family: "JetBrains Mono", "Fira Code", ui-monospace, monospace;
|
||||
background: var(--code-bg);
|
||||
color: var(--peach);
|
||||
padding: 0.15em 0.4em;
|
||||
border-radius: 4px;
|
||||
font-size: 0.875em;
|
||||
}
|
||||
|
||||
/* ── Code blocks ───────────────────────────────────────────── */
|
||||
pre {
|
||||
background: var(--code-bg);
|
||||
border: 1px solid var(--border);
|
||||
border-left: 3px solid var(--sapphire);
|
||||
border-radius: 0 8px 8px 0;
|
||||
padding: 1.1em 1.4em;
|
||||
overflow-x: auto;
|
||||
line-height: 1.55;
|
||||
margin: 1.2em 0;
|
||||
}
|
||||
pre code {
|
||||
background: none;
|
||||
color: var(--text);
|
||||
padding: 0;
|
||||
font-size: 0.88em;
|
||||
}
|
||||
|
||||
/* ── Blockquotes ───────────────────────────────────────────── */
|
||||
blockquote {
|
||||
border-left: 3px solid var(--yellow);
|
||||
margin: 1.5em 0;
|
||||
padding: 0.75em 1.25em;
|
||||
background: var(--surface);
|
||||
color: var(--sub1);
|
||||
border-radius: 0 6px 6px 0;
|
||||
}
|
||||
blockquote p { margin: 0.3em 0; }
|
||||
|
||||
/* ── Tables ────────────────────────────────────────────────── */
|
||||
table {
|
||||
border-collapse: collapse;
|
||||
width: 100%;
|
||||
margin: 1.4em 0;
|
||||
font-size: 0.93em;
|
||||
}
|
||||
th, td {
|
||||
border: 1px solid var(--border);
|
||||
padding: 0.55em 0.9em;
|
||||
text-align: left;
|
||||
}
|
||||
th {
|
||||
background: var(--surface);
|
||||
color: var(--lavender);
|
||||
font-weight: 600;
|
||||
font-family: "JetBrains Mono", "Fira Code", ui-monospace, monospace;
|
||||
font-size: 0.82em;
|
||||
letter-spacing: 0.06em;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
tr:nth-child(even) { background: var(--surface); }
|
||||
tr:hover { background: var(--overlay); }
|
||||
|
||||
/* ── HR ────────────────────────────────────────────────────── */
|
||||
hr { border: none; border-top: 1px solid var(--border); margin: 2.5em 0; }
|
||||
|
||||
/* ── Lists ─────────────────────────────────────────────────── */
|
||||
ul, ol { padding-left: 1.6em; }
|
||||
li { margin: 0.35em 0; }
|
||||
|
||||
/* ── Chunk navigation bar (prev / up / next) ───────────────── */
|
||||
nav:not(#TOC):not([role="doc-toc"]) {
|
||||
background: var(--surface);
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 8px;
|
||||
margin: 1.5em 0;
|
||||
font-size: 0.875em;
|
||||
overflow: hidden;
|
||||
}
|
||||
nav:not(#TOC):not([role="doc-toc"]) p {
|
||||
margin: 0;
|
||||
padding: 0.65em 1.2em;
|
||||
display: flex;
|
||||
gap: 0.4em 1.75em;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
}
|
||||
/* JS wraps each "Label: <a>" pair in .nav-item so they flex as a unit */
|
||||
.nav-item {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 0.3em;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.nav-item a { color: var(--blue); }
|
||||
.nav-item a:hover { color: var(--lavender); }
|
||||
|
||||
/* ── Table of contents panel ───────────────────────────────── */
|
||||
nav#TOC, nav[role="doc-toc"] {
|
||||
display: block;
|
||||
background: var(--surface);
|
||||
border: 1px solid var(--border);
|
||||
border-left: 3px solid var(--lavender);
|
||||
border-radius: 0 8px 8px 0;
|
||||
padding: 1.2em 1.5em;
|
||||
margin: 1.5em 0;
|
||||
}
|
||||
nav#TOC > h2,
|
||||
nav[role="doc-toc"] > h2 {
|
||||
font-size: 0.7rem;
|
||||
letter-spacing: 0.14em;
|
||||
text-transform: uppercase;
|
||||
color: var(--sub0);
|
||||
border: none;
|
||||
margin: 0 0 0.9em;
|
||||
padding: 0;
|
||||
}
|
||||
nav#TOC ul, nav[role="doc-toc"] ul {
|
||||
list-style: none;
|
||||
padding-left: 1em;
|
||||
margin: 0.25em 0;
|
||||
}
|
||||
nav#TOC > ul, nav[role="doc-toc"] > ul { padding-left: 0; }
|
||||
nav#TOC li, nav[role="doc-toc"] li {
|
||||
margin: 0.3em 0;
|
||||
padding-left: 0.75em;
|
||||
border-left: 1px solid transparent;
|
||||
transition: border-color 0.12s;
|
||||
}
|
||||
nav#TOC li:hover, nav[role="doc-toc"] li:hover {
|
||||
border-left-color: var(--lavender);
|
||||
}
|
||||
nav#TOC a, nav[role="doc-toc"] a {
|
||||
color: var(--sub1);
|
||||
font-size: 0.9em;
|
||||
}
|
||||
nav#TOC a:hover, nav[role="doc-toc"] a:hover {
|
||||
color: var(--lavender);
|
||||
text-decoration: none;
|
||||
}
|
||||
</style>
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
/* ── Hide ToC on every page except index.html ───────────── */
|
||||
var path = location.pathname;
|
||||
var onIndex = path === '/' || path === '' || /\/index\.html(\?.*)?$/.test(path);
|
||||
if (!onIndex) {
|
||||
var toc = document.getElementById('TOC') ||
|
||||
document.querySelector('[role="doc-toc"]');
|
||||
if (toc) toc.remove();
|
||||
}
|
||||
|
||||
/* ── Wrap each "Label: <a>" pair in a .nav-item span ───────
|
||||
Pandoc emits label text nodes and anchors as siblings;
|
||||
flex sees them as separate items, causing labels to split
|
||||
from their links when wrapping. Grouping them in a span
|
||||
keeps each label+link as a single flex unit. */
|
||||
document.querySelectorAll('nav:not(#TOC):not([role="doc-toc"])').forEach(function (nav) {
|
||||
var p = nav.querySelector('p');
|
||||
if (!p) return;
|
||||
var children = Array.from(p.childNodes);
|
||||
var pairs = [];
|
||||
for (var i = 0; i + 1 < children.length; i++) {
|
||||
var cur = children[i];
|
||||
var nxt = children[i + 1];
|
||||
if (cur.nodeType === Node.TEXT_NODE &&
|
||||
/[A-Z][a-z]*:\s*/.test(cur.textContent) &&
|
||||
nxt.nodeType === Node.ELEMENT_NODE &&
|
||||
nxt.tagName === 'A') {
|
||||
pairs.push([cur, nxt]);
|
||||
i++; // skip the anchor on the next iteration
|
||||
}
|
||||
}
|
||||
pairs.forEach(function (pair) {
|
||||
var span = document.createElement('span');
|
||||
span.className = 'nav-item';
|
||||
p.insertBefore(span, pair[0]);
|
||||
span.appendChild(pair[0]);
|
||||
span.appendChild(pair[1]);
|
||||
});
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<nav id="sitenav">
|
||||
<div class="sitenav">
|
||||
<span class="navlink">
|
||||
<span class="navlink-label">Up:</span> <a href="index.html" accesskey="u" rel="up">FISH-CONFIG</a>
|
||||
</span>
|
||||
<span class="navlink">
|
||||
<span class="navlink-label">Top:</span> <a href="index.html" accesskey="t" rel="top">FISH-CONFIG</a>
|
||||
</span>
|
||||
</div>
|
||||
<div class="sitenav">
|
||||
<span class="navlink">
|
||||
<span class="navlink-label">Next:</span> <a href="4-table-of-contents.html" accesskey="n" rel="next">TABLE OF CONTENTS</a>
|
||||
</span>
|
||||
<span class="navlink">
|
||||
<span class="navlink-label">Previous:</span> <a href="2-synopsis.html" accesskey="p" rel="previous">SYNOPSIS</a>
|
||||
</span>
|
||||
</div>
|
||||
</nav>
|
||||
<h1 data-number="3" id="description">DESCRIPTION</h1>
|
||||
<p>A production-grade Fish shell configuration targeting Fish 4.x. It
|
||||
provides:</p>
|
||||
<ul>
|
||||
<li>Drop-in replacements for common Unix tools (ls, cat, rm, du, ping,
|
||||
less)</li>
|
||||
<li>Deep Kitty and WezTerm terminal integration: tab/window/pane
|
||||
management from the command line</li>
|
||||
<li>Scrollback history snapshots saved to ~/.terminal_history on session
|
||||
exit</li>
|
||||
<li>Automatic Python virtualenv activation on directory change</li>
|
||||
<li>Cross-platform package management via pkg and fish-deps</li>
|
||||
<li>AI session helpers for Claude Code and Antigravity</li>
|
||||
<li>Catppuccin Mocha color theme throughout</li>
|
||||
</ul>
|
||||
<p>The configuration is split across:</p>
|
||||
<pre><code>config.fish Main entry point; sets env vars and PATH
|
||||
conf.d/
|
||||
abbr.fish All abbreviations
|
||||
cheat.fish cheat.sh completions
|
||||
done.fish Desktop notifications for long commands
|
||||
first_run.fish One-time init: Fisher bootstrap, theme, welcome
|
||||
key_bindings.fish Custom key bindings and Vi mode
|
||||
paru-wrapper.fish Auto-generates ~/.local/bin/paru logging wrapper
|
||||
starship.fish fish_prompt with OSC 133 shell-integration markers
|
||||
tailscale.fish Tailscale CLI tab completions
|
||||
theme.fish Catppuccin syntax highlight colors
|
||||
sponge_privacy.fish Sponge privacy patterns; filters credentials from history
|
||||
tricks.fish PATH, bang-bang helpers, bat man pages, aliases
|
||||
wakatime.fish WakaTime shell hook
|
||||
yay-wrapper.fish Auto-generates ~/.local/bin/yay logging wrapper
|
||||
zoxide.fish Zoxide z/zi integration; overrides cd
|
||||
functions/ Custom functions, one per file, autoloaded
|
||||
completions/ Tab completion scripts
|
||||
integrations/
|
||||
fzf.fish FZF Catppuccin theme and key binding config
|
||||
scripts/
|
||||
clean_progress_log.py Renders script(1) typescripts (paru/yay progress
|
||||
animations) to clean static logs, preserving color
|
||||
docs/ Offline documentation and compiled man page
|
||||
fish-config.md Primary source manual (terminal-readable)
|
||||
fish-config.1 Compiled man page (auto-generated by CI)
|
||||
fish-config.index Section index for help config navigation
|
||||
html/ Chunked HTML docs (auto-generated by CI)
|
||||
wiki/ Markdown wiki (auto-generated by CI)</code></pre>
|
||||
<hr />
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,530 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" lang="" xml:lang="">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="generator" content="pandoc" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" />
|
||||
<meta name="author" content="Rootiest" />
|
||||
<title>TABLE OF CONTENTS</title>
|
||||
<style>
|
||||
div.sitenav { display: flex; flex-direction: row; flex-wrap: wrap; }
|
||||
span.navlink { flex: 1; }
|
||||
span.navlink-label { display: inline-block; min-width: 4em; }
|
||||
html {
|
||||
color: #1a1a1a;
|
||||
background-color: #fdfdfd;
|
||||
}
|
||||
body {
|
||||
margin: 0 auto;
|
||||
max-width: 36em;
|
||||
padding-left: 50px;
|
||||
padding-right: 50px;
|
||||
padding-top: 50px;
|
||||
padding-bottom: 50px;
|
||||
hyphens: auto;
|
||||
overflow-wrap: break-word;
|
||||
text-rendering: optimizeLegibility;
|
||||
font-kerning: normal;
|
||||
}
|
||||
@media (max-width: 600px) {
|
||||
body {
|
||||
font-size: 0.9em;
|
||||
padding: 12px;
|
||||
}
|
||||
h1 {
|
||||
font-size: 1.8em;
|
||||
}
|
||||
}
|
||||
@media print {
|
||||
html {
|
||||
background-color: white;
|
||||
}
|
||||
body {
|
||||
background-color: transparent;
|
||||
color: black;
|
||||
font-size: 12pt;
|
||||
}
|
||||
p, h2, h3 {
|
||||
orphans: 3;
|
||||
widows: 3;
|
||||
}
|
||||
h2, h3, h4 {
|
||||
page-break-after: avoid;
|
||||
}
|
||||
}
|
||||
p {
|
||||
margin: 1em 0;
|
||||
}
|
||||
a {
|
||||
color: #1a1a1a;
|
||||
}
|
||||
a:visited {
|
||||
color: #1a1a1a;
|
||||
}
|
||||
img {
|
||||
max-width: 100%;
|
||||
}
|
||||
h1, h2, h3, h4, h5, h6 {
|
||||
margin-top: 1.4em;
|
||||
}
|
||||
h5, h6 {
|
||||
font-size: 1em;
|
||||
font-style: italic;
|
||||
}
|
||||
h6 {
|
||||
font-weight: normal;
|
||||
}
|
||||
ol, ul {
|
||||
padding-left: 1.7em;
|
||||
margin-top: 1em;
|
||||
}
|
||||
li > ol, li > ul {
|
||||
margin-top: 0;
|
||||
}
|
||||
blockquote {
|
||||
margin: 1em 0 1em 1.7em;
|
||||
padding-left: 1em;
|
||||
border-left: 2px solid #e6e6e6;
|
||||
color: #606060;
|
||||
}
|
||||
code {
|
||||
font-family: Menlo, Monaco, Consolas, 'Lucida Console', monospace;
|
||||
font-size: 85%;
|
||||
margin: 0;
|
||||
hyphens: manual;
|
||||
}
|
||||
pre {
|
||||
margin: 1em 0;
|
||||
overflow: auto;
|
||||
}
|
||||
pre code {
|
||||
padding: 0;
|
||||
overflow: visible;
|
||||
overflow-wrap: normal;
|
||||
}
|
||||
.sourceCode {
|
||||
background-color: transparent;
|
||||
overflow: visible;
|
||||
}
|
||||
hr {
|
||||
background-color: #1a1a1a;
|
||||
border: none;
|
||||
height: 1px;
|
||||
margin: 1em 0;
|
||||
}
|
||||
table {
|
||||
margin: 1em 0;
|
||||
border-collapse: collapse;
|
||||
width: 100%;
|
||||
overflow-x: auto;
|
||||
display: block;
|
||||
font-variant-numeric: lining-nums tabular-nums;
|
||||
}
|
||||
table caption {
|
||||
margin-bottom: 0.75em;
|
||||
}
|
||||
tbody {
|
||||
margin-top: 0.5em;
|
||||
border-top: 1px solid #1a1a1a;
|
||||
border-bottom: 1px solid #1a1a1a;
|
||||
}
|
||||
th {
|
||||
border-top: 1px solid #1a1a1a;
|
||||
padding: 0.25em 0.5em 0.25em 0.5em;
|
||||
}
|
||||
td {
|
||||
padding: 0.125em 0.5em 0.25em 0.5em;
|
||||
}
|
||||
header {
|
||||
margin-bottom: 4em;
|
||||
text-align: center;
|
||||
}
|
||||
#TOC li {
|
||||
list-style: none;
|
||||
}
|
||||
#TOC ul {
|
||||
padding-left: 1.3em;
|
||||
}
|
||||
#TOC > ul {
|
||||
padding-left: 0;
|
||||
}
|
||||
#TOC a:not(:hover) {
|
||||
text-decoration: none;
|
||||
}
|
||||
code{white-space: pre-wrap;}
|
||||
span.smallcaps{font-variant: small-caps;}
|
||||
div.columns{display: flex; gap: min(4vw, 1.5em);}
|
||||
div.column{flex: auto; overflow-x: auto;}
|
||||
div.hanging-indent{margin-left: 1.5em; text-indent: -1.5em;}
|
||||
/* The extra [class] is a hack that increases specificity enough to
|
||||
override a similar rule in reveal.js */
|
||||
ul.task-list[class]{list-style: none;}
|
||||
ul.task-list li input[type="checkbox"] {
|
||||
font-size: inherit;
|
||||
width: 0.8em;
|
||||
margin: 0 0.8em 0.2em -1.6em;
|
||||
vertical-align: middle;
|
||||
}
|
||||
.display.math{display: block; text-align: center; margin: 0.5rem auto;}
|
||||
</style>
|
||||
<style>
|
||||
/* ── Catppuccin Latte (light) / Mocha (dark) ─────────────────── */
|
||||
:root {
|
||||
color-scheme: light dark;
|
||||
--bg: #eff1f5;
|
||||
--surface: #e6e9ef;
|
||||
--overlay: #ccd0da;
|
||||
--text: #4c4f69;
|
||||
--sub1: #6c6f85;
|
||||
--sub0: #8c8fa1;
|
||||
--blue: #1e66f5;
|
||||
--lavender: #7287fd;
|
||||
--sapphire: #209fb5;
|
||||
--green: #40a02b;
|
||||
--yellow: #df8e1d;
|
||||
--peach: #fe640b;
|
||||
--mauve: #8839ef;
|
||||
--code-bg: #dce0e8;
|
||||
--border: #bcc0cc;
|
||||
--glow1: rgba(30, 102, 245, 0.05);
|
||||
--glow2: rgba(136, 57, 239, 0.04);
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
:root {
|
||||
--bg: #1e1e2e;
|
||||
--surface: #313244;
|
||||
--overlay: #45475a;
|
||||
--text: #cdd6f4;
|
||||
--sub1: #bac2de;
|
||||
--sub0: #a6adc8;
|
||||
--blue: #89b4fa;
|
||||
--lavender: #b4befe;
|
||||
--sapphire: #74c7ec;
|
||||
--green: #a6e3a1;
|
||||
--yellow: #f9e2af;
|
||||
--peach: #fab387;
|
||||
--mauve: #cba6f7;
|
||||
--code-bg: #181825;
|
||||
--border: #45475a;
|
||||
--glow1: rgba(137, 180, 250, 0.06);
|
||||
--glow2: rgba(203, 166, 247, 0.05);
|
||||
}
|
||||
}
|
||||
|
||||
*, *::before, *::after { box-sizing: border-box; }
|
||||
|
||||
html {
|
||||
background-color: var(--bg);
|
||||
background-image:
|
||||
radial-gradient(ellipse 55% 40% at 10% 5%, var(--glow1) 0%, transparent 100%),
|
||||
radial-gradient(ellipse 45% 45% at 90% 95%, var(--glow2) 0%, transparent 100%);
|
||||
min-height: 100%;
|
||||
}
|
||||
|
||||
body {
|
||||
color: var(--text);
|
||||
font-family: system-ui, -apple-system, "Segoe UI", Helvetica, sans-serif;
|
||||
font-size: 16px;
|
||||
line-height: 1.75;
|
||||
max-width: 880px;
|
||||
margin: 0 auto;
|
||||
padding: 2rem 2.5rem 5rem;
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
/* ── Links ─────────────────────────────────────────────────── */
|
||||
a { color: var(--blue); text-decoration: none; }
|
||||
a:hover { color: var(--lavender); text-decoration: underline; }
|
||||
a:visited { color: var(--lavender); }
|
||||
|
||||
/* ── Headings ──────────────────────────────────────────────── */
|
||||
h1, h2, h3, h4, h5, h6 {
|
||||
font-family: "JetBrains Mono", "Fira Code", ui-monospace, monospace;
|
||||
color: var(--lavender);
|
||||
line-height: 1.3;
|
||||
margin-top: 2em;
|
||||
margin-bottom: 0.5em;
|
||||
}
|
||||
h1 {
|
||||
font-size: 1.9rem;
|
||||
color: var(--text);
|
||||
border-bottom: 1px solid var(--border);
|
||||
padding-bottom: 0.4em;
|
||||
margin-top: 1.2em;
|
||||
}
|
||||
h2 {
|
||||
font-size: 1.35rem;
|
||||
border-bottom: 1px solid var(--border);
|
||||
padding-bottom: 0.2em;
|
||||
}
|
||||
h3 { font-size: 1.1rem; color: var(--sapphire); }
|
||||
h4 { font-size: 0.95rem; color: var(--sub1); }
|
||||
|
||||
p { margin: 0.8em 0; }
|
||||
|
||||
/* ── Title block (pandoc-generated cover) ──────────────────── */
|
||||
#title-block-header {
|
||||
text-align: center;
|
||||
padding: 2.5rem 0 2rem;
|
||||
margin-bottom: 1.5rem;
|
||||
border-bottom: 1px solid var(--border);
|
||||
}
|
||||
#title-block-header .title {
|
||||
font-family: "JetBrains Mono", "Fira Code", ui-monospace, monospace;
|
||||
font-size: 2.6rem;
|
||||
letter-spacing: 0.12em;
|
||||
color: var(--lavender);
|
||||
border: none;
|
||||
margin: 0 0 0.75rem;
|
||||
}
|
||||
#title-block-header .author,
|
||||
#title-block-header .date {
|
||||
color: var(--sub0);
|
||||
font-size: 0.875rem;
|
||||
margin: 0.2rem 0;
|
||||
}
|
||||
|
||||
/* ── Inline code ───────────────────────────────────────────── */
|
||||
code {
|
||||
font-family: "JetBrains Mono", "Fira Code", ui-monospace, monospace;
|
||||
background: var(--code-bg);
|
||||
color: var(--peach);
|
||||
padding: 0.15em 0.4em;
|
||||
border-radius: 4px;
|
||||
font-size: 0.875em;
|
||||
}
|
||||
|
||||
/* ── Code blocks ───────────────────────────────────────────── */
|
||||
pre {
|
||||
background: var(--code-bg);
|
||||
border: 1px solid var(--border);
|
||||
border-left: 3px solid var(--sapphire);
|
||||
border-radius: 0 8px 8px 0;
|
||||
padding: 1.1em 1.4em;
|
||||
overflow-x: auto;
|
||||
line-height: 1.55;
|
||||
margin: 1.2em 0;
|
||||
}
|
||||
pre code {
|
||||
background: none;
|
||||
color: var(--text);
|
||||
padding: 0;
|
||||
font-size: 0.88em;
|
||||
}
|
||||
|
||||
/* ── Blockquotes ───────────────────────────────────────────── */
|
||||
blockquote {
|
||||
border-left: 3px solid var(--yellow);
|
||||
margin: 1.5em 0;
|
||||
padding: 0.75em 1.25em;
|
||||
background: var(--surface);
|
||||
color: var(--sub1);
|
||||
border-radius: 0 6px 6px 0;
|
||||
}
|
||||
blockquote p { margin: 0.3em 0; }
|
||||
|
||||
/* ── Tables ────────────────────────────────────────────────── */
|
||||
table {
|
||||
border-collapse: collapse;
|
||||
width: 100%;
|
||||
margin: 1.4em 0;
|
||||
font-size: 0.93em;
|
||||
}
|
||||
th, td {
|
||||
border: 1px solid var(--border);
|
||||
padding: 0.55em 0.9em;
|
||||
text-align: left;
|
||||
}
|
||||
th {
|
||||
background: var(--surface);
|
||||
color: var(--lavender);
|
||||
font-weight: 600;
|
||||
font-family: "JetBrains Mono", "Fira Code", ui-monospace, monospace;
|
||||
font-size: 0.82em;
|
||||
letter-spacing: 0.06em;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
tr:nth-child(even) { background: var(--surface); }
|
||||
tr:hover { background: var(--overlay); }
|
||||
|
||||
/* ── HR ────────────────────────────────────────────────────── */
|
||||
hr { border: none; border-top: 1px solid var(--border); margin: 2.5em 0; }
|
||||
|
||||
/* ── Lists ─────────────────────────────────────────────────── */
|
||||
ul, ol { padding-left: 1.6em; }
|
||||
li { margin: 0.35em 0; }
|
||||
|
||||
/* ── Chunk navigation bar (prev / up / next) ───────────────── */
|
||||
nav:not(#TOC):not([role="doc-toc"]) {
|
||||
background: var(--surface);
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 8px;
|
||||
margin: 1.5em 0;
|
||||
font-size: 0.875em;
|
||||
overflow: hidden;
|
||||
}
|
||||
nav:not(#TOC):not([role="doc-toc"]) p {
|
||||
margin: 0;
|
||||
padding: 0.65em 1.2em;
|
||||
display: flex;
|
||||
gap: 0.4em 1.75em;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
}
|
||||
/* JS wraps each "Label: <a>" pair in .nav-item so they flex as a unit */
|
||||
.nav-item {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 0.3em;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.nav-item a { color: var(--blue); }
|
||||
.nav-item a:hover { color: var(--lavender); }
|
||||
|
||||
/* ── Table of contents panel ───────────────────────────────── */
|
||||
nav#TOC, nav[role="doc-toc"] {
|
||||
display: block;
|
||||
background: var(--surface);
|
||||
border: 1px solid var(--border);
|
||||
border-left: 3px solid var(--lavender);
|
||||
border-radius: 0 8px 8px 0;
|
||||
padding: 1.2em 1.5em;
|
||||
margin: 1.5em 0;
|
||||
}
|
||||
nav#TOC > h2,
|
||||
nav[role="doc-toc"] > h2 {
|
||||
font-size: 0.7rem;
|
||||
letter-spacing: 0.14em;
|
||||
text-transform: uppercase;
|
||||
color: var(--sub0);
|
||||
border: none;
|
||||
margin: 0 0 0.9em;
|
||||
padding: 0;
|
||||
}
|
||||
nav#TOC ul, nav[role="doc-toc"] ul {
|
||||
list-style: none;
|
||||
padding-left: 1em;
|
||||
margin: 0.25em 0;
|
||||
}
|
||||
nav#TOC > ul, nav[role="doc-toc"] > ul { padding-left: 0; }
|
||||
nav#TOC li, nav[role="doc-toc"] li {
|
||||
margin: 0.3em 0;
|
||||
padding-left: 0.75em;
|
||||
border-left: 1px solid transparent;
|
||||
transition: border-color 0.12s;
|
||||
}
|
||||
nav#TOC li:hover, nav[role="doc-toc"] li:hover {
|
||||
border-left-color: var(--lavender);
|
||||
}
|
||||
nav#TOC a, nav[role="doc-toc"] a {
|
||||
color: var(--sub1);
|
||||
font-size: 0.9em;
|
||||
}
|
||||
nav#TOC a:hover, nav[role="doc-toc"] a:hover {
|
||||
color: var(--lavender);
|
||||
text-decoration: none;
|
||||
}
|
||||
</style>
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
/* ── Hide ToC on every page except index.html ───────────── */
|
||||
var path = location.pathname;
|
||||
var onIndex = path === '/' || path === '' || /\/index\.html(\?.*)?$/.test(path);
|
||||
if (!onIndex) {
|
||||
var toc = document.getElementById('TOC') ||
|
||||
document.querySelector('[role="doc-toc"]');
|
||||
if (toc) toc.remove();
|
||||
}
|
||||
|
||||
/* ── Wrap each "Label: <a>" pair in a .nav-item span ───────
|
||||
Pandoc emits label text nodes and anchors as siblings;
|
||||
flex sees them as separate items, causing labels to split
|
||||
from their links when wrapping. Grouping them in a span
|
||||
keeps each label+link as a single flex unit. */
|
||||
document.querySelectorAll('nav:not(#TOC):not([role="doc-toc"])').forEach(function (nav) {
|
||||
var p = nav.querySelector('p');
|
||||
if (!p) return;
|
||||
var children = Array.from(p.childNodes);
|
||||
var pairs = [];
|
||||
for (var i = 0; i + 1 < children.length; i++) {
|
||||
var cur = children[i];
|
||||
var nxt = children[i + 1];
|
||||
if (cur.nodeType === Node.TEXT_NODE &&
|
||||
/[A-Z][a-z]*:\s*/.test(cur.textContent) &&
|
||||
nxt.nodeType === Node.ELEMENT_NODE &&
|
||||
nxt.tagName === 'A') {
|
||||
pairs.push([cur, nxt]);
|
||||
i++; // skip the anchor on the next iteration
|
||||
}
|
||||
}
|
||||
pairs.forEach(function (pair) {
|
||||
var span = document.createElement('span');
|
||||
span.className = 'nav-item';
|
||||
p.insertBefore(span, pair[0]);
|
||||
span.appendChild(pair[0]);
|
||||
span.appendChild(pair[1]);
|
||||
});
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<nav id="sitenav">
|
||||
<div class="sitenav">
|
||||
<span class="navlink">
|
||||
<span class="navlink-label">Up:</span> <a href="index.html" accesskey="u" rel="up">FISH-CONFIG</a>
|
||||
</span>
|
||||
<span class="navlink">
|
||||
<span class="navlink-label">Top:</span> <a href="index.html" accesskey="t" rel="top">FISH-CONFIG</a>
|
||||
</span>
|
||||
</div>
|
||||
<div class="sitenav">
|
||||
<span class="navlink">
|
||||
<span class="navlink-label">Next:</span> <a href="5-1-configuration-variables.html" accesskey="n" rel="next">1. CONFIGURATION VARIABLES</a>
|
||||
</span>
|
||||
<span class="navlink">
|
||||
<span class="navlink-label">Previous:</span> <a href="3-description.html" accesskey="p" rel="previous">DESCRIPTION</a>
|
||||
</span>
|
||||
</div>
|
||||
</nav>
|
||||
<h1 data-number="4" id="table-of-contents">TABLE OF CONTENTS</h1>
|
||||
<pre><code>1. Configuration Variables
|
||||
2. PATH Setup
|
||||
3. Key Bindings
|
||||
4. Abbreviations
|
||||
4.1 Editors
|
||||
4.2 Navigation and Listing
|
||||
4.3 Git
|
||||
4.4 Terminal Windows, Tabs, and Panes
|
||||
4.5 Chezmoi
|
||||
4.6 Docker
|
||||
4.7 Systemctl
|
||||
4.8 AI Assistants
|
||||
4.9 History Expansion
|
||||
4.10 Miscellaneous
|
||||
4.11 Shell Aliases
|
||||
5. Functions Reference
|
||||
5.1 File and Directory
|
||||
5.2 Navigation
|
||||
5.3 Editors and Viewers
|
||||
5.4 Git and Version Control
|
||||
5.5 Package Management
|
||||
5.6 Dependency Management
|
||||
5.7 System and Monitoring
|
||||
5.8 Terminal Management
|
||||
5.9 Clipboard
|
||||
5.10 Network
|
||||
5.11 Pager and Logging
|
||||
5.12 AI and Developer Tools
|
||||
5.13 Media and Utilities
|
||||
5.14 Miscellaneous
|
||||
6. Dependency Catalog
|
||||
7. Customization
|
||||
8. Fisher Plugins
|
||||
9. Installation
|
||||
10. Personalization
|
||||
11. Viewing This Manual</code></pre>
|
||||
<hr />
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,589 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" lang="" xml:lang="">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="generator" content="pandoc" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" />
|
||||
<meta name="author" content="Rootiest" />
|
||||
<title>1. CONFIGURATION VARIABLES</title>
|
||||
<style>
|
||||
div.sitenav { display: flex; flex-direction: row; flex-wrap: wrap; }
|
||||
span.navlink { flex: 1; }
|
||||
span.navlink-label { display: inline-block; min-width: 4em; }
|
||||
html {
|
||||
color: #1a1a1a;
|
||||
background-color: #fdfdfd;
|
||||
}
|
||||
body {
|
||||
margin: 0 auto;
|
||||
max-width: 36em;
|
||||
padding-left: 50px;
|
||||
padding-right: 50px;
|
||||
padding-top: 50px;
|
||||
padding-bottom: 50px;
|
||||
hyphens: auto;
|
||||
overflow-wrap: break-word;
|
||||
text-rendering: optimizeLegibility;
|
||||
font-kerning: normal;
|
||||
}
|
||||
@media (max-width: 600px) {
|
||||
body {
|
||||
font-size: 0.9em;
|
||||
padding: 12px;
|
||||
}
|
||||
h1 {
|
||||
font-size: 1.8em;
|
||||
}
|
||||
}
|
||||
@media print {
|
||||
html {
|
||||
background-color: white;
|
||||
}
|
||||
body {
|
||||
background-color: transparent;
|
||||
color: black;
|
||||
font-size: 12pt;
|
||||
}
|
||||
p, h2, h3 {
|
||||
orphans: 3;
|
||||
widows: 3;
|
||||
}
|
||||
h2, h3, h4 {
|
||||
page-break-after: avoid;
|
||||
}
|
||||
}
|
||||
p {
|
||||
margin: 1em 0;
|
||||
}
|
||||
a {
|
||||
color: #1a1a1a;
|
||||
}
|
||||
a:visited {
|
||||
color: #1a1a1a;
|
||||
}
|
||||
img {
|
||||
max-width: 100%;
|
||||
}
|
||||
h1, h2, h3, h4, h5, h6 {
|
||||
margin-top: 1.4em;
|
||||
}
|
||||
h5, h6 {
|
||||
font-size: 1em;
|
||||
font-style: italic;
|
||||
}
|
||||
h6 {
|
||||
font-weight: normal;
|
||||
}
|
||||
ol, ul {
|
||||
padding-left: 1.7em;
|
||||
margin-top: 1em;
|
||||
}
|
||||
li > ol, li > ul {
|
||||
margin-top: 0;
|
||||
}
|
||||
blockquote {
|
||||
margin: 1em 0 1em 1.7em;
|
||||
padding-left: 1em;
|
||||
border-left: 2px solid #e6e6e6;
|
||||
color: #606060;
|
||||
}
|
||||
code {
|
||||
font-family: Menlo, Monaco, Consolas, 'Lucida Console', monospace;
|
||||
font-size: 85%;
|
||||
margin: 0;
|
||||
hyphens: manual;
|
||||
}
|
||||
pre {
|
||||
margin: 1em 0;
|
||||
overflow: auto;
|
||||
}
|
||||
pre code {
|
||||
padding: 0;
|
||||
overflow: visible;
|
||||
overflow-wrap: normal;
|
||||
}
|
||||
.sourceCode {
|
||||
background-color: transparent;
|
||||
overflow: visible;
|
||||
}
|
||||
hr {
|
||||
background-color: #1a1a1a;
|
||||
border: none;
|
||||
height: 1px;
|
||||
margin: 1em 0;
|
||||
}
|
||||
table {
|
||||
margin: 1em 0;
|
||||
border-collapse: collapse;
|
||||
width: 100%;
|
||||
overflow-x: auto;
|
||||
display: block;
|
||||
font-variant-numeric: lining-nums tabular-nums;
|
||||
}
|
||||
table caption {
|
||||
margin-bottom: 0.75em;
|
||||
}
|
||||
tbody {
|
||||
margin-top: 0.5em;
|
||||
border-top: 1px solid #1a1a1a;
|
||||
border-bottom: 1px solid #1a1a1a;
|
||||
}
|
||||
th {
|
||||
border-top: 1px solid #1a1a1a;
|
||||
padding: 0.25em 0.5em 0.25em 0.5em;
|
||||
}
|
||||
td {
|
||||
padding: 0.125em 0.5em 0.25em 0.5em;
|
||||
}
|
||||
header {
|
||||
margin-bottom: 4em;
|
||||
text-align: center;
|
||||
}
|
||||
#TOC li {
|
||||
list-style: none;
|
||||
}
|
||||
#TOC ul {
|
||||
padding-left: 1.3em;
|
||||
}
|
||||
#TOC > ul {
|
||||
padding-left: 0;
|
||||
}
|
||||
#TOC a:not(:hover) {
|
||||
text-decoration: none;
|
||||
}
|
||||
code{white-space: pre-wrap;}
|
||||
span.smallcaps{font-variant: small-caps;}
|
||||
div.columns{display: flex; gap: min(4vw, 1.5em);}
|
||||
div.column{flex: auto; overflow-x: auto;}
|
||||
div.hanging-indent{margin-left: 1.5em; text-indent: -1.5em;}
|
||||
/* The extra [class] is a hack that increases specificity enough to
|
||||
override a similar rule in reveal.js */
|
||||
ul.task-list[class]{list-style: none;}
|
||||
ul.task-list li input[type="checkbox"] {
|
||||
font-size: inherit;
|
||||
width: 0.8em;
|
||||
margin: 0 0.8em 0.2em -1.6em;
|
||||
vertical-align: middle;
|
||||
}
|
||||
.display.math{display: block; text-align: center; margin: 0.5rem auto;}
|
||||
</style>
|
||||
<style>
|
||||
/* ── Catppuccin Latte (light) / Mocha (dark) ─────────────────── */
|
||||
:root {
|
||||
color-scheme: light dark;
|
||||
--bg: #eff1f5;
|
||||
--surface: #e6e9ef;
|
||||
--overlay: #ccd0da;
|
||||
--text: #4c4f69;
|
||||
--sub1: #6c6f85;
|
||||
--sub0: #8c8fa1;
|
||||
--blue: #1e66f5;
|
||||
--lavender: #7287fd;
|
||||
--sapphire: #209fb5;
|
||||
--green: #40a02b;
|
||||
--yellow: #df8e1d;
|
||||
--peach: #fe640b;
|
||||
--mauve: #8839ef;
|
||||
--code-bg: #dce0e8;
|
||||
--border: #bcc0cc;
|
||||
--glow1: rgba(30, 102, 245, 0.05);
|
||||
--glow2: rgba(136, 57, 239, 0.04);
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
:root {
|
||||
--bg: #1e1e2e;
|
||||
--surface: #313244;
|
||||
--overlay: #45475a;
|
||||
--text: #cdd6f4;
|
||||
--sub1: #bac2de;
|
||||
--sub0: #a6adc8;
|
||||
--blue: #89b4fa;
|
||||
--lavender: #b4befe;
|
||||
--sapphire: #74c7ec;
|
||||
--green: #a6e3a1;
|
||||
--yellow: #f9e2af;
|
||||
--peach: #fab387;
|
||||
--mauve: #cba6f7;
|
||||
--code-bg: #181825;
|
||||
--border: #45475a;
|
||||
--glow1: rgba(137, 180, 250, 0.06);
|
||||
--glow2: rgba(203, 166, 247, 0.05);
|
||||
}
|
||||
}
|
||||
|
||||
*, *::before, *::after { box-sizing: border-box; }
|
||||
|
||||
html {
|
||||
background-color: var(--bg);
|
||||
background-image:
|
||||
radial-gradient(ellipse 55% 40% at 10% 5%, var(--glow1) 0%, transparent 100%),
|
||||
radial-gradient(ellipse 45% 45% at 90% 95%, var(--glow2) 0%, transparent 100%);
|
||||
min-height: 100%;
|
||||
}
|
||||
|
||||
body {
|
||||
color: var(--text);
|
||||
font-family: system-ui, -apple-system, "Segoe UI", Helvetica, sans-serif;
|
||||
font-size: 16px;
|
||||
line-height: 1.75;
|
||||
max-width: 880px;
|
||||
margin: 0 auto;
|
||||
padding: 2rem 2.5rem 5rem;
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
/* ── Links ─────────────────────────────────────────────────── */
|
||||
a { color: var(--blue); text-decoration: none; }
|
||||
a:hover { color: var(--lavender); text-decoration: underline; }
|
||||
a:visited { color: var(--lavender); }
|
||||
|
||||
/* ── Headings ──────────────────────────────────────────────── */
|
||||
h1, h2, h3, h4, h5, h6 {
|
||||
font-family: "JetBrains Mono", "Fira Code", ui-monospace, monospace;
|
||||
color: var(--lavender);
|
||||
line-height: 1.3;
|
||||
margin-top: 2em;
|
||||
margin-bottom: 0.5em;
|
||||
}
|
||||
h1 {
|
||||
font-size: 1.9rem;
|
||||
color: var(--text);
|
||||
border-bottom: 1px solid var(--border);
|
||||
padding-bottom: 0.4em;
|
||||
margin-top: 1.2em;
|
||||
}
|
||||
h2 {
|
||||
font-size: 1.35rem;
|
||||
border-bottom: 1px solid var(--border);
|
||||
padding-bottom: 0.2em;
|
||||
}
|
||||
h3 { font-size: 1.1rem; color: var(--sapphire); }
|
||||
h4 { font-size: 0.95rem; color: var(--sub1); }
|
||||
|
||||
p { margin: 0.8em 0; }
|
||||
|
||||
/* ── Title block (pandoc-generated cover) ──────────────────── */
|
||||
#title-block-header {
|
||||
text-align: center;
|
||||
padding: 2.5rem 0 2rem;
|
||||
margin-bottom: 1.5rem;
|
||||
border-bottom: 1px solid var(--border);
|
||||
}
|
||||
#title-block-header .title {
|
||||
font-family: "JetBrains Mono", "Fira Code", ui-monospace, monospace;
|
||||
font-size: 2.6rem;
|
||||
letter-spacing: 0.12em;
|
||||
color: var(--lavender);
|
||||
border: none;
|
||||
margin: 0 0 0.75rem;
|
||||
}
|
||||
#title-block-header .author,
|
||||
#title-block-header .date {
|
||||
color: var(--sub0);
|
||||
font-size: 0.875rem;
|
||||
margin: 0.2rem 0;
|
||||
}
|
||||
|
||||
/* ── Inline code ───────────────────────────────────────────── */
|
||||
code {
|
||||
font-family: "JetBrains Mono", "Fira Code", ui-monospace, monospace;
|
||||
background: var(--code-bg);
|
||||
color: var(--peach);
|
||||
padding: 0.15em 0.4em;
|
||||
border-radius: 4px;
|
||||
font-size: 0.875em;
|
||||
}
|
||||
|
||||
/* ── Code blocks ───────────────────────────────────────────── */
|
||||
pre {
|
||||
background: var(--code-bg);
|
||||
border: 1px solid var(--border);
|
||||
border-left: 3px solid var(--sapphire);
|
||||
border-radius: 0 8px 8px 0;
|
||||
padding: 1.1em 1.4em;
|
||||
overflow-x: auto;
|
||||
line-height: 1.55;
|
||||
margin: 1.2em 0;
|
||||
}
|
||||
pre code {
|
||||
background: none;
|
||||
color: var(--text);
|
||||
padding: 0;
|
||||
font-size: 0.88em;
|
||||
}
|
||||
|
||||
/* ── Blockquotes ───────────────────────────────────────────── */
|
||||
blockquote {
|
||||
border-left: 3px solid var(--yellow);
|
||||
margin: 1.5em 0;
|
||||
padding: 0.75em 1.25em;
|
||||
background: var(--surface);
|
||||
color: var(--sub1);
|
||||
border-radius: 0 6px 6px 0;
|
||||
}
|
||||
blockquote p { margin: 0.3em 0; }
|
||||
|
||||
/* ── Tables ────────────────────────────────────────────────── */
|
||||
table {
|
||||
border-collapse: collapse;
|
||||
width: 100%;
|
||||
margin: 1.4em 0;
|
||||
font-size: 0.93em;
|
||||
}
|
||||
th, td {
|
||||
border: 1px solid var(--border);
|
||||
padding: 0.55em 0.9em;
|
||||
text-align: left;
|
||||
}
|
||||
th {
|
||||
background: var(--surface);
|
||||
color: var(--lavender);
|
||||
font-weight: 600;
|
||||
font-family: "JetBrains Mono", "Fira Code", ui-monospace, monospace;
|
||||
font-size: 0.82em;
|
||||
letter-spacing: 0.06em;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
tr:nth-child(even) { background: var(--surface); }
|
||||
tr:hover { background: var(--overlay); }
|
||||
|
||||
/* ── HR ────────────────────────────────────────────────────── */
|
||||
hr { border: none; border-top: 1px solid var(--border); margin: 2.5em 0; }
|
||||
|
||||
/* ── Lists ─────────────────────────────────────────────────── */
|
||||
ul, ol { padding-left: 1.6em; }
|
||||
li { margin: 0.35em 0; }
|
||||
|
||||
/* ── Chunk navigation bar (prev / up / next) ───────────────── */
|
||||
nav:not(#TOC):not([role="doc-toc"]) {
|
||||
background: var(--surface);
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 8px;
|
||||
margin: 1.5em 0;
|
||||
font-size: 0.875em;
|
||||
overflow: hidden;
|
||||
}
|
||||
nav:not(#TOC):not([role="doc-toc"]) p {
|
||||
margin: 0;
|
||||
padding: 0.65em 1.2em;
|
||||
display: flex;
|
||||
gap: 0.4em 1.75em;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
}
|
||||
/* JS wraps each "Label: <a>" pair in .nav-item so they flex as a unit */
|
||||
.nav-item {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 0.3em;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.nav-item a { color: var(--blue); }
|
||||
.nav-item a:hover { color: var(--lavender); }
|
||||
|
||||
/* ── Table of contents panel ───────────────────────────────── */
|
||||
nav#TOC, nav[role="doc-toc"] {
|
||||
display: block;
|
||||
background: var(--surface);
|
||||
border: 1px solid var(--border);
|
||||
border-left: 3px solid var(--lavender);
|
||||
border-radius: 0 8px 8px 0;
|
||||
padding: 1.2em 1.5em;
|
||||
margin: 1.5em 0;
|
||||
}
|
||||
nav#TOC > h2,
|
||||
nav[role="doc-toc"] > h2 {
|
||||
font-size: 0.7rem;
|
||||
letter-spacing: 0.14em;
|
||||
text-transform: uppercase;
|
||||
color: var(--sub0);
|
||||
border: none;
|
||||
margin: 0 0 0.9em;
|
||||
padding: 0;
|
||||
}
|
||||
nav#TOC ul, nav[role="doc-toc"] ul {
|
||||
list-style: none;
|
||||
padding-left: 1em;
|
||||
margin: 0.25em 0;
|
||||
}
|
||||
nav#TOC > ul, nav[role="doc-toc"] > ul { padding-left: 0; }
|
||||
nav#TOC li, nav[role="doc-toc"] li {
|
||||
margin: 0.3em 0;
|
||||
padding-left: 0.75em;
|
||||
border-left: 1px solid transparent;
|
||||
transition: border-color 0.12s;
|
||||
}
|
||||
nav#TOC li:hover, nav[role="doc-toc"] li:hover {
|
||||
border-left-color: var(--lavender);
|
||||
}
|
||||
nav#TOC a, nav[role="doc-toc"] a {
|
||||
color: var(--sub1);
|
||||
font-size: 0.9em;
|
||||
}
|
||||
nav#TOC a:hover, nav[role="doc-toc"] a:hover {
|
||||
color: var(--lavender);
|
||||
text-decoration: none;
|
||||
}
|
||||
</style>
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
/* ── Hide ToC on every page except index.html ───────────── */
|
||||
var path = location.pathname;
|
||||
var onIndex = path === '/' || path === '' || /\/index\.html(\?.*)?$/.test(path);
|
||||
if (!onIndex) {
|
||||
var toc = document.getElementById('TOC') ||
|
||||
document.querySelector('[role="doc-toc"]');
|
||||
if (toc) toc.remove();
|
||||
}
|
||||
|
||||
/* ── Wrap each "Label: <a>" pair in a .nav-item span ───────
|
||||
Pandoc emits label text nodes and anchors as siblings;
|
||||
flex sees them as separate items, causing labels to split
|
||||
from their links when wrapping. Grouping them in a span
|
||||
keeps each label+link as a single flex unit. */
|
||||
document.querySelectorAll('nav:not(#TOC):not([role="doc-toc"])').forEach(function (nav) {
|
||||
var p = nav.querySelector('p');
|
||||
if (!p) return;
|
||||
var children = Array.from(p.childNodes);
|
||||
var pairs = [];
|
||||
for (var i = 0; i + 1 < children.length; i++) {
|
||||
var cur = children[i];
|
||||
var nxt = children[i + 1];
|
||||
if (cur.nodeType === Node.TEXT_NODE &&
|
||||
/[A-Z][a-z]*:\s*/.test(cur.textContent) &&
|
||||
nxt.nodeType === Node.ELEMENT_NODE &&
|
||||
nxt.tagName === 'A') {
|
||||
pairs.push([cur, nxt]);
|
||||
i++; // skip the anchor on the next iteration
|
||||
}
|
||||
}
|
||||
pairs.forEach(function (pair) {
|
||||
var span = document.createElement('span');
|
||||
span.className = 'nav-item';
|
||||
p.insertBefore(span, pair[0]);
|
||||
span.appendChild(pair[0]);
|
||||
span.appendChild(pair[1]);
|
||||
});
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<nav id="sitenav">
|
||||
<div class="sitenav">
|
||||
<span class="navlink">
|
||||
<span class="navlink-label">Up:</span> <a href="index.html" accesskey="u" rel="up">FISH-CONFIG</a>
|
||||
</span>
|
||||
<span class="navlink">
|
||||
<span class="navlink-label">Top:</span> <a href="index.html" accesskey="t" rel="top">FISH-CONFIG</a>
|
||||
</span>
|
||||
</div>
|
||||
<div class="sitenav">
|
||||
<span class="navlink">
|
||||
<span class="navlink-label">Next:</span> <a href="6-2-path-setup.html" accesskey="n" rel="next">2. PATH SETUP</a>
|
||||
</span>
|
||||
<span class="navlink">
|
||||
<span class="navlink-label">Previous:</span> <a href="4-table-of-contents.html" accesskey="p" rel="previous">TABLE OF CONTENTS</a>
|
||||
</span>
|
||||
</div>
|
||||
</nav>
|
||||
<h1 data-number="5" id="1-configuration-variables">1. CONFIGURATION
|
||||
VARIABLES</h1>
|
||||
<p>These variables are exported from config.fish on every interactive
|
||||
session. Override them in ~/.config/.user-dots/fish/local.fish.</p>
|
||||
<h2 data-number="5.1" id="environment-directories-xdg">Environment
|
||||
Directories (XDG)</h2>
|
||||
<pre><code>XDG_CONFIG_HOME ~/.config
|
||||
XDG_CACHE_HOME ~/.cache
|
||||
XDG_DATA_HOME ~/.local/share
|
||||
XDG_STATE_HOME ~/.local/state</code></pre>
|
||||
<p>Tools that respect XDG are directed to these paths rather than
|
||||
polluting $HOME.</p>
|
||||
<h2 data-number="5.2" id="tool-homes-xdg-compliant">Tool Homes
|
||||
(XDG-compliant)</h2>
|
||||
<pre><code>CARGO_HOME $XDG_DATA_HOME/cargo
|
||||
RUSTUP_HOME $XDG_DATA_HOME/rustup
|
||||
GOPATH $XDG_DATA_HOME/go
|
||||
BUN_INSTALL $XDG_DATA_HOME/bun
|
||||
NPM_CONFIG_PREFIX $XDG_DATA_HOME/npm-global
|
||||
GNUPGHOME $XDG_CONFIG_HOME/gnupg
|
||||
WAKATIME_HOME $XDG_CONFIG_HOME/wakatime</code></pre>
|
||||
<h2 data-number="5.3" id="editor-and-pager">Editor and Pager</h2>
|
||||
<pre><code>EDITOR nvim (falls back to vi if nvim is absent)
|
||||
VISUAL same as EDITOR
|
||||
SUDO_EDITOR same as EDITOR
|
||||
PAGER ov (falls back to less)</code></pre>
|
||||
<h2 data-number="5.4" id="scrollback-history">Scrollback History</h2>
|
||||
<pre><code>SCROLLBACK_HISTORY_DIR ~/.terminal_history
|
||||
SCROLLBACK_HISTORY_MAX_FILES 100</code></pre>
|
||||
<p>Scrollback logs accumulate in SCROLLBACK_HISTORY_DIR as timestamped
|
||||
files. When the count exceeds SCROLLBACK_HISTORY_MAX_FILES the oldest
|
||||
are pruned automatically on exit. Use <code>logs</code> to browse them
|
||||
interactively.</p>
|
||||
<h2 data-number="5.5" id="other">Other</h2>
|
||||
<pre><code>GPG_TTY $(tty) — ensures GPG passphrase prompts work
|
||||
CLAUDE_CODE_NO_FLICKER 1 — suppress terminal flicker in Claude Code
|
||||
CDPATH . ~/projects ~</code></pre>
|
||||
<p>Opinionated defaults (CDPATH, PAGER/MANPAGER, Vi mode, command
|
||||
shadows, terminal integrations) can be switched off per category with
|
||||
universal variables — see Section 7, "Opinionated Components (Minimal
|
||||
Mode)".</p>
|
||||
<h2 data-number="5.6" id="pager-hierarchy">Pager Hierarchy</h2>
|
||||
<p>$PAGER is set to ov when available, falling back to less. The less
|
||||
wrapper function extends this into a full chain so anything that calls
|
||||
less directly also benefits:</p>
|
||||
<pre><code>$PAGER → ov → less → more → cat</code></pre>
|
||||
<p>When bat is installed, man pages are rendered with syntax
|
||||
highlighting:</p>
|
||||
<pre><code>MANROFFOPT -c
|
||||
MANPAGER sh -c 'col -bx | bat -l man -p'</code></pre>
|
||||
<h2 data-number="5.7" id="integrations">Integrations</h2>
|
||||
<h3 data-number="5.7.1" id="zoxide">Zoxide</h3>
|
||||
<p>cd, z, and cdi/zi are all mapped to zoxide-backed navigation. Tab
|
||||
completions for cd and z blend standard directory entries (CWD and
|
||||
CDPATH) with frecency results so both familiar and frequently-visited
|
||||
paths appear in one list.</p>
|
||||
<h3 data-number="5.7.2" id="direnv">DirEnv</h3>
|
||||
<p>Automatically loads .envrc files on directory change. Takes priority
|
||||
over the auto-venv logic — if a directory is managed by direnv, the
|
||||
auto-venv activation is skipped entirely.</p>
|
||||
<h3 data-number="5.7.3" id="auto-python-venv">Auto Python Venv</h3>
|
||||
<p>When entering a directory that contains a .venv/, the virtualenv is
|
||||
activated automatically and deactivated when you leave the project
|
||||
tree.</p>
|
||||
<h3 data-number="5.7.4" id="wakatime">WakaTime</h3>
|
||||
<p>Every shell command is reported to WakaTime for time-tracking. Set
|
||||
FISH_WAKATIME_DISABLED=1 to disable without removing the plugin.</p>
|
||||
<h3 data-number="5.7.5" id="tailscale">Tailscale</h3>
|
||||
<p>Full tab completion for the tailscale CLI is provided via
|
||||
conf.d/tailscale.fish.</p>
|
||||
<h3 data-number="5.7.6" id="done-notifications">Done Notifications</h3>
|
||||
<p>Desktop notifications fire when a command takes longer than 10
|
||||
seconds and the terminal window is not focused. Configured via fish
|
||||
universal variables:</p>
|
||||
<pre><code>__done_min_cmd_duration 10000 ms
|
||||
__done_notification_urgency_level low</code></pre>
|
||||
<h3 data-number="5.7.7" id="scrollback-history-1">Scrollback
|
||||
History</h3>
|
||||
<p>When running inside Kitty, closing a shell session via exit saves a
|
||||
timestamped scrollback snapshot to SCROLLBACK_HISTORY_DIR. Files are
|
||||
named:</p>
|
||||
<pre><code>scrollback_YYYY-MM-DD_HH-MM-SS.log</code></pre>
|
||||
<p>The paru and yay wrappers (auto-generated in ~/.local/bin/) run the
|
||||
command inside a PTY via script(1) so download progress bars are
|
||||
preserved on screen, then render the captured terminal animation down to
|
||||
a clean static log via scripts/clean_progress_log.py (a small
|
||||
terminal-screen emulator that replays cursor movements, collapses
|
||||
repainted progress frames to their final state, and preserves ANSI
|
||||
color). If python3 is unavailable the wrapper falls back to dropping
|
||||
only the script(1) header/footer. Output is saved to:</p>
|
||||
<pre><code>paru_YYYY-MM-DD_HH-MM-SS.log
|
||||
yay_YYYY-MM-DD_HH-MM-SS.log</code></pre>
|
||||
<p>Before pruning, _scrollback_prune_junk silently removes empty files,
|
||||
files with only a single meaningful line (e.g. bare [exited] captures),
|
||||
and Kitty tab-rename prompt captures. Use exit --no-log (or exit -n) to
|
||||
skip capture.</p>
|
||||
<hr />
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,506 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" lang="" xml:lang="">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="generator" content="pandoc" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" />
|
||||
<meta name="author" content="Rootiest" />
|
||||
<title>2. PATH SETUP</title>
|
||||
<style>
|
||||
div.sitenav { display: flex; flex-direction: row; flex-wrap: wrap; }
|
||||
span.navlink { flex: 1; }
|
||||
span.navlink-label { display: inline-block; min-width: 4em; }
|
||||
html {
|
||||
color: #1a1a1a;
|
||||
background-color: #fdfdfd;
|
||||
}
|
||||
body {
|
||||
margin: 0 auto;
|
||||
max-width: 36em;
|
||||
padding-left: 50px;
|
||||
padding-right: 50px;
|
||||
padding-top: 50px;
|
||||
padding-bottom: 50px;
|
||||
hyphens: auto;
|
||||
overflow-wrap: break-word;
|
||||
text-rendering: optimizeLegibility;
|
||||
font-kerning: normal;
|
||||
}
|
||||
@media (max-width: 600px) {
|
||||
body {
|
||||
font-size: 0.9em;
|
||||
padding: 12px;
|
||||
}
|
||||
h1 {
|
||||
font-size: 1.8em;
|
||||
}
|
||||
}
|
||||
@media print {
|
||||
html {
|
||||
background-color: white;
|
||||
}
|
||||
body {
|
||||
background-color: transparent;
|
||||
color: black;
|
||||
font-size: 12pt;
|
||||
}
|
||||
p, h2, h3 {
|
||||
orphans: 3;
|
||||
widows: 3;
|
||||
}
|
||||
h2, h3, h4 {
|
||||
page-break-after: avoid;
|
||||
}
|
||||
}
|
||||
p {
|
||||
margin: 1em 0;
|
||||
}
|
||||
a {
|
||||
color: #1a1a1a;
|
||||
}
|
||||
a:visited {
|
||||
color: #1a1a1a;
|
||||
}
|
||||
img {
|
||||
max-width: 100%;
|
||||
}
|
||||
h1, h2, h3, h4, h5, h6 {
|
||||
margin-top: 1.4em;
|
||||
}
|
||||
h5, h6 {
|
||||
font-size: 1em;
|
||||
font-style: italic;
|
||||
}
|
||||
h6 {
|
||||
font-weight: normal;
|
||||
}
|
||||
ol, ul {
|
||||
padding-left: 1.7em;
|
||||
margin-top: 1em;
|
||||
}
|
||||
li > ol, li > ul {
|
||||
margin-top: 0;
|
||||
}
|
||||
blockquote {
|
||||
margin: 1em 0 1em 1.7em;
|
||||
padding-left: 1em;
|
||||
border-left: 2px solid #e6e6e6;
|
||||
color: #606060;
|
||||
}
|
||||
code {
|
||||
font-family: Menlo, Monaco, Consolas, 'Lucida Console', monospace;
|
||||
font-size: 85%;
|
||||
margin: 0;
|
||||
hyphens: manual;
|
||||
}
|
||||
pre {
|
||||
margin: 1em 0;
|
||||
overflow: auto;
|
||||
}
|
||||
pre code {
|
||||
padding: 0;
|
||||
overflow: visible;
|
||||
overflow-wrap: normal;
|
||||
}
|
||||
.sourceCode {
|
||||
background-color: transparent;
|
||||
overflow: visible;
|
||||
}
|
||||
hr {
|
||||
background-color: #1a1a1a;
|
||||
border: none;
|
||||
height: 1px;
|
||||
margin: 1em 0;
|
||||
}
|
||||
table {
|
||||
margin: 1em 0;
|
||||
border-collapse: collapse;
|
||||
width: 100%;
|
||||
overflow-x: auto;
|
||||
display: block;
|
||||
font-variant-numeric: lining-nums tabular-nums;
|
||||
}
|
||||
table caption {
|
||||
margin-bottom: 0.75em;
|
||||
}
|
||||
tbody {
|
||||
margin-top: 0.5em;
|
||||
border-top: 1px solid #1a1a1a;
|
||||
border-bottom: 1px solid #1a1a1a;
|
||||
}
|
||||
th {
|
||||
border-top: 1px solid #1a1a1a;
|
||||
padding: 0.25em 0.5em 0.25em 0.5em;
|
||||
}
|
||||
td {
|
||||
padding: 0.125em 0.5em 0.25em 0.5em;
|
||||
}
|
||||
header {
|
||||
margin-bottom: 4em;
|
||||
text-align: center;
|
||||
}
|
||||
#TOC li {
|
||||
list-style: none;
|
||||
}
|
||||
#TOC ul {
|
||||
padding-left: 1.3em;
|
||||
}
|
||||
#TOC > ul {
|
||||
padding-left: 0;
|
||||
}
|
||||
#TOC a:not(:hover) {
|
||||
text-decoration: none;
|
||||
}
|
||||
code{white-space: pre-wrap;}
|
||||
span.smallcaps{font-variant: small-caps;}
|
||||
div.columns{display: flex; gap: min(4vw, 1.5em);}
|
||||
div.column{flex: auto; overflow-x: auto;}
|
||||
div.hanging-indent{margin-left: 1.5em; text-indent: -1.5em;}
|
||||
/* The extra [class] is a hack that increases specificity enough to
|
||||
override a similar rule in reveal.js */
|
||||
ul.task-list[class]{list-style: none;}
|
||||
ul.task-list li input[type="checkbox"] {
|
||||
font-size: inherit;
|
||||
width: 0.8em;
|
||||
margin: 0 0.8em 0.2em -1.6em;
|
||||
vertical-align: middle;
|
||||
}
|
||||
.display.math{display: block; text-align: center; margin: 0.5rem auto;}
|
||||
</style>
|
||||
<style>
|
||||
/* ── Catppuccin Latte (light) / Mocha (dark) ─────────────────── */
|
||||
:root {
|
||||
color-scheme: light dark;
|
||||
--bg: #eff1f5;
|
||||
--surface: #e6e9ef;
|
||||
--overlay: #ccd0da;
|
||||
--text: #4c4f69;
|
||||
--sub1: #6c6f85;
|
||||
--sub0: #8c8fa1;
|
||||
--blue: #1e66f5;
|
||||
--lavender: #7287fd;
|
||||
--sapphire: #209fb5;
|
||||
--green: #40a02b;
|
||||
--yellow: #df8e1d;
|
||||
--peach: #fe640b;
|
||||
--mauve: #8839ef;
|
||||
--code-bg: #dce0e8;
|
||||
--border: #bcc0cc;
|
||||
--glow1: rgba(30, 102, 245, 0.05);
|
||||
--glow2: rgba(136, 57, 239, 0.04);
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
:root {
|
||||
--bg: #1e1e2e;
|
||||
--surface: #313244;
|
||||
--overlay: #45475a;
|
||||
--text: #cdd6f4;
|
||||
--sub1: #bac2de;
|
||||
--sub0: #a6adc8;
|
||||
--blue: #89b4fa;
|
||||
--lavender: #b4befe;
|
||||
--sapphire: #74c7ec;
|
||||
--green: #a6e3a1;
|
||||
--yellow: #f9e2af;
|
||||
--peach: #fab387;
|
||||
--mauve: #cba6f7;
|
||||
--code-bg: #181825;
|
||||
--border: #45475a;
|
||||
--glow1: rgba(137, 180, 250, 0.06);
|
||||
--glow2: rgba(203, 166, 247, 0.05);
|
||||
}
|
||||
}
|
||||
|
||||
*, *::before, *::after { box-sizing: border-box; }
|
||||
|
||||
html {
|
||||
background-color: var(--bg);
|
||||
background-image:
|
||||
radial-gradient(ellipse 55% 40% at 10% 5%, var(--glow1) 0%, transparent 100%),
|
||||
radial-gradient(ellipse 45% 45% at 90% 95%, var(--glow2) 0%, transparent 100%);
|
||||
min-height: 100%;
|
||||
}
|
||||
|
||||
body {
|
||||
color: var(--text);
|
||||
font-family: system-ui, -apple-system, "Segoe UI", Helvetica, sans-serif;
|
||||
font-size: 16px;
|
||||
line-height: 1.75;
|
||||
max-width: 880px;
|
||||
margin: 0 auto;
|
||||
padding: 2rem 2.5rem 5rem;
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
/* ── Links ─────────────────────────────────────────────────── */
|
||||
a { color: var(--blue); text-decoration: none; }
|
||||
a:hover { color: var(--lavender); text-decoration: underline; }
|
||||
a:visited { color: var(--lavender); }
|
||||
|
||||
/* ── Headings ──────────────────────────────────────────────── */
|
||||
h1, h2, h3, h4, h5, h6 {
|
||||
font-family: "JetBrains Mono", "Fira Code", ui-monospace, monospace;
|
||||
color: var(--lavender);
|
||||
line-height: 1.3;
|
||||
margin-top: 2em;
|
||||
margin-bottom: 0.5em;
|
||||
}
|
||||
h1 {
|
||||
font-size: 1.9rem;
|
||||
color: var(--text);
|
||||
border-bottom: 1px solid var(--border);
|
||||
padding-bottom: 0.4em;
|
||||
margin-top: 1.2em;
|
||||
}
|
||||
h2 {
|
||||
font-size: 1.35rem;
|
||||
border-bottom: 1px solid var(--border);
|
||||
padding-bottom: 0.2em;
|
||||
}
|
||||
h3 { font-size: 1.1rem; color: var(--sapphire); }
|
||||
h4 { font-size: 0.95rem; color: var(--sub1); }
|
||||
|
||||
p { margin: 0.8em 0; }
|
||||
|
||||
/* ── Title block (pandoc-generated cover) ──────────────────── */
|
||||
#title-block-header {
|
||||
text-align: center;
|
||||
padding: 2.5rem 0 2rem;
|
||||
margin-bottom: 1.5rem;
|
||||
border-bottom: 1px solid var(--border);
|
||||
}
|
||||
#title-block-header .title {
|
||||
font-family: "JetBrains Mono", "Fira Code", ui-monospace, monospace;
|
||||
font-size: 2.6rem;
|
||||
letter-spacing: 0.12em;
|
||||
color: var(--lavender);
|
||||
border: none;
|
||||
margin: 0 0 0.75rem;
|
||||
}
|
||||
#title-block-header .author,
|
||||
#title-block-header .date {
|
||||
color: var(--sub0);
|
||||
font-size: 0.875rem;
|
||||
margin: 0.2rem 0;
|
||||
}
|
||||
|
||||
/* ── Inline code ───────────────────────────────────────────── */
|
||||
code {
|
||||
font-family: "JetBrains Mono", "Fira Code", ui-monospace, monospace;
|
||||
background: var(--code-bg);
|
||||
color: var(--peach);
|
||||
padding: 0.15em 0.4em;
|
||||
border-radius: 4px;
|
||||
font-size: 0.875em;
|
||||
}
|
||||
|
||||
/* ── Code blocks ───────────────────────────────────────────── */
|
||||
pre {
|
||||
background: var(--code-bg);
|
||||
border: 1px solid var(--border);
|
||||
border-left: 3px solid var(--sapphire);
|
||||
border-radius: 0 8px 8px 0;
|
||||
padding: 1.1em 1.4em;
|
||||
overflow-x: auto;
|
||||
line-height: 1.55;
|
||||
margin: 1.2em 0;
|
||||
}
|
||||
pre code {
|
||||
background: none;
|
||||
color: var(--text);
|
||||
padding: 0;
|
||||
font-size: 0.88em;
|
||||
}
|
||||
|
||||
/* ── Blockquotes ───────────────────────────────────────────── */
|
||||
blockquote {
|
||||
border-left: 3px solid var(--yellow);
|
||||
margin: 1.5em 0;
|
||||
padding: 0.75em 1.25em;
|
||||
background: var(--surface);
|
||||
color: var(--sub1);
|
||||
border-radius: 0 6px 6px 0;
|
||||
}
|
||||
blockquote p { margin: 0.3em 0; }
|
||||
|
||||
/* ── Tables ────────────────────────────────────────────────── */
|
||||
table {
|
||||
border-collapse: collapse;
|
||||
width: 100%;
|
||||
margin: 1.4em 0;
|
||||
font-size: 0.93em;
|
||||
}
|
||||
th, td {
|
||||
border: 1px solid var(--border);
|
||||
padding: 0.55em 0.9em;
|
||||
text-align: left;
|
||||
}
|
||||
th {
|
||||
background: var(--surface);
|
||||
color: var(--lavender);
|
||||
font-weight: 600;
|
||||
font-family: "JetBrains Mono", "Fira Code", ui-monospace, monospace;
|
||||
font-size: 0.82em;
|
||||
letter-spacing: 0.06em;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
tr:nth-child(even) { background: var(--surface); }
|
||||
tr:hover { background: var(--overlay); }
|
||||
|
||||
/* ── HR ────────────────────────────────────────────────────── */
|
||||
hr { border: none; border-top: 1px solid var(--border); margin: 2.5em 0; }
|
||||
|
||||
/* ── Lists ─────────────────────────────────────────────────── */
|
||||
ul, ol { padding-left: 1.6em; }
|
||||
li { margin: 0.35em 0; }
|
||||
|
||||
/* ── Chunk navigation bar (prev / up / next) ───────────────── */
|
||||
nav:not(#TOC):not([role="doc-toc"]) {
|
||||
background: var(--surface);
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 8px;
|
||||
margin: 1.5em 0;
|
||||
font-size: 0.875em;
|
||||
overflow: hidden;
|
||||
}
|
||||
nav:not(#TOC):not([role="doc-toc"]) p {
|
||||
margin: 0;
|
||||
padding: 0.65em 1.2em;
|
||||
display: flex;
|
||||
gap: 0.4em 1.75em;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
}
|
||||
/* JS wraps each "Label: <a>" pair in .nav-item so they flex as a unit */
|
||||
.nav-item {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 0.3em;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.nav-item a { color: var(--blue); }
|
||||
.nav-item a:hover { color: var(--lavender); }
|
||||
|
||||
/* ── Table of contents panel ───────────────────────────────── */
|
||||
nav#TOC, nav[role="doc-toc"] {
|
||||
display: block;
|
||||
background: var(--surface);
|
||||
border: 1px solid var(--border);
|
||||
border-left: 3px solid var(--lavender);
|
||||
border-radius: 0 8px 8px 0;
|
||||
padding: 1.2em 1.5em;
|
||||
margin: 1.5em 0;
|
||||
}
|
||||
nav#TOC > h2,
|
||||
nav[role="doc-toc"] > h2 {
|
||||
font-size: 0.7rem;
|
||||
letter-spacing: 0.14em;
|
||||
text-transform: uppercase;
|
||||
color: var(--sub0);
|
||||
border: none;
|
||||
margin: 0 0 0.9em;
|
||||
padding: 0;
|
||||
}
|
||||
nav#TOC ul, nav[role="doc-toc"] ul {
|
||||
list-style: none;
|
||||
padding-left: 1em;
|
||||
margin: 0.25em 0;
|
||||
}
|
||||
nav#TOC > ul, nav[role="doc-toc"] > ul { padding-left: 0; }
|
||||
nav#TOC li, nav[role="doc-toc"] li {
|
||||
margin: 0.3em 0;
|
||||
padding-left: 0.75em;
|
||||
border-left: 1px solid transparent;
|
||||
transition: border-color 0.12s;
|
||||
}
|
||||
nav#TOC li:hover, nav[role="doc-toc"] li:hover {
|
||||
border-left-color: var(--lavender);
|
||||
}
|
||||
nav#TOC a, nav[role="doc-toc"] a {
|
||||
color: var(--sub1);
|
||||
font-size: 0.9em;
|
||||
}
|
||||
nav#TOC a:hover, nav[role="doc-toc"] a:hover {
|
||||
color: var(--lavender);
|
||||
text-decoration: none;
|
||||
}
|
||||
</style>
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
/* ── Hide ToC on every page except index.html ───────────── */
|
||||
var path = location.pathname;
|
||||
var onIndex = path === '/' || path === '' || /\/index\.html(\?.*)?$/.test(path);
|
||||
if (!onIndex) {
|
||||
var toc = document.getElementById('TOC') ||
|
||||
document.querySelector('[role="doc-toc"]');
|
||||
if (toc) toc.remove();
|
||||
}
|
||||
|
||||
/* ── Wrap each "Label: <a>" pair in a .nav-item span ───────
|
||||
Pandoc emits label text nodes and anchors as siblings;
|
||||
flex sees them as separate items, causing labels to split
|
||||
from their links when wrapping. Grouping them in a span
|
||||
keeps each label+link as a single flex unit. */
|
||||
document.querySelectorAll('nav:not(#TOC):not([role="doc-toc"])').forEach(function (nav) {
|
||||
var p = nav.querySelector('p');
|
||||
if (!p) return;
|
||||
var children = Array.from(p.childNodes);
|
||||
var pairs = [];
|
||||
for (var i = 0; i + 1 < children.length; i++) {
|
||||
var cur = children[i];
|
||||
var nxt = children[i + 1];
|
||||
if (cur.nodeType === Node.TEXT_NODE &&
|
||||
/[A-Z][a-z]*:\s*/.test(cur.textContent) &&
|
||||
nxt.nodeType === Node.ELEMENT_NODE &&
|
||||
nxt.tagName === 'A') {
|
||||
pairs.push([cur, nxt]);
|
||||
i++; // skip the anchor on the next iteration
|
||||
}
|
||||
}
|
||||
pairs.forEach(function (pair) {
|
||||
var span = document.createElement('span');
|
||||
span.className = 'nav-item';
|
||||
p.insertBefore(span, pair[0]);
|
||||
span.appendChild(pair[0]);
|
||||
span.appendChild(pair[1]);
|
||||
});
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<nav id="sitenav">
|
||||
<div class="sitenav">
|
||||
<span class="navlink">
|
||||
<span class="navlink-label">Up:</span> <a href="index.html" accesskey="u" rel="up">FISH-CONFIG</a>
|
||||
</span>
|
||||
<span class="navlink">
|
||||
<span class="navlink-label">Top:</span> <a href="index.html" accesskey="t" rel="top">FISH-CONFIG</a>
|
||||
</span>
|
||||
</div>
|
||||
<div class="sitenav">
|
||||
<span class="navlink">
|
||||
<span class="navlink-label">Next:</span> <a href="7-3-key-bindings.html" accesskey="n" rel="next">3. KEY BINDINGS</a>
|
||||
</span>
|
||||
<span class="navlink">
|
||||
<span class="navlink-label">Previous:</span> <a href="5-1-configuration-variables.html" accesskey="p" rel="previous">1. CONFIGURATION VARIABLES</a>
|
||||
</span>
|
||||
</div>
|
||||
</nav>
|
||||
<h1 data-number="6" id="2-path-setup">2. PATH SETUP</h1>
|
||||
<p>Directories prepended to PATH in this order (first wins):</p>
|
||||
<pre><code>~/.local/bin Standard user-local executables
|
||||
~/Applications User-installed standalone apps
|
||||
~/scripts Personal shell scripts
|
||||
~/bin Cargo binaries (appended — lowest priority)
|
||||
$BUN_INSTALL/bin Bun runtime and global packages
|
||||
$NPM_CONFIG_PREFIX/bin Global npm packages
|
||||
~/.lmstudio/bin LM Studio CLI
|
||||
~/.resend/bin Resend CLI
|
||||
~/.fzf/bin fzf binary (git-installed)</code></pre>
|
||||
<p>Cargo binaries are intentionally appended (lowest priority) to avoid
|
||||
shadowing system-installed Rust tools.</p>
|
||||
<hr />
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,538 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" lang="" xml:lang="">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="generator" content="pandoc" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" />
|
||||
<meta name="author" content="Rootiest" />
|
||||
<title>3. KEY BINDINGS</title>
|
||||
<style>
|
||||
div.sitenav { display: flex; flex-direction: row; flex-wrap: wrap; }
|
||||
span.navlink { flex: 1; }
|
||||
span.navlink-label { display: inline-block; min-width: 4em; }
|
||||
html {
|
||||
color: #1a1a1a;
|
||||
background-color: #fdfdfd;
|
||||
}
|
||||
body {
|
||||
margin: 0 auto;
|
||||
max-width: 36em;
|
||||
padding-left: 50px;
|
||||
padding-right: 50px;
|
||||
padding-top: 50px;
|
||||
padding-bottom: 50px;
|
||||
hyphens: auto;
|
||||
overflow-wrap: break-word;
|
||||
text-rendering: optimizeLegibility;
|
||||
font-kerning: normal;
|
||||
}
|
||||
@media (max-width: 600px) {
|
||||
body {
|
||||
font-size: 0.9em;
|
||||
padding: 12px;
|
||||
}
|
||||
h1 {
|
||||
font-size: 1.8em;
|
||||
}
|
||||
}
|
||||
@media print {
|
||||
html {
|
||||
background-color: white;
|
||||
}
|
||||
body {
|
||||
background-color: transparent;
|
||||
color: black;
|
||||
font-size: 12pt;
|
||||
}
|
||||
p, h2, h3 {
|
||||
orphans: 3;
|
||||
widows: 3;
|
||||
}
|
||||
h2, h3, h4 {
|
||||
page-break-after: avoid;
|
||||
}
|
||||
}
|
||||
p {
|
||||
margin: 1em 0;
|
||||
}
|
||||
a {
|
||||
color: #1a1a1a;
|
||||
}
|
||||
a:visited {
|
||||
color: #1a1a1a;
|
||||
}
|
||||
img {
|
||||
max-width: 100%;
|
||||
}
|
||||
h1, h2, h3, h4, h5, h6 {
|
||||
margin-top: 1.4em;
|
||||
}
|
||||
h5, h6 {
|
||||
font-size: 1em;
|
||||
font-style: italic;
|
||||
}
|
||||
h6 {
|
||||
font-weight: normal;
|
||||
}
|
||||
ol, ul {
|
||||
padding-left: 1.7em;
|
||||
margin-top: 1em;
|
||||
}
|
||||
li > ol, li > ul {
|
||||
margin-top: 0;
|
||||
}
|
||||
blockquote {
|
||||
margin: 1em 0 1em 1.7em;
|
||||
padding-left: 1em;
|
||||
border-left: 2px solid #e6e6e6;
|
||||
color: #606060;
|
||||
}
|
||||
code {
|
||||
font-family: Menlo, Monaco, Consolas, 'Lucida Console', monospace;
|
||||
font-size: 85%;
|
||||
margin: 0;
|
||||
hyphens: manual;
|
||||
}
|
||||
pre {
|
||||
margin: 1em 0;
|
||||
overflow: auto;
|
||||
}
|
||||
pre code {
|
||||
padding: 0;
|
||||
overflow: visible;
|
||||
overflow-wrap: normal;
|
||||
}
|
||||
.sourceCode {
|
||||
background-color: transparent;
|
||||
overflow: visible;
|
||||
}
|
||||
hr {
|
||||
background-color: #1a1a1a;
|
||||
border: none;
|
||||
height: 1px;
|
||||
margin: 1em 0;
|
||||
}
|
||||
table {
|
||||
margin: 1em 0;
|
||||
border-collapse: collapse;
|
||||
width: 100%;
|
||||
overflow-x: auto;
|
||||
display: block;
|
||||
font-variant-numeric: lining-nums tabular-nums;
|
||||
}
|
||||
table caption {
|
||||
margin-bottom: 0.75em;
|
||||
}
|
||||
tbody {
|
||||
margin-top: 0.5em;
|
||||
border-top: 1px solid #1a1a1a;
|
||||
border-bottom: 1px solid #1a1a1a;
|
||||
}
|
||||
th {
|
||||
border-top: 1px solid #1a1a1a;
|
||||
padding: 0.25em 0.5em 0.25em 0.5em;
|
||||
}
|
||||
td {
|
||||
padding: 0.125em 0.5em 0.25em 0.5em;
|
||||
}
|
||||
header {
|
||||
margin-bottom: 4em;
|
||||
text-align: center;
|
||||
}
|
||||
#TOC li {
|
||||
list-style: none;
|
||||
}
|
||||
#TOC ul {
|
||||
padding-left: 1.3em;
|
||||
}
|
||||
#TOC > ul {
|
||||
padding-left: 0;
|
||||
}
|
||||
#TOC a:not(:hover) {
|
||||
text-decoration: none;
|
||||
}
|
||||
code{white-space: pre-wrap;}
|
||||
span.smallcaps{font-variant: small-caps;}
|
||||
div.columns{display: flex; gap: min(4vw, 1.5em);}
|
||||
div.column{flex: auto; overflow-x: auto;}
|
||||
div.hanging-indent{margin-left: 1.5em; text-indent: -1.5em;}
|
||||
/* The extra [class] is a hack that increases specificity enough to
|
||||
override a similar rule in reveal.js */
|
||||
ul.task-list[class]{list-style: none;}
|
||||
ul.task-list li input[type="checkbox"] {
|
||||
font-size: inherit;
|
||||
width: 0.8em;
|
||||
margin: 0 0.8em 0.2em -1.6em;
|
||||
vertical-align: middle;
|
||||
}
|
||||
.display.math{display: block; text-align: center; margin: 0.5rem auto;}
|
||||
</style>
|
||||
<style>
|
||||
/* ── Catppuccin Latte (light) / Mocha (dark) ─────────────────── */
|
||||
:root {
|
||||
color-scheme: light dark;
|
||||
--bg: #eff1f5;
|
||||
--surface: #e6e9ef;
|
||||
--overlay: #ccd0da;
|
||||
--text: #4c4f69;
|
||||
--sub1: #6c6f85;
|
||||
--sub0: #8c8fa1;
|
||||
--blue: #1e66f5;
|
||||
--lavender: #7287fd;
|
||||
--sapphire: #209fb5;
|
||||
--green: #40a02b;
|
||||
--yellow: #df8e1d;
|
||||
--peach: #fe640b;
|
||||
--mauve: #8839ef;
|
||||
--code-bg: #dce0e8;
|
||||
--border: #bcc0cc;
|
||||
--glow1: rgba(30, 102, 245, 0.05);
|
||||
--glow2: rgba(136, 57, 239, 0.04);
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
:root {
|
||||
--bg: #1e1e2e;
|
||||
--surface: #313244;
|
||||
--overlay: #45475a;
|
||||
--text: #cdd6f4;
|
||||
--sub1: #bac2de;
|
||||
--sub0: #a6adc8;
|
||||
--blue: #89b4fa;
|
||||
--lavender: #b4befe;
|
||||
--sapphire: #74c7ec;
|
||||
--green: #a6e3a1;
|
||||
--yellow: #f9e2af;
|
||||
--peach: #fab387;
|
||||
--mauve: #cba6f7;
|
||||
--code-bg: #181825;
|
||||
--border: #45475a;
|
||||
--glow1: rgba(137, 180, 250, 0.06);
|
||||
--glow2: rgba(203, 166, 247, 0.05);
|
||||
}
|
||||
}
|
||||
|
||||
*, *::before, *::after { box-sizing: border-box; }
|
||||
|
||||
html {
|
||||
background-color: var(--bg);
|
||||
background-image:
|
||||
radial-gradient(ellipse 55% 40% at 10% 5%, var(--glow1) 0%, transparent 100%),
|
||||
radial-gradient(ellipse 45% 45% at 90% 95%, var(--glow2) 0%, transparent 100%);
|
||||
min-height: 100%;
|
||||
}
|
||||
|
||||
body {
|
||||
color: var(--text);
|
||||
font-family: system-ui, -apple-system, "Segoe UI", Helvetica, sans-serif;
|
||||
font-size: 16px;
|
||||
line-height: 1.75;
|
||||
max-width: 880px;
|
||||
margin: 0 auto;
|
||||
padding: 2rem 2.5rem 5rem;
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
/* ── Links ─────────────────────────────────────────────────── */
|
||||
a { color: var(--blue); text-decoration: none; }
|
||||
a:hover { color: var(--lavender); text-decoration: underline; }
|
||||
a:visited { color: var(--lavender); }
|
||||
|
||||
/* ── Headings ──────────────────────────────────────────────── */
|
||||
h1, h2, h3, h4, h5, h6 {
|
||||
font-family: "JetBrains Mono", "Fira Code", ui-monospace, monospace;
|
||||
color: var(--lavender);
|
||||
line-height: 1.3;
|
||||
margin-top: 2em;
|
||||
margin-bottom: 0.5em;
|
||||
}
|
||||
h1 {
|
||||
font-size: 1.9rem;
|
||||
color: var(--text);
|
||||
border-bottom: 1px solid var(--border);
|
||||
padding-bottom: 0.4em;
|
||||
margin-top: 1.2em;
|
||||
}
|
||||
h2 {
|
||||
font-size: 1.35rem;
|
||||
border-bottom: 1px solid var(--border);
|
||||
padding-bottom: 0.2em;
|
||||
}
|
||||
h3 { font-size: 1.1rem; color: var(--sapphire); }
|
||||
h4 { font-size: 0.95rem; color: var(--sub1); }
|
||||
|
||||
p { margin: 0.8em 0; }
|
||||
|
||||
/* ── Title block (pandoc-generated cover) ──────────────────── */
|
||||
#title-block-header {
|
||||
text-align: center;
|
||||
padding: 2.5rem 0 2rem;
|
||||
margin-bottom: 1.5rem;
|
||||
border-bottom: 1px solid var(--border);
|
||||
}
|
||||
#title-block-header .title {
|
||||
font-family: "JetBrains Mono", "Fira Code", ui-monospace, monospace;
|
||||
font-size: 2.6rem;
|
||||
letter-spacing: 0.12em;
|
||||
color: var(--lavender);
|
||||
border: none;
|
||||
margin: 0 0 0.75rem;
|
||||
}
|
||||
#title-block-header .author,
|
||||
#title-block-header .date {
|
||||
color: var(--sub0);
|
||||
font-size: 0.875rem;
|
||||
margin: 0.2rem 0;
|
||||
}
|
||||
|
||||
/* ── Inline code ───────────────────────────────────────────── */
|
||||
code {
|
||||
font-family: "JetBrains Mono", "Fira Code", ui-monospace, monospace;
|
||||
background: var(--code-bg);
|
||||
color: var(--peach);
|
||||
padding: 0.15em 0.4em;
|
||||
border-radius: 4px;
|
||||
font-size: 0.875em;
|
||||
}
|
||||
|
||||
/* ── Code blocks ───────────────────────────────────────────── */
|
||||
pre {
|
||||
background: var(--code-bg);
|
||||
border: 1px solid var(--border);
|
||||
border-left: 3px solid var(--sapphire);
|
||||
border-radius: 0 8px 8px 0;
|
||||
padding: 1.1em 1.4em;
|
||||
overflow-x: auto;
|
||||
line-height: 1.55;
|
||||
margin: 1.2em 0;
|
||||
}
|
||||
pre code {
|
||||
background: none;
|
||||
color: var(--text);
|
||||
padding: 0;
|
||||
font-size: 0.88em;
|
||||
}
|
||||
|
||||
/* ── Blockquotes ───────────────────────────────────────────── */
|
||||
blockquote {
|
||||
border-left: 3px solid var(--yellow);
|
||||
margin: 1.5em 0;
|
||||
padding: 0.75em 1.25em;
|
||||
background: var(--surface);
|
||||
color: var(--sub1);
|
||||
border-radius: 0 6px 6px 0;
|
||||
}
|
||||
blockquote p { margin: 0.3em 0; }
|
||||
|
||||
/* ── Tables ────────────────────────────────────────────────── */
|
||||
table {
|
||||
border-collapse: collapse;
|
||||
width: 100%;
|
||||
margin: 1.4em 0;
|
||||
font-size: 0.93em;
|
||||
}
|
||||
th, td {
|
||||
border: 1px solid var(--border);
|
||||
padding: 0.55em 0.9em;
|
||||
text-align: left;
|
||||
}
|
||||
th {
|
||||
background: var(--surface);
|
||||
color: var(--lavender);
|
||||
font-weight: 600;
|
||||
font-family: "JetBrains Mono", "Fira Code", ui-monospace, monospace;
|
||||
font-size: 0.82em;
|
||||
letter-spacing: 0.06em;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
tr:nth-child(even) { background: var(--surface); }
|
||||
tr:hover { background: var(--overlay); }
|
||||
|
||||
/* ── HR ────────────────────────────────────────────────────── */
|
||||
hr { border: none; border-top: 1px solid var(--border); margin: 2.5em 0; }
|
||||
|
||||
/* ── Lists ─────────────────────────────────────────────────── */
|
||||
ul, ol { padding-left: 1.6em; }
|
||||
li { margin: 0.35em 0; }
|
||||
|
||||
/* ── Chunk navigation bar (prev / up / next) ───────────────── */
|
||||
nav:not(#TOC):not([role="doc-toc"]) {
|
||||
background: var(--surface);
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 8px;
|
||||
margin: 1.5em 0;
|
||||
font-size: 0.875em;
|
||||
overflow: hidden;
|
||||
}
|
||||
nav:not(#TOC):not([role="doc-toc"]) p {
|
||||
margin: 0;
|
||||
padding: 0.65em 1.2em;
|
||||
display: flex;
|
||||
gap: 0.4em 1.75em;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
}
|
||||
/* JS wraps each "Label: <a>" pair in .nav-item so they flex as a unit */
|
||||
.nav-item {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 0.3em;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.nav-item a { color: var(--blue); }
|
||||
.nav-item a:hover { color: var(--lavender); }
|
||||
|
||||
/* ── Table of contents panel ───────────────────────────────── */
|
||||
nav#TOC, nav[role="doc-toc"] {
|
||||
display: block;
|
||||
background: var(--surface);
|
||||
border: 1px solid var(--border);
|
||||
border-left: 3px solid var(--lavender);
|
||||
border-radius: 0 8px 8px 0;
|
||||
padding: 1.2em 1.5em;
|
||||
margin: 1.5em 0;
|
||||
}
|
||||
nav#TOC > h2,
|
||||
nav[role="doc-toc"] > h2 {
|
||||
font-size: 0.7rem;
|
||||
letter-spacing: 0.14em;
|
||||
text-transform: uppercase;
|
||||
color: var(--sub0);
|
||||
border: none;
|
||||
margin: 0 0 0.9em;
|
||||
padding: 0;
|
||||
}
|
||||
nav#TOC ul, nav[role="doc-toc"] ul {
|
||||
list-style: none;
|
||||
padding-left: 1em;
|
||||
margin: 0.25em 0;
|
||||
}
|
||||
nav#TOC > ul, nav[role="doc-toc"] > ul { padding-left: 0; }
|
||||
nav#TOC li, nav[role="doc-toc"] li {
|
||||
margin: 0.3em 0;
|
||||
padding-left: 0.75em;
|
||||
border-left: 1px solid transparent;
|
||||
transition: border-color 0.12s;
|
||||
}
|
||||
nav#TOC li:hover, nav[role="doc-toc"] li:hover {
|
||||
border-left-color: var(--lavender);
|
||||
}
|
||||
nav#TOC a, nav[role="doc-toc"] a {
|
||||
color: var(--sub1);
|
||||
font-size: 0.9em;
|
||||
}
|
||||
nav#TOC a:hover, nav[role="doc-toc"] a:hover {
|
||||
color: var(--lavender);
|
||||
text-decoration: none;
|
||||
}
|
||||
</style>
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
/* ── Hide ToC on every page except index.html ───────────── */
|
||||
var path = location.pathname;
|
||||
var onIndex = path === '/' || path === '' || /\/index\.html(\?.*)?$/.test(path);
|
||||
if (!onIndex) {
|
||||
var toc = document.getElementById('TOC') ||
|
||||
document.querySelector('[role="doc-toc"]');
|
||||
if (toc) toc.remove();
|
||||
}
|
||||
|
||||
/* ── Wrap each "Label: <a>" pair in a .nav-item span ───────
|
||||
Pandoc emits label text nodes and anchors as siblings;
|
||||
flex sees them as separate items, causing labels to split
|
||||
from their links when wrapping. Grouping them in a span
|
||||
keeps each label+link as a single flex unit. */
|
||||
document.querySelectorAll('nav:not(#TOC):not([role="doc-toc"])').forEach(function (nav) {
|
||||
var p = nav.querySelector('p');
|
||||
if (!p) return;
|
||||
var children = Array.from(p.childNodes);
|
||||
var pairs = [];
|
||||
for (var i = 0; i + 1 < children.length; i++) {
|
||||
var cur = children[i];
|
||||
var nxt = children[i + 1];
|
||||
if (cur.nodeType === Node.TEXT_NODE &&
|
||||
/[A-Z][a-z]*:\s*/.test(cur.textContent) &&
|
||||
nxt.nodeType === Node.ELEMENT_NODE &&
|
||||
nxt.tagName === 'A') {
|
||||
pairs.push([cur, nxt]);
|
||||
i++; // skip the anchor on the next iteration
|
||||
}
|
||||
}
|
||||
pairs.forEach(function (pair) {
|
||||
var span = document.createElement('span');
|
||||
span.className = 'nav-item';
|
||||
p.insertBefore(span, pair[0]);
|
||||
span.appendChild(pair[0]);
|
||||
span.appendChild(pair[1]);
|
||||
});
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<nav id="sitenav">
|
||||
<div class="sitenav">
|
||||
<span class="navlink">
|
||||
<span class="navlink-label">Up:</span> <a href="index.html" accesskey="u" rel="up">FISH-CONFIG</a>
|
||||
</span>
|
||||
<span class="navlink">
|
||||
<span class="navlink-label">Top:</span> <a href="index.html" accesskey="t" rel="top">FISH-CONFIG</a>
|
||||
</span>
|
||||
</div>
|
||||
<div class="sitenav">
|
||||
<span class="navlink">
|
||||
<span class="navlink-label">Next:</span> <a href="8-4-abbreviations.html" accesskey="n" rel="next">4. ABBREVIATIONS</a>
|
||||
</span>
|
||||
<span class="navlink">
|
||||
<span class="navlink-label">Previous:</span> <a href="6-2-path-setup.html" accesskey="p" rel="previous">2. PATH SETUP</a>
|
||||
</span>
|
||||
</div>
|
||||
</nav>
|
||||
<h1 data-number="7" id="3-key-bindings">3. KEY BINDINGS</h1>
|
||||
<p>The shell uses Vi key bindings (fish_vi_key_bindings). All custom
|
||||
bindings are active in Insert, Normal, and Visual modes unless
|
||||
noted.</p>
|
||||
<pre><code>Binding Action
|
||||
─────────────────────────────────────────────────────────────────────
|
||||
Ctrl+G Insert the head of the previous command's last path
|
||||
argument. Equivalent to !$:h in Bash.
|
||||
Example: previous = "cd /usr/local/bin"
|
||||
Ctrl+G inserts "/usr/local"
|
||||
|
||||
Ctrl+F Interactive history substitution. Type old/new then
|
||||
press Ctrl+F to apply s/old/new/ to the previous
|
||||
command. Equivalent to !!:s/old/new/ in Bash.
|
||||
Example: previous = "echo this is a test"
|
||||
type "this is/that was", press Ctrl+F
|
||||
result = "echo that was a test"
|
||||
|
||||
Ctrl+Alt+U Strip the first token of the current command line,
|
||||
leaving arguments in place with the cursor at the
|
||||
start. Useful for quickly retyping the command.
|
||||
Example: "mkdir new_folder" -> " new_folder"
|
||||
|
||||
Ctrl+Alt+= Evaluate the current command line buffer with
|
||||
Qalculate! (qalc) and print the result inline.
|
||||
Requires qalc to be installed.
|
||||
Example: type "150 * 1.08", press Ctrl+Alt+=
|
||||
prints 162
|
||||
|
||||
Ctrl+Enter Smart execute: runs commands instantly without
|
||||
pressing Enter a second time for certain fast-path
|
||||
commands (speedtest-fast, etc.).
|
||||
|
||||
@@ FZF inline picker. Type @@ anywhere on the command
|
||||
line to open an fzf picker and insert a selection
|
||||
at the cursor position.</code></pre>
|
||||
<h2 data-number="7.1"
|
||||
id="fzf-bindings-bundled-from-patrickf1fzffish">FZF Bindings (bundled
|
||||
from PatrickF1/fzf.fish)</h2>
|
||||
<pre><code>Ctrl+R Search command history
|
||||
Ctrl+Alt+F Search git-tracked files
|
||||
Ctrl+Alt+L Search git log
|
||||
Ctrl+Alt+S Search git status
|
||||
Ctrl+V Search shell variables
|
||||
Ctrl+Alt+P Search running processes</code></pre>
|
||||
<hr />
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,641 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" lang="" xml:lang="">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="generator" content="pandoc" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" />
|
||||
<meta name="author" content="Rootiest" />
|
||||
<title>4. ABBREVIATIONS</title>
|
||||
<style>
|
||||
div.sitenav { display: flex; flex-direction: row; flex-wrap: wrap; }
|
||||
span.navlink { flex: 1; }
|
||||
span.navlink-label { display: inline-block; min-width: 4em; }
|
||||
html {
|
||||
color: #1a1a1a;
|
||||
background-color: #fdfdfd;
|
||||
}
|
||||
body {
|
||||
margin: 0 auto;
|
||||
max-width: 36em;
|
||||
padding-left: 50px;
|
||||
padding-right: 50px;
|
||||
padding-top: 50px;
|
||||
padding-bottom: 50px;
|
||||
hyphens: auto;
|
||||
overflow-wrap: break-word;
|
||||
text-rendering: optimizeLegibility;
|
||||
font-kerning: normal;
|
||||
}
|
||||
@media (max-width: 600px) {
|
||||
body {
|
||||
font-size: 0.9em;
|
||||
padding: 12px;
|
||||
}
|
||||
h1 {
|
||||
font-size: 1.8em;
|
||||
}
|
||||
}
|
||||
@media print {
|
||||
html {
|
||||
background-color: white;
|
||||
}
|
||||
body {
|
||||
background-color: transparent;
|
||||
color: black;
|
||||
font-size: 12pt;
|
||||
}
|
||||
p, h2, h3 {
|
||||
orphans: 3;
|
||||
widows: 3;
|
||||
}
|
||||
h2, h3, h4 {
|
||||
page-break-after: avoid;
|
||||
}
|
||||
}
|
||||
p {
|
||||
margin: 1em 0;
|
||||
}
|
||||
a {
|
||||
color: #1a1a1a;
|
||||
}
|
||||
a:visited {
|
||||
color: #1a1a1a;
|
||||
}
|
||||
img {
|
||||
max-width: 100%;
|
||||
}
|
||||
h1, h2, h3, h4, h5, h6 {
|
||||
margin-top: 1.4em;
|
||||
}
|
||||
h5, h6 {
|
||||
font-size: 1em;
|
||||
font-style: italic;
|
||||
}
|
||||
h6 {
|
||||
font-weight: normal;
|
||||
}
|
||||
ol, ul {
|
||||
padding-left: 1.7em;
|
||||
margin-top: 1em;
|
||||
}
|
||||
li > ol, li > ul {
|
||||
margin-top: 0;
|
||||
}
|
||||
blockquote {
|
||||
margin: 1em 0 1em 1.7em;
|
||||
padding-left: 1em;
|
||||
border-left: 2px solid #e6e6e6;
|
||||
color: #606060;
|
||||
}
|
||||
code {
|
||||
font-family: Menlo, Monaco, Consolas, 'Lucida Console', monospace;
|
||||
font-size: 85%;
|
||||
margin: 0;
|
||||
hyphens: manual;
|
||||
}
|
||||
pre {
|
||||
margin: 1em 0;
|
||||
overflow: auto;
|
||||
}
|
||||
pre code {
|
||||
padding: 0;
|
||||
overflow: visible;
|
||||
overflow-wrap: normal;
|
||||
}
|
||||
.sourceCode {
|
||||
background-color: transparent;
|
||||
overflow: visible;
|
||||
}
|
||||
hr {
|
||||
background-color: #1a1a1a;
|
||||
border: none;
|
||||
height: 1px;
|
||||
margin: 1em 0;
|
||||
}
|
||||
table {
|
||||
margin: 1em 0;
|
||||
border-collapse: collapse;
|
||||
width: 100%;
|
||||
overflow-x: auto;
|
||||
display: block;
|
||||
font-variant-numeric: lining-nums tabular-nums;
|
||||
}
|
||||
table caption {
|
||||
margin-bottom: 0.75em;
|
||||
}
|
||||
tbody {
|
||||
margin-top: 0.5em;
|
||||
border-top: 1px solid #1a1a1a;
|
||||
border-bottom: 1px solid #1a1a1a;
|
||||
}
|
||||
th {
|
||||
border-top: 1px solid #1a1a1a;
|
||||
padding: 0.25em 0.5em 0.25em 0.5em;
|
||||
}
|
||||
td {
|
||||
padding: 0.125em 0.5em 0.25em 0.5em;
|
||||
}
|
||||
header {
|
||||
margin-bottom: 4em;
|
||||
text-align: center;
|
||||
}
|
||||
#TOC li {
|
||||
list-style: none;
|
||||
}
|
||||
#TOC ul {
|
||||
padding-left: 1.3em;
|
||||
}
|
||||
#TOC > ul {
|
||||
padding-left: 0;
|
||||
}
|
||||
#TOC a:not(:hover) {
|
||||
text-decoration: none;
|
||||
}
|
||||
code{white-space: pre-wrap;}
|
||||
span.smallcaps{font-variant: small-caps;}
|
||||
div.columns{display: flex; gap: min(4vw, 1.5em);}
|
||||
div.column{flex: auto; overflow-x: auto;}
|
||||
div.hanging-indent{margin-left: 1.5em; text-indent: -1.5em;}
|
||||
/* The extra [class] is a hack that increases specificity enough to
|
||||
override a similar rule in reveal.js */
|
||||
ul.task-list[class]{list-style: none;}
|
||||
ul.task-list li input[type="checkbox"] {
|
||||
font-size: inherit;
|
||||
width: 0.8em;
|
||||
margin: 0 0.8em 0.2em -1.6em;
|
||||
vertical-align: middle;
|
||||
}
|
||||
.display.math{display: block; text-align: center; margin: 0.5rem auto;}
|
||||
</style>
|
||||
<style>
|
||||
/* ── Catppuccin Latte (light) / Mocha (dark) ─────────────────── */
|
||||
:root {
|
||||
color-scheme: light dark;
|
||||
--bg: #eff1f5;
|
||||
--surface: #e6e9ef;
|
||||
--overlay: #ccd0da;
|
||||
--text: #4c4f69;
|
||||
--sub1: #6c6f85;
|
||||
--sub0: #8c8fa1;
|
||||
--blue: #1e66f5;
|
||||
--lavender: #7287fd;
|
||||
--sapphire: #209fb5;
|
||||
--green: #40a02b;
|
||||
--yellow: #df8e1d;
|
||||
--peach: #fe640b;
|
||||
--mauve: #8839ef;
|
||||
--code-bg: #dce0e8;
|
||||
--border: #bcc0cc;
|
||||
--glow1: rgba(30, 102, 245, 0.05);
|
||||
--glow2: rgba(136, 57, 239, 0.04);
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
:root {
|
||||
--bg: #1e1e2e;
|
||||
--surface: #313244;
|
||||
--overlay: #45475a;
|
||||
--text: #cdd6f4;
|
||||
--sub1: #bac2de;
|
||||
--sub0: #a6adc8;
|
||||
--blue: #89b4fa;
|
||||
--lavender: #b4befe;
|
||||
--sapphire: #74c7ec;
|
||||
--green: #a6e3a1;
|
||||
--yellow: #f9e2af;
|
||||
--peach: #fab387;
|
||||
--mauve: #cba6f7;
|
||||
--code-bg: #181825;
|
||||
--border: #45475a;
|
||||
--glow1: rgba(137, 180, 250, 0.06);
|
||||
--glow2: rgba(203, 166, 247, 0.05);
|
||||
}
|
||||
}
|
||||
|
||||
*, *::before, *::after { box-sizing: border-box; }
|
||||
|
||||
html {
|
||||
background-color: var(--bg);
|
||||
background-image:
|
||||
radial-gradient(ellipse 55% 40% at 10% 5%, var(--glow1) 0%, transparent 100%),
|
||||
radial-gradient(ellipse 45% 45% at 90% 95%, var(--glow2) 0%, transparent 100%);
|
||||
min-height: 100%;
|
||||
}
|
||||
|
||||
body {
|
||||
color: var(--text);
|
||||
font-family: system-ui, -apple-system, "Segoe UI", Helvetica, sans-serif;
|
||||
font-size: 16px;
|
||||
line-height: 1.75;
|
||||
max-width: 880px;
|
||||
margin: 0 auto;
|
||||
padding: 2rem 2.5rem 5rem;
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
/* ── Links ─────────────────────────────────────────────────── */
|
||||
a { color: var(--blue); text-decoration: none; }
|
||||
a:hover { color: var(--lavender); text-decoration: underline; }
|
||||
a:visited { color: var(--lavender); }
|
||||
|
||||
/* ── Headings ──────────────────────────────────────────────── */
|
||||
h1, h2, h3, h4, h5, h6 {
|
||||
font-family: "JetBrains Mono", "Fira Code", ui-monospace, monospace;
|
||||
color: var(--lavender);
|
||||
line-height: 1.3;
|
||||
margin-top: 2em;
|
||||
margin-bottom: 0.5em;
|
||||
}
|
||||
h1 {
|
||||
font-size: 1.9rem;
|
||||
color: var(--text);
|
||||
border-bottom: 1px solid var(--border);
|
||||
padding-bottom: 0.4em;
|
||||
margin-top: 1.2em;
|
||||
}
|
||||
h2 {
|
||||
font-size: 1.35rem;
|
||||
border-bottom: 1px solid var(--border);
|
||||
padding-bottom: 0.2em;
|
||||
}
|
||||
h3 { font-size: 1.1rem; color: var(--sapphire); }
|
||||
h4 { font-size: 0.95rem; color: var(--sub1); }
|
||||
|
||||
p { margin: 0.8em 0; }
|
||||
|
||||
/* ── Title block (pandoc-generated cover) ──────────────────── */
|
||||
#title-block-header {
|
||||
text-align: center;
|
||||
padding: 2.5rem 0 2rem;
|
||||
margin-bottom: 1.5rem;
|
||||
border-bottom: 1px solid var(--border);
|
||||
}
|
||||
#title-block-header .title {
|
||||
font-family: "JetBrains Mono", "Fira Code", ui-monospace, monospace;
|
||||
font-size: 2.6rem;
|
||||
letter-spacing: 0.12em;
|
||||
color: var(--lavender);
|
||||
border: none;
|
||||
margin: 0 0 0.75rem;
|
||||
}
|
||||
#title-block-header .author,
|
||||
#title-block-header .date {
|
||||
color: var(--sub0);
|
||||
font-size: 0.875rem;
|
||||
margin: 0.2rem 0;
|
||||
}
|
||||
|
||||
/* ── Inline code ───────────────────────────────────────────── */
|
||||
code {
|
||||
font-family: "JetBrains Mono", "Fira Code", ui-monospace, monospace;
|
||||
background: var(--code-bg);
|
||||
color: var(--peach);
|
||||
padding: 0.15em 0.4em;
|
||||
border-radius: 4px;
|
||||
font-size: 0.875em;
|
||||
}
|
||||
|
||||
/* ── Code blocks ───────────────────────────────────────────── */
|
||||
pre {
|
||||
background: var(--code-bg);
|
||||
border: 1px solid var(--border);
|
||||
border-left: 3px solid var(--sapphire);
|
||||
border-radius: 0 8px 8px 0;
|
||||
padding: 1.1em 1.4em;
|
||||
overflow-x: auto;
|
||||
line-height: 1.55;
|
||||
margin: 1.2em 0;
|
||||
}
|
||||
pre code {
|
||||
background: none;
|
||||
color: var(--text);
|
||||
padding: 0;
|
||||
font-size: 0.88em;
|
||||
}
|
||||
|
||||
/* ── Blockquotes ───────────────────────────────────────────── */
|
||||
blockquote {
|
||||
border-left: 3px solid var(--yellow);
|
||||
margin: 1.5em 0;
|
||||
padding: 0.75em 1.25em;
|
||||
background: var(--surface);
|
||||
color: var(--sub1);
|
||||
border-radius: 0 6px 6px 0;
|
||||
}
|
||||
blockquote p { margin: 0.3em 0; }
|
||||
|
||||
/* ── Tables ────────────────────────────────────────────────── */
|
||||
table {
|
||||
border-collapse: collapse;
|
||||
width: 100%;
|
||||
margin: 1.4em 0;
|
||||
font-size: 0.93em;
|
||||
}
|
||||
th, td {
|
||||
border: 1px solid var(--border);
|
||||
padding: 0.55em 0.9em;
|
||||
text-align: left;
|
||||
}
|
||||
th {
|
||||
background: var(--surface);
|
||||
color: var(--lavender);
|
||||
font-weight: 600;
|
||||
font-family: "JetBrains Mono", "Fira Code", ui-monospace, monospace;
|
||||
font-size: 0.82em;
|
||||
letter-spacing: 0.06em;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
tr:nth-child(even) { background: var(--surface); }
|
||||
tr:hover { background: var(--overlay); }
|
||||
|
||||
/* ── HR ────────────────────────────────────────────────────── */
|
||||
hr { border: none; border-top: 1px solid var(--border); margin: 2.5em 0; }
|
||||
|
||||
/* ── Lists ─────────────────────────────────────────────────── */
|
||||
ul, ol { padding-left: 1.6em; }
|
||||
li { margin: 0.35em 0; }
|
||||
|
||||
/* ── Chunk navigation bar (prev / up / next) ───────────────── */
|
||||
nav:not(#TOC):not([role="doc-toc"]) {
|
||||
background: var(--surface);
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 8px;
|
||||
margin: 1.5em 0;
|
||||
font-size: 0.875em;
|
||||
overflow: hidden;
|
||||
}
|
||||
nav:not(#TOC):not([role="doc-toc"]) p {
|
||||
margin: 0;
|
||||
padding: 0.65em 1.2em;
|
||||
display: flex;
|
||||
gap: 0.4em 1.75em;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
}
|
||||
/* JS wraps each "Label: <a>" pair in .nav-item so they flex as a unit */
|
||||
.nav-item {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 0.3em;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.nav-item a { color: var(--blue); }
|
||||
.nav-item a:hover { color: var(--lavender); }
|
||||
|
||||
/* ── Table of contents panel ───────────────────────────────── */
|
||||
nav#TOC, nav[role="doc-toc"] {
|
||||
display: block;
|
||||
background: var(--surface);
|
||||
border: 1px solid var(--border);
|
||||
border-left: 3px solid var(--lavender);
|
||||
border-radius: 0 8px 8px 0;
|
||||
padding: 1.2em 1.5em;
|
||||
margin: 1.5em 0;
|
||||
}
|
||||
nav#TOC > h2,
|
||||
nav[role="doc-toc"] > h2 {
|
||||
font-size: 0.7rem;
|
||||
letter-spacing: 0.14em;
|
||||
text-transform: uppercase;
|
||||
color: var(--sub0);
|
||||
border: none;
|
||||
margin: 0 0 0.9em;
|
||||
padding: 0;
|
||||
}
|
||||
nav#TOC ul, nav[role="doc-toc"] ul {
|
||||
list-style: none;
|
||||
padding-left: 1em;
|
||||
margin: 0.25em 0;
|
||||
}
|
||||
nav#TOC > ul, nav[role="doc-toc"] > ul { padding-left: 0; }
|
||||
nav#TOC li, nav[role="doc-toc"] li {
|
||||
margin: 0.3em 0;
|
||||
padding-left: 0.75em;
|
||||
border-left: 1px solid transparent;
|
||||
transition: border-color 0.12s;
|
||||
}
|
||||
nav#TOC li:hover, nav[role="doc-toc"] li:hover {
|
||||
border-left-color: var(--lavender);
|
||||
}
|
||||
nav#TOC a, nav[role="doc-toc"] a {
|
||||
color: var(--sub1);
|
||||
font-size: 0.9em;
|
||||
}
|
||||
nav#TOC a:hover, nav[role="doc-toc"] a:hover {
|
||||
color: var(--lavender);
|
||||
text-decoration: none;
|
||||
}
|
||||
</style>
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
/* ── Hide ToC on every page except index.html ───────────── */
|
||||
var path = location.pathname;
|
||||
var onIndex = path === '/' || path === '' || /\/index\.html(\?.*)?$/.test(path);
|
||||
if (!onIndex) {
|
||||
var toc = document.getElementById('TOC') ||
|
||||
document.querySelector('[role="doc-toc"]');
|
||||
if (toc) toc.remove();
|
||||
}
|
||||
|
||||
/* ── Wrap each "Label: <a>" pair in a .nav-item span ───────
|
||||
Pandoc emits label text nodes and anchors as siblings;
|
||||
flex sees them as separate items, causing labels to split
|
||||
from their links when wrapping. Grouping them in a span
|
||||
keeps each label+link as a single flex unit. */
|
||||
document.querySelectorAll('nav:not(#TOC):not([role="doc-toc"])').forEach(function (nav) {
|
||||
var p = nav.querySelector('p');
|
||||
if (!p) return;
|
||||
var children = Array.from(p.childNodes);
|
||||
var pairs = [];
|
||||
for (var i = 0; i + 1 < children.length; i++) {
|
||||
var cur = children[i];
|
||||
var nxt = children[i + 1];
|
||||
if (cur.nodeType === Node.TEXT_NODE &&
|
||||
/[A-Z][a-z]*:\s*/.test(cur.textContent) &&
|
||||
nxt.nodeType === Node.ELEMENT_NODE &&
|
||||
nxt.tagName === 'A') {
|
||||
pairs.push([cur, nxt]);
|
||||
i++; // skip the anchor on the next iteration
|
||||
}
|
||||
}
|
||||
pairs.forEach(function (pair) {
|
||||
var span = document.createElement('span');
|
||||
span.className = 'nav-item';
|
||||
p.insertBefore(span, pair[0]);
|
||||
span.appendChild(pair[0]);
|
||||
span.appendChild(pair[1]);
|
||||
});
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<nav id="sitenav">
|
||||
<div class="sitenav">
|
||||
<span class="navlink">
|
||||
<span class="navlink-label">Up:</span> <a href="index.html" accesskey="u" rel="up">FISH-CONFIG</a>
|
||||
</span>
|
||||
<span class="navlink">
|
||||
<span class="navlink-label">Top:</span> <a href="index.html" accesskey="t" rel="top">FISH-CONFIG</a>
|
||||
</span>
|
||||
</div>
|
||||
<div class="sitenav">
|
||||
<span class="navlink">
|
||||
<span class="navlink-label">Next:</span> <a href="9-5-functions-reference.html" accesskey="n" rel="next">5. FUNCTIONS REFERENCE</a>
|
||||
</span>
|
||||
<span class="navlink">
|
||||
<span class="navlink-label">Previous:</span> <a href="7-3-key-bindings.html" accesskey="p" rel="previous">3. KEY BINDINGS</a>
|
||||
</span>
|
||||
</div>
|
||||
</nav>
|
||||
<h1 data-number="8" id="4-abbreviations">4. ABBREVIATIONS</h1>
|
||||
<p>Abbreviations expand when you press Space or Enter. They are
|
||||
terminal-aware: some expand differently in Kitty vs WezTerm vs other
|
||||
terminals.</p>
|
||||
<h2 data-number="8.1" id="41-editors">4.1 Editors</h2>
|
||||
<pre><code>n / nv / neovim nvim
|
||||
e edit
|
||||
se sudoedit
|
||||
k kate
|
||||
editt Open new tab with nvim (terminal-aware)
|
||||
cdnv cd ~/.config/nvim
|
||||
cdnvn cd ~/.config/nvim; nvim</code></pre>
|
||||
<h2 data-number="8.2" id="42-navigation-and-listing">4.2 Navigation and
|
||||
Listing</h2>
|
||||
<pre><code>l ls
|
||||
lS lss (sort by size)
|
||||
lsR lsr (sort by time, oldest first)
|
||||
lX lx (sort by extension)
|
||||
lT lt (tree, depth 2)
|
||||
lsT lstree (full recursive tree)
|
||||
lzd ld (lazydocker)
|
||||
cdi zi (interactive zoxide picker)</code></pre>
|
||||
<h2 data-number="8.3" id="43-git">4.3 Git</h2>
|
||||
<pre><code>g git
|
||||
lg lazygit
|
||||
gitig / git-ignore gi (generate .gitignore)</code></pre>
|
||||
<h2 data-number="8.4" id="44-terminal-windows-tabs-and-panes">4.4
|
||||
Terminal Windows, Tabs, and Panes</h2>
|
||||
<p>These abbreviations control the terminal emulator. Each has a Kitty
|
||||
variant and a WezTerm variant; the correct one is inserted based on
|
||||
$TERM or $TERM_PROGRAM.</p>
|
||||
<pre><code>:w New OS window
|
||||
:wv Split pane horizontally (new pane below)
|
||||
:wh Split pane vertically (new pane to the right)
|
||||
:wo Detach current window to its own OS window
|
||||
:wot Move current pane to a new tab
|
||||
:t New tab
|
||||
:tl Set tab title
|
||||
:tw Set window title
|
||||
:twk Rename workspace (WezTerm only)
|
||||
:tp Focus previous tab
|
||||
:tn Focus next tab
|
||||
:q Close current pane/window
|
||||
:Q Close current tab
|
||||
:sw spwin (spawn new OS window)</code></pre>
|
||||
<p>Quick-navigate shortcuts open windows/tabs/panes with preset working
|
||||
dirs:</p>
|
||||
<pre><code>:tgk New tab at ~/.config/kitty
|
||||
:tgn New tab at ~/.config/nvim
|
||||
:tgf New tab at ~/.config/fish
|
||||
:tgh New tab at ~
|
||||
:tgcz New tab at chezmoi source dir
|
||||
:tgcm New tab at chezmoi source dir
|
||||
:tgp New tab at ~/projects
|
||||
:tgr New tab at / (root)</code></pre>
|
||||
<p>Prefixes :wg* and :wvg* / :whg* open OS windows or splits to the same
|
||||
set of dirs, respectively.</p>
|
||||
<p>Prefixes :cd* open tabs with a quick cd shortcut:</p>
|
||||
<pre><code>:cdn cd ~/.config/nvim
|
||||
:cdf cd ~/.config/fish
|
||||
:cdh cd ~
|
||||
:cdcz cd to chezmoi source
|
||||
:cdp cd ~/projects</code></pre>
|
||||
<p>Appending n to any :cd* abbreviation also runs nvim after changing
|
||||
dir.</p>
|
||||
<h2 data-number="8.5" id="45-chezmoi">4.5 Chezmoi</h2>
|
||||
<pre><code>cm / cme / cmi / cmap / cmad / cmrm / cmcd /
|
||||
cz / cze / czi / czap / czad / czrm / czcd
|
||||
|
||||
cm / cz chezmoi
|
||||
cmcd / czcd chezmoi cd
|
||||
cme / cze chezmoi edit
|
||||
cmad / czad chezmoi add
|
||||
cmap / czap chezmoi apply
|
||||
cmrm / cmf / czrm / czf chezmoi forget
|
||||
cmi / czi chezmoi init</code></pre>
|
||||
<h2 data-number="8.6" id="46-docker">4.6 Docker</h2>
|
||||
<pre><code>dcl docker context use default
|
||||
dcls docker context ls
|
||||
lzd ld (lazydocker)</code></pre>
|
||||
<h2 data-number="8.7" id="47-systemctl">4.7 Systemctl</h2>
|
||||
<pre><code>sc systemctl
|
||||
ssc sudo systemctl
|
||||
scu systemctl --user
|
||||
st systemctl status
|
||||
scs sudo systemctl start
|
||||
scr sudo systemctl restart
|
||||
ssct sudo systemctl start
|
||||
sscs sudo systemctl stop
|
||||
sscr sudo systemctl restart</code></pre>
|
||||
<h2 data-number="8.8" id="48-ai-assistants">4.8 AI Assistants</h2>
|
||||
<pre><code>ag antigravity
|
||||
ag. antigravity .
|
||||
v antigravity-ide
|
||||
s wezterm ssh (WezTerm only)</code></pre>
|
||||
<h2 data-number="8.9" id="49-history-expansion">4.9 History
|
||||
Expansion</h2>
|
||||
<p>These are implemented as keybinding helpers, but can also be
|
||||
typed:</p>
|
||||
<pre><code>!^ Expand to first argument of previous command
|
||||
!* Expand to all arguments of previous command
|
||||
typo_sub Interactive typo substitution (Ctrl+F)
|
||||
bang_string !string expansion
|
||||
bang_search !?string search
|
||||
bang_minus_n !-n (nth-previous command)</code></pre>
|
||||
<h2 data-number="8.10" id="410-miscellaneous">4.10 Miscellaneous</h2>
|
||||
<pre><code>/exit exit
|
||||
:q Close pane (alias for terminal close)
|
||||
:Q Close tab
|
||||
sudu sudo -s
|
||||
kt kitty (Kitty only)
|
||||
c cat
|
||||
speedtest-fast fast-cli
|
||||
bl bd list
|
||||
bs bd sync
|
||||
bC bd create --title
|
||||
bsh bd show
|
||||
lb lazybeads</code></pre>
|
||||
<h2 data-number="8.11" id="411-shell-aliases">4.11 Shell Aliases</h2>
|
||||
<p>These aliases are defined in conf.d/tricks.fish via alias (which
|
||||
creates Fish functions). They are active in all interactive
|
||||
sessions.</p>
|
||||
<h3 data-number="8.11.1" id="navigation">Navigation</h3>
|
||||
<pre><code>.. cd ..
|
||||
... cd ../..
|
||||
.... cd ../../..
|
||||
..... cd ../../../..
|
||||
...... cd ../../../../..</code></pre>
|
||||
<h3 data-number="8.11.2" id="color-overrides">Color Overrides</h3>
|
||||
<p>Force color output for common tools:</p>
|
||||
<pre><code>grep grep --color=auto
|
||||
fgrep fgrep --color=auto
|
||||
egrep egrep --color=auto
|
||||
dir dir --color=auto
|
||||
vdir vdir --color=auto</code></pre>
|
||||
<h3 data-number="8.11.3" id="safety-wrappers">Safety Wrappers</h3>
|
||||
<p>Add -i (interactive confirmation) to destructive commands:</p>
|
||||
<pre><code>cp cp -i
|
||||
mv mv -i</code></pre>
|
||||
<h3 data-number="8.11.4" id="archives-and-networking">Archives and
|
||||
Networking</h3>
|
||||
<pre><code>tarnow tar -acf Create compressed archive (auto-detects format)
|
||||
untar tar -zxvf Extract a gzip-compressed archive
|
||||
wget wget -c Resume interrupted downloads by default
|
||||
tb nc termbin.com 9999 Pipe content to termbin.com for quick sharing</code></pre>
|
||||
<h3 data-number="8.11.5" id="system-logs">System Logs</h3>
|
||||
<pre><code>jctl journalctl -p 3 -xb Show priority-3 (error) journal entries
|
||||
from the current boot</code></pre>
|
||||
<hr />
|
||||
</body>
|
||||
</html>
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,893 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" lang="" xml:lang="">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="generator" content="pandoc" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" />
|
||||
<meta name="author" content="Rootiest" />
|
||||
<title>FISH-CONFIG</title>
|
||||
<style>
|
||||
div.sitenav { display: flex; flex-direction: row; flex-wrap: wrap; }
|
||||
span.navlink { flex: 1; }
|
||||
span.navlink-label { display: inline-block; min-width: 4em; }
|
||||
html {
|
||||
color: #1a1a1a;
|
||||
background-color: #fdfdfd;
|
||||
}
|
||||
body {
|
||||
margin: 0 auto;
|
||||
max-width: 36em;
|
||||
padding-left: 50px;
|
||||
padding-right: 50px;
|
||||
padding-top: 50px;
|
||||
padding-bottom: 50px;
|
||||
hyphens: auto;
|
||||
overflow-wrap: break-word;
|
||||
text-rendering: optimizeLegibility;
|
||||
font-kerning: normal;
|
||||
}
|
||||
@media (max-width: 600px) {
|
||||
body {
|
||||
font-size: 0.9em;
|
||||
padding: 12px;
|
||||
}
|
||||
h1 {
|
||||
font-size: 1.8em;
|
||||
}
|
||||
}
|
||||
@media print {
|
||||
html {
|
||||
background-color: white;
|
||||
}
|
||||
body {
|
||||
background-color: transparent;
|
||||
color: black;
|
||||
font-size: 12pt;
|
||||
}
|
||||
p, h2, h3 {
|
||||
orphans: 3;
|
||||
widows: 3;
|
||||
}
|
||||
h2, h3, h4 {
|
||||
page-break-after: avoid;
|
||||
}
|
||||
}
|
||||
p {
|
||||
margin: 1em 0;
|
||||
}
|
||||
a {
|
||||
color: #1a1a1a;
|
||||
}
|
||||
a:visited {
|
||||
color: #1a1a1a;
|
||||
}
|
||||
img {
|
||||
max-width: 100%;
|
||||
}
|
||||
h1, h2, h3, h4, h5, h6 {
|
||||
margin-top: 1.4em;
|
||||
}
|
||||
h5, h6 {
|
||||
font-size: 1em;
|
||||
font-style: italic;
|
||||
}
|
||||
h6 {
|
||||
font-weight: normal;
|
||||
}
|
||||
ol, ul {
|
||||
padding-left: 1.7em;
|
||||
margin-top: 1em;
|
||||
}
|
||||
li > ol, li > ul {
|
||||
margin-top: 0;
|
||||
}
|
||||
blockquote {
|
||||
margin: 1em 0 1em 1.7em;
|
||||
padding-left: 1em;
|
||||
border-left: 2px solid #e6e6e6;
|
||||
color: #606060;
|
||||
}
|
||||
code {
|
||||
font-family: Menlo, Monaco, Consolas, 'Lucida Console', monospace;
|
||||
font-size: 85%;
|
||||
margin: 0;
|
||||
hyphens: manual;
|
||||
}
|
||||
pre {
|
||||
margin: 1em 0;
|
||||
overflow: auto;
|
||||
}
|
||||
pre code {
|
||||
padding: 0;
|
||||
overflow: visible;
|
||||
overflow-wrap: normal;
|
||||
}
|
||||
.sourceCode {
|
||||
background-color: transparent;
|
||||
overflow: visible;
|
||||
}
|
||||
hr {
|
||||
background-color: #1a1a1a;
|
||||
border: none;
|
||||
height: 1px;
|
||||
margin: 1em 0;
|
||||
}
|
||||
table {
|
||||
margin: 1em 0;
|
||||
border-collapse: collapse;
|
||||
width: 100%;
|
||||
overflow-x: auto;
|
||||
display: block;
|
||||
font-variant-numeric: lining-nums tabular-nums;
|
||||
}
|
||||
table caption {
|
||||
margin-bottom: 0.75em;
|
||||
}
|
||||
tbody {
|
||||
margin-top: 0.5em;
|
||||
border-top: 1px solid #1a1a1a;
|
||||
border-bottom: 1px solid #1a1a1a;
|
||||
}
|
||||
th {
|
||||
border-top: 1px solid #1a1a1a;
|
||||
padding: 0.25em 0.5em 0.25em 0.5em;
|
||||
}
|
||||
td {
|
||||
padding: 0.125em 0.5em 0.25em 0.5em;
|
||||
}
|
||||
header {
|
||||
margin-bottom: 4em;
|
||||
text-align: center;
|
||||
}
|
||||
#TOC li {
|
||||
list-style: none;
|
||||
}
|
||||
#TOC ul {
|
||||
padding-left: 1.3em;
|
||||
}
|
||||
#TOC > ul {
|
||||
padding-left: 0;
|
||||
}
|
||||
#TOC a:not(:hover) {
|
||||
text-decoration: none;
|
||||
}
|
||||
code{white-space: pre-wrap;}
|
||||
span.smallcaps{font-variant: small-caps;}
|
||||
div.columns{display: flex; gap: min(4vw, 1.5em);}
|
||||
div.column{flex: auto; overflow-x: auto;}
|
||||
div.hanging-indent{margin-left: 1.5em; text-indent: -1.5em;}
|
||||
/* The extra [class] is a hack that increases specificity enough to
|
||||
override a similar rule in reveal.js */
|
||||
ul.task-list[class]{list-style: none;}
|
||||
ul.task-list li input[type="checkbox"] {
|
||||
font-size: inherit;
|
||||
width: 0.8em;
|
||||
margin: 0 0.8em 0.2em -1.6em;
|
||||
vertical-align: middle;
|
||||
}
|
||||
.display.math{display: block; text-align: center; margin: 0.5rem auto;}
|
||||
</style>
|
||||
<style>
|
||||
/* ── Catppuccin Latte (light) / Mocha (dark) ─────────────────── */
|
||||
:root {
|
||||
color-scheme: light dark;
|
||||
--bg: #eff1f5;
|
||||
--surface: #e6e9ef;
|
||||
--overlay: #ccd0da;
|
||||
--text: #4c4f69;
|
||||
--sub1: #6c6f85;
|
||||
--sub0: #8c8fa1;
|
||||
--blue: #1e66f5;
|
||||
--lavender: #7287fd;
|
||||
--sapphire: #209fb5;
|
||||
--green: #40a02b;
|
||||
--yellow: #df8e1d;
|
||||
--peach: #fe640b;
|
||||
--mauve: #8839ef;
|
||||
--code-bg: #dce0e8;
|
||||
--border: #bcc0cc;
|
||||
--glow1: rgba(30, 102, 245, 0.05);
|
||||
--glow2: rgba(136, 57, 239, 0.04);
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
:root {
|
||||
--bg: #1e1e2e;
|
||||
--surface: #313244;
|
||||
--overlay: #45475a;
|
||||
--text: #cdd6f4;
|
||||
--sub1: #bac2de;
|
||||
--sub0: #a6adc8;
|
||||
--blue: #89b4fa;
|
||||
--lavender: #b4befe;
|
||||
--sapphire: #74c7ec;
|
||||
--green: #a6e3a1;
|
||||
--yellow: #f9e2af;
|
||||
--peach: #fab387;
|
||||
--mauve: #cba6f7;
|
||||
--code-bg: #181825;
|
||||
--border: #45475a;
|
||||
--glow1: rgba(137, 180, 250, 0.06);
|
||||
--glow2: rgba(203, 166, 247, 0.05);
|
||||
}
|
||||
}
|
||||
|
||||
*, *::before, *::after { box-sizing: border-box; }
|
||||
|
||||
html {
|
||||
background-color: var(--bg);
|
||||
background-image:
|
||||
radial-gradient(ellipse 55% 40% at 10% 5%, var(--glow1) 0%, transparent 100%),
|
||||
radial-gradient(ellipse 45% 45% at 90% 95%, var(--glow2) 0%, transparent 100%);
|
||||
min-height: 100%;
|
||||
}
|
||||
|
||||
body {
|
||||
color: var(--text);
|
||||
font-family: system-ui, -apple-system, "Segoe UI", Helvetica, sans-serif;
|
||||
font-size: 16px;
|
||||
line-height: 1.75;
|
||||
max-width: 880px;
|
||||
margin: 0 auto;
|
||||
padding: 2rem 2.5rem 5rem;
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
/* ── Links ─────────────────────────────────────────────────── */
|
||||
a { color: var(--blue); text-decoration: none; }
|
||||
a:hover { color: var(--lavender); text-decoration: underline; }
|
||||
a:visited { color: var(--lavender); }
|
||||
|
||||
/* ── Headings ──────────────────────────────────────────────── */
|
||||
h1, h2, h3, h4, h5, h6 {
|
||||
font-family: "JetBrains Mono", "Fira Code", ui-monospace, monospace;
|
||||
color: var(--lavender);
|
||||
line-height: 1.3;
|
||||
margin-top: 2em;
|
||||
margin-bottom: 0.5em;
|
||||
}
|
||||
h1 {
|
||||
font-size: 1.9rem;
|
||||
color: var(--text);
|
||||
border-bottom: 1px solid var(--border);
|
||||
padding-bottom: 0.4em;
|
||||
margin-top: 1.2em;
|
||||
}
|
||||
h2 {
|
||||
font-size: 1.35rem;
|
||||
border-bottom: 1px solid var(--border);
|
||||
padding-bottom: 0.2em;
|
||||
}
|
||||
h3 { font-size: 1.1rem; color: var(--sapphire); }
|
||||
h4 { font-size: 0.95rem; color: var(--sub1); }
|
||||
|
||||
p { margin: 0.8em 0; }
|
||||
|
||||
/* ── Title block (pandoc-generated cover) ──────────────────── */
|
||||
#title-block-header {
|
||||
text-align: center;
|
||||
padding: 2.5rem 0 2rem;
|
||||
margin-bottom: 1.5rem;
|
||||
border-bottom: 1px solid var(--border);
|
||||
}
|
||||
#title-block-header .title {
|
||||
font-family: "JetBrains Mono", "Fira Code", ui-monospace, monospace;
|
||||
font-size: 2.6rem;
|
||||
letter-spacing: 0.12em;
|
||||
color: var(--lavender);
|
||||
border: none;
|
||||
margin: 0 0 0.75rem;
|
||||
}
|
||||
#title-block-header .author,
|
||||
#title-block-header .date {
|
||||
color: var(--sub0);
|
||||
font-size: 0.875rem;
|
||||
margin: 0.2rem 0;
|
||||
}
|
||||
|
||||
/* ── Inline code ───────────────────────────────────────────── */
|
||||
code {
|
||||
font-family: "JetBrains Mono", "Fira Code", ui-monospace, monospace;
|
||||
background: var(--code-bg);
|
||||
color: var(--peach);
|
||||
padding: 0.15em 0.4em;
|
||||
border-radius: 4px;
|
||||
font-size: 0.875em;
|
||||
}
|
||||
|
||||
/* ── Code blocks ───────────────────────────────────────────── */
|
||||
pre {
|
||||
background: var(--code-bg);
|
||||
border: 1px solid var(--border);
|
||||
border-left: 3px solid var(--sapphire);
|
||||
border-radius: 0 8px 8px 0;
|
||||
padding: 1.1em 1.4em;
|
||||
overflow-x: auto;
|
||||
line-height: 1.55;
|
||||
margin: 1.2em 0;
|
||||
}
|
||||
pre code {
|
||||
background: none;
|
||||
color: var(--text);
|
||||
padding: 0;
|
||||
font-size: 0.88em;
|
||||
}
|
||||
|
||||
/* ── Blockquotes ───────────────────────────────────────────── */
|
||||
blockquote {
|
||||
border-left: 3px solid var(--yellow);
|
||||
margin: 1.5em 0;
|
||||
padding: 0.75em 1.25em;
|
||||
background: var(--surface);
|
||||
color: var(--sub1);
|
||||
border-radius: 0 6px 6px 0;
|
||||
}
|
||||
blockquote p { margin: 0.3em 0; }
|
||||
|
||||
/* ── Tables ────────────────────────────────────────────────── */
|
||||
table {
|
||||
border-collapse: collapse;
|
||||
width: 100%;
|
||||
margin: 1.4em 0;
|
||||
font-size: 0.93em;
|
||||
}
|
||||
th, td {
|
||||
border: 1px solid var(--border);
|
||||
padding: 0.55em 0.9em;
|
||||
text-align: left;
|
||||
}
|
||||
th {
|
||||
background: var(--surface);
|
||||
color: var(--lavender);
|
||||
font-weight: 600;
|
||||
font-family: "JetBrains Mono", "Fira Code", ui-monospace, monospace;
|
||||
font-size: 0.82em;
|
||||
letter-spacing: 0.06em;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
tr:nth-child(even) { background: var(--surface); }
|
||||
tr:hover { background: var(--overlay); }
|
||||
|
||||
/* ── HR ────────────────────────────────────────────────────── */
|
||||
hr { border: none; border-top: 1px solid var(--border); margin: 2.5em 0; }
|
||||
|
||||
/* ── Lists ─────────────────────────────────────────────────── */
|
||||
ul, ol { padding-left: 1.6em; }
|
||||
li { margin: 0.35em 0; }
|
||||
|
||||
/* ── Chunk navigation bar (prev / up / next) ───────────────── */
|
||||
nav:not(#TOC):not([role="doc-toc"]) {
|
||||
background: var(--surface);
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 8px;
|
||||
margin: 1.5em 0;
|
||||
font-size: 0.875em;
|
||||
overflow: hidden;
|
||||
}
|
||||
nav:not(#TOC):not([role="doc-toc"]) p {
|
||||
margin: 0;
|
||||
padding: 0.65em 1.2em;
|
||||
display: flex;
|
||||
gap: 0.4em 1.75em;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
}
|
||||
/* JS wraps each "Label: <a>" pair in .nav-item so they flex as a unit */
|
||||
.nav-item {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 0.3em;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.nav-item a { color: var(--blue); }
|
||||
.nav-item a:hover { color: var(--lavender); }
|
||||
|
||||
/* ── Table of contents panel ───────────────────────────────── */
|
||||
nav#TOC, nav[role="doc-toc"] {
|
||||
display: block;
|
||||
background: var(--surface);
|
||||
border: 1px solid var(--border);
|
||||
border-left: 3px solid var(--lavender);
|
||||
border-radius: 0 8px 8px 0;
|
||||
padding: 1.2em 1.5em;
|
||||
margin: 1.5em 0;
|
||||
}
|
||||
nav#TOC > h2,
|
||||
nav[role="doc-toc"] > h2 {
|
||||
font-size: 0.7rem;
|
||||
letter-spacing: 0.14em;
|
||||
text-transform: uppercase;
|
||||
color: var(--sub0);
|
||||
border: none;
|
||||
margin: 0 0 0.9em;
|
||||
padding: 0;
|
||||
}
|
||||
nav#TOC ul, nav[role="doc-toc"] ul {
|
||||
list-style: none;
|
||||
padding-left: 1em;
|
||||
margin: 0.25em 0;
|
||||
}
|
||||
nav#TOC > ul, nav[role="doc-toc"] > ul { padding-left: 0; }
|
||||
nav#TOC li, nav[role="doc-toc"] li {
|
||||
margin: 0.3em 0;
|
||||
padding-left: 0.75em;
|
||||
border-left: 1px solid transparent;
|
||||
transition: border-color 0.12s;
|
||||
}
|
||||
nav#TOC li:hover, nav[role="doc-toc"] li:hover {
|
||||
border-left-color: var(--lavender);
|
||||
}
|
||||
nav#TOC a, nav[role="doc-toc"] a {
|
||||
color: var(--sub1);
|
||||
font-size: 0.9em;
|
||||
}
|
||||
nav#TOC a:hover, nav[role="doc-toc"] a:hover {
|
||||
color: var(--lavender);
|
||||
text-decoration: none;
|
||||
}
|
||||
</style>
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
/* ── Hide ToC on every page except index.html ───────────── */
|
||||
var path = location.pathname;
|
||||
var onIndex = path === '/' || path === '' || /\/index\.html(\?.*)?$/.test(path);
|
||||
if (!onIndex) {
|
||||
var toc = document.getElementById('TOC') ||
|
||||
document.querySelector('[role="doc-toc"]');
|
||||
if (toc) toc.remove();
|
||||
}
|
||||
|
||||
/* ── Wrap each "Label: <a>" pair in a .nav-item span ───────
|
||||
Pandoc emits label text nodes and anchors as siblings;
|
||||
flex sees them as separate items, causing labels to split
|
||||
from their links when wrapping. Grouping them in a span
|
||||
keeps each label+link as a single flex unit. */
|
||||
document.querySelectorAll('nav:not(#TOC):not([role="doc-toc"])').forEach(function (nav) {
|
||||
var p = nav.querySelector('p');
|
||||
if (!p) return;
|
||||
var children = Array.from(p.childNodes);
|
||||
var pairs = [];
|
||||
for (var i = 0; i + 1 < children.length; i++) {
|
||||
var cur = children[i];
|
||||
var nxt = children[i + 1];
|
||||
if (cur.nodeType === Node.TEXT_NODE &&
|
||||
/[A-Z][a-z]*:\s*/.test(cur.textContent) &&
|
||||
nxt.nodeType === Node.ELEMENT_NODE &&
|
||||
nxt.tagName === 'A') {
|
||||
pairs.push([cur, nxt]);
|
||||
i++; // skip the anchor on the next iteration
|
||||
}
|
||||
}
|
||||
pairs.forEach(function (pair) {
|
||||
var span = document.createElement('span');
|
||||
span.className = 'nav-item';
|
||||
p.insertBefore(span, pair[0]);
|
||||
span.appendChild(pair[0]);
|
||||
span.appendChild(pair[1]);
|
||||
});
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<nav id="sitenav">
|
||||
<div class="sitenav">
|
||||
<span class="navlink">
|
||||
</span>
|
||||
<span class="navlink">
|
||||
</span>
|
||||
</div>
|
||||
<div class="sitenav">
|
||||
<span class="navlink">
|
||||
<span class="navlink-label">Next:</span> <a href="1-name.html" accesskey="n" rel="next">NAME</a>
|
||||
</span>
|
||||
<span class="navlink">
|
||||
</span>
|
||||
</div>
|
||||
</nav>
|
||||
<header id="title-block-header">
|
||||
<h1 class="title">FISH-CONFIG</h1>
|
||||
<p class="author">Rootiest</p>
|
||||
<p class="date">June 2026</p>
|
||||
</header>
|
||||
<nav id="TOC" role="doc-toc">
|
||||
<ul>
|
||||
<li><a href="1-name.html" id="toc-name">NAME</a></li>
|
||||
<li><a href="2-synopsis.html" id="toc-synopsis">SYNOPSIS</a></li>
|
||||
<li><a href="3-description.html"
|
||||
id="toc-description">DESCRIPTION</a></li>
|
||||
<li><a href="4-table-of-contents.html" id="toc-table-of-contents">TABLE
|
||||
OF CONTENTS</a></li>
|
||||
<li><a href="5-1-configuration-variables.html"
|
||||
id="toc-1-configuration-variables">1. CONFIGURATION VARIABLES</a>
|
||||
<ul>
|
||||
<li><a
|
||||
href="5-1-configuration-variables.html#environment-directories-xdg"
|
||||
id="toc-environment-directories-xdg">Environment Directories
|
||||
(XDG)</a></li>
|
||||
<li><a href="5-1-configuration-variables.html#tool-homes-xdg-compliant"
|
||||
id="toc-tool-homes-xdg-compliant">Tool Homes (XDG-compliant)</a></li>
|
||||
<li><a href="5-1-configuration-variables.html#editor-and-pager"
|
||||
id="toc-editor-and-pager">Editor and Pager</a></li>
|
||||
<li><a href="5-1-configuration-variables.html#scrollback-history"
|
||||
id="toc-scrollback-history">Scrollback History</a></li>
|
||||
<li><a href="5-1-configuration-variables.html#other"
|
||||
id="toc-other">Other</a></li>
|
||||
<li><a href="5-1-configuration-variables.html#pager-hierarchy"
|
||||
id="toc-pager-hierarchy">Pager Hierarchy</a></li>
|
||||
<li><a href="5-1-configuration-variables.html#integrations"
|
||||
id="toc-integrations">Integrations</a>
|
||||
<ul>
|
||||
<li><a href="5-1-configuration-variables.html#zoxide"
|
||||
id="toc-zoxide">Zoxide</a></li>
|
||||
<li><a href="5-1-configuration-variables.html#direnv"
|
||||
id="toc-direnv">DirEnv</a></li>
|
||||
<li><a href="5-1-configuration-variables.html#auto-python-venv"
|
||||
id="toc-auto-python-venv">Auto Python Venv</a></li>
|
||||
<li><a href="5-1-configuration-variables.html#wakatime"
|
||||
id="toc-wakatime">WakaTime</a></li>
|
||||
<li><a href="5-1-configuration-variables.html#tailscale"
|
||||
id="toc-tailscale">Tailscale</a></li>
|
||||
<li><a href="5-1-configuration-variables.html#done-notifications"
|
||||
id="toc-done-notifications">Done Notifications</a></li>
|
||||
<li><a href="5-1-configuration-variables.html#scrollback-history-1"
|
||||
id="toc-scrollback-history-1">Scrollback History</a></li>
|
||||
</ul></li>
|
||||
</ul></li>
|
||||
<li><a href="6-2-path-setup.html" id="toc-2-path-setup">2. PATH
|
||||
SETUP</a></li>
|
||||
<li><a href="7-3-key-bindings.html" id="toc-3-key-bindings">3. KEY
|
||||
BINDINGS</a>
|
||||
<ul>
|
||||
<li><a
|
||||
href="7-3-key-bindings.html#fzf-bindings-bundled-from-patrickf1fzffish"
|
||||
id="toc-fzf-bindings-bundled-from-patrickf1fzffish">FZF Bindings
|
||||
(bundled from PatrickF1/fzf.fish)</a></li>
|
||||
</ul></li>
|
||||
<li><a href="8-4-abbreviations.html" id="toc-4-abbreviations">4.
|
||||
ABBREVIATIONS</a>
|
||||
<ul>
|
||||
<li><a href="8-4-abbreviations.html#41-editors" id="toc-41-editors">4.1
|
||||
Editors</a></li>
|
||||
<li><a href="8-4-abbreviations.html#42-navigation-and-listing"
|
||||
id="toc-42-navigation-and-listing">4.2 Navigation and Listing</a></li>
|
||||
<li><a href="8-4-abbreviations.html#43-git" id="toc-43-git">4.3
|
||||
Git</a></li>
|
||||
<li><a href="8-4-abbreviations.html#44-terminal-windows-tabs-and-panes"
|
||||
id="toc-44-terminal-windows-tabs-and-panes">4.4 Terminal Windows, Tabs,
|
||||
and Panes</a></li>
|
||||
<li><a href="8-4-abbreviations.html#45-chezmoi" id="toc-45-chezmoi">4.5
|
||||
Chezmoi</a></li>
|
||||
<li><a href="8-4-abbreviations.html#46-docker" id="toc-46-docker">4.6
|
||||
Docker</a></li>
|
||||
<li><a href="8-4-abbreviations.html#47-systemctl"
|
||||
id="toc-47-systemctl">4.7 Systemctl</a></li>
|
||||
<li><a href="8-4-abbreviations.html#48-ai-assistants"
|
||||
id="toc-48-ai-assistants">4.8 AI Assistants</a></li>
|
||||
<li><a href="8-4-abbreviations.html#49-history-expansion"
|
||||
id="toc-49-history-expansion">4.9 History Expansion</a></li>
|
||||
<li><a href="8-4-abbreviations.html#410-miscellaneous"
|
||||
id="toc-410-miscellaneous">4.10 Miscellaneous</a></li>
|
||||
<li><a href="8-4-abbreviations.html#411-shell-aliases"
|
||||
id="toc-411-shell-aliases">4.11 Shell Aliases</a>
|
||||
<ul>
|
||||
<li><a href="8-4-abbreviations.html#navigation"
|
||||
id="toc-navigation">Navigation</a></li>
|
||||
<li><a href="8-4-abbreviations.html#color-overrides"
|
||||
id="toc-color-overrides">Color Overrides</a></li>
|
||||
<li><a href="8-4-abbreviations.html#safety-wrappers"
|
||||
id="toc-safety-wrappers">Safety Wrappers</a></li>
|
||||
<li><a href="8-4-abbreviations.html#archives-and-networking"
|
||||
id="toc-archives-and-networking">Archives and Networking</a></li>
|
||||
<li><a href="8-4-abbreviations.html#system-logs"
|
||||
id="toc-system-logs">System Logs</a></li>
|
||||
</ul></li>
|
||||
</ul></li>
|
||||
<li><a href="9-5-functions-reference.html"
|
||||
id="toc-5-functions-reference">5. FUNCTIONS REFERENCE</a>
|
||||
<ul>
|
||||
<li><a href="9-5-functions-reference.html#51-file-and-directory"
|
||||
id="toc-51-file-and-directory">5.1 File and Directory</a>
|
||||
<ul>
|
||||
<li><a href="9-5-functions-reference.html#cat" id="toc-cat">cat</a></li>
|
||||
<li><a href="9-5-functions-reference.html#copy"
|
||||
id="toc-copy">copy</a></li>
|
||||
<li><a href="9-5-functions-reference.html#du" id="toc-du">du</a></li>
|
||||
<li><a href="9-5-functions-reference.html#dusize"
|
||||
id="toc-dusize">dusize</a></li>
|
||||
<li><a href="9-5-functions-reference.html#ld" id="toc-ld">lD</a></li>
|
||||
<li><a href="9-5-functions-reference.html#ls" id="toc-ls">ls</a></li>
|
||||
<li><a href="9-5-functions-reference.html#lsr" id="toc-lsr">lsr</a></li>
|
||||
<li><a href="9-5-functions-reference.html#lss" id="toc-lss">lss</a></li>
|
||||
<li><a href="9-5-functions-reference.html#lstree"
|
||||
id="toc-lstree">lstree</a></li>
|
||||
<li><a href="9-5-functions-reference.html#lt" id="toc-lt">lt</a></li>
|
||||
<li><a href="9-5-functions-reference.html#ltr" id="toc-ltr">ltr</a></li>
|
||||
<li><a href="9-5-functions-reference.html#lx" id="toc-lx">lx</a></li>
|
||||
<li><a href="9-5-functions-reference.html#mkdir"
|
||||
id="toc-mkdir">mkdir</a></li>
|
||||
<li><a href="9-5-functions-reference.html#mkcd"
|
||||
id="toc-mkcd">mkcd</a></li>
|
||||
<li><a href="9-5-functions-reference.html#poke"
|
||||
id="toc-poke">poke</a></li>
|
||||
<li><a href="9-5-functions-reference.html#rm" id="toc-rm">rm</a></li>
|
||||
<li><a href="9-5-functions-reference.html#rg" id="toc-rg">rg</a></li>
|
||||
<li><a href="9-5-functions-reference.html#scrub"
|
||||
id="toc-scrub">scrub</a></li>
|
||||
</ul></li>
|
||||
<li><a href="9-5-functions-reference.html#52-navigation"
|
||||
id="toc-52-navigation">5.2 Navigation</a>
|
||||
<ul>
|
||||
<li><a href="9-5-functions-reference.html#cdi" id="toc-cdi">cdi</a></li>
|
||||
<li><a href="9-5-functions-reference.html#clone"
|
||||
id="toc-clone">clone</a></li>
|
||||
<li><a href="9-5-functions-reference.html#clonet"
|
||||
id="toc-clonet">clonet</a></li>
|
||||
</ul></li>
|
||||
<li><a href="9-5-functions-reference.html#53-editors-and-viewers"
|
||||
id="toc-53-editors-and-viewers">5.3 Editors and Viewers</a>
|
||||
<ul>
|
||||
<li><a href="9-5-functions-reference.html#edit"
|
||||
id="toc-edit">edit</a></li>
|
||||
<li><a href="9-5-functions-reference.html#fc" id="toc-fc">fc</a></li>
|
||||
<li><a href="9-5-functions-reference.html#less"
|
||||
id="toc-less">less</a></li>
|
||||
<li><a href="9-5-functions-reference.html#rawfish"
|
||||
id="toc-rawfish">rawfish</a></li>
|
||||
<li><a href="9-5-functions-reference.html#view"
|
||||
id="toc-view">view</a></li>
|
||||
</ul></li>
|
||||
<li><a href="9-5-functions-reference.html#54-git-and-version-control"
|
||||
id="toc-54-git-and-version-control">5.4 Git and Version Control</a>
|
||||
<ul>
|
||||
<li><a href="9-5-functions-reference.html#branch"
|
||||
id="toc-branch">branch</a></li>
|
||||
<li><a href="9-5-functions-reference.html#gi" id="toc-gi">gi</a></li>
|
||||
<li><a href="9-5-functions-reference.html#git-clean"
|
||||
id="toc-git-clean">git-clean</a></li>
|
||||
<li><a href="9-5-functions-reference.html#gitup"
|
||||
id="toc-gitup">gitup</a></li>
|
||||
<li><a href="9-5-functions-reference.html#gitui"
|
||||
id="toc-gitui">gitui</a></li>
|
||||
<li><a href="9-5-functions-reference.html#hist"
|
||||
id="toc-hist">hist</a></li>
|
||||
</ul></li>
|
||||
<li><a href="9-5-functions-reference.html#55-package-management"
|
||||
id="toc-55-package-management">5.5 Package Management</a>
|
||||
<ul>
|
||||
<li><a href="9-5-functions-reference.html#pkg" id="toc-pkg">pkg</a></li>
|
||||
<li><a href="9-5-functions-reference.html#search"
|
||||
id="toc-search">search</a></li>
|
||||
<li><a href="9-5-functions-reference.html#upgrade"
|
||||
id="toc-upgrade">upgrade</a></li>
|
||||
<li><a href="9-5-functions-reference.html#cleanup"
|
||||
id="toc-cleanup">cleanup</a></li>
|
||||
<li><a href="9-5-functions-reference.html#parur"
|
||||
id="toc-parur">parur</a></li>
|
||||
</ul></li>
|
||||
<li><a href="9-5-functions-reference.html#56-dependency-management"
|
||||
id="toc-56-dependency-management">5.6 Dependency Management</a>
|
||||
<ul>
|
||||
<li><a href="9-5-functions-reference.html#fish-deps"
|
||||
id="toc-fish-deps">fish-deps</a></li>
|
||||
<li><a href="9-5-functions-reference.html#check_fish_deps"
|
||||
id="toc-check_fish_deps">check_fish_deps</a></li>
|
||||
</ul></li>
|
||||
<li><a href="9-5-functions-reference.html#57-system-and-monitoring"
|
||||
id="toc-57-system-and-monitoring">5.7 System and Monitoring</a>
|
||||
<ul>
|
||||
<li><a href="9-5-functions-reference.html#top" id="toc-top">top</a></li>
|
||||
<li><a href="9-5-functions-reference.html#swapstat"
|
||||
id="toc-swapstat">swapstat</a></li>
|
||||
<li><a href="9-5-functions-reference.html#sbver"
|
||||
id="toc-sbver">sbver</a></li>
|
||||
<li><a href="9-5-functions-reference.html#ports"
|
||||
id="toc-ports">ports</a></li>
|
||||
<li><a href="9-5-functions-reference.html#screensleep"
|
||||
id="toc-screensleep">screensleep</a></li>
|
||||
<li><a href="9-5-functions-reference.html#lock"
|
||||
id="toc-lock">lock</a></li>
|
||||
<li><a href="9-5-functions-reference.html#sudo-toggle"
|
||||
id="toc-sudo-toggle">sudo-toggle</a></li>
|
||||
<li><a href="9-5-functions-reference.html#limine-edit"
|
||||
id="toc-limine-edit">limine-edit</a></li>
|
||||
</ul></li>
|
||||
<li><a href="9-5-functions-reference.html#58-terminal-management"
|
||||
id="toc-58-terminal-management">5.8 Terminal Management</a>
|
||||
<ul>
|
||||
<li><a href="9-5-functions-reference.html#tab" id="toc-tab">tab</a></li>
|
||||
<li><a href="9-5-functions-reference.html#split"
|
||||
id="toc-split">split</a></li>
|
||||
<li><a href="9-5-functions-reference.html#spwin"
|
||||
id="toc-spwin">spwin</a></li>
|
||||
<li><a href="9-5-functions-reference.html#detach"
|
||||
id="toc-detach">detach</a></li>
|
||||
<li><a href="9-5-functions-reference.html#bkg" id="toc-bkg">bkg</a></li>
|
||||
<li><a href="9-5-functions-reference.html#ssh" id="toc-ssh">ssh</a></li>
|
||||
</ul></li>
|
||||
<li><a href="9-5-functions-reference.html#59-clipboard"
|
||||
id="toc-59-clipboard">5.9 Clipboard</a>
|
||||
<ul>
|
||||
<li><a href="9-5-functions-reference.html#y" id="toc-y">y</a></li>
|
||||
<li><a href="9-5-functions-reference.html#p" id="toc-p">p</a></li>
|
||||
<li><a href="9-5-functions-reference.html#paste"
|
||||
id="toc-paste">paste</a></li>
|
||||
</ul></li>
|
||||
<li><a href="9-5-functions-reference.html#510-network"
|
||||
id="toc-510-network">5.10 Network</a>
|
||||
<ul>
|
||||
<li><a href="9-5-functions-reference.html#gip" id="toc-gip">gip</a></li>
|
||||
<li><a href="9-5-functions-reference.html#gip4"
|
||||
id="toc-gip4">gip4</a></li>
|
||||
<li><a href="9-5-functions-reference.html#gip6"
|
||||
id="toc-gip6">gip6</a></li>
|
||||
<li><a href="9-5-functions-reference.html#ping"
|
||||
id="toc-ping">ping</a></li>
|
||||
<li><a href="9-5-functions-reference.html#qr" id="toc-qr">qr</a></li>
|
||||
</ul></li>
|
||||
<li><a href="9-5-functions-reference.html#511-pager-and-logging"
|
||||
id="toc-511-pager-and-logging">5.11 Pager and Logging</a>
|
||||
<ul>
|
||||
<li><a href="9-5-functions-reference.html#logs"
|
||||
id="toc-logs">logs</a></li>
|
||||
<li><a href="9-5-functions-reference.html#smart_exit"
|
||||
id="toc-smart_exit">smart_exit</a></li>
|
||||
</ul></li>
|
||||
<li><a href="9-5-functions-reference.html#512-ai-and-developer-tools"
|
||||
id="toc-512-ai-and-developer-tools">5.12 AI and Developer Tools</a>
|
||||
<ul>
|
||||
<li><a href="9-5-functions-reference.html#antigravity"
|
||||
id="toc-antigravity">antigravity</a></li>
|
||||
<li><a href="9-5-functions-reference.html#antigravity-ide"
|
||||
id="toc-antigravity-ide">antigravity-ide</a></li>
|
||||
<li><a href="9-5-functions-reference.html#antigravity-resume"
|
||||
id="toc-antigravity-resume">antigravity-resume</a></li>
|
||||
<li><a href="9-5-functions-reference.html#claude-resume"
|
||||
id="toc-claude-resume">claude-resume</a></li>
|
||||
<li><a href="9-5-functions-reference.html#claude-docs"
|
||||
id="toc-claude-docs">claude-docs</a></li>
|
||||
<li><a href="9-5-functions-reference.html#claude-pr"
|
||||
id="toc-claude-pr">claude-pr</a></li>
|
||||
<li><a href="9-5-functions-reference.html#code-resume"
|
||||
id="toc-code-resume">code-resume</a></li>
|
||||
<li><a href="9-5-functions-reference.html#superpowers"
|
||||
id="toc-superpowers">superpowers</a></li>
|
||||
</ul></li>
|
||||
<li><a href="9-5-functions-reference.html#513-media-and-utilities"
|
||||
id="toc-513-media-and-utilities">5.13 Media and Utilities</a>
|
||||
<ul>
|
||||
<li><a href="9-5-functions-reference.html#dng2avif"
|
||||
id="toc-dng2avif">dng2avif</a></li>
|
||||
<li><a href="9-5-functions-reference.html#steam-dl"
|
||||
id="toc-steam-dl">steam-dl</a></li>
|
||||
<li><a href="9-5-functions-reference.html#spark"
|
||||
id="toc-spark">spark</a></li>
|
||||
</ul></li>
|
||||
<li><a href="9-5-functions-reference.html#514-miscellaneous"
|
||||
id="toc-514-miscellaneous">5.14 Miscellaneous</a>
|
||||
<ul>
|
||||
<li><a href="9-5-functions-reference.html#config-help"
|
||||
id="toc-config-help">config-help</a></li>
|
||||
<li><a href="9-5-functions-reference.html#config-update"
|
||||
id="toc-config-update">config-update</a></li>
|
||||
<li><a href="9-5-functions-reference.html#config-toggle"
|
||||
id="toc-config-toggle">config-toggle</a></li>
|
||||
<li><a href="9-5-functions-reference.html#bash"
|
||||
id="toc-bash">bash</a></li>
|
||||
<li><a href="9-5-functions-reference.html#bd-pull"
|
||||
id="toc-bd-pull">bd-pull</a></li>
|
||||
<li><a href="9-5-functions-reference.html#cheat"
|
||||
id="toc-cheat">cheat</a></li>
|
||||
<li><a href="9-5-functions-reference.html#cffetch--ffetch"
|
||||
id="toc-cffetch--ffetch">cffetch / ffetch</a></li>
|
||||
<li><a href="9-5-functions-reference.html#dockup"
|
||||
id="toc-dockup">dockup</a></li>
|
||||
<li><a href="9-5-functions-reference.html#joplin"
|
||||
id="toc-joplin">joplin</a></li>
|
||||
<li><a href="9-5-functions-reference.html#ld-1"
|
||||
id="toc-ld-1">ld</a></li>
|
||||
<li><a href="9-5-functions-reference.html#replay"
|
||||
id="toc-replay">replay</a></li>
|
||||
<li><a href="9-5-functions-reference.html#tmux-clean"
|
||||
id="toc-tmux-clean">tmux-clean</a></li>
|
||||
<li><a href="9-5-functions-reference.html#wake-lock"
|
||||
id="toc-wake-lock">wake-lock</a></li>
|
||||
<li><a href="9-5-functions-reference.html#zellij"
|
||||
id="toc-zellij">zellij</a></li>
|
||||
</ul></li>
|
||||
</ul></li>
|
||||
<li><a href="10-6-dependency-catalog.html"
|
||||
id="toc-6-dependency-catalog">6. DEPENDENCY CATALOG</a>
|
||||
<ul>
|
||||
<li><a href="10-6-dependency-catalog.html#required"
|
||||
id="toc-required">Required</a></li>
|
||||
<li><a href="10-6-dependency-catalog.html#integrations-1"
|
||||
id="toc-integrations-1">Integrations</a></li>
|
||||
<li><a href="10-6-dependency-catalog.html#recommended"
|
||||
id="toc-recommended">Recommended</a></li>
|
||||
<li><a href="10-6-dependency-catalog.html#install-methods"
|
||||
id="toc-install-methods">Install Methods</a></li>
|
||||
</ul></li>
|
||||
<li><a href="11-7-customization.html" id="toc-7-customization">7.
|
||||
CUSTOMIZATION</a>
|
||||
<ul>
|
||||
<li><a href="11-7-customization.html#machine-local-configuration"
|
||||
id="toc-machine-local-configuration">Machine-local
|
||||
Configuration</a></li>
|
||||
<li><a href="11-7-customization.html#secrets-and-api-keys"
|
||||
id="toc-secrets-and-api-keys">Secrets and API Keys</a></li>
|
||||
<li><a href="11-7-customization.html#overriding-configuration-variables"
|
||||
id="toc-overriding-configuration-variables">Overriding Configuration
|
||||
Variables</a></li>
|
||||
<li><a href="11-7-customization.html#fish-universal-variables"
|
||||
id="toc-fish-universal-variables">Fish Universal Variables</a></li>
|
||||
<li><a
|
||||
href="11-7-customization.html#opinionated-components-minimal-mode"
|
||||
id="toc-opinionated-components-minimal-mode">Opinionated Components
|
||||
(Minimal Mode)</a>
|
||||
<ul>
|
||||
<li><a href="11-7-customization.html#component-reference"
|
||||
id="toc-component-reference">Component Reference</a></li>
|
||||
</ul></li>
|
||||
<li><a href="11-7-customization.html#prompt-and-theme"
|
||||
id="toc-prompt-and-theme">Prompt and Theme</a>
|
||||
<ul>
|
||||
<li><a href="11-7-customization.html#starship"
|
||||
id="toc-starship">Starship</a></li>
|
||||
<li><a href="11-7-customization.html#fzf" id="toc-fzf">FZF</a></li>
|
||||
<li><a
|
||||
href="11-7-customization.html#catppuccin-mocha-syntax-highlighting"
|
||||
id="toc-catppuccin-mocha-syntax-highlighting">Catppuccin Mocha Syntax
|
||||
Highlighting</a></li>
|
||||
</ul></li>
|
||||
</ul></li>
|
||||
<li><a href="12-8-fisher-plugins.html" id="toc-8-fisher-plugins">8.
|
||||
FISHER PLUGINS</a>
|
||||
<ul>
|
||||
<li><a href="12-8-fisher-plugins.html#fisher-managed-plugins"
|
||||
id="toc-fisher-managed-plugins">Fisher-Managed Plugins</a></li>
|
||||
<li><a href="12-8-fisher-plugins.html#sponge-history-filtering"
|
||||
id="toc-sponge-history-filtering">Sponge History Filtering</a></li>
|
||||
<li><a href="12-8-fisher-plugins.html#bundled-plugin-functionality"
|
||||
id="toc-bundled-plugin-functionality">Bundled Plugin
|
||||
Functionality</a></li>
|
||||
<li><a href="12-8-fisher-plugins.html#fish_plugins-manifest"
|
||||
id="toc-fish_plugins-manifest">fish_plugins Manifest</a></li>
|
||||
</ul></li>
|
||||
<li><a href="13-9-installation.html" id="toc-9-installation">9.
|
||||
INSTALLATION</a>
|
||||
<ul>
|
||||
<li><a href="13-9-installation.html#return-sentinel"
|
||||
id="toc-return-sentinel">Return Sentinel</a></li>
|
||||
<li><a href="13-9-installation.html#updating"
|
||||
id="toc-updating">Updating</a></li>
|
||||
</ul></li>
|
||||
<li><a href="14-10-personalization.html" id="toc-10-personalization">10.
|
||||
PERSONALIZATION</a>
|
||||
<ul>
|
||||
<li><a href="14-10-personalization.html#secretsfish"
|
||||
id="toc-secretsfish">secrets.fish</a></li>
|
||||
<li><a href="14-10-personalization.html#localfish"
|
||||
id="toc-localfish">local.fish</a></li>
|
||||
</ul></li>
|
||||
<li><a href="15-11-viewing-this-manual.html"
|
||||
id="toc-11-viewing-this-manual">11. VIEWING THIS MANUAL</a>
|
||||
<ul>
|
||||
<li><a href="15-11-viewing-this-manual.html#with-ov-recommended"
|
||||
id="toc-with-ov-recommended">With ov (recommended)</a></li>
|
||||
<li><a href="15-11-viewing-this-manual.html#with-bat"
|
||||
id="toc-with-bat">With bat</a></li>
|
||||
<li><a href="15-11-viewing-this-manual.html#as-a-man-page"
|
||||
id="toc-as-a-man-page">As a man page</a></li>
|
||||
<li><a href="15-11-viewing-this-manual.html#in-the-browser-html"
|
||||
id="toc-in-the-browser-html">In the browser (HTML)</a></li>
|
||||
<li><a href="15-11-viewing-this-manual.html#as-a-wiki"
|
||||
id="toc-as-a-wiki">As a wiki</a></li>
|
||||
<li><a href="15-11-viewing-this-manual.html#jumping-to-a-section"
|
||||
id="toc-jumping-to-a-section">Jumping to a section</a></li>
|
||||
</ul></li>
|
||||
</ul>
|
||||
</nav>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,10 @@
|
||||
---
|
||||
title: Name
|
||||
manTitle: NAME
|
||||
man: true
|
||||
site: false
|
||||
sidebar:
|
||||
order: 1
|
||||
---
|
||||
|
||||
fish-config - personal fish shell configuration for Fish 4.x with modern CLI tool integration
|
||||
@@ -0,0 +1,21 @@
|
||||
---
|
||||
title: Synopsis
|
||||
manTitle: SYNOPSIS
|
||||
man: true
|
||||
site: false
|
||||
sidebar:
|
||||
order: 2
|
||||
---
|
||||
|
||||
help config [SECTION]
|
||||
|
||||
Open this manual in the best available pager. Optionally jump to a section
|
||||
by keyword:
|
||||
|
||||
help config keybindings
|
||||
help config pkg
|
||||
help config abbreviations
|
||||
help config logs
|
||||
|
||||
The `help config` syntax integrates with fish's built-in help command.
|
||||
The underlying `config-help` function is also available directly.
|
||||
@@ -0,0 +1,57 @@
|
||||
---
|
||||
title: Table Of Contents
|
||||
manTitle: TABLE OF CONTENTS
|
||||
man: true
|
||||
site: false
|
||||
sidebar:
|
||||
order: 4
|
||||
---
|
||||
|
||||
1. Configuration Variables
|
||||
2. PATH Setup
|
||||
3. Key Bindings
|
||||
4. Abbreviations
|
||||
4.1 Editors
|
||||
4.2 Navigation and Listing
|
||||
4.3 Git
|
||||
4.4 Terminal Windows, Tabs, and Panes
|
||||
4.5 Chezmoi
|
||||
4.6 Docker
|
||||
4.7 Systemctl
|
||||
4.8 AI Assistants
|
||||
4.9 History Expansion
|
||||
4.10 Miscellaneous
|
||||
4.11 Shell Aliases
|
||||
5. Functions Reference
|
||||
5.1 File and Directory
|
||||
5.2 Navigation
|
||||
5.3 Editors and Viewers
|
||||
5.4 Git and Version Control
|
||||
5.5 Package Management
|
||||
5.6 Dependency Management
|
||||
5.7 System and Monitoring
|
||||
5.8 Terminal Management
|
||||
5.9 Clipboard
|
||||
5.10 Network
|
||||
5.11 Pager and Logging
|
||||
5.12 AI and Developer Tools
|
||||
5.13 Media and Utilities
|
||||
5.14 Miscellaneous
|
||||
6. Dependency Catalog
|
||||
7. Customization
|
||||
8. Fisher Plugins
|
||||
9. Installation
|
||||
10. Personalization
|
||||
11. Troubleshooting
|
||||
11.1 Uninstalling and Reverting to Backup
|
||||
11.2 Fish Version Requirement
|
||||
11.3 Enable or Disable Session Logging
|
||||
11.4 Change or Disable the Greeting
|
||||
11.5 Secrets and Machine-Local Configuration
|
||||
11.6 Tool Init Does Nothing (Return Sentinel)
|
||||
11.7 Missing Dependencies
|
||||
11.8 Vi Mode Keybindings
|
||||
11.9 What's with the C1-C6 stuff?
|
||||
12. Viewing This Manual
|
||||
|
||||
---
|
||||
@@ -0,0 +1,155 @@
|
||||
---
|
||||
title: Configuration Variables
|
||||
manTitle: 1. CONFIGURATION VARIABLES
|
||||
sidebar:
|
||||
order: 5
|
||||
helpKeywords:
|
||||
- variables
|
||||
- config
|
||||
---
|
||||
|
||||
These variables are exported from config.fish on every interactive session.
|
||||
Override them in local.fish (see Section 10, Personalization).
|
||||
|
||||
## Environment Directories (XDG)
|
||||
|
||||
| Variable | Value |
|
||||
|---|---|
|
||||
| `XDG_CONFIG_HOME` | `~/.config` |
|
||||
| `XDG_CACHE_HOME` | `~/.cache` |
|
||||
| `XDG_DATA_HOME` | `~/.local/share` |
|
||||
| `XDG_STATE_HOME` | `~/.local/state` |
|
||||
|
||||
Tools that respect XDG are directed to these paths rather than polluting `$HOME`.
|
||||
|
||||
## Tool Homes (XDG-compliant)
|
||||
|
||||
| Variable | Value |
|
||||
|---|---|
|
||||
| `CARGO_HOME` | `$XDG_DATA_HOME/cargo` |
|
||||
| `RUSTUP_HOME` | `$XDG_DATA_HOME/rustup` |
|
||||
| `GOPATH` | `$XDG_DATA_HOME/go` |
|
||||
| `BUN_INSTALL` | `$XDG_DATA_HOME/bun` |
|
||||
| `NPM_CONFIG_PREFIX` | `$XDG_DATA_HOME/npm-global` |
|
||||
| `GNUPGHOME` | `$XDG_CONFIG_HOME/gnupg` |
|
||||
| `WAKATIME_HOME` | `$XDG_CONFIG_HOME/wakatime` |
|
||||
|
||||
## Editor and Pager
|
||||
|
||||
| Variable | Value / Notes |
|
||||
|---|---|
|
||||
| `EDITOR` | `nvim` (falls back to `vi` if `nvim` is absent) |
|
||||
| `VISUAL` | unset by default; set a GUI editor via `local.fish` (the `edit` function falls back to a GUI chain when `VISUAL` is empty) |
|
||||
| `SUDO_EDITOR` | same as `EDITOR` |
|
||||
| `PAGER` | `ov` (falls back to `less`) |
|
||||
|
||||
## Scrollback History
|
||||
|
||||
| Variable | Value / Notes |
|
||||
|---|---|
|
||||
| `__fish_scrollback_history_dir` | (unset → `~/.terminal_history`) |
|
||||
| `__fish_scrollback_history_max_files` | (unset → `100`) |
|
||||
| `SCROLLBACK_HISTORY_DIR` | `~/.terminal_history` (exported mirror) |
|
||||
| `SCROLLBACK_HISTORY_MAX_FILES` | `100` (exported mirror) |
|
||||
|
||||
The `__fish_scrollback_history_*` universal variables are the fish-style source
|
||||
of truth — set them via `config-settings` → Paths, or `set -U` directly.
|
||||
`config.fish` exports the `SCROLLBACK_HISTORY_*` mirrors from them, because the
|
||||
POSIX wrapper scripts (`paru`/`yay`/`tmux`/`zellij` logging and `_prune_terminal_logs`)
|
||||
read the exported names from the environment. When the `__fish_` vars are unset,
|
||||
the documented defaults are exported. `config.fish` deliberately does not create
|
||||
a global source var, which would shadow the universal and stop live edits from
|
||||
taking effect.
|
||||
|
||||
Scrollback logs accumulate in `SCROLLBACK_HISTORY_DIR` as timestamped files.
|
||||
When the count exceeds `SCROLLBACK_HISTORY_MAX_FILES` the oldest are pruned
|
||||
automatically on exit. Use `logs` to browse them interactively.
|
||||
|
||||
## Other
|
||||
|
||||
| Variable | Value | Notes |
|
||||
|---|---|---|
|
||||
| `GPG_TTY` | `$(tty)` | ensures GPG passphrase prompts work |
|
||||
| `CLAUDE_CODE_NO_FLICKER` | `1` | suppress terminal flicker in Claude Code |
|
||||
| `CDPATH` | `. ~/projects ~` | |
|
||||
|
||||
Opinionated defaults (`CDPATH`, `PAGER`/`MANPAGER`, Vi mode, command shadows,
|
||||
terminal integrations) can be switched off per category with universal
|
||||
variables — see Section 7, "Opinionated Components (Minimal Mode)".
|
||||
|
||||
## Pager Hierarchy
|
||||
|
||||
`$PAGER` is set to `ov` when available, falling back to `less`. The `less` wrapper
|
||||
function extends this into a full chain so anything that calls `less` directly
|
||||
also benefits:
|
||||
|
||||
`$PAGER` → `ov` → `less` → `more` → `cat`
|
||||
|
||||
When `bat` is installed, man pages are rendered with syntax highlighting:
|
||||
|
||||
| Variable | Value |
|
||||
|---|---|
|
||||
| `MANROFFOPT` | `-c` |
|
||||
| `MANPAGER` | `sh -c 'col -bx \| bat -l man -p'` |
|
||||
|
||||
## Integrations
|
||||
|
||||
### Zoxide
|
||||
|
||||
`cd`, `z`, and `cdi`/`zi` are all mapped to `zoxide`-backed navigation. Tab completions
|
||||
for `cd` and `z` blend standard directory entries (CWD and `CDPATH`) with frecency
|
||||
results so both familiar and frequently-visited paths appear in one list.
|
||||
|
||||
### DirEnv
|
||||
|
||||
Automatically loads `.envrc` files on directory change. Takes priority over
|
||||
the auto-venv logic — if a directory is managed by `direnv`, the auto-venv
|
||||
activation is skipped entirely.
|
||||
|
||||
### Auto Python Venv
|
||||
|
||||
When entering a directory that contains a `.venv/`, the virtualenv is activated
|
||||
automatically and deactivated when you leave the project tree.
|
||||
|
||||
### WakaTime
|
||||
|
||||
Every shell command is reported to WakaTime for time-tracking. Set
|
||||
`FISH_WAKATIME_DISABLED=1` to disable without removing the plugin.
|
||||
|
||||
### Tailscale
|
||||
|
||||
Full tab completion for the `tailscale` CLI is provided via `conf.d/tailscale.fish`.
|
||||
|
||||
### Done Notifications
|
||||
|
||||
Desktop notifications fire when a command takes longer than 10 seconds and
|
||||
the terminal window is not focused. Configured via fish universal variables:
|
||||
|
||||
| Variable | Value |
|
||||
|---|---|
|
||||
| `__done_min_cmd_duration` | `10000` ms |
|
||||
| `__done_notification_urgency_level` | `low` |
|
||||
|
||||
### Scrollback History
|
||||
|
||||
When running inside Kitty, closing a shell session via `exit` saves a timestamped
|
||||
scrollback snapshot to `SCROLLBACK_HISTORY_DIR`. Files are named:
|
||||
|
||||
`scrollback_YYYY-MM-DD_HH-MM-SS.log`
|
||||
|
||||
The `paru` and `yay` wrappers (auto-generated in `~/.local/bin/`) run the command
|
||||
inside a PTY via `script(1)` so download progress bars are preserved on screen,
|
||||
then render the captured terminal animation down to a clean static log via
|
||||
`scripts/clean_progress_log.py` (a small terminal-screen emulator that replays
|
||||
cursor movements, collapses repainted progress frames to their final state,
|
||||
and preserves ANSI color). If `python3` is unavailable the wrapper falls back to
|
||||
dropping only the `script(1)` header/footer. Output is saved to:
|
||||
|
||||
- `paru_YYYY-MM-DD_HH-MM-SS.log`
|
||||
- `yay_YYYY-MM-DD_HH-MM-SS.log`
|
||||
|
||||
Before pruning, `_scrollback_prune_junk` silently removes empty files, files
|
||||
with only a single meaningful line (e.g. bare `[exited]` captures), and Kitty
|
||||
tab-rename prompt captures. Use `exit --no-log` (or `exit -n`) to skip capture.
|
||||
|
||||
---
|
||||
@@ -0,0 +1,31 @@
|
||||
---
|
||||
title: PATH Setup
|
||||
manTitle: 2. PATH SETUP
|
||||
sidebar:
|
||||
order: 6
|
||||
helpKeywords:
|
||||
- path
|
||||
---
|
||||
|
||||
Directories prepended to PATH in this order (first wins):
|
||||
|
||||
| Directory | Purpose |
|
||||
|---|---|
|
||||
| `~/.local/bin` | Standard user-local executables |
|
||||
| `~/Applications` | User-installed standalone apps |
|
||||
| `~/scripts` | Personal shell scripts |
|
||||
| `~/bin` | Cargo binaries (appended — lowest priority) |
|
||||
| `$BUN_INSTALL/bin` | Bun runtime and global packages |
|
||||
| `$NPM_CONFIG_PREFIX/bin` | Global npm packages |
|
||||
| `~/.lmstudio/bin` | LM Studio CLI |
|
||||
| `~/.resend/bin` | Resend CLI |
|
||||
| `~/.fzf/bin` | `fzf` binary (git-installed) |
|
||||
|
||||
Cargo binaries are intentionally appended (lowest priority) to avoid
|
||||
shadowing system-installed Rust tools.
|
||||
|
||||
NOTE: While these directories are merged with your system's existing `$PATH` values, any executables in the prepended directories above will override (shadow) system binaries of the same name.
|
||||
|
||||
TIP: This standard PATH setup is gated behind the opinionated component overrides toggle. If you prefer to manage your PATH completely manually, you can disable it by setting `__fish_config_op_overrides` to `0` (or toggle it off in the `config-settings` menu).
|
||||
|
||||
---
|
||||
@@ -1,7 +1,13 @@
|
||||
# 3. KEY BINDINGS
|
||||
|
||||
**Sections:** [Index](index.md) | [1. Configuration Variables](1-configuration-variables.md) | [2. Path Setup](2-path-setup.md) | **3. Key Bindings** | [4. Abbreviations](4-abbreviations.md) | [5. Functions Reference](5-functions-reference.md) | [6. Dependency Catalog](6-dependency-catalog.md) | [7. Customization](7-customization.md) | [8. Fisher Plugins](8-fisher-plugins.md) | [9. Installation](9-installation.md) | [10. Personalization](10-personalization.md) | [11. Viewing This Manual](11-viewing-this-manual.md)
|
||||
|
||||
---
|
||||
title: Key Bindings
|
||||
manTitle: 3. KEY BINDINGS
|
||||
sidebar:
|
||||
order: 7
|
||||
helpKeywords:
|
||||
- keybindings
|
||||
- bindings
|
||||
- key-bindings
|
||||
- keys
|
||||
---
|
||||
|
||||
The shell uses Vi key bindings (fish_vi_key_bindings). All custom bindings
|
||||
@@ -40,6 +46,10 @@ are active in Insert, Normal, and Visual modes unless noted.
|
||||
line to open an fzf picker and insert a selection
|
||||
at the cursor position.
|
||||
|
||||
Ctrl+Right Accept autosuggestion one word/directory segment
|
||||
at a time. (Restores Fish 3.x behavior by binding
|
||||
to nextd-or-forward-word).
|
||||
|
||||
## FZF Bindings (bundled from PatrickF1/fzf.fish)
|
||||
|
||||
Ctrl+R Search command history
|
||||
@@ -0,0 +1,6 @@
|
||||
---
|
||||
title: Editors
|
||||
manTitle: 4.1 Editors
|
||||
---
|
||||
|
||||
<!-- GENERATED: Editors -->
|
||||
@@ -0,0 +1,6 @@
|
||||
---
|
||||
title: Navigation and Listing
|
||||
manTitle: 4.2 Navigation and Listing
|
||||
---
|
||||
|
||||
<!-- GENERATED: Navigation and Listing -->
|
||||
@@ -0,0 +1,6 @@
|
||||
---
|
||||
title: Git
|
||||
manTitle: 4.3 Git
|
||||
---
|
||||
|
||||
<!-- GENERATED: Git -->
|
||||
@@ -0,0 +1,10 @@
|
||||
---
|
||||
title: Terminal Windows, Tabs, and Panes
|
||||
manTitle: 4.4 Terminal Windows, Tabs, and Panes
|
||||
---
|
||||
|
||||
These abbreviations control the terminal emulator. Each has a Kitty
|
||||
variant and a WezTerm variant; the correct one is inserted based on
|
||||
`$TERM` or `$TERM_PROGRAM`.
|
||||
|
||||
<!-- GENERATED: Terminal Windows, Tabs, and Panes -->
|
||||
@@ -0,0 +1,6 @@
|
||||
---
|
||||
title: Chezmoi
|
||||
manTitle: 4.5 Chezmoi
|
||||
---
|
||||
|
||||
<!-- GENERATED: Chezmoi -->
|
||||
@@ -0,0 +1,6 @@
|
||||
---
|
||||
title: Docker
|
||||
manTitle: 4.6 Docker
|
||||
---
|
||||
|
||||
<!-- GENERATED: Docker -->
|
||||
@@ -0,0 +1,6 @@
|
||||
---
|
||||
title: Systemctl
|
||||
manTitle: 4.7 Systemctl
|
||||
---
|
||||
|
||||
<!-- GENERATED: Systemctl -->
|
||||
@@ -0,0 +1,6 @@
|
||||
---
|
||||
title: AI Assistants
|
||||
manTitle: 4.8 AI Assistants
|
||||
---
|
||||
|
||||
<!-- GENERATED: AI Assistants -->
|
||||
@@ -0,0 +1,10 @@
|
||||
---
|
||||
title: History Expansion
|
||||
manTitle: 4.9 History Expansion
|
||||
---
|
||||
|
||||
Bash-style history expansions trigger on Space or Enter. Some are implemented
|
||||
as abbreviations (e.g. `!*`), while others (`!!`, `!$`, `!.`) are implemented
|
||||
as keybindings, but they all serve the same purpose.
|
||||
|
||||
<!-- GENERATED: History Expansion -->
|
||||
@@ -0,0 +1,6 @@
|
||||
---
|
||||
title: Miscellaneous
|
||||
manTitle: 4.10 Miscellaneous
|
||||
---
|
||||
|
||||
<!-- GENERATED: Miscellaneous -->
|
||||
@@ -0,0 +1,9 @@
|
||||
---
|
||||
title: Shell Aliases
|
||||
manTitle: 4.11 Shell Aliases
|
||||
---
|
||||
|
||||
These aliases are defined in conf.d/tricks.fish via alias (which creates Fish
|
||||
functions). They are active in all interactive sessions.
|
||||
|
||||
<!-- GENERATED: Shell Aliases -->
|
||||
@@ -0,0 +1,27 @@
|
||||
---
|
||||
title: Abbreviations
|
||||
manTitle: 4. ABBREVIATIONS
|
||||
sidebar:
|
||||
order: 8
|
||||
helpKeywords:
|
||||
- abbreviations
|
||||
- abbr
|
||||
- abbrs
|
||||
---
|
||||
|
||||
Abbreviations expand when you press Space or Enter. They are terminal-aware:
|
||||
some expand differently in Kitty vs WezTerm vs other terminals.
|
||||
|
||||
<CardGrid>
|
||||
<LinkCard title="Editors" href="/04-abbreviations/01-editors/" />
|
||||
<LinkCard title="Navigation and Listing" href="/04-abbreviations/02-navigation-and-listing/" />
|
||||
<LinkCard title="Git" href="/04-abbreviations/03-git/" />
|
||||
<LinkCard title="Terminal Windows, Tabs, and Panes" href="/04-abbreviations/04-terminal-windows-tabs-and-panes/" />
|
||||
<LinkCard title="Chezmoi" href="/04-abbreviations/05-chezmoi/" />
|
||||
<LinkCard title="Docker" href="/04-abbreviations/06-docker/" />
|
||||
<LinkCard title="Systemctl" href="/04-abbreviations/07-systemctl/" />
|
||||
<LinkCard title="AI Assistants" href="/04-abbreviations/08-ai-assistants/" />
|
||||
<LinkCard title="History Expansion" href="/04-abbreviations/09-history-expansion/" />
|
||||
<LinkCard title="Miscellaneous" href="/04-abbreviations/10-miscellaneous/" />
|
||||
<LinkCard title="Shell Aliases" href="/04-abbreviations/11-shell-aliases/" />
|
||||
</CardGrid>
|
||||
@@ -0,0 +1,10 @@
|
||||
---
|
||||
title: File and Directory
|
||||
manTitle: 5.1 File and Directory
|
||||
sidebar:
|
||||
order: 1
|
||||
helpKeywords:
|
||||
- files
|
||||
---
|
||||
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
---
|
||||
title: Navigation
|
||||
manTitle: 5.2 Navigation
|
||||
sidebar:
|
||||
order: 2
|
||||
helpKeywords:
|
||||
- nav-fns
|
||||
---
|
||||
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
---
|
||||
title: Editors and Viewers
|
||||
manTitle: 5.3 Editors and Viewers
|
||||
sidebar:
|
||||
order: 3
|
||||
helpKeywords:
|
||||
- editors
|
||||
---
|
||||
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
---
|
||||
title: Git and Version Control
|
||||
manTitle: 5.4 Git and Version Control
|
||||
sidebar:
|
||||
order: 4
|
||||
helpKeywords:
|
||||
- git
|
||||
---
|
||||
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
---
|
||||
title: Package Management
|
||||
manTitle: 5.5 Package Management
|
||||
sidebar:
|
||||
order: 5
|
||||
helpKeywords:
|
||||
- package-manager
|
||||
- packages
|
||||
---
|
||||
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
---
|
||||
title: Dependency Management
|
||||
manTitle: 5.6 Dependency Management
|
||||
sidebar:
|
||||
order: 6
|
||||
helpKeywords:
|
||||
- deps
|
||||
---
|
||||
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
---
|
||||
title: System and Monitoring
|
||||
manTitle: 5.7 System and Monitoring
|
||||
sidebar:
|
||||
order: 7
|
||||
helpKeywords:
|
||||
- system
|
||||
---
|
||||
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
---
|
||||
title: Terminal Management
|
||||
manTitle: 5.8 Terminal Management
|
||||
sidebar:
|
||||
order: 8
|
||||
helpKeywords:
|
||||
- terminal-mgmt
|
||||
---
|
||||
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
---
|
||||
title: Clipboard
|
||||
manTitle: 5.9 Clipboard
|
||||
sidebar:
|
||||
order: 9
|
||||
helpKeywords:
|
||||
- clipboard
|
||||
---
|
||||
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
---
|
||||
title: Network
|
||||
manTitle: 5.10 Network
|
||||
sidebar:
|
||||
order: 10
|
||||
helpKeywords:
|
||||
- network
|
||||
---
|
||||
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
---
|
||||
title: Pager and Logging
|
||||
manTitle: 5.11 Pager and Logging
|
||||
sidebar:
|
||||
order: 11
|
||||
helpKeywords:
|
||||
- logging
|
||||
---
|
||||
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
---
|
||||
title: AI and Developer Tools
|
||||
manTitle: 5.12 AI and Developer Tools
|
||||
sidebar:
|
||||
order: 12
|
||||
helpKeywords:
|
||||
- ai
|
||||
---
|
||||
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
---
|
||||
title: Media and Utilities
|
||||
manTitle: 5.13 Media and Utilities
|
||||
sidebar:
|
||||
order: 13
|
||||
helpKeywords:
|
||||
- media
|
||||
---
|
||||
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
---
|
||||
title: Miscellaneous
|
||||
manTitle: 5.14 Miscellaneous
|
||||
sidebar:
|
||||
order: 14
|
||||
helpKeywords:
|
||||
- miscfns
|
||||
---
|
||||
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
---
|
||||
title: Functions Reference
|
||||
manTitle: 5. FUNCTIONS REFERENCE
|
||||
sidebar:
|
||||
order: 9
|
||||
helpKeywords:
|
||||
- functions
|
||||
---
|
||||
|
||||
|
||||
@@ -0,0 +1,94 @@
|
||||
---
|
||||
title: Dependency Catalog
|
||||
manTitle: 6. DEPENDENCY CATALOG
|
||||
sidebar:
|
||||
order: 10
|
||||
helpKeywords:
|
||||
- catalog
|
||||
- deps-catalog
|
||||
---
|
||||
|
||||
fish-deps manages these tools. Run `fish-deps` to check status,
|
||||
`fish-deps install` to install missing Required/Recommended ones, or add
|
||||
`--optional`, `--terminals`, or `--all` to also include the Optional and/or
|
||||
Terminal Emulators tiers.
|
||||
|
||||
## Required
|
||||
|
||||
| Tool | Description |
|
||||
|---|---|
|
||||
| `fish` | Fish shell >= 4.0 |
|
||||
| `fzf` | Fuzzy finder |
|
||||
|
||||
## Recommended
|
||||
|
||||
| Tool | Description |
|
||||
|---|---|
|
||||
| `cargo` | Rust toolchain (via rustup); used by `fish-deps` to install Rust-based tools and to build fish from source. All paths are gated on `type -q cargo` and degrade gracefully. |
|
||||
| `starship` | Cross-shell prompt; loaded via `type -q starship` guard. Without it the Catppuccin nim-style fallback prompt activates. |
|
||||
| `uv` | Python package and project manager (Astral); used by the fish-from-source build path in `fish-deps`. All consumers degrade gracefully without it. |
|
||||
| `direnv` | Per-directory environment loading; integration is fully guarded with `type -q direnv`. Without it the direnv hook is simply not loaded and auto-venv activates normally. |
|
||||
| `paru` | AUR helper (Arch only; preferred); guarded throughout — non-Arch systems silently skip AUR-specific paths. |
|
||||
| `yay` | AUR helper (Arch only; fallback to paru); same guards apply. |
|
||||
| `eza` | Modern `ls` replacement |
|
||||
| `zoxide` | Smart cd with frecency |
|
||||
| `lsd` | `ls` replacement (fallback to `eza`) |
|
||||
| `bat` | Syntax-highlighted `cat` |
|
||||
| `ov` | Modern pager (replaces `less`); also backs the `logs` viewer. Not a Rust crate, despite the name collision with an unrelated `ov` crate on crates.io. Prefers `go install github.com/noborus/ov@latest` when `go` is available (always gets the latest release, and covers distros like Debian/Ubuntu that don't package `ov` in their base repos); falls back to the system PM (AUR on Arch) otherwise. |
|
||||
| `ripgrep` | Fast line search |
|
||||
| `trash` | Safe delete (`trash-cli`); backs the `rm` and `scrub` wrappers. |
|
||||
| `python3` | Standalone interpreter — used by the `paru`/`yay` log cleaner. Note: `uv` does not provide `python3` on PATH, and Arch's base does not include it, so it is listed separately. All consumers degrade gracefully without it. |
|
||||
|
||||
## Optional
|
||||
|
||||
Single-purpose tools that back one wrapper function (or less) and only
|
||||
matter if you already use that specific tool. Skipped by
|
||||
`fish-deps install`/`sync` unless you pass `--optional`.
|
||||
|
||||
| Tool | Description |
|
||||
|---|---|
|
||||
| `btop` | Modern resource monitor; backs the `top` wrapper (falls back to system `top`). |
|
||||
| `dust` | Disk usage tree (Rust); one of two backends for the `du` wrapper (falls back to system `du`). |
|
||||
| `duf` | Disk usage/free overview; the other backend for the `du` wrapper (falls back to system `du`). |
|
||||
| `prettyping` | Colorized ping wrapper; backs the `ping` wrapper (falls back to system `ping`). |
|
||||
| `go` | Go toolchain; only used to install `ov` via `go install` (see below), which gets the latest release and doesn't depend on your distro packaging `ov`. Package name varies by distro (`go` on Arch/Homebrew, `golang`/`golang-go` on Debian/Fedora) — install manually if the listed package name doesn't resolve on your system. |
|
||||
| `lazygit` | Terminal git UI; only referenced by the `lg` abbreviation. |
|
||||
| `lazydocker` | Terminal docker UI; backs the `ld` wrapper. |
|
||||
| `docker` | Container runtime; gates the Docker context indicator in the right prompt and backs the `ld` wrapper. Both consumers are guarded with `type -q docker` and degrade gracefully without it. Installing the daemon package does not enable/start the service — do that yourself if you want it running. |
|
||||
| `yt-dlp` | Video/media downloader; backs the `yt-dlp` wrapper function. The wrapper falls back to the system `yt-dlp` and the rest of the config works without it. |
|
||||
| `screen` | GNU screen; fallback backend for `jobrunner` when `tmux` is unavailable. |
|
||||
|
||||
## Terminal Emulators
|
||||
|
||||
GPU-accelerated terminal emulators. Only one is ever relevant to a given
|
||||
user — the one matching `$TERM` — so neither is installed by default.
|
||||
Skipped by `fish-deps install`/`sync` unless you pass `--terminals` (or
|
||||
`--all`).
|
||||
|
||||
| Tool | Description |
|
||||
|---|---|
|
||||
| `kitty` | GPU-accelerated terminal; unlocks kitty-specific abbreviations and `--hyperlink-format=kitty` in the `rg` wrapper when `$TERM = xterm-kitty`. |
|
||||
| `wezterm` | GPU-accelerated terminal; unlocks WezTerm-specific abbreviations when it's the active terminal. |
|
||||
|
||||
## Integrations
|
||||
|
||||
Opt-in third-party services that require their own account/setup.
|
||||
|
||||
| Tool | Description |
|
||||
|---|---|
|
||||
| `wakatime` | Developer time tracking |
|
||||
| `tailscale` | Mesh VPN client |
|
||||
|
||||
## Install Methods
|
||||
|
||||
The install priority for each tool:
|
||||
|
||||
| Method | Packages |
|
||||
|---|---|
|
||||
| `cargo` | Rust tools (`eza`, `lsd`, `bat`, `dust`, `ripgrep`, `trashy`, `zoxide`, `starship`) — always gets the latest crate version |
|
||||
| `go install` | `ov` — preferred over the system PM when `go` is available; always gets the latest release |
|
||||
| system PM | `paru` / `apt` / `brew` / `dnf` / etc. — for tools without a crate or `go install` path |
|
||||
| `git clone` | `fzf` — installed from GitHub to `~/.fzf/` |
|
||||
| `curl` | `starship` installer, `fisher` bootstrap, `uv` installer |
|
||||
|
||||
---
|
||||
@@ -0,0 +1,225 @@
|
||||
---
|
||||
title: Customization
|
||||
manTitle: 7. CUSTOMIZATION
|
||||
sidebar:
|
||||
order: 11
|
||||
helpKeywords:
|
||||
- customization
|
||||
- customize
|
||||
---
|
||||
This section explains how to adapt the configuration to your specific workflow, including local machine overrides and opinionated component toggles.
|
||||
|
||||
|
||||
## Machine-local Configuration
|
||||
|
||||
Place machine-specific settings that should not be committed to git in:
|
||||
|
||||
$__fish_user_dots_path/local.fish
|
||||
|
||||
`__fish_user_dots_path` defaults to `~/.config/.user-dots/fish`. Set a
|
||||
custom location with:
|
||||
|
||||
set -U __fish_user_dots_path /path/to/your/dots/fish
|
||||
|
||||
Typical uses: additional PATH entries, local aliases, hostname-specific env
|
||||
vars, work-specific tool configs.
|
||||
|
||||
For convenience, a git-ignored `user-dots` symlink in the fish config
|
||||
directory tracks `$__fish_user_dots_path` so the overlay can be browsed from
|
||||
`~/.config/fish/`. It is created if missing and repointed if the path changes.
|
||||
Opt out by setting `__fish_user_dots_symlink` to a falsy value, or toggling
|
||||
"Dots link" off on the config-settings Paths page — this stops generation and
|
||||
removes any existing link. It only ever manages a symlink and never clobbers a
|
||||
real file or directory at that path.
|
||||
|
||||
|
||||
## Secrets and API Keys
|
||||
|
||||
$__fish_user_dots_path/secrets.fish
|
||||
|
||||
Store API tokens, GPG keys, private credentials here. This file is never
|
||||
committed. It is sourced by local.fish directly, not by config.fish.
|
||||
|
||||
`local.fish` is sourced at the end of config.fish on every interactive
|
||||
session, so it and its companion secrets.fish can override anything set
|
||||
earlier.
|
||||
|
||||
|
||||
## Overriding Configuration Variables
|
||||
|
||||
Any variable set in local.fish after the main config loads takes effect.
|
||||
Example: to increase the scrollback history limit:
|
||||
|
||||
# in local.fish
|
||||
set -gx SCROLLBACK_HISTORY_MAX_FILES 200
|
||||
|
||||
|
||||
## Fish Universal Variables
|
||||
|
||||
Some settings (fzf colors, theme) are stored in fish_variables via
|
||||
`set -U`. These are machine-local and git-ignored. Do not commit
|
||||
fish_variables.
|
||||
|
||||
|
||||
## Opinionated Components (Minimal Mode)
|
||||
|
||||
Every opinionated piece of this config is active by default but can be
|
||||
switched off through six category opt-out variables, each evaluated via
|
||||
`__fish_variable_check`. Set a variable to any falsy value (0, false, no,
|
||||
off, n) to disable its category; erase it or set a truthy value (1, true,
|
||||
yes, on, y) to re-enable. Unset means enabled — except for C5 logging, which
|
||||
is opt-in (see below).
|
||||
|
||||
An explicit per-category truthy value takes precedence over the master
|
||||
switch: setting `__fish_config_opinionated`=0 disables all unset categories,
|
||||
but a category with an explicit truthy value remains enabled regardless.
|
||||
|
||||
C5 (logging) is the one exception to "unset means enabled". Because it
|
||||
writes terminal output to disk, it is opt-in: unset means disabled, and the
|
||||
master switch cannot enable it. Only an explicit truthy value turns logging
|
||||
on.
|
||||
|
||||
Variable Disables
|
||||
────────────────────────────────────────
|
||||
__fish_config_op_aliases Command shadows and flag injection:
|
||||
ls->eza, cat->bat, cd->zoxide,
|
||||
rm->trash, less->ov, top->btop,
|
||||
ping->prettyping, ssh->kitten,
|
||||
du->duf/dust, mkdir/bash wrappers,
|
||||
history timestamps, grep/cp/mv/wget
|
||||
flag injection, help intercept, claude
|
||||
AGENTS.md auto-link
|
||||
__fish_config_op_autoexec Startup side-effects: Fisher
|
||||
bootstrap, theme apply, paru/yay
|
||||
wrapper generation, auto venv
|
||||
activation, WakaTime hook
|
||||
__fish_config_op_overrides Key and env overrides: Vi mode,
|
||||
exit->smart_exit, PAGER/MANPAGER,
|
||||
CDPATH, bang-bang system, autopair,
|
||||
puffer, starship prompt, theme
|
||||
colors, FZF_DEFAULT_OPTS, right
|
||||
prompt
|
||||
__fish_config_op_integrations Terminal/tool coupling: Kitty/
|
||||
WezTerm window abbreviations, done
|
||||
notifications, spwin/tab/split,
|
||||
hist, logs, upgrade, WakaTime
|
||||
__fish_config_op_logging Logging & capture (OPT-IN — this one
|
||||
is off unless explicitly enabled):
|
||||
scrollback capture on exit, paru/yay
|
||||
AUR log wrappers, Kitty watcher
|
||||
capture; sentinel file coordinates
|
||||
cross-process state
|
||||
__fish_config_op_greeting Greeting & first-run UI: per-session
|
||||
fish_greeting override (defines empty
|
||||
function late in config.fish to
|
||||
suppress distro greetings such as
|
||||
CachyOS fastfetch); first-run welcome
|
||||
banner in conf.d/first_run.fish
|
||||
|
||||
Examples:
|
||||
|
||||
# Disable command shadows only (rm becomes plain rm again):
|
||||
set -U __fish_config_op_aliases off
|
||||
|
||||
# Turn session logging on (opt-in; off until you do this):
|
||||
set -U __fish_config_op_logging on
|
||||
|
||||
# Full minimal mode — disable all six categories at once:
|
||||
set -U __fish_config_opinionated 0
|
||||
|
||||
# Re-enable everything (except C5 logging, which stays opt-in):
|
||||
set -Ue __fish_config_opinionated
|
||||
|
||||
# Minimal mode but keep the greeting:
|
||||
set -U __fish_config_opinionated 0
|
||||
set -U __fish_config_op_greeting 1
|
||||
# (erase both to go back to full-flavor defaults)
|
||||
|
||||
For an interactive alternative to setting these variables by hand, run
|
||||
config-settings — a full-screen TUI that flips any category (including C5
|
||||
logging) on or off, per session or universally. See its entry in Section 5.
|
||||
|
||||
NOTE:
|
||||
- Command shadows (rm, cat, ls, ...) react immediately; conf.d-level components (bindings, prompt, abbreviations, hooks) take effect in new shells.
|
||||
- With aliases disabled, rm falls back to bare `command rm` — files are deleted permanently, not trashed.
|
||||
- Disabled integration commands (spwin, tab, split, hist, logs, upgrade) print an error naming the variable that disabled them.
|
||||
- On CachyOS, the distro fish config's own aliases, history override, and bang-bang bindings are stripped per category as well.
|
||||
|
||||
### Sub-categories
|
||||
|
||||
Each of the six categories further sub-divides into two to six
|
||||
sub-categories, each with its own `__fish_config_op_<category>_<subcategory>`
|
||||
variable (e.g. `__fish_config_op_aliases_filesystem`). These follow the
|
||||
exact same truthy/falsy/unset cascade one level deeper: an explicit
|
||||
sub-category value overrides the master switch and the parent category's
|
||||
setting, and an unset sub-category inherits from its parent category (which
|
||||
in turn inherits from `__fish_config_opinionated`). Run config-settings and
|
||||
press Enter on a category row to browse and toggle its sub-categories
|
||||
interactively. See [Components Reference](/08-components-reference/) for the
|
||||
full sub-category breakdown of every category.
|
||||
|
||||
|
||||
## Prompt and Theme
|
||||
|
||||
### Starship
|
||||
|
||||
The primary prompt is Starship, initialized by conf.d/starship.fish.
|
||||
Configure it via ~/.config/starship.toml.
|
||||
|
||||
conf.d/starship.fish defines a fish_prompt wrapper that only activates when
|
||||
starship is in PATH. It emits OSC 133;A (prompt start) immediately before
|
||||
Starship renders and OSC 133;B (input start) immediately after, placing both
|
||||
markers on the prompt line itself. This allows ov to use them as sticky
|
||||
section headers when browsing scrollback logs. Without Starship, fish's
|
||||
built-in prompt handles these markers automatically.
|
||||
|
||||
### Catppuccin Fallback Prompt
|
||||
|
||||
When Starship is absent or C3 overrides are disabled, a built-in nim-style
|
||||
two-line prompt activates from functions/fish_prompt.fish. No external
|
||||
dependencies — fish builtins only.
|
||||
|
||||
Layout:
|
||||
|
||||
┬─[user@host:~/path] (main)
|
||||
╰─>$
|
||||
|
||||
Elements:
|
||||
|
||||
user Yellow (Catppuccin Yellow); red if root
|
||||
@host Blue (local) or Teal (SSH)
|
||||
~/path prompt_pwd abbreviation (Catppuccin Text)
|
||||
(main) Current git branch in Catppuccin Pink; omitted outside repos
|
||||
─[V:name] Active Python venv basename; omitted when none
|
||||
─[N/I/R/V] Vi-mode indicator when vi bindings are active
|
||||
┬─ / ╰─> Connector lines: Catppuccin Green on success, Red on failure
|
||||
|
||||
The right prompt (fish_right_prompt.fish) always renders, regardless of C3
|
||||
state. On failure it shows a red ✘ and the exit code; on success it shows
|
||||
only the dim timestamp. When starship is installed and C3 is enabled, the
|
||||
active Docker context is also shown (if non-default):
|
||||
|
||||
✘ 1 myctx Fri Jun 12 00:51:21 2026 ← failed, starship+C3 active
|
||||
✘ 1 Fri Jun 12 00:51:21 2026 ← failed, fallback prompt
|
||||
Fri Jun 12 00:51:21 2026 ← success (no ✘)
|
||||
|
||||
### FZF
|
||||
|
||||
FZF is themed to Catppuccin Mocha via FZF_DEFAULT_OPTS set in
|
||||
integrations/fzf.fish. The colors applied:
|
||||
|
||||
Background: #1E1E2E (base) #313244 (surface0)
|
||||
Foreground: #CDD6F4 (text)
|
||||
Highlights: #F38BA8 (red) #CBA6F7 (mauve) #B4BEFE (lavender)
|
||||
|
||||
To customize, override FZF_DEFAULT_OPTS in local.fish.
|
||||
|
||||
### Catppuccin Mocha Syntax Highlighting
|
||||
|
||||
The Catppuccin Mocha theme ships with this config in themes/ and is applied
|
||||
on first run via `conf.d/first_run.fish`. Colors are stored in fish_variables
|
||||
(universal). To switch variants, install a different theme from themes/:
|
||||
|
||||
fish_config theme save "Catppuccin Latte"
|
||||
|
||||
`---`
|
||||
@@ -0,0 +1,65 @@
|
||||
---
|
||||
title: C1 — Command Shadows
|
||||
---
|
||||
|
||||
Disabling `__fish_config_op_aliases` restores standard system behavior for
|
||||
all of these commands.
|
||||
|
||||
Command / Alias Active behavior Disabled fallback
|
||||
───────────────────────────────────────────────────────────────────────────
|
||||
ls eza -l -a --icons --hyperlink system ls
|
||||
cat bat syntax-highlighted; dirs → ls /usr/bin/cat
|
||||
cd zoxide frecency-based navigation fish builtin cd
|
||||
rm moves files to trash (recoverable) command rm (permanent)
|
||||
less $PAGER → ov → less → more → cat system less
|
||||
du duf (disk overview) or dust (dir tree) system du
|
||||
top btop resource monitor system top
|
||||
ping prettyping --nolegend animation system ping
|
||||
ssh kitten ssh in Kitty terminal system ssh
|
||||
rg rg --hyperlink-format=kitty system rg
|
||||
mkdir verbose path-tree display on creation mkdir -p silently
|
||||
bash XDG bashrc + $SHELL reset on exit system bash
|
||||
history timestamps prepended to every entry fish builtin history
|
||||
cp / mv forced -i confirmation prompt cp / mv unmodified
|
||||
wget forced --continue (resume downloads) system wget
|
||||
grep/fgrep/egrep forced --color=auto system grep variants
|
||||
dir / vdir forced --color=auto system dir / vdir
|
||||
help config intercepts "help config" → config-help fish builtin help
|
||||
claude auto-links AGENTS.md as CLAUDE.md before launch command claude
|
||||
edit multi-editor launcher (GUI/term + fallbacks) $EDITOR/nvim/nano/vi
|
||||
|
||||
When C1 is disabled, `rm` uses bare `command rm` with no wrapper — files
|
||||
are permanently deleted, not trashed. There is no intermediate safety net.
|
||||
|
||||
## Sub-categories
|
||||
|
||||
`__fish_config_op_aliases` sub-divides into six sub-categories, each with
|
||||
its own `__fish_config_op_aliases_<slug>` toggle:
|
||||
|
||||
## filesystem
|
||||
|
||||
`ls`, `cat`, `cd`, `du`, `mkdir`, `rm`, `mv`, and `cd`/zoxide navigation --
|
||||
the everyday filesystem-inspection and -modification shadows.
|
||||
|
||||
## search
|
||||
|
||||
`rg`, with its Kitty hyperlink formatting.
|
||||
|
||||
## network
|
||||
|
||||
`ping`, `ssh`, and `yt-dlp` -- shadows that talk to the network.
|
||||
|
||||
## monitor
|
||||
|
||||
`top` -> `btop`.
|
||||
|
||||
## shell-tools
|
||||
|
||||
`bash` (XDG bashrc + `$SHELL` reset), `less` (`$PAGER` fallback chain),
|
||||
and the `help config` interception.
|
||||
|
||||
## dev-tools
|
||||
|
||||
`claude` (AGENTS.md/CLAUDE.md auto-linking) and `edit` (multi-editor
|
||||
launcher), plus `agy`.
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
---
|
||||
title: C2 — Startup Side-Effects
|
||||
---
|
||||
|
||||
These run automatically without any user action. Disabling
|
||||
`__fish_config_op_autoexec` prevents all of them.
|
||||
|
||||
Component Trigger What it does
|
||||
───────────────────────────────────────────────────────────────────────────
|
||||
Fisher bootstrap First shell only Downloads and installs fisher
|
||||
Fisher update After bootstrap Installs all fish_plugins entries
|
||||
Catppuccin Mocha theme First shell only Applies theme via fish_config
|
||||
paru wrapper Every startup Writes ~/.local/bin/paru wrapper
|
||||
yay wrapper Every startup Writes ~/.local/bin/yay wrapper
|
||||
Python venv activation On every cd Sources .venv/bin/activate.fish
|
||||
WakaTime command hook On every command Reports to WakaTime API
|
||||
Auto-pull fast-forward On entering a repo Background ff-only git pull
|
||||
user-dots symlink Every startup Links $__fish_config_dir/user-dots
|
||||
to $__fish_user_dots_path
|
||||
|
||||
When C2 is disabled: no Fisher install, no theme application, no paru/yay
|
||||
wrapper generation, no automatic venv activation, no WakaTime reporting,
|
||||
no auto-pull (the PWD handler is never registered), and the user-dots
|
||||
convenience symlink is not created. The symlink is git-ignored and only ever
|
||||
managed as a symlink — a real file or directory at that path is left untouched.
|
||||
The symlink has its own opt-out independent of C2: set `__fish_user_dots_symlink`
|
||||
to a falsy value (or toggle "Dots link" off on the config-settings Paths page)
|
||||
to stop generating it and remove any existing link — honoured even when C2 is
|
||||
enabled. Managed by the `__fish_user_dots_link` helper.
|
||||
The first-run completion marker (`__fish_config_first_run_complete`) is still
|
||||
set so the init does not re-run on subsequent shells.
|
||||
|
||||
Python venv activation fires on every directory change. If a directory uses
|
||||
direnv (`.envrc` present), direnv takes priority and auto-venv is skipped for
|
||||
that directory.
|
||||
|
||||
Auto-pull fast-forwards opted-in repositories in the background when you cd
|
||||
into them. The fish-config repo is always covered; other repos are added with
|
||||
the `auto-pull` command (see its entry in the functions reference). It only
|
||||
ever fast-forwards a clean repo whose branch has an upstream — never rebases,
|
||||
merges, or overwrites work — so it is a no-op on dirty trees, divergent
|
||||
branches, or repos without a remote. The handler fires once per repo entry
|
||||
(not on every sub-directory `cd`). The registry is machine-local at
|
||||
`$__fish_user_dots_path/auto-pull.list` (defaults to `~/.config/.user-dots/fish/auto-pull.list`) and is never committed.
|
||||
|
||||
## Sub-categories
|
||||
|
||||
`__fish_config_op_autoexec` sub-divides into five sub-categories, each
|
||||
with its own `__fish_config_op_autoexec_<slug>` toggle:
|
||||
|
||||
## plugin-management
|
||||
|
||||
Fisher bootstrap on first run.
|
||||
|
||||
## pkg-wrappers
|
||||
|
||||
`paru`/`yay` wrapper generation.
|
||||
|
||||
## venv
|
||||
|
||||
Automatic Python virtualenv activation.
|
||||
|
||||
## telemetry
|
||||
|
||||
The WakaTime hook's startup bootstrap.
|
||||
|
||||
## sync
|
||||
|
||||
Auto-pull background fast-forward, and the user-dots convenience symlink.
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
---
|
||||
title: C3 — Key and Environment Overrides
|
||||
---
|
||||
|
||||
These change fundamental shell behavior: how keys work, which pager opens,
|
||||
and what the prompt looks like. Disabling `__fish_config_op_overrides` removes
|
||||
all of them.
|
||||
|
||||
Override What it replaces or sets
|
||||
───────────────────────────────────────────────────────────────────────────
|
||||
Vi mode fish_vi_key_bindings replaces default Emacs mode
|
||||
PATH setup Prepends custom bin directories to the PATH
|
||||
exit → smart_exit exit wrapper that captures scrollback before closing
|
||||
PAGER=ov ov used by git, man, and all $PAGER-aware tools
|
||||
EDITOR=nvim nvim fallback to vi for git commit, etc.
|
||||
GPG_TTY Sets GPG_TTY to current terminal tty
|
||||
MANPAGER=bat pipeline man pages rendered with syntax highlighting
|
||||
CDPATH=. ~/projects ~ bare dir names resolve against ~/projects and ~
|
||||
Bang-bang system ! and $ keys expand history; !^, !*, !-N, !?str?,
|
||||
^old^new abbreviations; six expand_bang_* helpers
|
||||
Autopair ( [ { " ' auto-close to (), [], {}, "", ''
|
||||
Puffer key intercepts . ! $ * keys intercepted for smart expansion
|
||||
Starship prompt fish_prompt replaced by Starship + OSC 133 markers
|
||||
Catppuccin colors 30+ fish_color_* variables set to Mocha palette
|
||||
FZF_DEFAULT_OPTS FZF themed to Catppuccin Mocha colors
|
||||
Right prompt fish_right_prompt: exit code (on failure) + dim timestamp; always rendered; Docker context added when starship+C3 active
|
||||
|
||||
The bang-bang system spans `key_bindings.fish`, `abbr.fish`, `puffer.fish`, and
|
||||
six `expand_bang_*.fish` functions. All are gated together — disabling C3
|
||||
removes the entire bang-expansion system at once.
|
||||
|
||||
When C3 is disabled, `exit` falls back to `builtin exit` with no scrollback
|
||||
capture, no Kitty IPC, and no file I/O on exit. The scrollback capture block
|
||||
is independently controlled by C5 (see below).
|
||||
|
||||
## Sub-categories
|
||||
|
||||
`__fish_config_op_overrides` sub-divides into three sub-categories, each
|
||||
with its own `__fish_config_op_overrides_<slug>` toggle:
|
||||
|
||||
## key-bindings
|
||||
|
||||
Vi mode, autopair, puffer key intercepts, bang-bang history expansion,
|
||||
and `smart_exit`'s plain-exit path.
|
||||
|
||||
## environment
|
||||
|
||||
`$PATH`, `$PAGER`/`$EDITOR`/`$GPG_TTY`, and `$CDPATH`.
|
||||
|
||||
## prompt
|
||||
|
||||
Starship, the right prompt, Catppuccin syntax/prompt colors, and FZF
|
||||
theming (`$FZF_DEFAULT_OPTS`) -- all driven by the same guard as a single
|
||||
unit, not independently toggleable from each other.
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
---
|
||||
title: C4 — Terminal and Tool Integration
|
||||
---
|
||||
|
||||
These features couple the shell to specific external tools. Disabling
|
||||
`__fish_config_op_integrations` disables all of them.
|
||||
|
||||
Component Requires
|
||||
───────────────────────────────────────────────────────────────────────────
|
||||
≈ 60 Kitty/WezTerm abbrs Active Kitty or WezTerm session
|
||||
(:w, :wv, :wh, :t, etc.)
|
||||
Done desktop notifications Graphical desktop with a notification daemon
|
||||
spwin Kitty or WezTerm
|
||||
tab Kitty, WezTerm, or Konsole
|
||||
split Kitty or WezTerm
|
||||
hist fzf + wl-copy (Wayland clipboard)
|
||||
logs fzf + ov; reads from ~/.terminal_history/
|
||||
upgrade paru or yay (Arch Linux only)
|
||||
WakaTime hook wakatime CLI and a configured API key
|
||||
|
||||
Disabled integration commands (`spwin`, `tab`, `split`, `hist`, `logs`, `upgrade`) print
|
||||
a colored error to stderr naming the variable that disabled them rather than
|
||||
silently failing.
|
||||
|
||||
## Sub-categories
|
||||
|
||||
`__fish_config_op_integrations` sub-divides into five sub-categories,
|
||||
each with its own `__fish_config_op_integrations_<slug>` toggle:
|
||||
|
||||
## terminal-abbrs
|
||||
|
||||
The Kitty/WezTerm abbreviation set.
|
||||
|
||||
## window-mgmt
|
||||
|
||||
`spwin`, `tab`, `split`.
|
||||
|
||||
## notifications
|
||||
|
||||
`done`'s completion notifications, and the WakaTime activity hook.
|
||||
|
||||
## history-logs
|
||||
|
||||
`hist`, `logs`.
|
||||
|
||||
## pkg-upgrade
|
||||
|
||||
`upgrade`.
|
||||
|
||||
@@ -0,0 +1,133 @@
|
||||
---
|
||||
title: C5 — Logging and Capture
|
||||
---
|
||||
|
||||
Five components capture shell output to disk. Unlike every other category,
|
||||
C5 is opt-in: it stays off until `__fish_config_op_logging` is set to an
|
||||
explicit truthy value, and a truthy master switch does not enable it. While
|
||||
it is off, all capture is skipped and the logging wrappers are removed.
|
||||
|
||||
CAUTION: This configuration is capable of silently recording terminal output and secrets directly to disk. See below for details on how this capture mechanism works, where files are stored, and how to manage its state.
|
||||
|
||||
# Turn it on (persistently, in every shell):
|
||||
set -U __fish_config_op_logging on
|
||||
|
||||
# Turn it back off:
|
||||
set -U __fish_config_op_logging off # or: set -Ue __fish_config_op_logging
|
||||
|
||||
Component What it captures
|
||||
───────────────────────────────────────────────────────────────────────────
|
||||
Scrollback capture Terminal session output saved to:
|
||||
`~/.terminal_history/scrollback_YYYY-MM-DD_HH-MM-SS.log`
|
||||
tmux pane capture Continuous pane stream via pipe-pane, saved to:
|
||||
`~/.terminal_history/tmux_<session>-w<win>-p<pane>_YYYY-MM-DD_HH-MM-SS.log`
|
||||
zellij pane capture Pane scrollback snapshot on shell exit, saved to:
|
||||
`~/.terminal_history/zellij_<session>-p<pane>_YYYY-MM-DD_HH-MM-SS.log`
|
||||
paru wrapper All paru/AUR output captured to:
|
||||
`~/.terminal_history/paru_YYYY-MM-DD_HH-MM-SS.log`
|
||||
yay wrapper All yay/AUR output captured to:
|
||||
`~/.terminal_history/yay_YYYY-MM-DD_HH-MM-SS.log`
|
||||
Kitty watcher `watcher.py` captures scrollback when Kitty closes
|
||||
|
||||
NOTE: **Turning off logging does not delete any existing logs.**
|
||||
They remain in `$SCROLLBACK_HISTORY_DIR` (defaults to: `~/.terminal_history/`)
|
||||
until you remove them manually.
|
||||
|
||||
The tmux capture starts automatically when fish launches inside any tmux
|
||||
pane (`$TMUX` is set). It uses tmux's native pipe-pane to stream all pane
|
||||
output directly to disk without an intermediate process. Each fish shell
|
||||
session gets its own log file; a new log is created on each shell start
|
||||
(including exec fish and new splits). Before each new log, the oldest
|
||||
`tmux_*.log` files are pruned (by modification time) to keep the total within
|
||||
`SCROLLBACK_HISTORY_MAX_FILES`, matching the paru/yay wrapper behaviour.
|
||||
|
||||
The zellij capture works differently: Zellij has no live output-streaming
|
||||
facility like pipe-pane, so the log is taken as a one-shot snapshot when the
|
||||
shell exits, via `zellij action dump-screen --full --ansi` (the `--ansi` flag
|
||||
preserves color). The dump is captured on the fish process's stdout and
|
||||
written to the log file by fish itself (not via `--path`, which would make the
|
||||
zellij server write the file). A fish_exit handler (registered whenever
|
||||
`$ZELLIJ` is set) writes the pane's full scrollback and then prunes old
|
||||
`zellij_*.log` files the same way. Because the capture happens at exit, toggling
|
||||
`__fish_config_op_logging` takes effect on the next exit with no restart or
|
||||
sentinel coordination needed — the C5 guard is re-checked when the handler
|
||||
fires.
|
||||
|
||||
LIMITATION — zellij capture only fires on a clean shell exit (typing `exit`,
|
||||
Ctrl-D, or a logout), because that is when the fish_exit handler runs. It does
|
||||
NOT capture when you close a pane or quit zellij through zellij itself:
|
||||
|
||||
- Closing a pane signals the shell and tears the pane down concurrently, so
|
||||
even if the handler runs, `dump-screen` may find the pane buffer already
|
||||
gone.
|
||||
- Quitting zellij kills the zellij server, and `dump-screen` needs a live
|
||||
server to read from — there is nothing left to snapshot.
|
||||
|
||||
This is a structural difference from tmux, NOT a bug. tmux streams pane output
|
||||
to disk continuously via pipe-pane, so whatever was printed is already saved
|
||||
no matter how the pane dies. Zellij can only snapshot, and the only reliable
|
||||
snapshot point from the shell is a clean exit. To guarantee a zellij pane is
|
||||
logged, end the session with `exit` or Ctrl-D rather than zellij's close-pane
|
||||
or quit actions.
|
||||
|
||||
The Kitty watcher is managed by the kitty-logging command: it symlinks the
|
||||
watcher (`fish-config-watcher.py`) into the Kitty config directory and wires it
|
||||
into `kitty.conf` via a managed block. Inside Kitty, a non-blocking
|
||||
per-session reminder points first-time users at `kitty-logging install` until
|
||||
they install or run `kitty-logging dismiss`; the reminder is itself gated on
|
||||
C5, so it stays silent until you enable logging. Install affects new Kitty
|
||||
windows only; runtime disable is still handled by the `.logging_disabled`
|
||||
sentinel.
|
||||
|
||||
Logging coordination via sentinel file
|
||||
|
||||
C5 uses a sentinel file to synchronize state between the shell and
|
||||
out-of-process components (the Kitty watcher and all running shells):
|
||||
|
||||
~/.config/fish/.logging_disabled
|
||||
|
||||
Because C5 is off by default, the sentinel is present on a fresh install —
|
||||
the startup sync in `conf.d/logging-events.fish` reconciles it on every shell
|
||||
start, so it appears without any action on your part.
|
||||
|
||||
Disabling `__fish_config_op_logging` (or leaving it unset):
|
||||
1. Creates the sentinel immediately in every open shell.
|
||||
2. Removes `~/.local/bin/paru` and `~/.local/bin/yay` logging wrappers;
|
||||
bare `/usr/bin/paru` and `/usr/bin/yay` are used instead.
|
||||
3. Kitty's `watcher.py` reads the sentinel on each save attempt and
|
||||
skips capture — no Kitty restart required.
|
||||
4. smart_exit stops saving scrollback logs.
|
||||
5. Stops `tmux pipe-pane` capture in every open fish shell inside tmux.
|
||||
|
||||
Enabling `__fish_config_op_logging`:
|
||||
1. Removes the sentinel in every open shell.
|
||||
2. Regenerates paru/yay logging wrappers in `~/.local/bin/`.
|
||||
3. Kitty watcher resumes capture on the next session exit.
|
||||
4. Restarts tmux pipe-pane capture in every open fish shell inside tmux.
|
||||
|
||||
Changes propagate to all running shells through an event handler that fires
|
||||
whenever `__fish_config_op_logging` changes — no shell restart needed.
|
||||
|
||||
Note: C3 and C5 compose independently. C3 controls whether the smart_exit
|
||||
wrapper is active at all; C5 controls only the scrollback-capture block
|
||||
inside it. With C3 disabled, exit is plain builtin exit regardless of C5.
|
||||
|
||||
## Sub-categories
|
||||
|
||||
`__fish_config_op_logging` sub-divides into three sub-categories, each
|
||||
with its own `__fish_config_op_logging_<slug>` toggle (all still opt-in
|
||||
by default, inherited from C5's own opt-in behavior -- see §3 of the
|
||||
design spec):
|
||||
|
||||
## terminal-capture
|
||||
|
||||
Kitty watcher scrollback capture, and `smart_exit`'s logging-guard path.
|
||||
|
||||
## multiplexer-capture
|
||||
|
||||
tmux `pipe-pane` and zellij `dump-screen` capture.
|
||||
|
||||
## pkg-logs
|
||||
|
||||
`paru`/`yay` AUR log wrappers.
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user