Files
profile/doc/todo.md
T

175 lines
8.4 KiB
Markdown

# profile — to-do list
Items marked **[easy]**, **[medium]**, or **[hard]** give a rough effort hint.
Items marked **[breaking]** would change existing behaviour and require a
version-bump.
---
## Shell / compatibility
- [ ] **ZSH compatibility layer** — most functions work already; the remaining
blockers are `local -A` (no associative arrays in ZSH without `typeset -A`)
and `local -n` namerefs. A thin compatibility shim would open the project to
ZSH users. **[hard]**
- [ ] **Bash completion** — add a more bash completion directory and write
`_profile_upgrade`, `_taz`, `_utaz`, `_meteo`, etc. completions so that
`<Tab>` works on all public functions. **[medium]**
---
## Prompt & theming
- [x] **Git branch in prompt** — show the current branch name (with dirty and
upstream drift indicators) in the PS1 bar when inside a Git repository,
gated by `[prompt]` config keys. **[medium]**
- [x] **Virtual-env / conda indicator** — detect `$VIRTUAL_ENV` / `$CONDA_DEFAULT_ENV`
and display the active environment in the prompt bar. **[easy]**
- [x] **Session context markers** — display lightweight session markers
(`ssh`, `tmux`, `screen`) at the end of the prompt bar, gated by
`[prompt]` config keys. **[easy]**
- [x] **True-colour terminal auto-detection** — query `$COLORTERM` and
`$TERM` at load time; automatically fall back from a 24-bit theme to its
16-colour equivalent when the terminal does not support true colour. **[medium]**
- [ ] **True-colour variants of other themes** — create `monokai-tc.theme`,
`abyss-tc.theme`, etc. using the same `\e[38;2;R;G;Bm` approach as the
Solarized themes. **[easy]** _(per theme)_
- [X] **Theme preview command** — add a `theme_preview` (or `profile_theme`)
function that renders a colour swatch and a sample prompt line for the
currently loaded theme, so users can evaluate themes without reloading
the session. **[medium]**
- [ ] **`load_theme` — DEFAULTCOL rebuild** — after overriding `DEFAULTFG` and
`DEFAULTBG`, automatically recompute `DEFAULTCOL` from the new values instead
of requiring the theme file to set it explicitly. **[easy]**
---
## Module improvements
### compress
- [ ] **`taz` progress bar** — show a `pv` / `dd`-based progress indicator when
compressing large trees, gated behind a `-p` flag. **[medium]**
- [ ] **`utaz` integrity check** — run `tar -tOf` / `unzip -t` / `7z t` before
extracting and abort if the archive is corrupt. **[easy]**
### filefct
- [x] **`findbig` / `findzero` / `finddead` — `fd` integration** — optionally
use `fd` instead of `find` when available for faster traversal. **[easy]**
- [x] **`file_stats` — human-readable totals** — add `--human` flag to emit
sizes in K/M/G instead of bytes. **[easy]**
### info
- [X] **`showinfo` fallback** — when neither `neofetch` nor `fastfetch` is
installed, print a minimal sysinfo block (hostname, OS, kernel, uptime,
CPU, RAM) using pure Bash + `/proc`. **[medium]**
### net
- [X] **`dwl` resume support** — pass `-C -` to curl / `--continue-at -` to
wget for interrupted downloads; gate behind a `-r` flag. **[easy]**
- [ ] **`myextip` multiple providers** — fall back to a secondary URL
(configurable via `MYEXTIP_FALLBACK_URL`) when the primary times out.
**[easy]**
### processes
- [X] **`ku` dry-run flag** — add `-n` / `--dry-run` to print what would be
killed without acting. **[easy]**
### pwd
- [ ] **`genpwd` passphrase mode** — add `-w` / `--words N` to generate
word-based passphrases (diceware-style) from `/usr/share/dict/words`.
**[medium]**
### ssh
- [ ] **SSH agent management** — add `ssh_agent_start` / `ssh_agent_stop` helpers
that start a persistent `ssh-agent`, add configured keys, and survive
re-login via a socket stored in `~/.ssh/agent.env`. **[medium]**
- [x] **`rmhost` glob support** — allow `rmhost '*.example.com'` to remove all
matching entries in one call. **[easy]**
### updates
- [ ] **Automatic update check age** — store a timestamp in `~/.cache/profile_last_check`;
skip the network request in `check_updates -q` if the last check was less
than `UPDT_CHECK_INTERVAL` hours ago (configurable, default 24). **[medium]**
- [ ] **Changelog display** — after a successful `profile_upgrade`, fetch and
display `CHANGELOG.md` entries newer than the previously installed version.
**[medium]**
---
## Structure
- [ ] **Helpers must not stay in the environment (do first)** — internal
functions (`_` prefix, `helpers/`) are not part of the user interface, yet 16
of them are `export -f`, so they leak into the environment of every child
process. By design they should only exist where they are needed:
- stop exporting helpers by default; unset the ones only needed at load time
(as `profile.sh` already does for `parse_conf`, `load_alias`, ...);
- a helper stays exported only when an exported public function calls it and
must work in a child bash (`bash -c`, `find -exec`, `xargs`), which has to
be checked and documented one by one (otherwise that public function is no
longer exported either, or waits for the stub mechanism below);
- add a check (shellcheck-like script or `bats` test) listing exported
functions starting with `_`, so none comes back unnoticed.
This is the first step: it does not depend on the lazy loading below, which
builds on it. **[medium]**
- [ ] **Load code on demand (stubs, lazy loading, optional unloading)** —
today every module is sourced at startup (about 63 ms, 109 functions) and 80
functions are exported (about 250 KB of environment inherited by every
external command, which makes each one about 25 % slower and eats `ARG_MAX`).
Replace this by:
- *Stubs*: each lazy command is a tiny generated function
(`rain() { _lazy rain "$@"; }`), the only thing exported. The stubs come
from a command-to-module index, built at upgrade time from a
`# provides: ...` header in each module (so `help`, `type` and completion
still see every command).
- *Lazy loading* (`_try_load`): the first call sources the module and its
`helpers/<module>.sh` (and the modules it depends on, declared in the
header), then runs the real function (`_exec`). The code stays loaded
afterwards. Helpers and implementations are no longer exported, which also
removes them from the environment of child shells.
- *Optional unloading* (`_free`, e.g. `PROFILE_UNLOAD=1`): after the call,
put the stub back instead of unsetting the function. Must be idempotent
(Ctrl-C or `return` skip the cleanup), must not free code still referenced
by a trap (`_rain_stop`, WINCH handler) or used by a running caller
(reference count), and costs about 4 ms per call, so it is not the default.
- *Always resident*: `disp`, `conf`, `debug`, `prompt` (and the `DEBUG` timer
hook), `lang` shortcuts and `help`. With unloading, state kept across calls
(`pwd` pool, current theme, `settrace`) must live in variables that are not
freed. Lazy candidates: `compress`,
`filefct`, `fun`, `git`, `info`, `net`, `packages`, `processes`, `pwd`,
`rain`, `ssh`, `updates`.
- *To solve*: `load_conf`/`CONF_*` must stay available at call time; child
shells need `MYPATH` and the loader exported to resolve stubs; tracebacks
show the loader frames. Do it after the test suite exists, as regressions
would be silent. **[hard]**
---
## Infrastructure
- [ ] **Test suite** — add a `test/` directory with `bats` (Bash Automated
Testing System) unit tests for pure functions (`expandlist`, `genpwd`,
`pwdscore`, `isipv4`, `isipv6`, `parse_conf`, `load_theme`, …). Target for
CI. **[hard]**
- [ ] **CI pipeline** — Gitea Actions (or similar) job that runs `shellcheck`
and the `bats` suite on every push. **[medium]**
- [ ] **`profile_status` function** — print a diagnostic summary: installed
version, active theme, loaded modules, detected Bash version, interactive /
login shell flags, and `profile.conf` path. **[easy]**
- [ ] **`profile_uninstall` function** — remove the `source` line from
`~/.bashrc` / `~/.profile` and optionally delete the install directory,
with a dry-run mode. **[medium]**
- [ ] **`disp` syslog integration** — add a `DISP_SYSLOG=<context>` config key that
additionally pipes E/W messages to `logger`. **[easy]**
- [ ] **XDG base-dir support** — honour `$XDG_CONFIG_HOME` as an alternative
location for `profile.conf` so users can keep `~` tidy. **[medium]**
**[breaking]**