Files
fish-config/docs/html/5-1-configuration-variables.html
T
2026-06-12 03:02:58 +00:00

590 lines
19 KiB
HTML

<!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 &#39;col -bx | bat -l man -p&#39;</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>