28 Commits

Author SHA1 Message Date
fatalerrors
1225230a07 4.0 released 2026-04-22 17:56:08 +02:00
fatalerrors
9c43190202 bugfix: removed last french words and frenglish 2026-04-22 17:54:42 +02:00
fatalerrors
9477638a28 bugfix: no error on missing configuration, just use default 2026-04-22 17:16:33 +02:00
fatalerrors
f16ad711fb color adjustments 2026-04-21 16:51:57 +02:00
fatalerrors
15ef317029 themes adjustments 2026-04-21 16:07:16 +02:00
fatalerrors
a6e4d7a256 get ready for release 2026-04-21 15:24:04 +02:00
fatalerrors
6106ca7684 proper package manager detection 2026-04-21 14:18:37 +02:00
fatalerrors
1088029ae6 fix extra shift 2026-04-21 14:03:57 +02:00
fatalerrors
eb4c89759b fix display in kt 2026-04-21 14:03:22 +02:00
fatalerrors
1dc5d72ac6 fix display of return code in prompt 2026-04-21 14:02:45 +02:00
fatalerrors
d49703c5d5 fix themes right 2026-04-18 00:19:07 +02:00
fatalerrors
066f2e353e fix all spellsheck 2026-04-16 17:53:46 +02:00
fatalerrors
c011f03aee add missing help 2026-04-15 17:47:15 +02:00
fatalerrors
c4b0516c45 fix hardcoded setfr in main file 2026-04-15 17:36:15 +02:00
fatalerrors
4da29872fc refining themes 2026-04-15 17:00:04 +02:00
fatalerrors
d7a0e2c5f5 refining themes 2026-04-15 16:53:33 +02:00
fatalerrors
d60a93814b typo 2026-04-15 16:34:54 +02:00
fatalerrors
d27935eedd bugfix 2026-04-15 16:33:45 +02:00
fatalerrors
e77232b3ca bugfix 2026-04-15 16:29:04 +02:00
fatalerrors
d6dce2d91e bugfix 2026-04-15 16:08:34 +02:00
fatalerrors
4e3cccff64 bugfix 2026-04-15 16:03:10 +02:00
fatalerrors
91f033743d bugfix 2026-04-15 15:54:58 +02:00
fatalerrors
9fcf21c55e bugfix 2026-04-15 15:45:55 +02:00
fatalerrors
5300386941 bugfix 2026-04-15 15:39:45 +02:00
fatalerrors
dfad345be3 reset color definitions before loading a new theme 2026-04-15 15:16:11 +02:00
fatalerrors
1b16878ea8 allow dynamic theme change 2026-04-15 15:03:43 +02:00
fatalerrors
30b8b8241a bugfix 2026-04-15 14:54:49 +02:00
fatalerrors
a4056b9e82 fix line ending 2026-04-15 14:53:55 +02:00
35 changed files with 1914 additions and 1562 deletions

View File

@@ -1,4 +1,4 @@
Copyright 2013-2022 Geoffray Levasseur <fatalerrors@geoffray-levasseur.org> Copyright 2013-2026 Geoffray Levasseur <fatalerrors@geoffray-levasseur.org>
This is distributed with BSD-3-Clause license with the following terms and This is distributed with BSD-3-Clause license with the following terms and
condition: condition:

View File

@@ -68,7 +68,8 @@ A bar-style prompt showing current time, execution time of the last command
| `mcd` | filefct | Create a directory and immediately move into it | | `mcd` | filefct | Create a directory and immediately move into it |
| `meteo` | info | Display weather forecast for the configured or given city | | `meteo` | info | Display weather forecast for the configured or given city |
| `myextip` | net | Get information about your public IP address | | `myextip` | net | Get information about your public IP address |
| `pkgs` | packages | Search for a pattern in installed package names (dpkg/rpm, supports `-i`) | | `get_pkgmgr` | packages | Detect the active package manager of the running distribution (`apt`, `dnf`, `yum`, `zypper`, `pacman`, `apk`, `portage`, `xbps`, `nix`) |
| `pkgs` | packages | Search for a pattern in installed package names (distro-aware via `get_pkgmgr`, supports `-i`) |
| `ppg` | processes | Look for the given pattern in running processes | | `ppg` | processes | Look for the given pattern in running processes |
| `ppn` | processes | List processes matching an exact command name | | `ppn` | processes | List processes matching an exact command name |
| `ppu` | processes | List processes owned by a specific user | | `ppu` | processes | List processes owned by a specific user |
@@ -204,7 +205,7 @@ change the default without having to pass flags every time.
### 4.3. Locale shortcuts ### 4.3. Locale shortcuts
The `[general]` key `SET_LOCALE` accepts a comma-separated list of The `[lang]` key `SET_LOCALE` accepts a comma-separated list of
`alias:locale` pairs. Each pair generates a function of that name at startup: `alias:locale` pairs. Each pair generates a function of that name at startup:
```ini ```ini
@@ -214,6 +215,16 @@ SET_LOCALE = fr:fr_FR.UTF-8, us:en_US.UTF-8
This creates `setfr` and `setus`. Use `setlocale <locale>` to switch to any This creates `setfr` and `setus`. Use `setlocale <locale>` to switch to any
installed locale directly. installed locale directly.
Set `DEFAULT_LANG` to one of the defined aliases to activate that locale
automatically at login:
```ini
DEFAULT_LANG = fr
```
If `DEFAULT_LANG` is set but does not match any alias in `SET_LOCALE`, a
warning is displayed and no locale change is applied.
### 4.4. Prompt theming ### 4.4. Prompt theming
The prompt appearance is controlled by two mechanisms that are applied in order The prompt appearance is controlled by two mechanisms that are applied in order

View File

@@ -1,71 +1,97 @@
# Changelog # Changelog
All notable changes to this project will be documented in this file. All notable changes to this project will be documented in this file.
The format follows [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). The format follows [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
Versions follow `MAJOR.MINOR.PATCH-REVISION_STAGE_N` (e.g. `3.99.1-4_rc_1`). Versions follow `MAJOR.MINOR.PATCH-REVISION_STAGE_N` (e.g. `3.99.1-4_rc_1`).
--- ---
## [3.99.1-4_rc_1] — 2026 ## [3.99.2-4_rc_2] — 2026-04-21
### Added ### Fixed
- **Theming system** — `load_theme` in `profile.d/prompt.sh` loads `.theme` - **`prompt.sh`** — `\$Last_Command` in PS1 was escaped, preventing the exit
files from `profile.d/themes/` (or a custom directory set via code from ever appearing in the prompt (the local variable no longer exists
`PROMPT_THEME_DIR`). Theme files are **parsed, not executed** — no shell code when PS1 is rendered by bash). Removed the backslash so the value is embedded
ever runs from a theme. at `set_prompt` build time.
- **Built-in themes** — `default`, `dark`, `light`, `solarized` (24-bit - **`filefct.sh``file_stats()`** — a stray unconditional `shift` after
true-colour), `solarized-light` (24-bit), `monokai`, `monochrome`, `abyss`, `esac` doubled-shifted arguments already shifted by each `case` branch;
`plasma`, `adwaita`. successive options such as `-H -d` were silently skipped.
- **`[prompt]` section** — `PROMPT_THEME` and `PROMPT_THEME_DIR` keys to select - **`packages.sh``pkgs()`** — replaced the unreliable binary-presence test
a theme; eleven `PROMPT_COLOR_*` keys for per-key overrides in `profile.conf`. (`command -v dpkg / rpm`) with the new `get_pkgmgr` function. Also corrected
- **Standard colour variables as theme keys** — theme files may also override a typo in the "no package manager" error message (`avialable``available`).
the `disp.sh` colour variables (`Black`, `Blue`, `On_IBlack`, …) to remap the - **`processes.sh``kt()`** — copy-paste error: usage error message read
terminal palette used by `ls`, `grep`, and colour-aware tools. `"Usage: ppg <string>"` instead of `"Usage: kt <pid>"`.
- **Module configuration defaults** — all modules now expose their hardcoded
defaults as `profile.conf` keys: `TAZ_*`, `UTAZ_*`, `EXPANDLIST_*`, ### Added
`CLEAN_*`, `RMSPC_*`, `FINDBIG_*`, `RAIN_*`, `MATRIX_*`, `SSH_DEFAULT_OPT`, - **`packages.sh``get_pkgmgr()`** — new exported helper that detects the
`GENPWD_*`, `PWDSCORE_*`, `BUSY_*`, `METEO_DEFAULT_CITY`, `DWL_*`, active package manager of the running distribution. Detection first reads
`MYEXTIP_*`, `PKGS_*`, `PPU_*`, `KU_*`, `UPDT_DEFAULT_BRANCH`. `/etc/os-release` (`ID` then `ID_LIKE`), then falls back to a
- **`UPDT_DEFAULT_BRANCH`** — configures the git branch used by `check_updates` fixed-priority binary scan. Supported families: `apt`, `dnf`, `yum`,
and `profile_upgrade`. Changing the key causes `profile_upgrade` to `zypper`, `pacman`, `apk`, `portage`, `xbps`, `nix`. Returns 1 when
automatically switch the local checkout to the new branch and display a nothing is identified. Available to all future commands in `packages.sh`.
warning.
- **`doc/` directory** — `CONTRIBUTING.md`, `FAQ.md`, `profile.conf.example` ---
(annotated template), `todo.md`.
- **`.gitignore`** — `profile.conf` is now git-ignored so personal settings are ## [3.99.1-4_rc_1] — 2026
never accidentally staged.
### Added
### Changed - **Theming system** — `load_theme` in `profile.d/prompt.sh` loads `.theme`
- README §2 now explains how to create `profile.conf` from files from `profile.d/themes/` (or a custom directory set via
`doc/profile.conf.example` (new section 2.1 "Initial configuration"). `PROMPT_THEME_DIR`). Theme files are **parsed, not executed** — no shell code
- README §4 updated with full module-defaults tables, theming reference, and a ever runs from a theme.
note about `profile.conf` being git-ignored. - **Built-in themes** — `default`, `dark`, `light`, `solarized` (24-bit
- Theme values no longer carry the `export` keyword (they are not shell true-colour), `solarized-light` (24-bit), `monokai`, `monochrome`, `abyss`,
variables, only data). `plasma`, `adwaita`.
- **`[prompt]` section** — `PROMPT_THEME` and `PROMPT_THEME_DIR` keys to select
### Security a theme; eleven `PROMPT_COLOR_*` keys for per-key overrides in `profile.conf`.
- `load_theme` uses a strict allowlist (no `eval`, no sourcing). Only - **Standard colour variables as theme keys** — theme files may also override
`PROMPT_COLOR_*` keys and known `disp.sh` colour variable names are accepted. the `disp.sh` colour variables (`Black`, `Blue`, `On_IBlack`, …) to remap the
Values must match `\$[A-Za-z_][A-Za-z0-9_]*` or `\\e\[[0-9;]*m`; any other terminal palette used by `ls`, `grep`, and colour-aware tools.
value is discarded with a warning. - **Module configuration defaults** — all modules now expose their hardcoded
defaults as `profile.conf` keys: `TAZ_*`, `UTAZ_*`, `EXPANDLIST_*`,
--- `CLEAN_*`, `RMSPC_*`, `FINDBIG_*`, `RAIN_*`, `MATRIX_*`, `SSH_DEFAULT_OPT`,
`GENPWD_*`, `PWDSCORE_*`, `BUSY_*`, `METEO_DEFAULT_CITY`, `DWL_*`,
--- `MYEXTIP_*`, `PKGS_*`, `PPU_*`, `KU_*`, `UPDT_DEFAULT_BRANCH`.
- **`UPDT_DEFAULT_BRANCH`** — configures the git branch used by `check_updates`
> **Note:** Versions prior to `3.95.x-4_beta` did not maintain a formal and `profile_upgrade`. Changing the key causes `profile_upgrade` to
> changelog. The full history of earlier changes is available through the git automatically switch the local checkout to the new branch and display a
> log (`git log --oneline`). warning.
- **`doc/` directory** — `CONTRIBUTING.md`, `FAQ.md`, `profile.conf.example`
## [3.95.3-4_beta_3] — 2024 (annotated template), `todo.md`.
- **`.gitignore`** — `profile.conf` is now git-ignored so personal settings are
### Added never accidentally staged.
- Initial public release candidate series.
- Core modules: `compress`, `disp`, `filefct`, `fun`, `help`, `info`, `lang`, ### Changed
`net`, `packages`, `processes`, `prompt`, `pwd`, `rain`, `ssh`, `updates`. - README §2 now explains how to create `profile.conf` from
- Bar-style prompt with time, command duration, and exit code. `doc/profile.conf.example` (new section 2.1 "Initial configuration").
- `taz` / `utaz` archive helpers. - README §4 updated with full module-defaults tables, theming reference, and a
- `genpwd` / `pwdscore` password tools. note about `profile.conf` being git-ignored.
- `matrix` / `rain` screensavers. - Theme values no longer carry the `export` keyword (they are not shell
- `profile_upgrade` with git and archive download support. variables, only data).
### Security
- `load_theme` uses a strict allowlist (no `eval`, no sourcing). Only
`PROMPT_COLOR_*` keys and known `disp.sh` colour variable names are accepted.
Values must match `\$[A-Za-z_][A-Za-z0-9_]*` or `\\e\[[0-9;]*m`; any other
value is discarded with a warning.
---
---
> **Note:** Versions prior to `3.95.x-4_beta` did not maintain a formal
> changelog. The full history of earlier changes is available through the git
> log (`git log --oneline`).
## [3.95.3-4_beta_3] — 2024
### Added
- Initial public release candidate series.
- Core modules: `compress`, `disp`, `filefct`, `fun`, `help`, `info`, `lang`,
`net`, `packages`, `processes`, `prompt`, `pwd`, `rain`, `ssh`, `updates`.
- Bar-style prompt with time, command duration, and exit code.
- `taz` / `utaz` archive helpers.
- `genpwd` / `pwdscore` password tools.
- `matrix` / `rain` screensavers.
- `profile_upgrade` with git and archive download support.

View File

@@ -1,171 +1,210 @@
# Contributing to profile # Contributing to profile
Thank you for your interest in contributing. This document explains how to get Thank you for your interest in contributing. This document explains how to get
set up, what the conventions are, and how to submit work. set up, what the conventions are, and how to submit work.
--- ---
## 1. Before you start ## 1. Before you start
- Check the [to-do list](./todo.md) to see if your idea is already planned. - Check the [to-do list](./todo.md) to see if your idea is already planned.
- Check the [issue tracker](https://git.geoffray-levasseur.org/fatalerrors/profile/issues) - Check the [issue tracker](https://git.geoffray-levasseur.org/fatalerrors/profile/issues)
to avoid duplicate work. to avoid duplicate work.
- For significant changes, open an issue or contact the maintainer before - For significant changes, open an issue or contact the maintainer before
writing code — alignment on design saves everyone time. writing code — alignment on design saves everyone time.
--- ---
## 2. Getting the source ## 2. Getting the source
A Git clone is mandatory for contributions: A Git clone is mandatory for contributions:
```bash ```bash
git clone https://git.geoffray-levasseur.org/fatalerrors/profile.git git clone https://git.geoffray-levasseur.org/fatalerrors/profile.git
cd profile cd profile
``` ```
Always work from the **latest commit on `master`** (or the branch you intend Always work from the **latest commit on `master`** (or the branch you intend
to target). Stale forks cause avoidable merge conflicts. to target). Stale forks cause avoidable merge conflicts.
--- ---
## 3. Development environment ## 3. Branch policy
| Requirement | Minimum version | Notes | | Branch | Purpose |
|---|---|---| |---|---|
| Bash | 4.3 | Namerefs (`local -n`) required | | `master` | Main development branch — new features and enhancements go here |
| shellcheck | any recent | Run before every commit | | `<version>` (e.g. `3.x`) | Maintenance branch for a released version — bugfixes backported from `master` |
| git | any | For contributing patches |
| bats-core | 1.x | Optional — for running the test suite | **New functionality** must always target `master`.
Install shellcheck: **Bugfixes** must target the branch where the bug was introduced:
```bash - If the bug exists in a released version, open the fix against that version's
# Debian / Ubuntu maintenance branch first, then cherry-pick onto `master`.
apt-get install shellcheck - If the bug is only in `master` (unreleased), fix it directly on `master`.
- During a release-candidate cycle, bugfixes go on the `x.*` branch and are
# Fedora / RHEL merged back into `master` before the final release.
dnf install ShellCheck
Do **not** add new features to a maintenance branch.
# macOS
brew install shellcheck ---
```
## 4. Versioning scheme
---
Versions follow the format **`MAJOR.MINOR.PATCH`** where the `MINOR` number
## 4. Code style conveys the development stage of the next major release:
### General rules | Minor range | Stage | Rules |
- **Bash only** — no external interpreters in core modules. Python or Perl is |---|---|---|
acceptable for completely self-contained, optional utilities that have no | `x.90.y` | **Alpha** toward `x+1` | Stays on `master`. Development is open: new features are welcome, regressions are acceptable. |
dependencies beyond a minimal Debian or CentOS installation. | `x.95.y` | **Beta** toward `x+1` | The `x+1.*` maintenance branch is created at this point. No regression unless absolutely necessary; new features still allowed. |
- **4-space indentation** — no tabs. | `x.99.y` | **RC** toward `x+1` | Bugfixes only. No new features. No regression allowed. Becomes `x+1.0.0` when stable. |
- **`[[ … ]]`** for all conditionals — not `[ … ]`.
- **`(( … ))`** for arithmetic — not `$(( … ))` in conditionals. Examples: `3.90.1` is the first alpha toward `4.0`, `3.99.2` is the second
- **`local`** for all function-internal variables — avoid polluting the release candidate for `4.0`.
environment.
- **`printf`** instead of `echo` wherever the format matters. The `PATCH` number increments freely within a stage. A bump in `MINOR`
- **Never `eval`** — use namerefs (`local -n`), `${!varname}` indirection, or (e.g. `90``95`) always indicates a stage promotion in development phase.
`declare -g` instead.
- **No hardcoded defaults** — wire every configurable value through Any experimental version must have it's dedicated branch.
`${VAR:-default}` and document the key in `profile.conf` and `README.md §4`.
---
### Function conventions
- Public functions **must** be exported: `export -f funcname`. ## 5. Development environment
- Every public function **must** support `-h` / `--help` and print usage to |---|---|---|
stdout, returning 0. | Bash | 4.3 | Namerefs (`local -n`) required |
- Use `getopt` (not `getopts`) for option parsing — it handles long options and | shellcheck | any recent | Run before every commit |
`--` correctly. | git | any | For contributing patches |
- Follow existing error-return conventions: 0 = success, 1 = usage error, | bats-core | 1.x | Optional — for running the test suite |
2 = bad options, 3 = missing dependency, 4+ = runtime failure.
- Prefix all local helper variables with a short unique prefix (e.g. `_taz_`) Install shellcheck:
to prevent collisions with caller-scope variables. ```bash
# Debian / Ubuntu
### Module structure apt-get install shellcheck
Every new module should follow this pattern:
# Fedora / RHEL
```bash dnf install ShellCheck
#!/usr/bin/env bash
# <copyright block identical to existing modules> # macOS
brew install shellcheck
load_conf "<module_name>" ```
# --- functions --- ---
export -f my_function ## 6. Code style
# EOF ### General rules
``` - **Bash only** — no external interpreters in core modules. Python or Perl is
acceptable for completely self-contained, optional utilities that have no
Add the `load_conf` call near the top after any variable declarations. dependencies beyond a minimal Debian or CentOS installation.
- **4-space indentation** — no tabs.
--- - **`[[ … ]]`** for all conditionals — not `[ … ]`.
- **`(( … ))`** for arithmetic — not `$(( … ))` in conditionals.
## 5. Configuration keys - **`local`** for all function-internal variables — avoid polluting the
environment. Prefer upper case for global and lowercase for local.
When adding a configurable default: - **`printf`** instead of `echo` all the time.
- **Never `eval`** — use namerefs (`local -n`), `${!varname}` indirection, or
1. Use `${MY_VAR:-hardcoded_default}` in the function body. `declare -g` instead.
2. Add a commented-out entry with a description to `profile.conf`. - **No hardcoded defaults** — wire every configurable value through
3. Document the key in the matching table in `README.md §4.2`. `${VAR:-default}` and document the key in `profile.conf` and `README.md §4`.
--- ### Function conventions
- Public functions **must** be exported: `export -f funcname`.
## 6. Theming - Every public function **must** support `-h` / `--help` and print usage to
stdout, returning 0.
New theme files go in `profile.d/themes/` with a `.theme` extension. - Use `getopt` (not `getopts`) for option parsing — it handles long options and
They are **parsed, not executed** — do not add shell logic. `--` correctly.
See the existing themes and `README.md §4.4` for the allowed syntax. - Follow existing error-return conventions: 0 = success, 1 = usage error,
2 = bad options, 3 = missing dependency, 4+ = runtime failure.
--- - Prefix all local helper variables with a short unique prefix (e.g. `_taz_`)
to prevent collisions with caller-scope variables.
## 7. Running shellcheck
### Module structure
```bash Every new module should follow this pattern:
shellcheck -x profile.sh profile.d/*.sh
``` ```bash
#!/usr/bin/env bash
All warnings must be resolved before a patch will be accepted. Accepted # <copyright block identical to existing modules>
suppression directives (`# shellcheck disable=SCxxxx`) require an inline
comment explaining why the suppression is necessary. load_conf "<module_name>"
--- # --- functions ---
## 8. Submitting a contribution export -f my_function
### Via Git (preferred) # EOF
1. Contact the maintainer to obtain push access, or fork on the Gitea instance. ```
2. Create a branch: `git checkout -b feature/my-feature`.
3. Commit with a clear subject line: `module: short description (≤ 72 chars)`. Add the `load_conf` call near the top after any variable declarations.
4. Push and open a pull request against `master`.
---
### Via patch
If you do not have push access: ## 7. Configuration keys
```bash
git format-patch origin/master When adding a configurable default:
```
Send the resulting `.patch` file(s) to 1. Use `${MY_VAR:-hardcoded_default}` in the function body.
`fatalerrors <at> geoffray-levasseur <dot> org`. 2. Add a commented-out entry with a description to `profile.conf`.
3. Document the key in the matching table in `README.md §4.2`.
### Commit message format
``` ---
module: imperative short description
## 8. Theming
Optional longer explanation of what changed and why. Wrap at 72 characters.
Reference issue numbers if applicable: closes #42. New theme files go in `profile.d/themes/` with a `.theme` extension.
``` They are **parsed, not executed** — do not add shell logic.
See the existing themes and `README.md §4.4` for the allowed syntax.
---
---
## 9. What will be rejected
## 9. Running shellcheck
- Code requiring packages not in a minimal Debian or CentOS install.
- Use of `eval`, `source`-based config loading, or other code-injection vectors. ```bash
- Changes that break Bash 4.3 compatibility. shellcheck -x profile.sh profile.d/*.sh
- Patches without a passing `shellcheck` run. ```
- New functions without `--help` support.
All warnings must be resolved before a patch will be accepted. Accepted
--- suppression directives (`# shellcheck disable=SCxxxx`) require an inline
comment explaining why the suppression is necessary.
## 10. Financial contributions
---
Contact the maintainer by mail if you wish to make a financial contribution.
## 10. Submitting a contribution
### Via Git (preferred)
1. Contact the maintainer to obtain push access, or fork on the Gitea instance.
2. Create a branch: `git checkout -b feature/my-feature`.
3. Commit with a clear subject line: `module: short description (≤ 72 chars)`.
4. Push and open a pull request against `master`.
### Via patch
If you do not have push access:
```bash
git format-patch origin/master
```
Send the resulting `.patch` file(s) to
`fatalerrors <at> geoffray-levasseur <dot> org`.
### Commit message format
```
module: imperative short description
Optional longer explanation of what changed and why. Wrap at 72 characters.
Reference issue numbers if applicable: closes #42.
```
---
## 11. What will be rejected
- Code requiring packages not in a minimal Debian or CentOS install.
- Use of `eval`, `source`-based config loading, or other code-injection vectors.
- Changes that break Bash 4.3 compatibility.
- Patches without a passing `shellcheck` run.
- New functions without `--help` support.
---
## 12. Financial contributions
Contact the maintainer by mail if you wish to make a financial contribution.

View File

@@ -1,208 +1,208 @@
# Frequently Asked Questions # Frequently Asked Questions
--- ---
## Installation & loading ## Installation & loading
**Q: profile refuses to load and prints "This profile requires Bash 4.3 or higher."** **Q: profile refuses to load and prints "This profile requires Bash 4.3 or higher."**
Your system's default shell is an older Bash (common on macOS, which ships Your system's default shell is an older Bash (common on macOS, which ships
Bash 3.x for licensing reasons). Install a newer Bash: Bash 3.x for licensing reasons). Install a newer Bash:
```bash ```bash
# macOS # macOS
brew install bash brew install bash
# then add /opt/homebrew/bin/bash to /etc/shells and chsh # then add /opt/homebrew/bin/bash to /etc/shells and chsh
``` ```
Or point your terminal emulator at the newer binary explicitly. Or point your terminal emulator at the newer binary explicitly.
--- ---
**Q: I sourced `profile.sh` but functions are not available in sub-shells or scripts.** **Q: I sourced `profile.sh` but functions are not available in sub-shells or scripts.**
All public functions are exported with `export -f`. They are available in All public functions are exported with `export -f`. They are available in
child Bash processes, but **not** in POSIX `sh` sub-shells. Make sure your child Bash processes, but **not** in POSIX `sh` sub-shells. Make sure your
scripts start with `#!/usr/bin/env bash`. scripts start with `#!/usr/bin/env bash`.
--- ---
**Q: I set `PROFILE_PATH` but profile still can't find its modules.** **Q: I set `PROFILE_PATH` but profile still can't find its modules.**
`PROFILE_PATH` must be exported *before* you source `profile.sh`: `PROFILE_PATH` must be exported *before* you source `profile.sh`:
```bash ```bash
export PROFILE_PATH=/opt/profile export PROFILE_PATH=/opt/profile
source /opt/profile/profile.sh source /opt/profile/profile.sh
``` ```
If set after sourcing, `MYPATH` is already locked in and the variable has If set after sourcing, `MYPATH` is already locked in and the variable has
no effect. no effect.
--- ---
**Q: Can I load profile system-wide via `/etc/profile`?** **Q: Can I load profile system-wide via `/etc/profile`?**
It is not recommended. User `.bashrc` files frequently set variables that It is not recommended. User `.bashrc` files frequently set variables that
conflict with the aliases and locale functions defined here, leading to conflict with the aliases and locale functions defined here, leading to
surprising behaviour. Per-user sourcing from `~/.bashrc` is the supported surprising behaviour. Per-user sourcing from `~/.bashrc` is the supported
method. method.
--- ---
## Configuration ## Configuration
**Q: I edited `profile.conf` but my changes have no effect.** **Q: I edited `profile.conf` but my changes have no effect.**
`profile.conf` is parsed once per shell session at load time. Open a new `profile.conf` is parsed once per shell session at load time. Open a new
terminal (or `exec bash`) to pick up the changes. There is no live-reload. terminal (or `exec bash`) to pick up the changes. There is no live-reload.
--- ---
**Q: How do I find out which configuration keys a module supports?** **Q: How do I find out which configuration keys a module supports?**
Every supported key is documented with a comment in `profile.conf`. Every supported key is documented with a comment in `profile.conf`.
See also `README.md §4.2` for a consolidated table. See also `README.md §4.2` for a consolidated table.
--- ---
**Q: A key I set in `profile.conf` is being ignored.** **Q: A key I set in `profile.conf` is being ignored.**
Check that: Check that:
1. The key is inside the correct `[section]` header. 1. The key is inside the correct `[section]` header.
2. There is no leading space before the section name (`[section]` not 2. There is no leading space before the section name (`[section]` not
`[ section ]`). `[ section ]`).
3. The key is not commented out (no leading `#`). 3. The key is not commented out (no leading `#`).
4. The value contains no backticks or `$(…)` — these are stripped by the 4. The value contains no backticks or `$(…)` — these are stripped by the
parser as a security measure. parser as a security measure.
--- ---
## Prompt & theming ## Prompt & theming
**Q: How do I change the prompt theme?** **Q: How do I change the prompt theme?**
Add to `profile.conf`: Add to `profile.conf`:
```ini ```ini
[prompt] [prompt]
PROMPT_THEME = dark PROMPT_THEME = dark
``` ```
Built-in names: `default`, `dark`, `light`, `solarized`, `solarized-light`, Built-in names: `default`, `dark`, `light`, `solarized`, `solarized-light`,
`monokai`, `monochrome`, `abyss`, `plasma`, `adwaita`. `monokai`, `monochrome`, `abyss`, `plasma`, `adwaita`.
--- ---
**Q: The solarized or solarized-light theme shows wrong colours.** **Q: The solarized or solarized-light theme shows wrong colours.**
Those themes use 24-bit / true-colour ANSI sequences (`\e[38;2;R;G;Bm`). Those themes use 24-bit / true-colour ANSI sequences (`\e[38;2;R;G;Bm`).
Test your terminal: Test your terminal:
```bash ```bash
printf '\e[38;2;38;139;210mTrue colour test\e[0m\n' printf '\e[38;2;38;139;210mTrue colour test\e[0m\n'
``` ```
If you see a solid blue word your terminal supports true colour. If you see a solid blue word your terminal supports true colour.
If you see garbage or plain text, switch to a 16-colour theme If you see garbage or plain text, switch to a 16-colour theme
(`dark`, `default`, etc.) or upgrade your terminal emulator. (`dark`, `default`, etc.) or upgrade your terminal emulator.
--- ---
**Q: I created a custom theme but `load_theme` emits "key not allowed" warnings.** **Q: I created a custom theme but `load_theme` emits "key not allowed" warnings.**
Theme files are parsed, not executed. Only `PROMPT_COLOR_*` keys and the Theme files are parsed, not executed. Only `PROMPT_COLOR_*` keys and the
standard colour variable names from `disp.sh` (`Black`, `Blue`, `On_IBlack`, standard colour variable names from `disp.sh` (`Black`, `Blue`, `On_IBlack`,
…) are accepted. Any other key — including custom variables — is rejected. …) are accepted. Any other key — including custom variables — is rejected.
See `README.md §4.4` for the full list of accepted keys and value forms. See `README.md §4.4` for the full list of accepted keys and value forms.
--- ---
**Q: Can a theme file contain shell logic or `$(…)` command substitutions?** **Q: Can a theme file contain shell logic or `$(…)` command substitutions?**
No, and intentionally so. Theme files are parsed line-by-line; shell No, and intentionally so. Theme files are parsed line-by-line; shell
constructs are never evaluated. This is a security boundary — a malicious constructs are never evaluated. This is a security boundary — a malicious
theme file cannot execute code. Values must be a colour variable reference theme file cannot execute code. Values must be a colour variable reference
(`$Blue`) or a raw ANSI escape literal (`\e[0;34m`). (`$Blue`) or a raw ANSI escape literal (`\e[0;34m`).
--- ---
## Functions ## Functions
**Q: `meteo` prints "No city specified" even though I set a default.** **Q: `meteo` prints "No city specified" even though I set a default.**
The key is `METEO_DEFAULT_CITY` (not `DEFAULT_CITY`), and it must be in the The key is `METEO_DEFAULT_CITY` (not `DEFAULT_CITY`), and it must be in the
`[info]` section: `[info]` section:
```ini ```ini
[info] [info]
METEO_DEFAULT_CITY = Paris METEO_DEFAULT_CITY = Paris
``` ```
--- ---
**Q: `dwl` fails with "no download tool found".** **Q: `dwl` fails with "no download tool found".**
`dwl` requires one of `curl`, `wget`, or `fetch` to be installed. `dwl` requires one of `curl`, `wget`, or `fetch` to be installed.
Install curl: Install curl:
```bash ```bash
# Debian / Ubuntu # Debian / Ubuntu
apt-get install curl apt-get install curl
# Fedora / RHEL # Fedora / RHEL
dnf install curl dnf install curl
``` ```
Or set `DWL_PREFERRED_TOOL` in `[net]` to whichever tool you have. Or set `DWL_PREFERRED_TOOL` in `[net]` to whichever tool you have.
--- ---
**Q: `pkgs` does not find packages I know are installed.** **Q: `pkgs` does not find packages I know are installed.**
`pkgs` delegates to `dpkg -l` (Debian/Ubuntu) or `rpm -qa` (RHEL/Fedora). `pkgs` delegates to `dpkg -l` (Debian/Ubuntu) or `rpm -qa` (RHEL/Fedora).
If your distribution uses a different package manager (pacman, apk, brew …) If your distribution uses a different package manager (pacman, apk, brew …)
it is not yet supported. See `doc/todo.md` for the tracking issue. it is not yet supported. See `doc/todo.md` for the tracking issue.
--- ---
**Q: `profile_upgrade` says "no update available" but I know there is one.** **Q: `profile_upgrade` says "no update available" but I know there is one.**
`check_updates` compares the content of the remote `version` file against `check_updates` compares the content of the remote `version` file against
`$PROFVERSION`. If `UPDT_DEFAULT_BRANCH` in `[updates]` points to a different `$PROFVERSION`. If `UPDT_DEFAULT_BRANCH` in `[updates]` points to a different
branch than your installation, the version files may not match. Check: branch than your installation, the version files may not match. Check:
```bash ```bash
cat "$MYPATH/version" cat "$MYPATH/version"
``` ```
and make sure `UPDT_DEFAULT_BRANCH` matches the branch you track. and make sure `UPDT_DEFAULT_BRANCH` matches the branch you track.
--- ---
## Compatibility ## Compatibility
**Q: Some functions misbehave on macOS / Cygwin.** **Q: Some functions misbehave on macOS / Cygwin.**
Both environments ship non-GNU userland utilities with different flags and Both environments ship non-GNU userland utilities with different flags and
behaviour. profile is primarily developed and tested on Linux (Debian and behaviour. profile is primarily developed and tested on Linux (Debian and
RHEL families). macOS and Cygwin bugs are low priority; patches that add RHEL families). macOS and Cygwin bugs are low priority; patches that add
compatibility without breaking Linux support are welcome. compatibility without breaking Linux support are welcome.
--- ---
**Q: Can I use profile with ZSH?** **Q: Can I use profile with ZSH?**
Not officially. Blockers include `local -A` (ZSH requires `typeset -A`) and Not officially. Blockers include `local -A` (ZSH requires `typeset -A`) and
`local -n` namerefs. A compatibility layer is listed in `doc/todo.md` but `local -n` namerefs. A compatibility layer is listed in `doc/todo.md` but
has not been implemented yet. has not been implemented yet.
--- ---
## Miscellaneous ## Miscellaneous
**Q: How do I completely disable profile for one session?** **Q: How do I completely disable profile for one session?**
```bash ```bash
PROFILE_DISABLED=1 bash --norc PROFILE_DISABLED=1 bash --norc
``` ```
Or simply open a shell without sourcing `~/.bashrc` (`bash --norc`). Or simply open a shell without sourcing `~/.bashrc` (`bash --norc`).
--- ---
**Q: How do I report a bug?** **Q: How do I report a bug?**
Open an issue on the Open an issue on the
[Gitea tracker](https://git.geoffray-levasseur.org/fatalerrors/profile/issues) [Gitea tracker](https://git.geoffray-levasseur.org/fatalerrors/profile/issues)
or send a mail to `fatalerrors <at> geoffray-levasseur <dot> org` with: or send a mail to `fatalerrors <at> geoffray-levasseur <dot> org` with:
- The exact command that triggered the bug - The exact command that triggered the bug
- Your OS and Bash version (`bash --version`) - Your OS and Bash version (`bash --version`)
- The module involved - The module involved
- Any relevant error output - Any relevant error output

29
doc/LICENSE Executable file
View File

@@ -0,0 +1,29 @@
Copyright 2021-2026 Geoffray Levasseur <fatalerrors@geoffray-levasseur.org>
This software is distributed under the BSD-3-Clause license with the
following terms and conditions:
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its contributors
may be used to endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View File

@@ -1,247 +1,252 @@
# profile.conf — example / reference configuration # profile.conf — example / reference configuration
# Copy this file to the profile installation directory as "profile.conf" # Copy this file to the profile installation directory as "profile.conf"
# and uncomment / edit the keys you want to change. # and uncomment / edit the keys you want to change.
# #
# Format: # Format:
# [section_name] — starts a section # [section_name] — starts a section
# key = value — sets a key (whitespace around = is optional) # key = value — sets a key (whitespace around = is optional)
# # comment — line comment # # comment — line comment
# #
# All keys are optional. Sensible defaults apply when unset. # All keys are optional. Sensible defaults apply when unset.
# Values must not contain backticks or $(…) — those are stripped for security. # Values must not contain backticks or $(…) — those are stripped for security.
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
# ============================================================================== # ==============================================================================
[system] [system]
# Bash history settings # Bash history settings
HISTSIZE=50000 HISTSIZE=50000
HISTFILESIZE=100000 HISTFILESIZE=100000
HISTIGNORE="&:[bf]g:exit" HISTIGNORE="&:[bf]g:exit"
# Default pager # Default pager
PAGER=less PAGER=less
# Terminal colour capability # Terminal colour capability
TERM=xterm-256color TERM=xterm-256color
# ============================================================================== # ==============================================================================
[compress] [compress]
# taz: Default archive format (-f/--format). # taz: Default archive format (-f/--format).
# Supported: lz (default), xz, bz2, gz, lzo, tar, zip, zst # Supported: lz (default), xz, bz2, gz, lzo, tar, zip, zst
#TAZ_DEFAULT_FORMAT=lz #TAZ_DEFAULT_FORMAT=lz
# taz: Number of compression threads (0 = auto-detect CPU count). # taz: Number of compression threads (0 = auto-detect CPU count).
#TAZ_DEFAULT_THREADS=0 #TAZ_DEFAULT_THREADS=0
# taz: Compression level 1 (fast/large) … 9 (slow/small). # taz: Compression level 1 (fast/large) … 9 (slow/small).
#TAZ_DEFAULT_LEVEL=6 #TAZ_DEFAULT_LEVEL=6
# utaz: Delete source archive after successful extraction (0=no, 1=yes). # utaz: Delete source archive after successful extraction (0=no, 1=yes).
#UTAZ_DEFAULT_DELETE=0 #UTAZ_DEFAULT_DELETE=0
# utaz: Subdirectory creation policy. # utaz: Subdirectory creation policy.
# auto — create one only when the archive has multiple top-level entries # auto — create one only when the archive has multiple top-level entries
# always — always extract into a new subdirectory # always — always extract into a new subdirectory
# never — always flatten into the current directory # never — always flatten into the current directory
#UTAZ_DEFAULT_DIR_MODE=auto #UTAZ_DEFAULT_DIR_MODE=auto
# ============================================================================== # ==============================================================================
[debug] [debug]
# (no configurable keys yet) # (no configurable keys yet)
# ============================================================================== # ==============================================================================
[disp] [disp]
# Uncomment to disable ANSI colours in profile's own output messages. # Uncomment to disable ANSI colours in profile's own output messages.
#NO_COLOR=1 #NO_COLOR=1
# ============================================================================== # ==============================================================================
[filefct] [filefct]
# expandlist: Separator between items (default: space). Use \n for newline. # expandlist: Separator between items (default: space). Use \n for newline.
#EXPANDLIST_DEFAULT_SEPARATOR=" " #EXPANDLIST_DEFAULT_SEPARATOR=" "
# clean: Recurse into subdirectories by default (0=no, 1=yes). # clean: Recurse into subdirectories by default (0=no, 1=yes).
#CLEAN_DEFAULT_RECURSIVE=0 #CLEAN_DEFAULT_RECURSIVE=0
# rmspc: Replacement character for spaces in filenames (default: underscore). # rmspc: Replacement character for spaces in filenames (default: underscore).
#RMSPC_DEFAULT_CHAR=_ #RMSPC_DEFAULT_CHAR=_
# findbig: Number of results to display (default: 10). # findbig: Number of results to display (default: 10).
#FINDBIG_DEFAULT_LIMIT=10 #FINDBIG_DEFAULT_LIMIT=10
# ============================================================================== # ==============================================================================
[fun] [fun]
# busy: Hex pattern searched in /dev/urandom hexdump. # busy: Hex pattern searched in /dev/urandom hexdump.
#BUSY_DEFAULT_PATTERN=ca fe #BUSY_DEFAULT_PATTERN=ca fe
# busy: Delay between matched lines in milliseconds (0 = no delay). # busy: Delay between matched lines in milliseconds (0 = no delay).
#BUSY_DEFAULT_DELAY=0 #BUSY_DEFAULT_DELAY=0
# ============================================================================== # ==============================================================================
[info] [info]
# meteo: Default city when no argument is given. Leave unset to require an # meteo: Default city when no argument is given. Leave unset to require an
# explicit city argument every time. # explicit city argument every time.
#METEO_DEFAULT_CITY=Paris #METEO_DEFAULT_CITY=Paris
# ============================================================================== # ==============================================================================
[lang] [lang]
# Comma-separated alias:locale pairs. One function is generated per entry. # Comma-separated alias:locale pairs. One function is generated per entry.
# Example: SET_LOCALE="fr:fr_FR.UTF-8,us:en_US.UTF-8,es:es_ES.UTF-8" # Example: SET_LOCALE="fr:fr_FR.UTF-8,us:en_US.UTF-8,es:es_ES.UTF-8"
# creates setfr, setus, setes. # creates setfr, setus, setes.
#SET_LOCALE=fr:fr_FR.UTF-8,us:en_US.UTF-8 #SET_LOCALE=fr:fr_FR.UTF-8,us:en_US.UTF-8
# ============================================================================== # Alias to activate at login. Must match one of the aliases defined in SET_LOCALE above.
[net] # Example: DEFAULT_LANG=fr → calls setfr at startup.
# dwl: Force a specific download tool (curl, wget, fetch). # Leave unset to keep the system default locale.
# Unset = auto-detect (curl preferred, then wget, then fetch). #DEFAULT_LANG=fr
#DWL_PREFERRED_TOOL=curl
# ==============================================================================
# myextip: API endpoint for external IP lookup. [net]
# Alternatives: https://ipinfo.io/json, https://ip-api.com/json/ # dwl: Force a specific download tool (curl, wget, fetch).
#MYEXTIP_DEFAULT_URL=https://ip-api.com/json/ # Unset = auto-detect (curl preferred, then wget, then fetch).
#DWL_PREFERRED_TOOL=curl
# ==============================================================================
[packages] # myextip: API endpoint for external IP lookup.
# pkgs: Case-insensitive search by default (0=no, 1=yes). # Alternatives: https://ipinfo.io/json, https://ip-api.com/json/
#PKGS_DEFAULT_IGNORE_CASE=0 #MYEXTIP_DEFAULT_URL=https://ip-api.com/json/
# ============================================================================== # ==============================================================================
[processes] [packages]
# ppu: ps output columns (comma-separated ps field names). # pkgs: Case-insensitive search by default (0=no, 1=yes).
#PPU_DEFAULT_FORMAT=pid,user,%cpu,%mem,start,time,command #PKGS_DEFAULT_IGNORE_CASE=0
# ku: Signal sent when killing a user's processes (without SIG prefix). # ==============================================================================
#KU_DEFAULT_SIGNAL=TERM [processes]
# ppu: ps output columns (comma-separated ps field names).
# ============================================================================== #PPU_DEFAULT_FORMAT=pid,user,%cpu,%mem,start,time,command
[prompt]
# Name of the prompt theme to load, or an explicit path to a .theme file. # ku: Signal sent when killing a user's processes (without SIG prefix).
# Built-in themes: default, dark, light, solarized, solarized-light, #KU_DEFAULT_SIGNAL=TERM
# monokai, monochrome, abyss, plasma, adwaita
# Solarized variants require a terminal with 24-bit true-colour support. # ==============================================================================
#PROMPT_THEME=default [prompt]
# Name of the prompt theme to load, or an explicit path to a .theme file.
# Directory searched for bare theme names. Defaults to profile.d/themes/. # Built-in themes: default, dark, light, solarized, solarized-light,
#PROMPT_THEME_DIR=/path/to/my/themes # monokai, monochrome, abyss, plasma, adwaita
# Solarized variants require a terminal with 24-bit true-colour support.
# Individual colour overrides — these always win over the loaded theme. #PROMPT_THEME=default
# Values must be colour variable names from disp.sh (e.g. $Blue, $On_IBlack)
# or raw ANSI escape sequences (e.g. \e[0;34m). # Directory searched for bare theme names. Defaults to profile.d/themes/.
# #PROMPT_THEME_DIR=/path/to/my/themes
# Clock segment
#PROMPT_COLOR_TIME_FG=$Blue # Individual colour overrides — these always win over the loaded theme.
#PROMPT_COLOR_TIME_BG=$On_IBlack # Values must be colour variable names from disp.sh (e.g. $Blue, $On_IBlack)
# # or raw ANSI escape sequences (e.g. \e[0;34m).
# Main bar background #
#PROMPT_COLOR_BAR_BG=$On_Blue # Clock segment
# #PROMPT_COLOR_TIME_FG=$Blue
# Exit-code segment — success #PROMPT_COLOR_TIME_BG=$On_IBlack
#PROMPT_COLOR_OK_FG=$White #
#PROMPT_COLOR_OK_MARK=$Green # Main bar background
# #PROMPT_COLOR_BAR_BG=$On_Blue
# Exit-code segment — failure #
#PROMPT_COLOR_ERR_BG=$On_Red # Exit-code segment — success
#PROMPT_COLOR_ERR_FG=$White #PROMPT_COLOR_OK_FG=$White
#PROMPT_COLOR_ERR_MARK=$BYellow #PROMPT_COLOR_OK_MARK=$Green
# #
# User / host # Exit-code segment — failure
#PROMPT_COLOR_ROOT_FG=$Red #PROMPT_COLOR_ERR_BG=$On_Red
#PROMPT_COLOR_USER_FG=$Green #PROMPT_COLOR_ERR_FG=$White
# #PROMPT_COLOR_ERR_MARK=$BYellow
# Working directory #
#PROMPT_COLOR_DIR_FG=$ICyan # User / host
#PROMPT_COLOR_ROOT_FG=$Red
# ============================================================================== #PROMPT_COLOR_USER_FG=$Green
[pwd] #
# genpwd: Default password length. # Working directory
#GENPWD_DEFAULT_LENGTH=16 #PROMPT_COLOR_DIR_FG=$ICyan
# genpwd: Maximum occurrences of any single character. # ==============================================================================
#GENPWD_DEFAULT_OCCURS=2 [pwd]
# genpwd: Default password length.
# genpwd: Number of passwords generated per invocation. #GENPWD_DEFAULT_LENGTH=16
#GENPWD_DEFAULT_COUNT=1
# genpwd: Maximum occurrences of any single character.
# genpwd: Include symbols (1=yes, 0=no). #GENPWD_DEFAULT_OCCURS=2
#GENPWD_DEFAULT_SYMBOLS=1
# genpwd: Number of passwords generated per invocation.
# genpwd: Include uppercase letters (1=yes, 0=no). #GENPWD_DEFAULT_COUNT=1
#GENPWD_DEFAULT_UPPERCASE=1
# genpwd: Include symbols (1=yes, 0=no).
# genpwd: Include lowercase letters (1=yes, 0=no). #GENPWD_DEFAULT_SYMBOLS=1
#GENPWD_DEFAULT_LOWERCASE=1
# genpwd: Include uppercase letters (1=yes, 0=no).
# genpwd: Include digits (1=yes, 0=no). #GENPWD_DEFAULT_UPPERCASE=1
#GENPWD_DEFAULT_NUMBERS=1
# genpwd: Include lowercase letters (1=yes, 0=no).
# pwdscore: Show verbose breakdown by default (1=yes, 0=no). #GENPWD_DEFAULT_LOWERCASE=1
#PWDSCORE_DEFAULT_VERBOSE=0
# genpwd: Include digits (1=yes, 0=no).
# ============================================================================== #GENPWD_DEFAULT_NUMBERS=1
[rain]
# rain: Falling speed — integer/100 gives seconds (5 → 0.05 s). # pwdscore: Show verbose breakdown by default (1=yes, 0=no).
# Values < 1 are used as raw seconds. #PWDSCORE_DEFAULT_VERBOSE=0
#RAIN_DEFAULT_SPEED=5
# ==============================================================================
# rain: Colour theme. Supported: white (default), green, blue, red, yellow, cyan [rain]
#RAIN_DEFAULT_COLOR=white # rain: Falling speed — integer/100 gives seconds (5 → 0.05 s).
# Values < 1 are used as raw seconds.
# matrix: Falling speed. #RAIN_DEFAULT_SPEED=5
#MATRIX_DEFAULT_SPEED=3.5
# rain: Colour theme. Supported: white (default), green, blue, red, yellow, cyan
# matrix: Colour theme. Supported: green (default), blue, red, yellow, cyan, white #RAIN_DEFAULT_COLOR=white
#MATRIX_DEFAULT_COLOR=green
# matrix: Falling speed.
# matrix: Character set. Supported: binary (default), kana, ascii #MATRIX_DEFAULT_SPEED=3.5
#MATRIX_DEFAULT_CHARSET=binary
# matrix: Colour theme. Supported: green (default), blue, red, yellow, cyan, white
# ============================================================================== #MATRIX_DEFAULT_COLOR=green
[ssh]
# ssr: Default SSH options prepended to every ssr call. # matrix: Character set. Supported: binary (default), kana, ascii
# Examples: #MATRIX_DEFAULT_CHARSET=binary
# SSH_DEFAULT_OPT=-Y # X11 forwarding
# SSH_DEFAULT_OPT=-Y -o StrictHostKeyChecking=accept-new # ==============================================================================
# SSH_DEFAULT_OPT= # no default options [ssh]
#SSH_DEFAULT_OPT=-Y # ssr: Default SSH options prepended to every ssr call.
# Examples:
# ============================================================================== # SSH_DEFAULT_OPT=-Y # X11 forwarding
[updates] # SSH_DEFAULT_OPT=-Y -o StrictHostKeyChecking=accept-new
# Git branch used for update checks and profile_upgrade. # SSH_DEFAULT_OPT= # no default options
# Changing this causes profile_upgrade to automatically switch the local #SSH_DEFAULT_OPT=-Y
# checkout to the new branch on the next run and display a warning.
#UPDT_DEFAULT_BRANCH=master # ==============================================================================
[updates]
# ============================================================================== # Git branch used for update checks and profile_upgrade.
[general] # Changing this causes profile_upgrade to automatically switch the local
# General-purpose section — set any environment variable you need globally. # checkout to the new branch on the next run and display a warning.
# Good place for compilation flags, personal PATH additions, etc. #UPDT_DEFAULT_BRANCH=master
#CFLAGS=-O2 -pipe -march=native
#CXXFLAGS=$CFLAGS # ==============================================================================
#MAKEFLAGS=-j4 [general]
#PKGSOURCES=/usr/local/src # General-purpose section — set any environment variable you need globally.
# Good place for compilation flags, personal PATH additions, etc.
# ============================================================================== #CFLAGS=-O2 -pipe -march=native
[aliases] #CXXFLAGS=$CFLAGS
# Command aliases loaded for interactive shells only. #MAKEFLAGS=-j4
# The value is the full command string; the key becomes the alias name. #PKGSOURCES=/usr/local/src
# The base command must be executable; if not, the alias is silently skipped.
# # ==============================================================================
# ls [aliases]
ll=ls -laFh --color=auto # Command aliases loaded for interactive shells only.
la=ls -Ah --color=auto # The value is the full command string; the key becomes the alias name.
l=ls -CF --color=auto # The base command must be executable; if not, the alias is silently skipped.
ls=ls --color=auto #
# # ls
# grep ll=ls -laFh --color=auto
grep=grep --color=auto la=ls -Ah --color=auto
egrep=egrep --color=auto l=ls -CF --color=auto
fgrep=fgrep --color=auto ls=ls --color=auto
# #
# disk usage # grep
df=df -H grep=grep --color=auto
du=du -ch egrep=egrep --color=auto
# fgrep=fgrep --color=auto
# make shortcuts #
#mk=make # disk usage
#mkin=make install df=df -H
du=du -ch
# End of profile.conf.example #
# make shortcuts
#mk=make
#mkin=make install
# End of profile.conf.example

View File

@@ -1,121 +1,114 @@
# profile — to-do list # profile — to-do list
Items marked **[easy]**, **[medium]**, or **[hard]** give a rough effort hint. Items marked **[easy]**, **[medium]**, or **[hard]** give a rough effort hint.
Items marked **[breaking]** would change existing behaviour and require a Items marked **[breaking]** would change existing behaviour and require a
version-bump. version-bump.
--- ---
## Shell / compatibility ## Shell / compatibility
- [ ] **ZSH compatibility layer** — most functions work already; the remaining - [ ] **ZSH compatibility layer** — most functions work already; the remaining
blockers are `local -A` (no associative arrays in ZSH without `typeset -A`) 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 and `local -n` namerefs. A thin compatibility shim would open the project to
ZSH users. **[hard]** ZSH users. **[hard]**
- [ ] **Bash completion** — add a `profile.d/completion/` directory and write - [ ] **Bash completion** — add a `profile.d/completion/` directory and write
`_profile_upgrade`, `_taz`, `_utaz`, `_meteo`, etc. completions so that `_profile_upgrade`, `_taz`, `_utaz`, `_meteo`, etc. completions so that
`<Tab>` works on all public functions. **[medium]** `<Tab>` works on all public functions. **[medium]**
- [ ] **`shellcheck` clean pass** — run `shellcheck -x profile.sh profile.d/*.sh`
and address every remaining warning (currently a handful of SC2034 and SC2086 ---
items). Integrate as a pre-commit hook. **[easy]**
## Prompt & theming
---
- [ ] **Git branch in prompt** — show the current branch name (and dirty
## Prompt & theming indicator) in the PS1 bar when inside a Git repository. Should be
gated behind a `[prompt]` config key so it can be disabled. **[medium]**
- [ ] **Git branch in prompt** — show the current branch name (and dirty - [ ] **Virtual-env / conda indicator** — detect `$VIRTUAL_ENV` / `$CONDA_DEFAULT_ENV`
indicator) in the PS1 bar when inside a Git repository. Should be and display the name in the prompt bar. **[easy]**
gated behind a `[prompt]` config key so it can be disabled. **[medium]** - [ ] **True-colour terminal auto-detection** — query `$COLORTERM` and
- [ ] **Virtual-env / conda indicator** — detect `$VIRTUAL_ENV` / `$CONDA_DEFAULT_ENV` `$TERM` at load time; automatically fall back from a 24-bit theme to its
and display the name in the prompt bar. **[easy]** 16-colour equivalent when the terminal does not support true colour. **[medium]**
- [ ] **True-colour terminal auto-detection** — query `$COLORTERM` and - [ ] **True-colour variants of other themes** — create `monokai-tc.theme`,
`$TERM` at load time; automatically fall back from a 24-bit theme to its `abyss-tc.theme`, etc. using the same `\e[38;2;R;G;Bm` approach as the
16-colour equivalent when the terminal does not support true colour. **[medium]** Solarized themes. **[easy]** _(per theme)_
- [ ] **True-colour variants of other themes** — create `monokai-tc.theme`, - [ ] **Theme preview command** — add a `theme_preview` (or `profile_theme`)
`abyss-tc.theme`, etc. using the same `\e[38;2;R;G;Bm` approach as the function that renders a colour swatch and a sample prompt line for the
Solarized themes. **[easy]** _(per theme)_ currently loaded theme, so users can evaluate themes without reloading
- [ ] **Theme preview command** — add a `theme_preview` (or `profile_theme`) the session. **[medium]**
function that renders a colour swatch and a sample prompt line for the - [ ] **`load_theme` — DEFAULTCOL rebuild** — after overriding `DEFAULTFG` and
currently loaded theme, so users can evaluate themes without reloading `DEFAULTBG`, automatically recompute `DEFAULTCOL` from the new values instead
the session. **[medium]** of requiring the theme file to set it explicitly. **[easy]**
- [ ] **`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
## Module improvements - [ ] **`taz` progress bar** — show a `pv` / `dd`-based progress indicator when
compressing large trees, gated behind a `-p` flag. **[medium]**
### compress - [ ] **`utaz` integrity check** — run `tar -tOf` / `unzip -t` / `7z t` before
- [ ] **`taz` progress bar** — show a `pv` / `dd`-based progress indicator when extracting and abort if the archive is corrupt. **[easy]**
compressing large trees, gated behind a `-p` flag. **[medium]**
- [ ] **`utaz` integrity check** — run `tar -tOf` / `unzip -t` / `7z t` before ### filefct
extracting and abort if the archive is corrupt. **[easy]** - [ ] **`findbig` / `findzero` / `finddead``fd` integration** — optionally
use `fd` instead of `find` when available for faster traversal. **[easy]**
### filefct - [ ] **`file_stats` — human-readable totals** — add `--human` flag to emit
- [ ] **`findbig` / `findzero` / `finddead``fd` integration** — optionally sizes in K/M/G instead of bytes. **[easy]**
use `fd` instead of `find` when available for faster traversal. **[easy]**
- [ ] **`file_stats` — human-readable totals** — add `--human` flag to emit ### info
sizes in K/M/G instead of bytes. **[easy]** - [ ] **`showinfo` fallback** — when neither `neofetch` nor `fastfetch` is
installed, print a minimal sysinfo block (hostname, OS, kernel, uptime,
### info CPU, RAM) using pure Bash + `/proc`. **[medium]**
- [ ] **`showinfo` fallback** — when neither `neofetch` nor `fastfetch` is
installed, print a minimal sysinfo block (hostname, OS, kernel, uptime, ### net
CPU, RAM) using pure Bash + `/proc`. **[medium]** - [ ] **`dwl` resume support** — pass `-C -` to curl / `--continue-at -` to
wget for interrupted downloads; gate behind a `-r` flag. **[easy]**
### net - [ ] **`myextip` multiple providers** — fall back to a secondary URL
- [ ] **`dwl` resume support** — pass `-C -` to curl / `--continue-at -` to (configurable via `MYEXTIP_FALLBACK_URL`) when the primary times out.
wget for interrupted downloads; gate behind a `-r` flag. **[easy]** **[easy]**
- [ ] **`myextip` multiple providers** — fall back to a secondary URL
(configurable via `MYEXTIP_FALLBACK_URL`) when the primary times out. ### processes
**[easy]** - [ ] **`ku` dry-run flag** — add `-n` / `--dry-run` to print what would be
killed without acting. **[easy]**
### packages
- [ ] **Additional backends** — add support for `pacman` (Arch), `apk` (Alpine), ### pwd
`xbps-query` (Void), and `brew` (macOS). **[medium]** - [ ] **`genpwd` passphrase mode** — add `-w` / `--words N` to generate
word-based passphrases (diceware-style) from `/usr/share/dict/words`.
### processes **[medium]**
- [ ] **`ku` dry-run flag** — add `-n` / `--dry-run` to print what would be
killed without acting. **[easy]** ### ssh
- [ ] **SSH agent management** — add `ssh_agent_start` / `ssh_agent_stop` helpers
### pwd that start a persistent `ssh-agent`, add configured keys, and survive
- [ ] **`genpwd` passphrase mode** — add `-w` / `--words N` to generate re-login via a socket stored in `~/.ssh/agent.env`. **[medium]**
word-based passphrases (diceware-style) from `/usr/share/dict/words`. - [ ] **`rmhost` glob support** — allow `rmhost '*.example.com'` to remove all
**[medium]** matching entries in one call. **[easy]**
### ssh ### updates
- [ ] **SSH agent management** — add `ssh_agent_start` / `ssh_agent_stop` helpers - [ ] **Automatic update check age** — store a timestamp in `~/.cache/profile_last_check`;
that start a persistent `ssh-agent`, add configured keys, and survive skip the network request in `check_updates -q` if the last check was less
re-login via a socket stored in `~/.ssh/agent.env`. **[medium]** than `UPDT_CHECK_INTERVAL` hours ago (configurable, default 24). **[medium]**
- [ ] **`rmhost` glob support** — allow `rmhost '*.example.com'` to remove all - [ ] **Changelog display** — after a successful `profile_upgrade`, fetch and
matching entries in one call. **[easy]** display `CHANGELOG.md` entries newer than the previously installed version.
**[medium]**
### 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]** ## Infrastructure
- [ ] **Changelog display** — after a successful `profile_upgrade`, fetch and
display `CHANGELOG.md` entries newer than the previously installed version. - [ ] **Test suite** — add a `test/` directory with `bats` (Bash Automated
**[medium]** 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`
## Infrastructure and the `bats` suite on every push. **[medium]**
- [ ] **`profile_status` function** — print a diagnostic summary: installed
- [ ] **Test suite**add a `test/` directory with `bats` (Bash Automated version, active theme, loaded modules, detected Bash version, interactive /
Testing System) unit tests for pure functions (`expandlist`, `genpwd`, login shell flags, and `profile.conf` path. **[easy]**
`pwdscore`, `isipv4`, `isipv6`, `parse_conf`, `load_theme`, …). Target for - [ ] **`profile_uninstall` function** — remove the `source` line from
CI. **[hard]** `~/.bashrc` / `~/.profile` and optionally delete the install directory,
- [ ] **CI pipeline** — Gitea Actions (or similar) job that runs `shellcheck` with a dry-run mode. **[medium]**
and the `bats` suite on every push. **[medium]** - [ ] **`disp` syslog integration** — add a `DISP_SYSLOG=1` config key that
- [ ] **`profile_status` function** — print a diagnostic summary: installed additionally pipes E/W messages to `logger`. **[easy]**
version, active theme, loaded modules, detected Bash version, interactive / - [ ] **XDG base-dir support** — honour `$XDG_CONFIG_HOME` as an alternative
login shell flags, and `profile.conf` path. **[easy]** location for `profile.conf` so users can keep `~` tidy. **[medium]**
- [ ] **`profile_uninstall` function** — remove the `source` line from **[breaking]**
`~/.bashrc` / `~/.profile` and optionally delete the install directory,
with a dry-run mode. **[medium]**
- [ ] **`disp` syslog integration** — add a `DISP_SYSLOG=1` 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]**

View File

@@ -44,36 +44,42 @@
# -n, --no-dir Never create a host directory # -n, --no-dir Never create a host directory
utaz() utaz()
{ {
# shellcheck disable=SC2329
_ununzip() _ununzip()
{ {
unzip -o "$1" -d "$2" >/dev/null 2>&1 unzip -o "$1" -d "$2" >/dev/null 2>&1
} }
# shellcheck disable=SC2329
_untar() _untar()
{ {
tar -xf "$1" -C "$2" tar -xf "$1" -C "$2"
} }
# shellcheck disable=SC2329
_ungzip() _ungzip()
{ {
tar -xzf "$1" -C "$2" tar -xzf "$1" -C "$2"
} }
# shellcheck disable=SC2329
_unbzip2() _unbzip2()
{ {
tar -xjf "$1" -C "$2" tar -xjf "$1" -C "$2"
} }
# shellcheck disable=SC2329
_unxz() _unxz()
{ {
tar -xJf "$1" -C "$2" tar -xJf "$1" -C "$2"
} }
# shellcheck disable=SC2329
_unlzop() _unlzop()
{ {
lzop -d "$1" -o "$2/$(basename "${1%.*}")" lzop -d "$1" -o "$2/$(basename "${1%.*}")"
} }
# shellcheck disable=SC2329
_unlzip() _unlzip()
{ {
if command -v plzip >/dev/null 2>&1; then if command -v plzip >/dev/null 2>&1; then
@@ -83,16 +89,19 @@ utaz()
fi fi
} }
# shellcheck disable=SC2329
_ununrar() _ununrar()
{ {
unrar x -o+ "$1" "$2/" >/dev/null 2>&1 unrar x -o+ "$1" "$2/" >/dev/null 2>&1
} }
# shellcheck disable=SC2329
_ununarj() _ununarj()
{ {
unarj e "$1" "$2/" >/dev/null 2>&1 unarj e "$1" "$2/" >/dev/null 2>&1
} }
# shellcheck disable=SC2329
_unlha() _unlha()
{ {
# lha typically extracts into the current directory # lha typically extracts into the current directory
@@ -100,40 +109,47 @@ utaz()
(cd "$2" && lha -x "../$1") >/dev/null 2>&1 (cd "$2" && lha -x "../$1") >/dev/null 2>&1
} }
# shellcheck disable=SC2329
_ununace() _ununace()
{ {
unace x "$1" "$2/" >/dev/null 2>&1 unace x "$1" "$2/" >/dev/null 2>&1
} }
# shellcheck disable=SC2329
_un7z() _un7z()
{ {
7z x "$1" -o"$2/" >/dev/null 2>&1 7z x "$1" -o"$2/" >/dev/null 2>&1
} }
# shellcheck disable=SC2329
_unzstd() _unzstd()
{ {
# Zstd decompresses files directly, often requiring tar for archives # Zstd decompresses files directly, often requiring tar for archives
tar --zstd -xf "$1" -C "$2" tar --zstd -xf "$1" -C "$2"
} }
# shellcheck disable=SC2329
_uncpio() _uncpio()
{ {
# CPIO requires careful directory handling # CPIO requires careful directory handling
(cd "$2" && cpio -id < "../$1") >/dev/null 2>&1 (cd "$2" && cpio -id < "../$1") >/dev/null 2>&1
} }
# shellcheck disable=SC2329
_uncabextract() _uncabextract()
{ {
# Requires 'cabextract' package # Requires 'cabextract' package
cabextract "$1" -d "$2/" >/dev/null 2>&1 cabextract "$1" -d "$2/" >/dev/null 2>&1
} }
# shellcheck disable=SC2329
_undeb() _undeb()
{ {
# Extracts data content from a Debian package # Extracts data content from a Debian package
dpkg-deb -x "$1" "$2/" >/dev/null 2>&1 dpkg-deb -x "$1" "$2/" >/dev/null 2>&1
} }
# shellcheck disable=SC2329
_unrpm() _unrpm()
{ {
# Extracts CPIO-based payload from an RPM package # Extracts CPIO-based payload from an RPM package
@@ -141,8 +157,9 @@ utaz()
rpm2cpio "$1" | (cd "$2/" && cpio -idmv) >/dev/null 2>&1 rpm2cpio "$1" | (cd "$2/" && cpio -idmv) >/dev/null 2>&1
} }
local PARSED=$(getopt -o hdcn --long help,delete,create-dir,no-dir -n 'utaz' -- "$@") local PARSED
PARSED=$(getopt -o hdcn --long help,delete,create-dir,no-dir -n 'utaz' -- "$@")
# shellcheck disable=SC2181 # getopt return code is checked immediately after
if [ $? -ne 0 ]; then if [ $? -ne 0 ]; then
disp E "Invalid options, use \"utaz --help\" to display usage." disp E "Invalid options, use \"utaz --help\" to display usage."
return 1 return 1
@@ -314,10 +331,10 @@ utaz()
fi fi
disp I "Processing archive ${f} with ${extractor}..." disp I "Processing archive ${f} with ${extractor}..."
mkdir -p "${dir}" if ! mkdir -p "${dir}"; then
[[ $? -gt 0 ]] &&
disp E "The filesystem can't create directories, exit!" && disp E "The filesystem can't create directories, exit!" &&
return 1 return 1
fi
${extractor} "${f}" "${dir}" ${extractor} "${f}" "${dir}"
case $? in case $? in
@@ -390,6 +407,7 @@ export -f utaz
# -1, .., -9 Compression level to use [1=fast/biggest, 9=slow/smallest] # -1, .., -9 Compression level to use [1=fast/biggest, 9=slow/smallest]
taz() taz()
{ {
# shellcheck disable=SC2329
_doxz() _doxz()
{ {
command -v xz >/dev/null 2>&1 || { command -v xz >/dev/null 2>&1 || {
@@ -397,17 +415,19 @@ taz()
return 127 return 127
} }
[[ $4 ]] && local verb='-v' local verb=()
[[ $4 ]] && verb=('-v')
# Display a warning for this format # Display a warning for this format
disp W "xz format is not suited for long term archiving." disp W "xz format is not suited for long term archiving."
disp I "See https://www.nongnu.org/lzip/xz_inadequate.html for details." disp I "See https://www.nongnu.org/lzip/xz_inadequate.html for details."
# Compresse to xz (lzma2) - Deprecated # Compress with xz (lzma2) - Deprecated
xz $verb --compress --keep -$3 -T $2 $1 xz "${verb[@]}" --compress --keep "-$3" -T "$2" "$1"
return $? return $?
} }
# shellcheck disable=SC2329
_dolz() _dolz()
{ {
local procopt="--threads $2" local procopt="--threads $2"
@@ -425,13 +445,16 @@ taz()
disp W "Consider installing plzip to obtain multithreading abilities." disp W "Consider installing plzip to obtain multithreading abilities."
} }
[[ $4 ]] && local verb="-vv" local opt=()
[[ $4 ]] && opt=('-vv')
opt+=("$procopt")
# Compresse au format lzip (lzma) # Compress with lzip (lzma)
$command $verb $procopt --keep -$3 $1 $command "${opt[@]}" --keep "-$3" "$1"
return $? return $?
} }
# shellcheck disable=SC2329
_dogz() _dogz()
{ {
local procopt="--processes $2" local procopt="--processes $2"
@@ -449,13 +472,16 @@ taz()
disp W "Consider installing pigz to obtain multithreading abilities." disp W "Consider installing pigz to obtain multithreading abilities."
} }
[[ $4 ]] && local verb="--verbose" local opt=()
[[ $4 ]] && opt=('--verbose')
opt+=("$procopt")
# Compresse au format bz2 # Compresse au format bz2
$command $verb $procopt --keep -$3 $1 $command "${opt[@]}" --keep "-$3" "$1"
return $? return $?
} }
# shellcheck disable=SC2329
_dobz2() _dobz2()
{ {
local procopt="-p$2" local procopt="-p$2"
@@ -473,13 +499,16 @@ taz()
disp W "Consider installing pbzip2 to obtain multithreading abilities." disp W "Consider installing pbzip2 to obtain multithreading abilities."
} }
[[ $4 ]] && local verb="-v" local opt=()
[[ $4 ]] && opt=('-v')
opt+=("$procopt")
# Compresse au format bz2 # Compress with bz2
$command $verb --compress $procopt --keep -$3 $1 $command "${opt[@]}" --compress --keep "-$3" "$1"
return $? return $?
} }
# shellcheck disable=SC2329
_dolzo() _dolzo()
{ {
command -v lzop >/dev/null 2>&1 || { command -v lzop >/dev/null 2>&1 || {
@@ -487,16 +516,18 @@ taz()
return 127 return 127
} }
[[ $4 ]] && local verb='-v' local verb=()
[[ $4 ]] && verb=('-v')
[[ $2 -gt 1 ]] && disp W "lzop doesn't support multithreading, falling back to 1 thread." [[ $2 -gt 1 ]] && disp W "lzop doesn't support multithreading, falling back to 1 thread."
# Compresse au format lzo # Compresse au format lzo
lzop --keep -$3 $1 lzop "${verb[@]}" --keep "-$3" "$1"
return $? return $?
} }
local PARSED local PARSED
PARSED=$(getopt -o hdf:p:vq123456789 --long help,delete,format:,parallel:,verbose,quiet --name "taz" -- "$@") PARSED=$(getopt -o hdf:p:vq123456789 --long help,delete,format:,parallel:,verbose,quiet --name "taz" -- "$@")
# shellcheck disable=SC2181 # getopt return code is checked immediately after
if [ $? -ne 0 ]; then if [ $? -ne 0 ]; then
disp E "Invalid options, use \"taz --help\" to display usage." disp E "Invalid options, use \"taz --help\" to display usage."
return 1 return 1
@@ -587,8 +618,7 @@ taz()
if [[ -d "$item" ]]; then if [[ -d "$item" ]]; then
disp I "\t Creating $item.tar... " disp I "\t Creating $item.tar... "
tar -cf "$item.tar" "$item" if ! tar -cf "$item.tar" "$item"; then
if [[ ! $? -eq 0 ]]; then
disp E "tar file creation failed, skipping to next item." disp E "tar file creation failed, skipping to next item."
continue continue
fi fi
@@ -602,8 +632,9 @@ taz()
# Skip compression part if tar is asked # Skip compression part if tar is asked
if [[ $compform != "tar" ]]; then if [[ $compform != "tar" ]]; then
disp I "\t Compressing archive..." disp I "\t Compressing archive..."
_do$compform "$fname" "$nproc" "$complevel" "$verbose" local exec_code=0
[[ ! $? -eq 0 ]] && case $? in "_do$compform" "$fname" "$nproc" "$complevel" "$verbose" || exec_code=$?
[[ ! $exec_code -eq 0 ]] && case $exec_code in
127) 127)
disp E "Compression program unavailable, aborting." disp E "Compression program unavailable, aborting."
return 127 return 127

View File

@@ -70,6 +70,7 @@ settrace()
local PARSED local PARSED
PARSED=$(getopt -oh --long help,on,off,status,force -- "$@") PARSED=$(getopt -oh --long help,on,off,status,force -- "$@")
# shellcheck disable=SC2181 # getopt return code is checked immediately after
if [[ $? -ne 0 ]]; then if [[ $? -ne 0 ]]; then
disp E "Invalid options, use \"settrace --help\" to display usage." disp E "Invalid options, use \"settrace --help\" to display usage."
return 1 return 1

View File

@@ -36,81 +36,85 @@
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
# Color definitions # Color definitions
# Standard 16 colors display declaration set_colors()
export DEFAULTFG='\e[0;39m' {
export DEFAULTBG='\e[0;49m' # Standard 16 colors display declaration
export DEFAULTCOL="${DEFAULTBG}${DEFAULTFG}" export DEFAULTFG='\e[0;39m'
export RESETCOL=$'\e[0m' export DEFAULTBG='\e[0;49m'
export DEFAULTCOL="${DEFAULTBG}${DEFAULTFG}"
export RESETCOL=$'\e[0m'
# Regular Colors # Regular Colors
export Black='\e[0;30m' export Black='\e[0;30m'
export Red='\e[0;31m' export Red='\e[0;31m'
export Green='\e[0;32m' export Green='\e[0;32m'
export Yellow='\e[0;33m' export Yellow='\e[0;33m'
export Blue='\e[0;34m' export Blue='\e[0;34m'
export Purple='\e[0;35m' export Purple='\e[0;35m'
export Cyan='\e[0;36m' export Cyan='\e[0;36m'
export White='\e[0;37m' export White='\e[0;37m'
# Bold # Bold
export BBlack='\e[1;30m' export BBlack='\e[1;30m'
export BRed='\e[1;31m' export BRed='\e[1;31m'
export BGreen='\e[1;32m' export BGreen='\e[1;32m'
export BYellow='\e[1;33m' export BYellow='\e[1;33m'
export BBlue='\e[1;34m' export BBlue='\e[1;34m'
export BPurple='\e[1;35m' export BPurple='\e[1;35m'
export BCyan='\e[1;36m' export BCyan='\e[1;36m'
export BWhite='\e[1;37m' export BWhite='\e[1;37m'
# Underline # Underline
export UBlack='\e[4;30m' export UBlack='\e[4;30m'
export URed='\e[4;31m' export URed='\e[4;31m'
export UGreen='\e[4;32m' export UGreen='\e[4;32m'
export UYellow='\e[4;33m' export UYellow='\e[4;33m'
export UBlue='\e[4;34m' export UBlue='\e[4;34m'
export UPurple='\e[4;35m' export UPurple='\e[4;35m'
export UCyan='\e[4;36m' export UCyan='\e[4;36m'
export UWhite='\e[4;37m' export UWhite='\e[4;37m'
# Background # Background
export On_Black='\e[40m' export On_Black='\e[40m'
export On_Red='\e[41m' export On_Red='\e[41m'
export On_Green='\e[42m' export On_Green='\e[42m'
export On_Yellow='\e[43m' export On_Yellow='\e[43m'
export On_Blue='\e[44m' export On_Blue='\e[44m'
export On_Purple='\e[45m' export On_Purple='\e[45m'
export On_Cyan='\e[46m' export On_Cyan='\e[46m'
export On_White='\e[47m' export On_White='\e[47m'
# High Intensity # High Intensity
export IBlack='\e[0;90m' export IBlack='\e[0;90m'
export IRed='\e[0;91m' export IRed='\e[0;91m'
export IGreen='\e[0;92m' export IGreen='\e[0;92m'
export IYellow='\e[0;93m' export IYellow='\e[0;93m'
export IBlue='\e[0;94m' export IBlue='\e[0;94m'
export IPurple='\e[0;95m' export IPurple='\e[0;95m'
export ICyan='\e[0;96m' export ICyan='\e[0;96m'
export IWhite='\e[0;97m' export IWhite='\e[0;97m'
# Bold High Intensity # Bold High Intensity
export BIBlack='\e[1;90m' export BIBlack='\e[1;90m'
export BIRed='\e[1;91m' export BIRed='\e[1;91m'
export BIGreen='\e[1;92m' export BIGreen='\e[1;92m'
export BIYellow='\e[1;93m' export BIYellow='\e[1;93m'
export BIBlue='\e[1;94m' export BIBlue='\e[1;94m'
export BIPurple='\e[1;95m' export BIPurple='\e[1;95m'
export BICyan='\e[1;96m' export BICyan='\e[1;96m'
export BIWhite='\e[1;97m' export BIWhite='\e[1;97m'
# High Intensity backgrounds # High Intensity backgrounds
export On_IBlack='\e[0;100m' export On_IBlack='\e[0;100m'
export On_IRed='\e[0;101m' export On_IRed='\e[0;101m'
export On_IGreen='\e[0;102m' export On_IGreen='\e[0;102m'
export On_IYellow='\e[0;103m' export On_IYellow='\e[0;103m'
export On_IBlue='\e[0;104m' export On_IBlue='\e[0;104m'
export On_IPurple='\e[0;105m' export On_IPurple='\e[0;105m'
export On_ICyan='\e[0;106m' export On_ICyan='\e[0;106m'
export On_IWhite='\e[0;107m' export On_IWhite='\e[0;107m'
}
export -f set_colors
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
@@ -179,5 +183,6 @@ export -f disp
# Load disp section variables # Load disp section variables
load_conf disp load_conf disp
set_colors
# EOF # EOF

View File

@@ -41,8 +41,8 @@ expandlist()
{ {
local separator="${EXPANDLIST_DEFAULT_SEPARATOR:- }" local separator="${EXPANDLIST_DEFAULT_SEPARATOR:- }"
local PARSED local PARSED
PARSED=$(getopt -o hs:n --long help,separator:,newline -n 'expandlist' -- "$@") PARSED=$(getopt -o hs:n --long help,separator:,newline -n 'expandlist' -- "$@")
# shellcheck disable=SC2181 # getopt return code is checked immediately after
if [[ $? -ne 0 ]]; then if [[ $? -ne 0 ]]; then
disp E "Invalid options, use \"expandlist --help\" to display usage." disp E "Invalid options, use \"expandlist --help\" to display usage."
return 1 return 1
@@ -87,6 +87,7 @@ expandlist()
# True glob expansion when wildcards are present. # True glob expansion when wildcards are present.
if [[ "$item" == *'*'* || "$item" == *'?'* || "$item" == *'['* ]]; then if [[ "$item" == *'*'* || "$item" == *'?'* || "$item" == *'['* ]]; then
# shellcheck disable=SC2206 # We actually want the word splitting
expanded=( $item ) expanded=( $item )
else else
expanded=( "$item" ) expanded=( "$item" )
@@ -127,7 +128,7 @@ clean()
# Define short and long options # Define short and long options
local PARSED local PARSED
PARSED=$(getopt -o hrsf --long help,recurs,shell,force -n 'clean' -- "$@") PARSED=$(getopt -o hrsf --long help,recurs,shell,force -n 'clean' -- "$@")
# shellcheck disable=SC2181 # getopt return code is checked immediately after
if [[ $? -ne 0 ]]; then if [[ $? -ne 0 ]]; then
disp E "Invalid options, use \"clean --help\" to display usage." disp E "Invalid options, use \"clean --help\" to display usage."
return 1 return 1
@@ -215,10 +216,14 @@ mcd()
disp E "Missing parameter. Use \"mcd --help\" to display usage." disp E "Missing parameter. Use \"mcd --help\" to display usage."
return 1 return 1
fi fi
mkdir -pv "$1" && cd "$1" || { if ! mkdir -pv "$1"; then
printf "Failed create and/or change directory.\n" disp E "Failed to create directory \"$1\"."
return 1 return 1
} fi
if ! cd "$1"; then
disp E "Failed to change to directory \"$1\"."
return 1
fi
} }
export -f mcd export -f mcd
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
@@ -241,6 +246,7 @@ rmspc()
local PARSED local PARSED
PARSED=$(getopt -o hr:c::vs --long help,recursive,subst-char::,verbose,shell -n 'rmspc' -- "$@") PARSED=$(getopt -o hr:c::vs --long help,recursive,subst-char::,verbose,shell -n 'rmspc' -- "$@")
# shellcheck disable=SC2181 # getopt return code is checked immediately after
if [[ $? -ne 0 ]]; then if [[ $? -ne 0 ]]; then
disp E "Invalid options, use \"rmspc --help\" to display usage." disp E "Invalid options, use \"rmspc --help\" to display usage."
return 1 return 1
@@ -359,7 +365,7 @@ file_stats()
# Short: H, d, m, M, c, t, a, x:, X: # Short: H, d, m, M, c, t, a, x:, X:
# Long: human, details, average, median, count, total, all, ext:, ext-list:, min:, max:, help # Long: human, details, average, median, count, total, all, ext:, ext-list:, min:, max:, help
PARSED=$(getopt -o HdmMctax:X:h --long human,details,average,median,count,total,all,ext:,ext-list:,min:,max:,help -n 'file_stats' -- "$@") PARSED=$(getopt -o HdmMctax:X:h --long human,details,average,median,count,total,all,ext:,ext-list:,min:,max:,help -n 'file_stats' -- "$@")
# shellcheck disable=SC2181 # getopt return code is checked immediately after
if [[ $? -ne 0 ]]; then if [[ $? -ne 0 ]]; then
disp E "Invalid options, use \"file_stats --help\" to display usage." disp E "Invalid options, use \"file_stats --help\" to display usage."
return 1 return 1
@@ -441,7 +447,6 @@ file_stats()
return 1 return 1
;; ;;
esac esac
shift
done done
[[ -n "$1" ]] && path="$1" [[ -n "$1" ]] && path="$1"
@@ -578,6 +583,7 @@ findbig()
local PARSED local PARSED
PARSED=$(getopt -o hdl:x --long help,details,limit:,one-fs -n 'findbig' -- "$@") PARSED=$(getopt -o hdl:x --long help,details,limit:,one-fs -n 'findbig' -- "$@")
# shellcheck disable=SC2181 # getopt return code is checked immediately after
if [[ $? -ne 0 ]]; then if [[ $? -ne 0 ]]; then
disp E "Invalid options, use \"findbig --help\" to display usage." disp E "Invalid options, use \"findbig --help\" to display usage."
return 1 return 1
@@ -660,6 +666,7 @@ findzero()
local PARSED local PARSED
# o: options, long: long equivalents # o: options, long: long equivalents
PARSED=$(getopt -o hdx --long help,details,one-fs,delete -n 'findzero' -- "$@") PARSED=$(getopt -o hdx --long help,details,one-fs,delete -n 'findzero' -- "$@")
# shellcheck disable=SC2181 # getopt return code is checked immediately after
if [[ $? -ne 0 ]]; then if [[ $? -ne 0 ]]; then
disp E "Invalid options, use \"findzero --help\" to display usage." disp E "Invalid options, use \"findzero --help\" to display usage."
return 1 return 1
@@ -733,6 +740,7 @@ finddead()
local PARSED local PARSED
PARSED=$(getopt -o hdx --long help,details,one-fs,delete -n 'finddead' -- "$@") PARSED=$(getopt -o hdx --long help,details,one-fs,delete -n 'finddead' -- "$@")
# shellcheck disable=SC2181 # getopt return code is checked immediately after
if [[ $? -ne 0 ]]; then if [[ $? -ne 0 ]]; then
disp E "Invalid options, use \"finddead --help\" to display usage." disp E "Invalid options, use \"finddead --help\" to display usage."
return 1 return 1

View File

@@ -48,6 +48,7 @@ busy()
# Short: h, p:, d: # Short: h, p:, d:
# Long: help, pattern:, delay: # Long: help, pattern:, delay:
PARSED=$(getopt -o hp:d: --long help,pattern:,delay: -n 'busy' -- "$@") PARSED=$(getopt -o hp:d: --long help,pattern:,delay: -n 'busy' -- "$@")
# shellcheck disable=SC2181 # getopt return code is checked immediately after
if [[ $? -ne 0 ]]; then if [[ $? -ne 0 ]]; then
disp E "Invalid options, use \"busy --help\" to display usage." disp E "Invalid options, use \"busy --help\" to display usage."
return 1 return 1
@@ -89,7 +90,8 @@ busy()
done done
# Convert milliseconds to seconds for 'sleep' # Convert milliseconds to seconds for 'sleep'
local delay_s=$(awk "BEGIN{ local delay_s
delay_s=$(awk "BEGIN{
printf \"%.3f\", $delay_ms / 1000 }") printf \"%.3f\", $delay_ms / 1000 }")
# Monitor /dev/urandom # Monitor /dev/urandom

View File

@@ -39,6 +39,8 @@
# Usage: help # Usage: help
help() help()
{ {
# shellcheck disable=SC2154 # color code in disp.sh
# shellcheck disable=SC2059 # printf format is a color variable
printf "${BIWhite}Welcome to your profile! Here is a list of available commands:${DEFAULTCOL}\n\n" printf "${BIWhite}Welcome to your profile! Here is a list of available commands:${DEFAULTCOL}\n\n"
printf "busy\t\tMonitor /dev/urandom for a hex pattern — look busy\n" printf "busy\t\tMonitor /dev/urandom for a hex pattern — look busy\n"
printf "check_updates\tCheck for new versions of profile\n" printf "check_updates\tCheck for new versions of profile\n"
@@ -72,6 +74,7 @@ help()
printf " * setc\tSet locale to standard C (POSIX)\n" printf " * setc\tSet locale to standard C (POSIX)\n"
printf " * set*\tLocale shortcuts generated from SET_LOCALE in profile.conf\n" printf " * set*\tLocale shortcuts generated from SET_LOCALE in profile.conf\n"
printf "settrace\tActivate or deactivate ERR trap to display backtrace on script errors\n" printf "settrace\tActivate or deactivate ERR trap to display backtrace on script errors\n"
printf "set_theme\tSwitch the prompt colour theme; no argument lists available themes\n"
printf "showinfo\tDisplay welcome banner and system information (figlet + neofetch/fastfetch)\n" printf "showinfo\tDisplay welcome banner and system information (figlet + neofetch/fastfetch)\n"
printf "ssr\t\tSSH into a server as root, forwarding extra ssh options\n" printf "ssr\t\tSSH into a server as root, forwarding extra ssh options\n"
printf "taz\t\tCompress files and directories into a chosen archive format\n" printf "taz\t\tCompress files and directories into a chosen archive format\n"

View File

@@ -42,6 +42,7 @@ ver()
local PARSED local PARSED
PARSED=$(getopt -o h --long help -n 'ver' -- "$@") PARSED=$(getopt -o h --long help -n 'ver' -- "$@")
# shellcheck disable=SC2181 # getopt return code is checked immediately after
if [[ $? -ne 0 ]]; then if [[ $? -ne 0 ]]; then
disp E "Invalid options, use \"ver --help\" to display usage." disp E "Invalid options, use \"ver --help\" to display usage."
return 1 return 1
@@ -82,6 +83,7 @@ meteo()
local PARSED local PARSED
PARSED=$(getopt -o h --long help -n 'meteo' -- "$@") PARSED=$(getopt -o h --long help -n 'meteo' -- "$@")
# shellcheck disable=SC2181 # getopt return code is checked immediately after
if [[ $? -ne 0 ]]; then if [[ $? -ne 0 ]]; then
disp E "Invalid options, use \"meteo --help\" to display usage." disp E "Invalid options, use \"meteo --help\" to display usage."
return 1 return 1
@@ -133,6 +135,7 @@ showinfo()
local PARSED local PARSED
PARSED=$(getopt -o h --long help -n 'showinfo' -- "$@") PARSED=$(getopt -o h --long help -n 'showinfo' -- "$@")
# shellcheck disable=SC2181 # getopt return code is checked immediately after
if [[ $? -ne 0 ]]; then if [[ $? -ne 0 ]]; then
disp E "Invalid options, use \"showinfo --help\" to display usage." disp E "Invalid options, use \"showinfo --help\" to display usage."
return 1 return 1

View File

@@ -51,6 +51,7 @@ setlocale()
{ {
local PARSED local PARSED
PARSED=$(getopt -o h --long help -n 'setlocale' -- "$@") PARSED=$(getopt -o h --long help -n 'setlocale' -- "$@")
# shellcheck disable=SC2181 # getopt return code is checked immediately after
if [[ $? -ne 0 ]]; then if [[ $? -ne 0 ]]; then
disp E "Invalid options, use \"setlocale --help\" to display usage." disp E "Invalid options, use \"setlocale --help\" to display usage."
return 1 return 1

View File

@@ -70,9 +70,32 @@ dwl()
# Honour preferred tool from configuration; fall back to auto-detection. # Honour preferred tool from configuration; fall back to auto-detection.
local preferred="${DWL_PREFERRED_TOOL:-}" local preferred="${DWL_PREFERRED_TOOL:-}"
_try_curl() { [ -z "$output" ] && curl -sL "$url" || curl -sL -o "$output" "$url"; } _try_curl()
_try_wget() { [ -z "$output" ] && wget -qO- "$url" || wget -q -O "$output" "$url"; } {
_try_fetch() { [ -z "$output" ] && fetch -o - "$url" || fetch -o "$output" "$url"; } if [[ -z "$output" ]]; then
curl -sL "$url"
else
curl -sL -o "$output" "$url"
fi
}
_try_wget()
{
if [[ -z "$output" ]]; then
wget -qO- "$url"
else
wget -q -O "$output" "$url"
fi
}
_try_fetch()
{
if [[ -z "$output" ]]; then
fetch -o - "$url"
else
fetch -o "$output" "$url"
fi
}
if [[ -n "$preferred" ]]; then if [[ -n "$preferred" ]]; then
command -v "$preferred" >/dev/null 2>&1 || { command -v "$preferred" >/dev/null 2>&1 || {

View File

@@ -34,15 +34,80 @@
# * OF SUCH DAMAGE. # * OF SUCH DAMAGE.
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
# ------------------------------------------------------------------------------
# Detect the active package manager of the current distribution.
# Detection is based on /etc/os-release (ID / ID_LIKE), then falls back to
# checking available binaries in a fixed priority order.
# Echoes one of: apt dnf yum zypper pacman apk portage xbps nix
# Returns 1 if no known package manager could be identified.
_get_pkgmgr()
{
local distro_id="" distro_like=""
if [[ -r /etc/os-release ]]; then
# shellcheck disable=SC1091
distro_id=$( . /etc/os-release 2>/dev/null; printf '%s' "${ID:-}" )
# shellcheck disable=SC1091
distro_like=$( . /etc/os-release 2>/dev/null; printf '%s' "${ID_LIKE:-}" )
fi
# Map distro IDs/families to a package manager.
# ID_LIKE is space-separated and may list multiple families.
local id
for id in $distro_id $distro_like; do
case "${id,,}" in
debian|ubuntu|linuxmint|raspbian|pop|kali|elementary|zorin|neon|parrot)
echo "apt"; return 0 ;;
fedora)
echo "dnf"; return 0 ;;
rhel|centos|rocky|almalinux|ol|scientific|amzn)
command -v dnf >/dev/null 2>&1 && { echo "dnf"; return 0; }
echo "yum"; return 0 ;;
opensuse*|sles|sled)
echo "zypper"; return 0 ;;
arch|manjaro|endeavouros|garuda|artix|cachyos)
echo "pacman"; return 0 ;;
alpine)
echo "apk"; return 0 ;;
gentoo)
echo "portage"; return 0 ;;
void)
echo "xbps"; return 0 ;;
nixos)
echo "nix"; return 0 ;;
esac
done
# Fallback: check for binaries in priority order.
local bin
for bin in apt-get dnf yum zypper pacman apk emerge xbps-install nix-env; do
command -v "$bin" >/dev/null 2>&1 && {
case "$bin" in
apt-get) echo "apt" ;;
emerge) echo "portage" ;;
xbps-install) echo "xbps" ;;
nix-env) echo "nix" ;;
*) echo "$bin" ;;
esac
return 0
}
done
return 1
}
export -f _get_pkgmgr
# ------------------------------------------------------------------------------
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
# Look for a package within installed one # Look for a package within installed one
# Usage: dpkgs <string> # Usage: pkgs <string>
pkgs() pkgs()
{ {
local ignore_case=${PKGS_DEFAULT_IGNORE_CASE:-0} local ignore_case=${PKGS_DEFAULT_IGNORE_CASE:-0}
local PARSED local PARSED
PARSED=$(getopt -o hi --long help,ignore-case -n 'pkgs' -- "$@") PARSED=$(getopt -o hi --long help,ignore-case -n 'pkgs' -- "$@")
# shellcheck disable=SC2181 # getopt return code is checked immediately after
if [[ $? -ne 0 ]]; then if [[ $? -ne 0 ]]; then
disp E "Invalid options, use \"pkgs --help\" to display usage." disp E "Invalid options, use \"pkgs --help\" to display usage."
return 1 return 1
@@ -84,13 +149,28 @@ pkgs()
local grep_opt="" local grep_opt=""
(( ignore_case )) && grep_opt="-i" (( ignore_case )) && grep_opt="-i"
command -v dpkg >/dev/null 2>&1 && local cmd="dpkg -l" local pkgmgr
command -v rpm >/dev/null 2>&1 && local cmd="rpm -qa" pkgmgr=$(_get_pkgmgr) || {
if [[ -z $cmd ]]; then disp E "No usable package manager could be detected on this system."
disp E "No usable package manager seems unavialable."
return 2 return 2
fi }
$cmd | grep $grep_opt $pkg
local -a list_cmd
case "$pkgmgr" in
apt) list_cmd=(dpkg-query -l) ;;
dnf|yum|zypper) list_cmd=(rpm -qa) ;;
pacman) list_cmd=(pacman -Q) ;;
apk) list_cmd=(apk list --installed) ;;
portage) list_cmd=(qlist -I) ;;
xbps) list_cmd=(xbps-query -l) ;;
nix) list_cmd=(nix-env -q) ;;
*)
disp E "Package manager '$pkgmgr' is not supported by pkgs."
return 2
;;
esac
"${list_cmd[@]}" | grep ${grep_opt:+"$grep_opt"} "$pkg"
} }
export -f pkgs export -f pkgs
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------

View File

@@ -121,6 +121,7 @@ ppn()
# -e: select all processes # -e: select all processes
# -o: specify custom output columns (PID and Command name) # -o: specify custom output columns (PID and Command name)
# grep -w: ensures exact word matching so 'bash' doesn't match 'dbash' # grep -w: ensures exact word matching so 'bash' doesn't match 'dbash'
# shellcheck disable=SC2009 # pgrep do not offer the -w switch
ps -eo pid,comm | grep -w "$1" ps -eo pid,comm | grep -w "$1"
} }
export -f ppn export -f ppn
@@ -200,8 +201,7 @@ ku()
disp E "Usage: ku <username1 [username2 ...]>" disp E "Usage: ku <username1 [username2 ...]>"
return 1 return 1
fi fi
local users="$@" for u in "$@"; do
for u in $users; do
if ! id "$u" >/dev/null 2>&1; then if ! id "$u" >/dev/null 2>&1; then
disp E "User '$u' does not exist." disp E "User '$u' does not exist."
return 1 return 1
@@ -227,7 +227,7 @@ kt()
return 0 return 0
fi fi
if [[ -z "$1" ]]; then if [[ -z "$1" ]]; then
disp E "Usage: ppg <string>" disp E "Usage: kt <pid>"
return 1 return 1
fi fi
@@ -238,7 +238,8 @@ kt()
return 1 return 1
fi fi
local children_pids=$(pgrep -P "$parent_pid") local children_pids
children_pids=$(pgrep -P "$parent_pid")
for pid in $children_pids; do for pid in $children_pids; do
kt "$pid" "$@" || break kt "$pid" "$@" || break

View File

@@ -140,9 +140,14 @@ load_theme()
continue continue
fi fi
# Strip surrounding quotes # Strip surrounding quotes (handles inline trailing comments like KEY="val" # note)
_lth_value="${_lth_value#\"}" ; _lth_value="${_lth_value%\"}" if [[ "$_lth_value" == '"'* ]]; then
_lth_value="${_lth_value#\'}" ; _lth_value="${_lth_value%\'}" _lth_value="${_lth_value#\"}"
_lth_value="${_lth_value%%\"*}"
elif [[ "$_lth_value" == "'"* ]]; then
_lth_value="${_lth_value#\'}"
_lth_value="${_lth_value%%\'*}"
fi
if [[ "$_lth_value" =~ $_lth_ref_re ]]; then if [[ "$_lth_value" =~ $_lth_ref_re ]]; then
# Safe colour variable reference — resolve via indirection # Safe colour variable reference — resolve via indirection
@@ -159,6 +164,67 @@ load_theme()
fi fi
done < "$theme_file" done < "$theme_file"
} }
# Not exported, it remains private
# ------------------------------------------------------------------------------
# ------------------------------------------------------------------------------
# Dynamically switch the prompt theme for the current shell session.
# Calls load_theme to apply the new colour values immediately, then updates
# PROMPT_THEME so subshells and the set_prompt fallback chain reflect the
# change. PROMPT_THEME_DIR is honoured when set.
# Usage: set_theme [theme_name_or_path]
# With no argument (or -l / --list), lists available .theme files.
set_theme()
{
local theme_dir="${PROMPT_THEME_DIR:-${MYPATH}/profile.d/themes}"
# -- help mode -----------------------------------------------------------
if [[ "$1" == "-h" || "$1" == "--help" ]]; then
printf "set_theme: Switch the prompt colour theme for the current shell session.\n\n"
printf "Usage: set_theme [options] [theme]\n\n"
printf "Options:\n"
printf " -h, --help Display this help screen\n"
printf " -l, --list List available themes (default when no argument is given)\n\n"
printf "Arguments:\n"
printf " theme Bare theme name (e.g. 'dark') or an explicit path to a .theme file.\n"
printf " Themes are searched in: %s\n" "$theme_dir"
printf " Override with PROMPT_THEME_DIR in profile.conf [prompt].\n\n"
printf "Examples:\n"
printf " set_theme — list available themes\n"
printf " set_theme dark — apply the dark theme\n"
printf " set_theme ~/my.theme — apply a theme by path\n"
return 0
fi
# -- list mode -----------------------------------------------------------
if [[ $# -eq 0 || "$1" == "-l" || "$1" == "--list" ]]; then
printf "Available themes in %s:\n" "$theme_dir"
local f name
for f in "$theme_dir"/*.theme; do
[[ -f "$f" ]] || continue
name="${f##*/}"
name="${name%.theme}"
if [[ "$name" == "${PROMPT_THEME:-}" ]]; then
printf " * %s (active)\n" "$name"
else
printf " %s\n" "$name"
fi
done
return 0
fi
# -- apply mode ----------------------------------------------------------
local theme_name="$1"
# Reset colours to defaults before loading the new theme
set_colors
load_theme "$theme_name" || return 1
export PROMPT_THEME="$theme_name"
disp I "Prompt theme set to $theme_name."
}
export -f set_theme
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
@@ -186,7 +252,7 @@ function timer_start
# into a human-readable string with appropriate units (us, ms, s, m, h # into a human-readable string with appropriate units (us, ms, s, m, h
function timer_stop function timer_stop
{ {
local delta_us=$((($(timer_now) - $timer_start) / 1000)) local delta_us=$((($(timer_now) - timer_start) / 1000))
local us=$((delta_us % 1000)) local us=$((delta_us % 1000))
local ms=$(((delta_us / 1000) % 1000)) local ms=$(((delta_us / 1000) % 1000))
local s=$(((delta_us / 1000000) % 60)) local s=$(((delta_us / 1000000) % 60))
@@ -225,43 +291,48 @@ set_prompt()
# Resolve theme/config colours with hardcoded fallbacks # Resolve theme/config colours with hardcoded fallbacks
local _time_fg="${PROMPT_COLOR_TIME_FG:-$Blue}" local _time_fg="${PROMPT_COLOR_TIME_FG:-$Blue}"
local _time_bg="${PROMPT_COLOR_TIME_BG:-$On_IBlack}" local _time_bg="${PROMPT_COLOR_TIME_BG:-$On_White}"
local _bar_bg="${PROMPT_COLOR_BAR_BG:-$On_Blue}" local _bar_bg="${PROMPT_COLOR_BAR_BG:-$On_Blue}"
local _ok_fg="${PROMPT_COLOR_OK_FG:-$White}" local _ok_fg="${PROMPT_COLOR_OK_FG:-$BWhite}"
local _ok_mark="${PROMPT_COLOR_OK_MARK:-$Green}" local _ok_mark="${PROMPT_COLOR_OK_MARK:-$BGreen}"
local _err_bg="${PROMPT_COLOR_ERR_BG:-$On_Red}" local _err_bg="${PROMPT_COLOR_ERR_BG:-$On_Red}"
local _err_fg="${PROMPT_COLOR_ERR_FG:-$White}" local _err_fg="${PROMPT_COLOR_ERR_FG:-$White}"
local _err_mark="${PROMPT_COLOR_ERR_MARK:-$BYellow}" local _err_mark="${PROMPT_COLOR_ERR_MARK:-$BYellow}"
local _root_fg="${PROMPT_COLOR_ROOT_FG:-$Red}" local _root_fg="${PROMPT_COLOR_ROOT_FG:-$Red}"
local _user_fg="${PROMPT_COLOR_USER_FG:-$Green}" local _user_fg="${PROMPT_COLOR_USER_FG:-$BGreen}"
local _dir_fg="${PROMPT_COLOR_DIR_FG:-$ICyan}" local _dir_fg="${PROMPT_COLOR_DIR_FG:-$ICyan}"
# Begin with time # Begin with time (cursor-save is non-printing; all ANSI sequences wrapped
PS1="\[\e[s${_time_fg}${_time_bg} [ \t ] ${_bar_bg}" # in \[...\] so bash does not count them toward the visible line width).
# Every fg colour is combined with its section bg in the same \[...\] block
# so that even "reset" colours (0;Xm) cannot strip the background.
PS1="\[\e[s\]\[${_time_fg}${_time_bg}\] [ \t ] \[${_bar_bg}\]"
# Add exit status of the last command. # Add exit status of the last command.
# If it was successful, print a green check mark. Otherwise, print a red X. # If it was successful, print a green check mark. Otherwise, print a red X.
if [[ $Last_Command == 0 ]]; then if [[ $Last_Command == 0 ]]; then
PS1+="${_ok_fg}${_bar_bg} [ \$Last_Command " PS1+="\[${_ok_fg}${_bar_bg}\] [ $Last_Command "
PS1+="${_ok_mark}${Checkmark} " PS1+="\[${_ok_mark}${_bar_bg}\]${Checkmark} "
# Add the elapsed time, then close the status section and return to bar bg.
timer_stop
PS1+="($timer_show)\[${_ok_fg}${_bar_bg}\] ] "
else else
PS1+="${_err_fg}${_err_bg} [ \$Last_Command " PS1+="\[${_err_fg}${_err_bg}\] [ $Last_Command "
PS1+="${_err_mark}${FancyX} " PS1+="\[${_err_mark}${_err_bg}\]${FancyX} "
timer_stop
PS1+="($timer_show)\[${_err_fg}${_err_bg}\] ] "
fi fi
# Add the elapsed time
timer_stop
PS1+="($timer_show)${_ok_fg} ] ${_bar_bg} "
# If root, print the host in root colour. Otherwise use user colour. # If root, print the host in root colour. Otherwise use user colour.
if [[ $EUID -eq 0 ]]; then if [[ $EUID -eq 0 ]]; then
PS1+="${_root_fg}\\u${_user_fg}@\\h" PS1+="\[${_root_fg}${_bar_bg}\] \\u\[${_user_fg}${_bar_bg}\]@\\h"
else else
PS1+="${_user_fg}\\u@\\h" PS1+="\[${_user_fg}${_bar_bg}\] \\u@\\h"
fi fi
PS1+="\e[K\e[u$DEFAULTCOL\n" PS1+="\[\e[K\e[u\]\[$RESETCOL\]\n"
# Print the working directory and prompt marker, then reset colour. # Print the working directory and prompt marker, then reset colour.
PS1+="${_dir_fg}\\w \\\$$DEFAULTCOL " PS1+="\[${_dir_fg}\]\\w \\\$\[$RESETCOL\] "
} }
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------

View File

@@ -65,6 +65,7 @@ genpwd()
PARSED=$(getopt -o hsnule:L:o: --long \ PARSED=$(getopt -o hsnule:L:o: --long \
help,nosymbols,nonumbers,noup,nolow,extracars:,length:,occurences:,occurrences: \ help,nosymbols,nonumbers,noup,nolow,extracars:,length:,occurences:,occurrences: \
-n 'genpwd' -- "$@") -n 'genpwd' -- "$@")
# shellcheck disable=SC2181 # getopt return code is checked immediately after
if [[ $? -ne 0 ]]; then return 1; fi if [[ $? -ne 0 ]]; then return 1; fi
eval set -- "$PARSED" eval set -- "$PARSED"

View File

@@ -44,6 +44,7 @@ rmhost()
local -a known_hosts_files=() local -a known_hosts_files=()
PARSED=$(getopt -o ha --long help,all-users -n 'rmhost' -- "$@") PARSED=$(getopt -o ha --long help,all-users -n 'rmhost' -- "$@")
# shellcheck disable=SC2181 # getopt return code is checked immediately after
if [[ $? -ne 0 ]]; then return 1; fi if [[ $? -ne 0 ]]; then return 1; fi
eval set -- "$PARSED" eval set -- "$PARSED"
@@ -194,6 +195,7 @@ ssr()
ssh_default_opts=(-Y) ssh_default_opts=(-Y)
fi fi
# shellcheck disable=SC2029
ssh "${ssh_default_opts[@]}" root@"$srv" "$@" ssh "${ssh_default_opts[@]}" root@"$srv" "$@"
} }
export -f ssr export -f ssr

84
profile.d/themes/abyss.theme Executable file → Normal file
View File

@@ -1,42 +1,42 @@
# Abyss prompt theme — deep ocean navy, electric teal, golden accents # Abyss prompt theme — deep ocean navy, electric teal, golden accents
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
# Theme files are NOT executed as shell scripts. load_theme() parses them # Theme files are NOT executed as shell scripts. load_theme() parses them
# line by line. Only the following value forms are accepted: # line by line. Only the following value forms are accepted:
# #
# KEY="$ColorVarName" — reference to a colour variable from disp.sh # KEY="$ColorVarName" — reference to a colour variable from disp.sh
# KEY="${ColorVarName}" — same with braces # KEY="${ColorVarName}" — same with braces
# KEY="\e[...m" — raw ANSI escape sequence (single block) # KEY="\e[...m" — raw ANSI escape sequence (single block)
# #
# Accepted keys: # Accepted keys:
# PROMPT_COLOR_* — prompt slot colours (see profile.conf [prompt]) # PROMPT_COLOR_* — prompt slot colours (see profile.conf [prompt])
# Standard colour vars — Black, Blue, On_IBlack, … (overrides the palette # Standard colour vars — Black, Blue, On_IBlack, … (overrides the palette
# from disp.sh for the whole shell session) # from disp.sh for the whole shell session)
# #
# Any unknown key, unsafe value, or shell construct will be ignored with a # Any unknown key, unsafe value, or shell construct will be ignored with a
# warning — theme files cannot execute code. # warning — theme files cannot execute code.
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
# Inspired by the VS Code "Abyss" theme: deep navy/black backdrop, electric # Inspired by the VS Code "Abyss" theme: deep navy/black backdrop, electric
# teal highlights, golden-yellow accents, cool electric blue for identifiers. # teal highlights, golden-yellow accents, cool electric blue for identifiers.
# Palette overrides shift the cooler hues to their high-intensity (electric) # Palette overrides shift the cooler hues to their high-intensity (electric)
# equivalents — blue becomes IBlue, green shifts toward teal (ICyan). # equivalents — blue becomes IBlue, green shifts toward teal (ICyan).
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
# Palette overrides — shift colours toward cool electric hues # Palette overrides — shift colours toward cool electric hues
Blue="\e[0;94m" # electric blue (IBlue — abyss identifier colour) Blue="\e[0;94m" # electric blue (IBlue — abyss identifier colour)
Green="\e[0;96m" # teal (ICyan — abyss string colour) Green="\e[0;96m" # teal (ICyan — abyss string colour)
Yellow="\e[0;93m" # bright gold (IYellow — abyss constant colour) Yellow="\e[0;93m" # bright gold (IYellow — abyss constant colour)
PROMPT_COLOR_TIME_FG="$ICyan" # electric teal clock PROMPT_COLOR_TIME_FG="$ICyan" # electric teal clock
PROMPT_COLOR_TIME_BG="$On_Black" # deep black background PROMPT_COLOR_TIME_BG="\e[48;2;0;60;70m" # very dark cyan bg for time
PROMPT_COLOR_BAR_BG="$On_Blue" # deep blue bar PROMPT_COLOR_BAR_BG="\e[48;2;0;30;70m" # deep navy bar (24-bit)
PROMPT_COLOR_OK_FG="$ICyan" # teal on success PROMPT_COLOR_OK_FG="$ICyan" # teal on success
PROMPT_COLOR_OK_MARK="$IGreen" # bright teal-green checkmark PROMPT_COLOR_OK_MARK="$IGreen" # bright teal-green checkmark
PROMPT_COLOR_ERR_BG="$On_Red" # red background on failure PROMPT_COLOR_ERR_BG="\e[48;2;180;20;20m" # vivid crimson background (24-bit)
PROMPT_COLOR_ERR_FG="$IWhite" # bright white text PROMPT_COLOR_ERR_FG="\e[1;97m" # bold bright white — maximum contrast
PROMPT_COLOR_ERR_MARK="$IYellow" # golden X PROMPT_COLOR_ERR_MARK="$IYellow" # golden X
PROMPT_COLOR_ROOT_FG="$IRed" # red for root PROMPT_COLOR_ROOT_FG="$IRed" # red for root
PROMPT_COLOR_USER_FG="$IBlue" # electric blue for user PROMPT_COLOR_USER_FG="$IBlue" # electric blue for user
PROMPT_COLOR_DIR_FG="$ICyan" # teal path PROMPT_COLOR_DIR_FG="$ICyan" # teal path

84
profile.d/themes/adwaita.theme Executable file → Normal file
View File

@@ -1,42 +1,42 @@
# Adwaita prompt theme — clean GNOME defaults, blue accent, green/red status # Adwaita prompt theme — clean GNOME defaults, blue accent, green/red status
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
# Theme files are NOT executed as shell scripts. load_theme() parses them # Theme files are NOT executed as shell scripts. load_theme() parses them
# line by line. Only the following value forms are accepted: # line by line. Only the following value forms are accepted:
# #
# KEY="$ColorVarName" — reference to a colour variable from disp.sh # KEY="$ColorVarName" — reference to a colour variable from disp.sh
# KEY="${ColorVarName}" — same with braces # KEY="${ColorVarName}" — same with braces
# KEY="\e[...m" — raw ANSI escape sequence (single block) # KEY="\e[...m" — raw ANSI escape sequence (single block)
# #
# Accepted keys: # Accepted keys:
# PROMPT_COLOR_* — prompt slot colours (see profile.conf [prompt]) # PROMPT_COLOR_* — prompt slot colours (see profile.conf [prompt])
# Standard colour vars — Black, Blue, On_IBlack, … (overrides the palette # Standard colour vars — Black, Blue, On_IBlack, … (overrides the palette
# from disp.sh for the whole shell session) # from disp.sh for the whole shell session)
# #
# Any unknown key, unsafe value, or shell construct will be ignored with a # Any unknown key, unsafe value, or shell construct will be ignored with a
# warning — theme files cannot execute code. # warning — theme files cannot execute code.
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
# Follows the GNOME HIG colour intent: a single calm blue accent (#3584e4), # Follows the GNOME HIG colour intent: a single calm blue accent (#3584e4),
# pleasant green for success (#33d17a), clear red for errors (#e01b24). # pleasant green for success (#33d17a), clear red for errors (#e01b24).
# No intense saturation, no heavy remapping — legibility over spectacle. # No intense saturation, no heavy remapping — legibility over spectacle.
# Palette overrides gently shift Blue and Green to their IBlue/IGreen # Palette overrides gently shift Blue and Green to their IBlue/IGreen
# variants to better match Adwaita's brighter, flatter tones. # variants to better match Adwaita's brighter, flatter tones.
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
# Palette overrides — align to Adwaita's brighter accent tones # Palette overrides — align to Adwaita's brighter accent tones
Blue="\e[0;94m" # IBlue → closer to Adwaita blue (#3584e4) Blue="\e[0;94m" # IBlue → closer to Adwaita blue (#3584e4)
Green="\e[0;92m" # IGreen → closer to Adwaita green (#33d17a) Green="\e[0;92m" # IGreen → closer to Adwaita green (#33d17a)
PROMPT_COLOR_TIME_FG="$Cyan" # calm cyan clock text PROMPT_COLOR_TIME_FG="$Cyan" # calm cyan clock text
PROMPT_COLOR_TIME_BG="$On_IBlack" # dark grey clock background PROMPT_COLOR_TIME_BG="$On_IBlack" # dark grey clock background
PROMPT_COLOR_BAR_BG="$On_Blue" # blue main bar (Adwaita accent) PROMPT_COLOR_BAR_BG="$On_Blue" # blue main bar (Adwaita accent)
PROMPT_COLOR_OK_FG="$White" # clean white on success PROMPT_COLOR_OK_FG="$White" # clean white on success
PROMPT_COLOR_OK_MARK="$Green" # Adwaita green checkmark PROMPT_COLOR_OK_MARK="$Green" # Adwaita green checkmark
PROMPT_COLOR_ERR_BG="$On_Red" # Adwaita red on failure PROMPT_COLOR_ERR_BG="$On_Red" # Adwaita red on failure
PROMPT_COLOR_ERR_FG="$White" # white text PROMPT_COLOR_ERR_FG="$BIWhite" # bold bright white for maximum legibility
PROMPT_COLOR_ERR_MARK="$Yellow" # yellow X (warning intent) PROMPT_COLOR_ERR_MARK="$Yellow" # yellow X (warning intent)
PROMPT_COLOR_ROOT_FG="$Red" # Adwaita red for root PROMPT_COLOR_ROOT_FG="$Red" # Adwaita red for root
PROMPT_COLOR_USER_FG="$IBlue" # Adwaita blue for user PROMPT_COLOR_USER_FG="$BBlue" # darker bold blue — readable on blue bar
PROMPT_COLOR_DIR_FG="$IGreen" # Adwaita green for path PROMPT_COLOR_DIR_FG="$IGreen" # Adwaita green for path

64
profile.d/themes/dark.theme Executable file → Normal file
View File

@@ -1,32 +1,32 @@
# Dark prompt theme — dark grey bar, cyan user, magenta path # Dark prompt theme — dark grey bar, cyan user, magenta path
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
# Theme files are NOT executed as shell scripts. load_theme() parses them # Theme files are NOT executed as shell scripts. load_theme() parses them
# line by line. Only the following value forms are accepted: # line by line. Only the following value forms are accepted:
# #
# KEY="$ColorVarName" — reference to a colour variable from disp.sh # KEY="$ColorVarName" — reference to a colour variable from disp.sh
# KEY="${ColorVarName}" — same with braces # KEY="${ColorVarName}" — same with braces
# KEY="\e[...m" — raw ANSI escape sequence (single block) # KEY="\e[...m" — raw ANSI escape sequence (single block)
# #
# Accepted keys: # Accepted keys:
# PROMPT_COLOR_* — prompt slot colours (see profile.conf [prompt]) # PROMPT_COLOR_* — prompt slot colours (see profile.conf [prompt])
# Standard colour vars — Black, Blue, On_IBlack, … (overrides the palette # Standard colour vars — Black, Blue, On_IBlack, … (overrides the palette
# from disp.sh for the whole shell session) # from disp.sh for the whole shell session)
# #
# Any unknown key, unsafe value, or shell construct will be ignored with a # Any unknown key, unsafe value, or shell construct will be ignored with a
# warning — theme files cannot execute code. # warning — theme files cannot execute code.
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
PROMPT_COLOR_TIME_FG="$ICyan" # Clock text PROMPT_COLOR_TIME_FG="$ICyan" # Clock text
PROMPT_COLOR_TIME_BG="$On_Black" # Clock background (black) PROMPT_COLOR_TIME_BG="$On_IBlack" # Clock background (black)
PROMPT_COLOR_BAR_BG="$On_IBlack" # Main bar background (dark grey) PROMPT_COLOR_BAR_BG="$On_Black" # Main bar background (dark grey)
PROMPT_COLOR_OK_FG="$IGreen" # Exit-code text on success PROMPT_COLOR_OK_FG="$IGreen" # Exit-code text on success
PROMPT_COLOR_OK_MARK="$BGreen" # Checkmark colour on success PROMPT_COLOR_OK_MARK="$BGreen" # Checkmark colour on success
PROMPT_COLOR_ERR_BG="$On_Red" # Exit-code background on failure PROMPT_COLOR_ERR_BG="$On_Red" # Exit-code background on failure
PROMPT_COLOR_ERR_FG="$BIWhite" # Exit-code text on failure PROMPT_COLOR_ERR_FG="$BIWhite" # Exit-code text on failure
PROMPT_COLOR_ERR_MARK="$BIYellow" # X mark colour on failure PROMPT_COLOR_ERR_MARK="$BIYellow" # X mark colour on failure
PROMPT_COLOR_ROOT_FG="$BIRed" # Username colour when root PROMPT_COLOR_ROOT_FG="$BIRed" # Username colour when root
PROMPT_COLOR_USER_FG="$ICyan" # Username@host colour for normal users PROMPT_COLOR_USER_FG="$ICyan" # Username@host colour for normal users
PROMPT_COLOR_DIR_FG="$IPurple" # Working directory colour PROMPT_COLOR_DIR_FG="$IPurple" # Working directory colour

64
profile.d/themes/default.theme Executable file → Normal file
View File

@@ -1,32 +1,32 @@
# Default prompt theme — blue bar, green user, cyan path # Default prompt theme — blue bar, green user, cyan path
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
# Theme files are NOT executed as shell scripts. load_theme() parses them # Theme files are NOT executed as shell scripts. load_theme() parses them
# line by line. Only the following value forms are accepted: # line by line. Only the following value forms are accepted:
# #
# KEY="$ColorVarName" — reference to a colour variable from disp.sh # KEY="$ColorVarName" — reference to a colour variable from disp.sh
# KEY="${ColorVarName}" — same with braces # KEY="${ColorVarName}" — same with braces
# KEY="\e[...m" — raw ANSI escape sequence (single block) # KEY="\e[...m" — raw ANSI escape sequence (single block)
# #
# Accepted keys: # Accepted keys:
# PROMPT_COLOR_* — prompt slot colours (see profile.conf [prompt]) # PROMPT_COLOR_* — prompt slot colours (see profile.conf [prompt])
# Standard colour vars — Black, Blue, On_IBlack, … (overrides the palette # Standard colour vars — Black, Blue, On_IBlack, … (overrides the palette
# from disp.sh for the whole shell session) # from disp.sh for the whole shell session)
# #
# Any unknown key, unsafe value, or shell construct will be ignored with a # Any unknown key, unsafe value, or shell construct will be ignored with a
# warning — theme files cannot execute code. # warning — theme files cannot execute code.
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
PROMPT_COLOR_TIME_FG="$Blue" # Clock text PROMPT_COLOR_TIME_FG="$Blue" # Clock text
PROMPT_COLOR_TIME_BG="$On_IBlack" # Clock background (dark grey) PROMPT_COLOR_TIME_BG="$On_White" # Clock background (dark grey)
PROMPT_COLOR_BAR_BG="$On_Blue" # Main bar background PROMPT_COLOR_BAR_BG="$On_Blue" # Main bar background
PROMPT_COLOR_OK_FG="$White" # Exit-code text on success PROMPT_COLOR_OK_FG="$White" # Exit-code text on success
PROMPT_COLOR_OK_MARK="$Green" # Checkmark colour on success PROMPT_COLOR_OK_MARK="$Green" # Checkmark colour on success
PROMPT_COLOR_ERR_BG="$On_Red" # Exit-code background on failure PROMPT_COLOR_ERR_BG="$On_Red" # Exit-code background on failure
PROMPT_COLOR_ERR_FG="$White" # Exit-code text on failure PROMPT_COLOR_ERR_FG="$White" # Exit-code text on failure
PROMPT_COLOR_ERR_MARK="$BYellow" # X mark colour on failure PROMPT_COLOR_ERR_MARK="$BYellow" # X mark colour on failure
PROMPT_COLOR_ROOT_FG="$Red" # Username colour when root PROMPT_COLOR_ROOT_FG="$Red" # Username colour when root
PROMPT_COLOR_USER_FG="$Green" # Username@host colour for normal users PROMPT_COLOR_USER_FG="$Green" # Username@host colour for normal users
PROMPT_COLOR_DIR_FG="$ICyan" # Working directory colour PROMPT_COLOR_DIR_FG="$ICyan" # Working directory colour

70
profile.d/themes/light.theme Executable file → Normal file
View File

@@ -1,35 +1,35 @@
# Light prompt theme — white bar, blue user, purple path # Light prompt theme — white bar, blue user, purple path
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
# Theme files are NOT executed as shell scripts. load_theme() parses them # Theme files are NOT executed as shell scripts. load_theme() parses them
# line by line. Only the following value forms are accepted: # line by line. Only the following value forms are accepted:
# #
# KEY="$ColorVarName" — reference to a colour variable from disp.sh # KEY="$ColorVarName" — reference to a colour variable from disp.sh
# KEY="${ColorVarName}" — same with braces # KEY="${ColorVarName}" — same with braces
# KEY="\e[...m" — raw ANSI escape sequence (single block) # KEY="\e[...m" — raw ANSI escape sequence (single block)
# #
# Accepted keys: # Accepted keys:
# PROMPT_COLOR_* — prompt slot colours (see profile.conf [prompt]) # PROMPT_COLOR_* — prompt slot colours (see profile.conf [prompt])
# Standard colour vars — Black, Blue, On_IBlack, … (overrides the palette # Standard colour vars — Black, Blue, On_IBlack, … (overrides the palette
# from disp.sh for the whole shell session) # from disp.sh for the whole shell session)
# #
# Any unknown key, unsafe value, or shell construct will be ignored with a # Any unknown key, unsafe value, or shell construct will be ignored with a
# warning — theme files cannot execute code. # warning — theme files cannot execute code.
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
# Opposite of dark.theme: backgrounds flip to bright whites, foregrounds # Opposite of dark.theme: backgrounds flip to bright whites, foregrounds
# shift to their dark/regular equivalents for contrast on a light terminal. # shift to their dark/regular equivalents for contrast on a light terminal.
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
PROMPT_COLOR_TIME_FG="$Blue" # Clock text (ICyan → Blue, darker for light bg) PROMPT_COLOR_TIME_FG="$BBlack" # Clock text (bold black — forces true black on terminals that render Black as dark grey)
PROMPT_COLOR_TIME_BG="$On_IWhite" # Clock background (On_Black → On_IWhite) PROMPT_COLOR_TIME_BG="$On_IWhite" # Clock background (On_Black → On_IWhite)
PROMPT_COLOR_BAR_BG="$On_White" # Main bar background (On_IBlack → On_White) PROMPT_COLOR_BAR_BG="$On_White" # Main bar background (On_IBlack → On_White)
PROMPT_COLOR_OK_FG="$Green" # Exit-code text on success (IGreen → Green) PROMPT_COLOR_OK_FG="$Green" # Exit-code text on success (IGreen → Green)
PROMPT_COLOR_OK_MARK="$BGreen" # Checkmark colour on success (unchanged — bold green reads on both) PROMPT_COLOR_OK_MARK="$BGreen" # Checkmark colour on success (unchanged — bold green reads on both)
PROMPT_COLOR_ERR_BG="$On_Red" # Exit-code background on failure (unchanged) PROMPT_COLOR_ERR_BG="$On_Red" # Exit-code background on failure (unchanged)
PROMPT_COLOR_ERR_FG="$BIWhite" # Exit-code text on failure (unchanged — white on red works on both) PROMPT_COLOR_ERR_FG="$BIWhite" # Exit-code text on failure (unchanged — white on red works on both)
PROMPT_COLOR_ERR_MARK="$BYellow" # X mark on failure (BIYellow → BYellow, less glaring on light) PROMPT_COLOR_ERR_MARK="$BYellow" # X mark on failure (BIYellow → BYellow, less glaring on light)
PROMPT_COLOR_ROOT_FG="$Red" # Username when root (BIRed → Red) PROMPT_COLOR_ROOT_FG="$Red" # Username when root (BIRed → Red)
PROMPT_COLOR_USER_FG="$Blue" # Username@host normal user (ICyan → Blue) PROMPT_COLOR_USER_FG="$Blue" # Username@host normal user (ICyan → Blue)
PROMPT_COLOR_DIR_FG="$Purple" # Working directory (IPurple → Purple) PROMPT_COLOR_DIR_FG="$Purple" # Working directory (IPurple → Purple)

128
profile.d/themes/monochrome.theme Executable file → Normal file
View File

@@ -1,64 +1,64 @@
# Monochrome prompt theme — strict greyscale, no hue at all # Monochrome prompt theme — strict greyscale, no hue at all
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
# Theme files are NOT executed as shell scripts. load_theme() parses them # Theme files are NOT executed as shell scripts. load_theme() parses them
# line by line. Only the following value forms are accepted: # line by line. Only the following value forms are accepted:
# #
# KEY="$ColorVarName" — reference to a colour variable from disp.sh # KEY="$ColorVarName" — reference to a colour variable from disp.sh
# KEY="${ColorVarName}" — same with braces # KEY="${ColorVarName}" — same with braces
# KEY="\e[...m" — raw ANSI escape sequence (single block) # KEY="\e[...m" — raw ANSI escape sequence (single block)
# #
# Accepted keys: # Accepted keys:
# PROMPT_COLOR_* — prompt slot colours (see profile.conf [prompt]) # PROMPT_COLOR_* — prompt slot colours (see profile.conf [prompt])
# Standard colour vars — Black, Blue, On_IBlack, … (overrides the palette # Standard colour vars — Black, Blue, On_IBlack, … (overrides the palette
# from disp.sh for the whole shell session) # from disp.sh for the whole shell session)
# #
# Any unknown key, unsafe value, or shell construct will be ignored with a # Any unknown key, unsafe value, or shell construct will be ignored with a
# warning — theme files cannot execute code. # warning — theme files cannot execute code.
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
# All hues are silenced — colour variables are remapped to greyscale ANSI # All hues are silenced — colour variables are remapped to greyscale ANSI
# codes so that ls, man, grep, etc. also lose their colour cues. Contrast # codes so that ls, man, grep, etc. also lose their colour cues. Contrast
# is achieved entirely through brightness: dark grey / light grey / white. # is achieved entirely through brightness: dark grey / light grey / white.
# Error state uses an inverted (white background, black text) bar so it # Error state uses an inverted (white background, black text) bar so it
# remains visually distinct without relying on red. # remains visually distinct without relying on red.
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
# Palette overrides — replace every hue with a grey equivalent # Palette overrides — replace every hue with a grey equivalent
Red="\e[0;37m" # light grey Red="\e[0;37m" # light grey
Green="\e[0;97m" # bright white (success intent kept as brightest) Green="\e[0;97m" # bright white (success intent kept as brightest)
Yellow="\e[0;90m" # dark grey Yellow="\e[0;90m" # dark grey
Blue="\e[0;90m" # dark grey Blue="\e[0;90m" # dark grey
Purple="\e[0;37m" # light grey Purple="\e[0;37m" # light grey
Cyan="\e[0;37m" # light grey Cyan="\e[0;37m" # light grey
BRed="\e[1;37m" # bold light grey BRed="\e[1;37m" # bold light grey
BGreen="\e[1;97m" # bold bright white BGreen="\e[1;97m" # bold bright white
BYellow="\e[1;90m" # bold dark grey BYellow="\e[1;90m" # bold dark grey
BBlue="\e[1;90m" # bold dark grey BBlue="\e[1;90m" # bold dark grey
BPurple="\e[1;37m" # bold light grey BPurple="\e[1;37m" # bold light grey
BCyan="\e[1;37m" # bold light grey BCyan="\e[1;37m" # bold light grey
IRed="\e[0;97m" # bright white IRed="\e[0;97m" # bright white
IGreen="\e[0;97m" # bright white IGreen="\e[0;97m" # bright white
IYellow="\e[0;90m" # dark grey IYellow="\e[0;90m" # dark grey
IBlue="\e[0;90m" # dark grey IBlue="\e[0;90m" # dark grey
IPurple="\e[0;37m" # light grey IPurple="\e[0;37m" # light grey
ICyan="\e[0;37m" # light grey ICyan="\e[0;37m" # light grey
BIRed="\e[1;97m" # bold bright white BIRed="\e[1;97m" # bold bright white
BIGreen="\e[1;97m" # bold bright white BIGreen="\e[1;97m" # bold bright white
BIYellow="\e[1;90m" # bold dark grey BIYellow="\e[1;90m" # bold dark grey
BIBlue="\e[1;90m" # bold dark grey BIBlue="\e[1;90m" # bold dark grey
BIPurple="\e[1;37m" # bold light grey BIPurple="\e[1;37m" # bold light grey
BICyan="\e[1;37m" # bold light grey BICyan="\e[1;37m" # bold light grey
PROMPT_COLOR_TIME_FG="$IBlack" # dark grey clock text (subtle) PROMPT_COLOR_TIME_FG="$IBlack" # dark grey clock text (subtle)
PROMPT_COLOR_TIME_BG="$On_IBlack" # dark grey clock background PROMPT_COLOR_TIME_BG="$On_IBlack" # dark grey clock background
PROMPT_COLOR_BAR_BG="$On_IBlack" # dark grey main bar PROMPT_COLOR_BAR_BG="$On_IBlack" # dark grey main bar
PROMPT_COLOR_OK_FG="$IWhite" # bright white on success PROMPT_COLOR_OK_FG="$IWhite" # bright white on success
PROMPT_COLOR_OK_MARK="$BIWhite" # bold bright white checkmark PROMPT_COLOR_OK_MARK="$BIWhite" # bold bright white checkmark
PROMPT_COLOR_ERR_BG="$On_White" # inverted: bright white bar on error PROMPT_COLOR_ERR_BG="$On_White" # inverted: bright white bar on error
PROMPT_COLOR_ERR_FG="$Black" # black text on white background PROMPT_COLOR_ERR_FG="$Black" # black text on white background
PROMPT_COLOR_ERR_MARK="$BBlack" # bold black X PROMPT_COLOR_ERR_MARK="$BBlack" # bold black X
PROMPT_COLOR_ROOT_FG="$BIWhite" # bold bright white for root warning PROMPT_COLOR_ROOT_FG="$BIWhite" # bold bright white for root warning
PROMPT_COLOR_USER_FG="$IWhite" # bright white for normal user PROMPT_COLOR_USER_FG="$IWhite" # bright white for normal user
PROMPT_COLOR_DIR_FG="$White" # standard white for path PROMPT_COLOR_DIR_FG="$White" # standard white for path

90
profile.d/themes/monokai.theme Executable file → Normal file
View File

@@ -1,45 +1,45 @@
# Monokai prompt theme — high-saturation, vivid hues on near-black # Monokai prompt theme — high-saturation, vivid hues on near-black
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
# Theme files are NOT executed as shell scripts. load_theme() parses them # Theme files are NOT executed as shell scripts. load_theme() parses them
# line by line. Only the following value forms are accepted: # line by line. Only the following value forms are accepted:
# #
# KEY="$ColorVarName" — reference to a colour variable from disp.sh # KEY="$ColorVarName" — reference to a colour variable from disp.sh
# KEY="${ColorVarName}" — same with braces # KEY="${ColorVarName}" — same with braces
# KEY="\e[...m" — raw ANSI escape sequence (single block) # KEY="\e[...m" — raw ANSI escape sequence (single block)
# #
# Accepted keys: # Accepted keys:
# PROMPT_COLOR_* — prompt slot colours (see profile.conf [prompt]) # PROMPT_COLOR_* — prompt slot colours (see profile.conf [prompt])
# Standard colour vars — Black, Blue, On_IBlack, … (overrides the palette # Standard colour vars — Black, Blue, On_IBlack, … (overrides the palette
# from disp.sh for the whole shell session) # from disp.sh for the whole shell session)
# #
# Any unknown key, unsafe value, or shell construct will be ignored with a # Any unknown key, unsafe value, or shell construct will be ignored with a
# warning — theme files cannot execute code. # warning — theme files cannot execute code.
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
# Monokai's signature: lime green, orange-yellow, hot pink/red, bright violet, # Monokai's signature: lime green, orange-yellow, hot pink/red, bright violet,
# electric cyan — all on a near-black (#272822) background. # electric cyan — all on a near-black (#272822) background.
# Palette overrides remap the dim ANSI regulars to their vivid high-intensity # Palette overrides remap the dim ANSI regulars to their vivid high-intensity
# equivalents so that ls, grep colour output, etc. also look more "Monokai". # equivalents so that ls, grep colour output, etc. also look more "Monokai".
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
# Palette overrides — boost regular colours to Monokai-vivid equivalents # Palette overrides — boost regular colours to Monokai-vivid equivalents
Red="\e[0;91m" # hot pink/red (#F92672) Red="\e[0;91m" # hot pink/red (#F92672)
Green="\e[0;92m" # lime green (#A6E22E) Green="\e[0;92m" # lime green (#A6E22E)
Yellow="\e[0;93m" # orange-yellow (#E6DB74 / #FD971F) Yellow="\e[0;93m" # orange-yellow (#E6DB74 / #FD971F)
Blue="\e[0;94m" # electric blue (#66D9E8 → shift blue) Blue="\e[0;94m" # electric blue (#66D9E8 → shift blue)
Purple="\e[0;95m" # bright violet (#AE81FF) Purple="\e[0;95m" # bright violet (#AE81FF)
Cyan="\e[0;96m" # electric cyan (#66D9E8) Cyan="\e[0;96m" # electric cyan (#66D9E8)
PROMPT_COLOR_TIME_FG="$IYellow" # orange clock text PROMPT_COLOR_TIME_FG="$IYellow" # orange clock text
PROMPT_COLOR_TIME_BG="$On_IBlack" # near-black Monokai background PROMPT_COLOR_TIME_BG="$On_IBlack" # near-black Monokai background
PROMPT_COLOR_BAR_BG="$On_IBlack" # flat dark bar PROMPT_COLOR_BAR_BG="$On_IBlack" # flat dark bar
PROMPT_COLOR_OK_FG="$IGreen" # lime green on success PROMPT_COLOR_OK_FG="$IGreen" # lime green on success
PROMPT_COLOR_OK_MARK="$IGreen" # lime green checkmark PROMPT_COLOR_OK_MARK="$IGreen" # lime green checkmark
PROMPT_COLOR_ERR_BG="$On_IBlack" # keep dark — use colour for contrast PROMPT_COLOR_ERR_BG="$On_IBlack" # keep dark — use colour for contrast
PROMPT_COLOR_ERR_FG="$IRed" # hot pink on failure PROMPT_COLOR_ERR_FG="$IRed" # hot pink on failure
PROMPT_COLOR_ERR_MARK="$IRed" # hot pink X PROMPT_COLOR_ERR_MARK="$IRed" # hot pink X
PROMPT_COLOR_ROOT_FG="$IRed" # hot pink for root PROMPT_COLOR_ROOT_FG="$IRed" # hot pink for root
PROMPT_COLOR_USER_FG="$IYellow" # orange-yellow for user PROMPT_COLOR_USER_FG="$IYellow" # orange-yellow for user
PROMPT_COLOR_DIR_FG="$ICyan" # electric cyan for path PROMPT_COLOR_DIR_FG="$ICyan" # electric cyan for path

84
profile.d/themes/plasma.theme Executable file → Normal file
View File

@@ -1,42 +1,42 @@
# Plasma prompt theme — vivid KDE Plasma purples and electric cyan # Plasma prompt theme — vivid KDE Plasma purples and electric cyan
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
# Theme files are NOT executed as shell scripts. load_theme() parses them # Theme files are NOT executed as shell scripts. load_theme() parses them
# line by line. Only the following value forms are accepted: # line by line. Only the following value forms are accepted:
# #
# KEY="$ColorVarName" — reference to a colour variable from disp.sh # KEY="$ColorVarName" — reference to a colour variable from disp.sh
# KEY="${ColorVarName}" — same with braces # KEY="${ColorVarName}" — same with braces
# KEY="\e[...m" — raw ANSI escape sequence (single block) # KEY="\e[...m" — raw ANSI escape sequence (single block)
# #
# Accepted keys: # Accepted keys:
# PROMPT_COLOR_* — prompt slot colours (see profile.conf [prompt]) # PROMPT_COLOR_* — prompt slot colours (see profile.conf [prompt])
# Standard colour vars — Black, Blue, On_IBlack, … (overrides the palette # Standard colour vars — Black, Blue, On_IBlack, … (overrides the palette
# from disp.sh for the whole shell session) # from disp.sh for the whole shell session)
# #
# Any unknown key, unsafe value, or shell construct will be ignored with a # Any unknown key, unsafe value, or shell construct will be ignored with a
# warning — theme files cannot execute code. # warning — theme files cannot execute code.
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
# Captures the charged, vivid energy of KDE Plasma: dominant bright magenta/ # Captures the charged, vivid energy of KDE Plasma: dominant bright magenta/
# purple, electric cyan highlights, all on a dark background. Palette overrides # purple, electric cyan highlights, all on a dark background. Palette overrides
# boost Blue, Purple, and Cyan to their high-intensity equivalents so that # boost Blue, Purple, and Cyan to their high-intensity equivalents so that
# shell colour output reflects the same vivid palette. # shell colour output reflects the same vivid palette.
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
# Palette overrides — vivid charged hues # Palette overrides — vivid charged hues
Blue="\e[0;94m" # electric blue (IBlue) Blue="\e[0;94m" # electric blue (IBlue)
Purple="\e[0;95m" # vivid magenta (IPurple — Plasma's signature colour) Purple="\e[0;95m" # vivid magenta (IPurple — Plasma's signature colour)
Cyan="\e[0;96m" # electric cyan (ICyan) Cyan="\e[0;96m" # electric cyan (ICyan)
PROMPT_COLOR_TIME_FG="$IPurple" # vivid purple clock text PROMPT_COLOR_TIME_FG="$BIPurple" # vivid purple clock text
PROMPT_COLOR_TIME_BG="$On_IBlack" # dark grey background PROMPT_COLOR_TIME_BG="\e[48;2;50;50;55m" # deep charcoal (darker than On_IBlack)
PROMPT_COLOR_BAR_BG="$On_Purple" # bright magenta bar PROMPT_COLOR_BAR_BG="\e[48;2;75;0;130m" # deep indigo-purple (24-bit) — darker than On_Purple
PROMPT_COLOR_OK_FG="$ICyan" # electric cyan on success PROMPT_COLOR_OK_FG="$ICyan" # electric cyan on success
PROMPT_COLOR_OK_MARK="$IGreen" # green checkmark PROMPT_COLOR_OK_MARK="$IGreen" # green checkmark
PROMPT_COLOR_ERR_BG="$On_Red" # red bar on failure PROMPT_COLOR_ERR_BG="$On_Red" # red bar on failure
PROMPT_COLOR_ERR_FG="$IWhite" # bright white text PROMPT_COLOR_ERR_FG="$IWhite" # bright white text
PROMPT_COLOR_ERR_MARK="$IYellow" # yellow X PROMPT_COLOR_ERR_MARK="$IYellow" # yellow X
PROMPT_COLOR_ROOT_FG="$IRed" # red for root PROMPT_COLOR_ROOT_FG="$IRed" # red for root
PROMPT_COLOR_USER_FG="$BIPurple" # bold vivid purple for user PROMPT_COLOR_USER_FG="$BIPurple" # bold vivid purple for user
PROMPT_COLOR_DIR_FG="$ICyan" # electric cyan path PROMPT_COLOR_DIR_FG="$ICyan" # electric cyan path

254
profile.d/themes/solarized-light.theme Executable file → Normal file
View File

@@ -1,127 +1,127 @@
# Solarized Light prompt theme — exact 24-bit / true-colour palette # Solarized Light prompt theme — exact 24-bit / true-colour palette
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
# Theme files are NOT executed as shell scripts. load_theme() parses them # Theme files are NOT executed as shell scripts. load_theme() parses them
# line by line. Only the following value forms are accepted: # line by line. Only the following value forms are accepted:
# #
# KEY="$ColorVarName" — reference to a colour variable from disp.sh # KEY="$ColorVarName" — reference to a colour variable from disp.sh
# KEY="${ColorVarName}" — same with braces # KEY="${ColorVarName}" — same with braces
# KEY="\e[...m" — raw ANSI escape sequence (single block) # KEY="\e[...m" — raw ANSI escape sequence (single block)
# #
# Accepted keys: # Accepted keys:
# PROMPT_COLOR_* — prompt slot colours (see profile.conf [prompt]) # PROMPT_COLOR_* — prompt slot colours (see profile.conf [prompt])
# Standard colour vars — Black, Blue, On_IBlack, … (overrides the palette # Standard colour vars — Black, Blue, On_IBlack, … (overrides the palette
# from disp.sh for the whole shell session) # from disp.sh for the whole shell session)
# #
# Any unknown key, unsafe value, or shell construct will be ignored with a # Any unknown key, unsafe value, or shell construct will be ignored with a
# warning — theme files cannot execute code. # warning — theme files cannot execute code.
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
# Requires a terminal with true-colour / 24-bit support. # Requires a terminal with true-colour / 24-bit support.
# Check with: printf '\e[38;2;220;50;47mred\e[0m\n' # Check with: printf '\e[38;2;220;50;47mred\e[0m\n'
# If you see solid red text, your terminal supports this theme. # If you see solid red text, your terminal supports this theme.
# (konsole, iTerm2, kitty, alacritty, Windows Terminal all do) # (konsole, iTerm2, kitty, alacritty, Windows Terminal all do)
# #
# Solarized Light base tones (inverted vs Dark): # Solarized Light base tones (inverted vs Dark):
# Base3 #fdf6e3 →253 246 227 (main background — lightest) # Base3 #fdf6e3 →253 246 227 (main background — lightest)
# Base2 #eee8d5 →238 232 213 (background highlights) # Base2 #eee8d5 →238 232 213 (background highlights)
# Base1 #93a1a1 →147 161 161 (comments / secondary content) # Base1 #93a1a1 →147 161 161 (comments / secondary content)
# Base0 #839496 →131 148 150 (body text — secondary) # Base0 #839496 →131 148 150 (body text — secondary)
# Base00 #657b83 →101 123 131 (body text — main on light bg) # Base00 #657b83 →101 123 131 (body text — main on light bg)
# Base01 #586e75 → 88 110 117 (emphasis) # Base01 #586e75 → 88 110 117 (emphasis)
# Base02 #073642 → 7 54 66 (darkest — used for strong contrast) # Base02 #073642 → 7 54 66 (darkest — used for strong contrast)
# #
# Accent colours are identical to Solarized Dark: # Accent colours are identical to Solarized Dark:
# Yellow #b58900 →181 137 0 # Yellow #b58900 →181 137 0
# Orange #cb4b16 →203 75 22 # Orange #cb4b16 →203 75 22
# Red #dc322f →220 50 47 # Red #dc322f →220 50 47
# Magenta #d33682 →211 54 130 # Magenta #d33682 →211 54 130
# Violet #6c71c4 →108 113 196 # Violet #6c71c4 →108 113 196
# Blue #268bd2 → 38 139 210 # Blue #268bd2 → 38 139 210
# Cyan #2aa198 → 42 161 152 # Cyan #2aa198 → 42 161 152
# Green #859900 →133 153 0 # Green #859900 →133 153 0
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
# ---- Foreground palette overrides ------------------------------------------- # ---- Foreground palette overrides -------------------------------------------
# The accent fg colours are identical to Dark — only the base/neutral roles flip. # The accent fg colours are identical to Dark — only the base/neutral roles flip.
# Regular # Regular
Black="\e[38;2;253;246;227m" # Base3 — lightest (fg on light bg = invisible; used as bg fg pair complement) Black="\e[38;2;253;246;227m" # Base3 — lightest (fg on light bg = invisible; used as bg fg pair complement)
Red="\e[38;2;220;50;47m" # Red Red="\e[38;2;220;50;47m" # Red
Green="\e[38;2;133;153;0m" # Green Green="\e[38;2;133;153;0m" # Green
Yellow="\e[38;2;181;137;0m" # Yellow — primary accent Yellow="\e[38;2;181;137;0m" # Yellow — primary accent
Blue="\e[38;2;38;139;210m" # Blue Blue="\e[38;2;38;139;210m" # Blue
Purple="\e[38;2;211;54;130m" # Magenta Purple="\e[38;2;211;54;130m" # Magenta
Cyan="\e[38;2;42;161;152m" # Cyan Cyan="\e[38;2;42;161;152m" # Cyan
White="\e[38;2;101;123;131m" # Base00 — main body text on light bg White="\e[38;2;101;123;131m" # Base00 — main body text on light bg
# Bold # Bold
BBlack="\e[1;38;2;238;232;213m" # Base2 bold BBlack="\e[1;38;2;238;232;213m" # Base2 bold
BRed="\e[1;38;2;220;50;47m" # Red bold BRed="\e[1;38;2;220;50;47m" # Red bold
BGreen="\e[1;38;2;133;153;0m" # Green bold BGreen="\e[1;38;2;133;153;0m" # Green bold
BYellow="\e[1;38;2;181;137;0m" # Yellow bold BYellow="\e[1;38;2;181;137;0m" # Yellow bold
BBlue="\e[1;38;2;38;139;210m" # Blue bold BBlue="\e[1;38;2;38;139;210m" # Blue bold
BPurple="\e[1;38;2;211;54;130m" # Magenta bold BPurple="\e[1;38;2;211;54;130m" # Magenta bold
BCyan="\e[1;38;2;42;161;152m" # Cyan bold BCyan="\e[1;38;2;42;161;152m" # Cyan bold
BWhite="\e[1;38;2;88;110;117m" # Base01 bold — emphasis text BWhite="\e[1;38;2;88;110;117m" # Base01 bold — emphasis text
# High intensity (emphasis / I* family) # High intensity (emphasis / I* family)
IBlack="\e[38;2;147;161;161m" # Base1 — secondary/comments IBlack="\e[38;2;147;161;161m" # Base1 — secondary/comments
IRed="\e[38;2;203;75;22m" # Orange — Solarized's "bright red" IRed="\e[38;2;203;75;22m" # Orange — Solarized's "bright red"
IGreen="\e[38;2;133;153;0m" # Green (no brighter variant) IGreen="\e[38;2;133;153;0m" # Green (no brighter variant)
IYellow="\e[38;2;181;137;0m" # Yellow (no brighter variant) IYellow="\e[38;2;181;137;0m" # Yellow (no brighter variant)
IBlue="\e[38;2;108;113;196m" # Violet — Solarized's "bright blue" IBlue="\e[38;2;108;113;196m" # Violet — Solarized's "bright blue"
IPurple="\e[38;2;211;54;130m" # Magenta (no brighter variant) IPurple="\e[38;2;211;54;130m" # Magenta (no brighter variant)
ICyan="\e[38;2;42;161;152m" # Cyan (no brighter variant) ICyan="\e[38;2;42;161;152m" # Cyan (no brighter variant)
IWhite="\e[38;2;88;110;117m" # Base01 — emphasis IWhite="\e[38;2;88;110;117m" # Base01 — emphasis
# Bold high intensity # Bold high intensity
BIBlack="\e[1;38;2;147;161;161m" # Base1 bold BIBlack="\e[1;38;2;147;161;161m" # Base1 bold
BIRed="\e[1;38;2;203;75;22m" # Orange bold BIRed="\e[1;38;2;203;75;22m" # Orange bold
BIGreen="\e[1;38;2;133;153;0m" # Green bold BIGreen="\e[1;38;2;133;153;0m" # Green bold
BIYellow="\e[1;38;2;181;137;0m" # Yellow bold BIYellow="\e[1;38;2;181;137;0m" # Yellow bold
BIBlue="\e[1;38;2;108;113;196m" # Violet bold BIBlue="\e[1;38;2;108;113;196m" # Violet bold
BIPurple="\e[1;38;2;211;54;130m" # Magenta bold BIPurple="\e[1;38;2;211;54;130m" # Magenta bold
BICyan="\e[1;38;2;42;161;152m" # Cyan bold BICyan="\e[1;38;2;42;161;152m" # Cyan bold
BIWhite="\e[1;38;2;88;110;117m" # Base01 bold BIWhite="\e[1;38;2;88;110;117m" # Base01 bold
# ---- Background palette overrides ------------------------------------------- # ---- Background palette overrides -------------------------------------------
# Light bases flip: On_Black → Base3 (lightest), On_IBlack → Base2 (highlights) # Light bases flip: On_Black → Base3 (lightest), On_IBlack → Base2 (highlights)
On_Black="\e[48;2;253;246;227m" # Base3 — main light background On_Black="\e[48;2;253;246;227m" # Base3 — main light background
On_Red="\e[48;2;220;50;47m" # Red On_Red="\e[48;2;220;50;47m" # Red
On_Green="\e[48;2;133;153;0m" # Green On_Green="\e[48;2;133;153;0m" # Green
On_Yellow="\e[48;2;181;137;0m" # Yellow On_Yellow="\e[48;2;181;137;0m" # Yellow
On_Blue="\e[48;2;38;139;210m" # Blue On_Blue="\e[48;2;38;139;210m" # Blue
On_Purple="\e[48;2;211;54;130m" # Magenta On_Purple="\e[48;2;211;54;130m" # Magenta
On_Cyan="\e[48;2;42;161;152m" # Cyan On_Cyan="\e[48;2;42;161;152m" # Cyan
On_White="\e[48;2;101;123;131m" # Base00 On_White="\e[48;2;101;123;131m" # Base00
On_IBlack="\e[48;2;238;232;213m" # Base2 — background highlights (slightly darker than Base3) On_IBlack="\e[48;2;238;232;213m" # Base2 — background highlights (slightly darker than Base3)
On_IRed="\e[48;2;203;75;22m" # Orange On_IRed="\e[48;2;203;75;22m" # Orange
On_IGreen="\e[48;2;133;153;0m" # Green On_IGreen="\e[48;2;133;153;0m" # Green
On_IYellow="\e[48;2;181;137;0m" # Yellow On_IYellow="\e[48;2;181;137;0m" # Yellow
On_IBlue="\e[48;2;108;113;196m" # Violet On_IBlue="\e[48;2;108;113;196m" # Violet
On_IPurple="\e[48;2;211;54;130m" # Magenta On_IPurple="\e[48;2;211;54;130m" # Magenta
On_ICyan="\e[48;2;42;161;152m" # Cyan On_ICyan="\e[48;2;42;161;152m" # Cyan
On_IWhite="\e[48;2;88;110;117m" # Base01 On_IWhite="\e[48;2;88;110;117m" # Base01
# ---- Special codes ---------------------------------------------------------- # ---- Special codes ----------------------------------------------------------
DEFAULTFG="\e[38;2;101;123;131m" # Base00 — default foreground on light bg DEFAULTFG="\e[38;2;101;123;131m" # Base00 — default foreground on light bg
DEFAULTBG="\e[48;2;253;246;227m" # Base3 — default background DEFAULTBG="\e[48;2;253;246;227m" # Base3 — default background
RESETCOL="\e[0m" RESETCOL="\e[0m"
# ---- Prompt colour slots ---------------------------------------------------- # ---- Prompt colour slots ----------------------------------------------------
# All specified as direct ANSI sequences to avoid ordering dependencies # All specified as direct ANSI sequences to avoid ordering dependencies
# with the palette overrides above. # with the palette overrides above.
PROMPT_COLOR_TIME_FG="\e[38;2;181;137;0m" # Yellow — primary accent PROMPT_COLOR_TIME_FG="\e[38;2;181;137;0m" # Yellow — primary accent
PROMPT_COLOR_TIME_BG="\e[48;2;238;232;213m" # Base2 — slightly darker than bg PROMPT_COLOR_TIME_BG="\e[48;2;238;232;213m" # Base2 — slightly darker than bg
PROMPT_COLOR_BAR_BG="\e[48;2;238;232;213m" # Base2 — warm light bar PROMPT_COLOR_BAR_BG="\e[48;2;238;232;213m" # Base2 — warm light bar
PROMPT_COLOR_OK_FG="\e[38;2;7;54;66m" # Base02 — dark text for contrast on light PROMPT_COLOR_OK_FG="\e[38;2;7;54;66m" # Base02 — dark text for contrast on light
PROMPT_COLOR_OK_MARK="\e[38;2;133;153;0m" # Green — checkmark PROMPT_COLOR_OK_MARK="\e[38;2;133;153;0m" # Green — checkmark
PROMPT_COLOR_ERR_BG="\e[48;2;220;50;47m" # Red — error background PROMPT_COLOR_ERR_BG="\e[48;2;220;50;47m" # Red — error background
PROMPT_COLOR_ERR_FG="\e[38;2;253;246;227m" # Base3 — light text on red PROMPT_COLOR_ERR_FG="\e[38;2;253;246;227m" # Base3 — light text on red
PROMPT_COLOR_ERR_MARK="\e[38;2;253;246;227m" # Base3 — X mark (bright on red) PROMPT_COLOR_ERR_MARK="\e[38;2;253;246;227m" # Base3 — X mark (bright on red)
PROMPT_COLOR_ROOT_FG="\e[38;2;220;50;47m" # Red — root warning PROMPT_COLOR_ROOT_FG="\e[38;2;220;50;47m" # Red — root warning
PROMPT_COLOR_USER_FG="\e[38;2;42;161;152m" # Cyan — normal user PROMPT_COLOR_USER_FG="\e[38;2;42;161;152m" # Cyan — normal user
PROMPT_COLOR_DIR_FG="\e[38;2;38;139;210m" # Blue — working directory PROMPT_COLOR_DIR_FG="\e[38;2;38;139;210m" # Blue — working directory

244
profile.d/themes/solarized.theme Executable file → Normal file
View File

@@ -1,122 +1,122 @@
# Solarized Dark prompt theme — exact 24-bit / true-colour palette # Solarized Dark prompt theme — exact 24-bit / true-colour palette
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
# Theme files are NOT executed as shell scripts. load_theme() parses them # Theme files are NOT executed as shell scripts. load_theme() parses them
# line by line. Only the following value forms are accepted: # line by line. Only the following value forms are accepted:
# #
# KEY="$ColorVarName" — reference to a colour variable from disp.sh # KEY="$ColorVarName" — reference to a colour variable from disp.sh
# KEY="${ColorVarName}" — same with braces # KEY="${ColorVarName}" — same with braces
# KEY="\e[...m" — raw ANSI escape sequence (single block) # KEY="\e[...m" — raw ANSI escape sequence (single block)
# #
# Accepted keys: # Accepted keys:
# PROMPT_COLOR_* — prompt slot colours (see profile.conf [prompt]) # PROMPT_COLOR_* — prompt slot colours (see profile.conf [prompt])
# Standard colour vars — Black, Blue, On_IBlack, … (overrides the palette # Standard colour vars — Black, Blue, On_IBlack, … (overrides the palette
# from disp.sh for the whole shell session) # from disp.sh for the whole shell session)
# #
# Any unknown key, unsafe value, or shell construct will be ignored with a # Any unknown key, unsafe value, or shell construct will be ignored with a
# warning — theme files cannot execute code. # warning — theme files cannot execute code.
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
# Requires a terminal with true-colour / 24-bit support. # Requires a terminal with true-colour / 24-bit support.
# Check with: printf '\e[38;2;220;50;47mred\e[0m\n' # Check with: printf '\e[38;2;220;50;47mred\e[0m\n'
# If you see solid red text, your terminal supports this theme. # If you see solid red text, your terminal supports this theme.
# (konsole, iTerm2, kitty, alacritty, Windows Terminal all do) # (konsole, iTerm2, kitty, alacritty, Windows Terminal all do)
# #
# Solarized Dark exact hex → RGB mapping used below: # Solarized Dark exact hex → RGB mapping used below:
# Base03 #002b36 → 0 43 54 (darkest background) # Base03 #002b36 → 0 43 54 (darkest background)
# Base02 #073642 → 7 54 66 (background highlights) # Base02 #073642 → 7 54 66 (background highlights)
# Base01 #586e75 → 88 110 117 (comments / secondary content) # Base01 #586e75 → 88 110 117 (comments / secondary content)
# Base00 #657b83 →101 123 131 (body text — dark background) # Base00 #657b83 →101 123 131 (body text — dark background)
# Base0 #839496 →131 148 150 (body text — main) # Base0 #839496 →131 148 150 (body text — main)
# Base1 #93a1a1 →147 161 161 (optional emphasis) # Base1 #93a1a1 →147 161 161 (optional emphasis)
# Yellow #b58900 →181 137 0 # Yellow #b58900 →181 137 0
# Orange #cb4b16 →203 75 22 # Orange #cb4b16 →203 75 22
# Red #dc322f →220 50 47 # Red #dc322f →220 50 47
# Magenta #d33682 →211 54 130 # Magenta #d33682 →211 54 130
# Violet #6c71c4 →108 113 196 # Violet #6c71c4 →108 113 196
# Blue #268bd2 → 38 139 210 # Blue #268bd2 → 38 139 210
# Cyan #2aa198 → 42 161 152 # Cyan #2aa198 → 42 161 152
# Green #859900 →133 153 0 # Green #859900 →133 153 0
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
# ---- Foreground palette overrides ------------------------------------------- # ---- Foreground palette overrides -------------------------------------------
# Regular # Regular
Black="\e[38;2;0;43;54m" # Base03 — darkest content fg Black="\e[38;2;0;43;54m" # Base03 — darkest content fg
Red="\e[38;2;220;50;47m" # Red Red="\e[38;2;220;50;47m" # Red
Green="\e[38;2;133;153;0m" # Green Green="\e[38;2;133;153;0m" # Green
Yellow="\e[38;2;181;137;0m" # Yellow — primary accent Yellow="\e[38;2;181;137;0m" # Yellow — primary accent
Blue="\e[38;2;38;139;210m" # Blue Blue="\e[38;2;38;139;210m" # Blue
Purple="\e[38;2;211;54;130m" # Magenta Purple="\e[38;2;211;54;130m" # Magenta
Cyan="\e[38;2;42;161;152m" # Cyan Cyan="\e[38;2;42;161;152m" # Cyan
White="\e[38;2;131;148;150m" # Base0 — body text White="\e[38;2;131;148;150m" # Base0 — body text
# Bold # Bold
BBlack="\e[1;38;2;7;54;66m" # Base02 bold BBlack="\e[1;38;2;7;54;66m" # Base02 bold
BRed="\e[1;38;2;220;50;47m" # Red bold BRed="\e[1;38;2;220;50;47m" # Red bold
BGreen="\e[1;38;2;133;153;0m" # Green bold BGreen="\e[1;38;2;133;153;0m" # Green bold
BYellow="\e[1;38;2;181;137;0m" # Yellow bold BYellow="\e[1;38;2;181;137;0m" # Yellow bold
BBlue="\e[1;38;2;38;139;210m" # Blue bold BBlue="\e[1;38;2;38;139;210m" # Blue bold
BPurple="\e[1;38;2;211;54;130m" # Magenta bold BPurple="\e[1;38;2;211;54;130m" # Magenta bold
BCyan="\e[1;38;2;42;161;152m" # Cyan bold BCyan="\e[1;38;2;42;161;152m" # Cyan bold
BWhite="\e[1;38;2;147;161;161m" # Base1 bold BWhite="\e[1;38;2;147;161;161m" # Base1 bold
# High intensity (brighter / emphasis roles in Solarized) # High intensity (brighter / emphasis roles in Solarized)
IBlack="\e[38;2;88;110;117m" # Base01 — secondary/comments IBlack="\e[38;2;88;110;117m" # Base01 — secondary/comments
IRed="\e[38;2;203;75;22m" # Orange — Solarized's "bright red" IRed="\e[38;2;203;75;22m" # Orange — Solarized's "bright red"
IGreen="\e[38;2;133;153;0m" # Green (no brighter variant) IGreen="\e[38;2;133;153;0m" # Green (no brighter variant)
IYellow="\e[38;2;181;137;0m" # Yellow (no brighter variant) IYellow="\e[38;2;181;137;0m" # Yellow (no brighter variant)
IBlue="\e[38;2;108;113;196m" # Violet — Solarized's "bright blue" IBlue="\e[38;2;108;113;196m" # Violet — Solarized's "bright blue"
IPurple="\e[38;2;211;54;130m" # Magenta (no brighter variant) IPurple="\e[38;2;211;54;130m" # Magenta (no brighter variant)
ICyan="\e[38;2;42;161;152m" # Cyan (no brighter variant) ICyan="\e[38;2;42;161;152m" # Cyan (no brighter variant)
IWhite="\e[38;2;147;161;161m" # Base1 — optional emphasis IWhite="\e[38;2;147;161;161m" # Base1 — optional emphasis
# Bold high intensity # Bold high intensity
BIBlack="\e[1;38;2;88;110;117m" # Base01 bold BIBlack="\e[1;38;2;88;110;117m" # Base01 bold
BIRed="\e[1;38;2;203;75;22m" # Orange bold BIRed="\e[1;38;2;203;75;22m" # Orange bold
BIGreen="\e[1;38;2;133;153;0m" # Green bold BIGreen="\e[1;38;2;133;153;0m" # Green bold
BIYellow="\e[1;38;2;181;137;0m" # Yellow bold BIYellow="\e[1;38;2;181;137;0m" # Yellow bold
BIBlue="\e[1;38;2;108;113;196m" # Violet bold BIBlue="\e[1;38;2;108;113;196m" # Violet bold
BIPurple="\e[1;38;2;211;54;130m" # Magenta bold BIPurple="\e[1;38;2;211;54;130m" # Magenta bold
BICyan="\e[1;38;2;42;161;152m" # Cyan bold BICyan="\e[1;38;2;42;161;152m" # Cyan bold
BIWhite="\e[1;38;2;147;161;161m" # Base1 bold BIWhite="\e[1;38;2;147;161;161m" # Base1 bold
# ---- Background palette overrides ------------------------------------------- # ---- Background palette overrides -------------------------------------------
On_Black="\e[48;2;0;43;54m" # Base03 On_Black="\e[48;2;0;43;54m" # Base03
On_Red="\e[48;2;220;50;47m" # Red On_Red="\e[48;2;220;50;47m" # Red
On_Green="\e[48;2;133;153;0m" # Green On_Green="\e[48;2;133;153;0m" # Green
On_Yellow="\e[48;2;181;137;0m" # Yellow On_Yellow="\e[48;2;181;137;0m" # Yellow
On_Blue="\e[48;2;38;139;210m" # Blue On_Blue="\e[48;2;38;139;210m" # Blue
On_Purple="\e[48;2;211;54;130m" # Magenta On_Purple="\e[48;2;211;54;130m" # Magenta
On_Cyan="\e[48;2;42;161;152m" # Cyan On_Cyan="\e[48;2;42;161;152m" # Cyan
On_White="\e[48;2;131;148;150m" # Base0 On_White="\e[48;2;131;148;150m" # Base0
On_IBlack="\e[48;2;7;54;66m" # Base02 — background highlights On_IBlack="\e[48;2;7;54;66m" # Base02 — background highlights
On_IRed="\e[48;2;203;75;22m" # Orange On_IRed="\e[48;2;203;75;22m" # Orange
On_IGreen="\e[48;2;133;153;0m" # Green On_IGreen="\e[48;2;133;153;0m" # Green
On_IYellow="\e[48;2;181;137;0m" # Yellow On_IYellow="\e[48;2;181;137;0m" # Yellow
On_IBlue="\e[48;2;108;113;196m" # Violet On_IBlue="\e[48;2;108;113;196m" # Violet
On_IPurple="\e[48;2;211;54;130m" # Magenta On_IPurple="\e[48;2;211;54;130m" # Magenta
On_ICyan="\e[48;2;42;161;152m" # Cyan On_ICyan="\e[48;2;42;161;152m" # Cyan
On_IWhite="\e[48;2;147;161;161m" # Base1 On_IWhite="\e[48;2;147;161;161m" # Base1
# ---- Special codes ---------------------------------------------------------- # ---- Special codes ----------------------------------------------------------
DEFAULTFG="\e[38;2;131;148;150m" # Base0 — default foreground DEFAULTFG="\e[38;2;131;148;150m" # Base0 — default foreground
DEFAULTBG="\e[48;2;0;43;54m" # Base03 — default background DEFAULTBG="\e[48;2;0;43;54m" # Base03 — default background
RESETCOL="\e[0m" RESETCOL="\e[0m"
# ---- Prompt colour slots ---------------------------------------------------- # ---- Prompt colour slots ----------------------------------------------------
# All specified as direct ANSI sequences to avoid ordering dependencies # All specified as direct ANSI sequences to avoid ordering dependencies
# with the palette overrides above. # with the palette overrides above.
PROMPT_COLOR_TIME_FG="\e[38;2;181;137;0m" # Yellow — primary accent PROMPT_COLOR_TIME_FG="\e[38;2;181;137;0m" # Yellow — primary accent
PROMPT_COLOR_TIME_BG="\e[48;2;0;43;54m" # Base03 — darkest background PROMPT_COLOR_TIME_BG="\e[48;2;0;43;54m" # Base03 — darkest background
PROMPT_COLOR_BAR_BG="\e[48;2;7;54;66m" # Base02bar background PROMPT_COLOR_BAR_BG="\e[48;2;88;110;117m" # Base01slightly brighter bar (was Base02)
PROMPT_COLOR_OK_FG="\e[38;2;131;148;150m" # Base0 — body text on success PROMPT_COLOR_OK_FG="\e[38;2;131;148;150m" # Base0 — body text on success
PROMPT_COLOR_OK_MARK="\e[38;2;133;153;0m" # Green — checkmark PROMPT_COLOR_OK_MARK="\e[38;2;133;153;0m" # Green — checkmark
PROMPT_COLOR_ERR_BG="\e[48;2;220;50;47m" # Red — error background PROMPT_COLOR_ERR_BG="\e[48;2;180;20;15m" # deeper crimson — more contrast than Solarized Red
PROMPT_COLOR_ERR_FG="\e[38;2;253;246;227m" # Base3 — bright fg on red PROMPT_COLOR_ERR_FG="\e[1;38;2;255;255;255m" # bold pure white — maximum contrast on dark red
PROMPT_COLOR_ERR_MARK="\e[38;2;181;137;0m" # Yellow — X mark on red bg PROMPT_COLOR_ERR_MARK="\e[1;38;2;253;246;227m" # Base3 bold — bright warm mark stands out on crimson
PROMPT_COLOR_ROOT_FG="\e[38;2;220;50;47m" # Red — root warning PROMPT_COLOR_ROOT_FG="\e[38;2;220;50;47m" # Red — root warning
PROMPT_COLOR_USER_FG="\e[38;2;42;161;152m" # Cyan — normal user PROMPT_COLOR_USER_FG="\e[38;2;42;161;152m" # Cyan — normal user
PROMPT_COLOR_DIR_FG="\e[38;2;38;139;210m" # Blue — working directory PROMPT_COLOR_DIR_FG="\e[38;2;38;139;210m" # Blue — working directory

View File

@@ -54,6 +54,7 @@ check_updates()
local vfile="" lastver="" local vfile="" lastver=""
PARSED=$(getopt -o hq --long help,quiet -n 'check_updates' -- "$@") PARSED=$(getopt -o hq --long help,quiet -n 'check_updates' -- "$@")
# shellcheck disable=SC2181 # getopt return code is checked immediately after
if [[ $? -ne 0 ]]; then if [[ $? -ne 0 ]]; then
disp E "Invalid options, use \"check_updates --help\" to display usage." disp E "Invalid options, use \"check_updates --help\" to display usage."
return 2 return 2
@@ -128,6 +129,7 @@ profile_upgrade()
local tmpdir="" archive="" extracted_root="" local tmpdir="" archive="" extracted_root=""
PARSED=$(getopt -o hf:t:nFb:g --long help,file:,tmpdir:,dry-run,force,branch:,switch-to-git -n 'profile_upgrade' -- "$@") PARSED=$(getopt -o hf:t:nFb:g --long help,file:,tmpdir:,dry-run,force,branch:,switch-to-git -n 'profile_upgrade' -- "$@")
# shellcheck disable=SC2181 # getopt return code is checked immediately after
if [[ $? -ne 0 ]]; then if [[ $? -ne 0 ]]; then
disp E "Invalid options, use \"profile_upgrade --help\" to display usage." disp E "Invalid options, use \"profile_upgrade --help\" to display usage."
return 2 return 2
@@ -215,8 +217,8 @@ profile_upgrade()
} }
if (( dry_run )); then if (( dry_run )); then
disp I "[dry-run] rm -rf \"$MYPATH\"/.git" disp I "[dry-run] rm -rf \"$MYPATH\"/.git"
disp I "[dry-run] git clone "$BASE_URL" \"$MYPATH\"" disp I "[dry-run] git clone $BASE_URL \"$MYPATH\""
[[ -n "$branch" ]] && disp I "[dry-run] git -C \"$MYPATH\" checkout "$branch"" [[ -n "$branch" ]] && disp I "[dry-run] git -C \"$MYPATH\" checkout $branch"
return 0 return 0
fi fi

View File

@@ -45,7 +45,7 @@ fi
if ((BASH_VERSINFO[0] < 4)) || [[ ${BASH_VERSINFO[0]} -eq 4 && ${BASH_VERSINFO[1]} -lt 3 ]]; then if ((BASH_VERSINFO[0] < 4)) || [[ ${BASH_VERSINFO[0]} -eq 4 && ${BASH_VERSINFO[1]} -lt 3 ]]; then
echo "[ Error ] This profile requires Bash 4.3 or higher." echo "[ Error ] This profile requires Bash 4.3 or higher."
echo "Current version: $BASH_VERSION" echo "Current version: $BASH_VERSION"
return 1 2>/dev/null || exit 1 (return 0 2>/dev/null) && return 1 || exit 1
fi fi
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
@@ -66,17 +66,17 @@ pathremove()
export "$pathvar=$newpath" export "$pathvar=$newpath"
} }
pathprepend() #pathprepend() # Unused for now, but might be useful in the future
{ #{
[[ -z "$1" ]] && return 0 # [[ -z "$1" ]] && return 0
local pathvar="${2:-PATH}" # local pathvar="${2:-PATH}"
[[ "$pathvar" =~ ^[a-zA-Z_][a-zA-Z0-9_]*$ ]] || { # [[ "$pathvar" =~ ^[a-zA-Z_][a-zA-Z0-9_]*$ ]] || {
printf "pathprepend: unsafe variable name '%s'\n" "$pathvar" >&2 # printf "pathprepend: unsafe variable name '%s'\n" "$pathvar" >&2
return 1 # return 1
} # }
pathremove "$1" "$pathvar" # pathremove "$1" "$pathvar"
export "$pathvar=$1${!pathvar:+:${!pathvar}}" # export "$pathvar=$1${!pathvar:+:${!pathvar}}"
} #}
pathappend() pathappend()
{ {
@@ -98,7 +98,7 @@ parse_conf()
{ {
local config_file="$1" local config_file="$1"
local current_section="" local current_section=""
local line key value local key value
[[ ! -f "$config_file" ]] && return 1 [[ ! -f "$config_file" ]] && return 1
@@ -140,6 +140,7 @@ parse_conf()
# Use a nameref for safe, eval-free assignment # Use a nameref for safe, eval-free assignment
local -n current_array="CONF_$current_section" local -n current_array="CONF_$current_section"
# shellcheck disable=SC2034 # Dynamic var creation
current_array["$key"]="$value" current_array["$key"]="$value"
fi fi
done < "$config_file" done < "$config_file"
@@ -168,6 +169,7 @@ load_alias()
# Only alias if the base command is executable # Only alias if the base command is executable
if command -v "$base_cmd" >/dev/null 2>&1; then if command -v "$base_cmd" >/dev/null 2>&1; then
# shellcheck disable=SC2139 # Dynamic alias creation
alias "$key"="$cmd" alias "$key"="$cmd"
fi fi
done done
@@ -181,7 +183,8 @@ load_conf()
{ {
local section_name="CONF_$1" local section_name="CONF_$1"
[[ "$(declare -p "$section_name" 2>/dev/null)" != "declare -A"* ]] && return 1 # Missing section is not an error: modules can rely on built-in defaults.
[[ "$(declare -p "$section_name" 2>/dev/null)" != "declare -A"* ]] && return 0
local -n current_vars="$section_name" local -n current_vars="$section_name"
@@ -204,22 +207,24 @@ load_conf()
# Because we're more likely to be sourced, we use BASH_SOURCE to get the path # Because we're more likely to be sourced, we use BASH_SOURCE to get the path
# of the sourced file instead of $0 # of the sourced file instead of $0
if [[ -z "$PROFILE_PATH" ]]; then if [[ -z "$PROFILE_PATH" ]]; then
export MYPATH=$(dirname "$(realpath -s "${BASH_SOURCE[0]}")") MYPATH=$(dirname "$(realpath -s "${BASH_SOURCE[0]}")")
else else
export MYPATH="$PROFILE_PATH" MYPATH="$PROFILE_PATH"
fi fi
export MYPATH
if [[ ! -e "$MYPATH/profile.sh" ]]; then if [[ ! -e "$MYPATH/profile.sh" ]]; then
echo "[ Warning ] Path detection failed, trying to use pwd..." echo "[ Warning ] Path detection failed, trying to use pwd..."
MYPATH=$(pwd) MYPATH=$(pwd)
if [[ ! -e "$MYPATH/profile.sh" ]]; then if [[ ! -e "$MYPATH/profile.sh" ]]; then
echo "[ Error ] Impossible to determine installation path, pretty much nothing will work." echo "[ Error ] Unable to determine installation path, pretty much nothing will work."
fi fi
fi fi
if [[ ! -s "$MYPATH/version" ]]; then if [[ ! -s "$MYPATH/version" ]]; then
echo "[ Warning ] Impossible to determine running version of profile, your installation might be broken." echo "[ Warning ] Unable to determine running profile version; your installation might be broken."
fi fi
export PROFVERSION=$(cat "$MYPATH"/version) PROFVERSION=$(cat "$MYPATH"/version)
export PROFVERSION
# Build PATH environment variable # Build PATH environment variable
if [[ $EUID -eq 0 ]]; then if [[ $EUID -eq 0 ]]; then
@@ -258,11 +263,21 @@ if [[ $INTERACTIVE ]]; then
trap 'timer_start' DEBUG trap 'timer_start' DEBUG
PROMPT_COMMAND='set_prompt' PROMPT_COMMAND='set_prompt'
# Set default language # Set default language from DEFAULT_LANG config key (set in [general]).
setfr # The value must match one of the alias names defined in SET_LOCALE so that
# the corresponding set<alias> function exists after build_locale_shortcuts.
if [[ -n "${DEFAULT_LANG:-}" ]]; then
_lang_fn="set${DEFAULT_LANG}"
if declare -F "$_lang_fn" >/dev/null 2>&1; then
"$_lang_fn"
else
disp W "DEFAULT_LANG '$DEFAULT_LANG' has no matching locale shortcut (check SET_LOCALE in profile.conf)."
fi
unset _lang_fn
fi
showinfo && printf "\n" showinfo && printf "\n"
check_updates -q check_updates -q
disp I "Profile version $PROFVERSION chargé..." disp I "Profile version $PROFVERSION loaded..."
fi fi
# Cleanup # Cleanup

View File

@@ -1 +1 @@
3.99.1-4_rc_1 4.0.0