feat: CLASSIFICATION function-header field + shadow-classification lint #163
+6
-4
@@ -97,11 +97,13 @@ if __fish_config_op_enabled (status basename) tricks-bang
|
||||
end
|
||||
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.
|
||||
# Timestamped history view. Named pretty-history (not history) so it never
|
||||
# shadows the fish builtin -- every function in this config that expects
|
||||
# stock `history` semantics (search, --max, merge, ...) would otherwise
|
||||
# silently break, which has happened more than once. Opinionated (C1
|
||||
# aliasing); when disabled, the function is never defined.
|
||||
if __fish_config_op_enabled (status basename) aliases-tricks
|
||||
function history
|
||||
function pretty-history --description 'History with timestamps prepended to every entry'
|
||||
builtin history --show-time='%F %T '
|
||||
end
|
||||
end
|
||||
|
||||
@@ -703,6 +703,29 @@ ENTRY_HEADS = {
|
||||
}
|
||||
|
||||
|
||||
def _classification_tags(raw: list[str]) -> list[str]:
|
||||
"""Split a CLASSIFICATION body into its comma-separated tags.
|
||||
|
||||
A plain comma split (as `names()` uses for DEPENDENCIES) would break on
|
||||
the commas inside `uses-shadow(rm, cp)`-style tags, so this only splits
|
||||
on commas at paren depth 0.
|
||||
"""
|
||||
text = " ".join(raw)
|
||||
tags: list[str] = []
|
||||
depth = 0
|
||||
start = 0
|
||||
for i, ch in enumerate(text):
|
||||
if ch == "(":
|
||||
depth += 1
|
||||
elif ch == ")":
|
||||
depth = max(0, depth - 1)
|
||||
elif ch == "," and depth == 0:
|
||||
tags.append(text[start:i].strip())
|
||||
start = i + 1
|
||||
tags.append(text[start:].strip())
|
||||
return [t for t in tags if t]
|
||||
|
||||
|
||||
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.
|
||||
|
||||
@@ -739,6 +762,7 @@ def render_entry(fn: dict[str, list[str]], used_by: list[str], link=None) -> str
|
||||
refs = []
|
||||
for label, values in (
|
||||
("Dependencies", names(fn.get("DEPENDENCIES", []))),
|
||||
("Classification", _classification_tags(fn.get("CLASSIFICATION", []))),
|
||||
("Used by", sorted(used_by)),
|
||||
):
|
||||
if values:
|
||||
@@ -884,6 +908,7 @@ def render_entry_site(fn: dict[str, list[str]], used_by: list[str], link=None) -
|
||||
refs = []
|
||||
for label, values in (
|
||||
("Dependencies", names(fn.get("DEPENDENCIES", []))),
|
||||
("Classification", _classification_tags(fn.get("CLASSIFICATION", []))),
|
||||
("Used by", sorted(used_by)),
|
||||
):
|
||||
if values:
|
||||
|
||||
@@ -19,7 +19,6 @@ all of these commands.
|
||||
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
|
||||
@@ -31,6 +30,11 @@ all of these commands.
|
||||
When C1 is disabled, `rm` uses bare `command rm` with no wrapper — files
|
||||
are permanently deleted, not trashed. There is no intermediate safety net.
|
||||
|
||||
`history` itself is never shadowed — every function in this config that
|
||||
reads history depends on its stock builtin semantics. `pretty-history`
|
||||
(same `aliases-tricks` toggle) is a separate command that prints history
|
||||
with a timestamp prepended to every entry.
|
||||
|
||||
## Sub-categories
|
||||
|
||||
`__fish_config_op_aliases` sub-divides into six sub-categories, each with
|
||||
@@ -63,3 +67,47 @@ and the `help config` interception.
|
||||
`claude` (AGENTS.md/CLAUDE.md auto-linking) and `edit` (multi-editor
|
||||
launcher), plus `agy`.
|
||||
|
||||
## For function authors
|
||||
|
||||
Calling one of these names bare from inside your own function means the
|
||||
override runs whenever C1 (or its sub-category) is on — which may not be
|
||||
what your function wants: a shadow can change stdout (`cat`'s syntax
|
||||
highlighting, `mkdir`'s tree display), prompt interactively where none is
|
||||
expected (`cp`/`mv`'s forced `-i`), or reshape output structurally (`ls`'s
|
||||
icons/columns, `rg`'s hyperlink markers). If your function's logic depends
|
||||
on stock behavior, bypass the shadow deterministically, regardless of the
|
||||
toggle state:
|
||||
|
||||
Shadow Bypass Why
|
||||
─────────────────────────────────────────────────────────────────────────
|
||||
ls, cat, rm, less, du, command <name> Real external
|
||||
top, ping, ssh, rg, binaries — a
|
||||
mkdir, bash, cp, mv, real system command
|
||||
wget, grep/fgrep/egrep, exists to fall
|
||||
dir/vdir, claude back to.
|
||||
cd builtin cd The one true
|
||||
fish builtin
|
||||
in this table.
|
||||
help config __original_help $argv `help` is neither
|
||||
a builtin nor an
|
||||
external binary
|
||||
(embedded in the
|
||||
fish binary
|
||||
itself) — see
|
||||
conf.d/help.fish
|
||||
for why the
|
||||
wrapper keeps its
|
||||
own backup copy.
|
||||
edit (nothing to bypass to) Purely our own
|
||||
invention, no
|
||||
stock command
|
||||
exists. Call
|
||||
$EDITOR/$VISUAL
|
||||
yourself if you
|
||||
want a plain
|
||||
editor launch.
|
||||
|
||||
A function's own doc header records which of these it depends on: see the
|
||||
`CLASSIFICATION` label (`uses-shadow(...)` / `bypasses-shadow(...)`) in
|
||||
`AGENTS/functions/CLAUDE.md`.
|
||||
|
||||
|
||||
@@ -64,6 +64,7 @@ SECTIONS = (
|
||||
"CATEGORY",
|
||||
"COMPONENT",
|
||||
"DEPENDENCIES",
|
||||
"CLASSIFICATION",
|
||||
"SYNOPSIS",
|
||||
"DESCRIPTION",
|
||||
"ARGUMENTS",
|
||||
|
||||
+1
-1
@@ -34,7 +34,7 @@ function hist --description 'Search fish history and put it in the prompt'
|
||||
return 1
|
||||
end
|
||||
|
||||
set -l selected (history | fzf --reverse --height 40% --with-nth 3..)
|
||||
set -l selected (builtin history --show-time='%F %T ' | fzf --reverse --height 40% --with-nth 3..)
|
||||
|
||||
if test -n "$selected"
|
||||
# Strip the timestamp for the final output
|
||||
|
||||
Reference in New Issue
Block a user