max / alloy
8 files changed,
+62 insertions,
-41 deletions
| @@ -274,6 +274,35 @@ | |||
| 274 | 274 | # /etc/shells". bash stays at /bin/sh and /bin/bash for scripts. | |
| 275 | 275 | RUN echo /usr/bin/nu >> /etc/shells | |
| 276 | 276 | ||
| 277 | + | # ===================================================================== | |
| 278 | + | # Shell integrations, generated once into nushell's system autoload dir. | |
| 279 | + | # ===================================================================== | |
| 280 | + | # nushell sources every .nu in its autoload directories at startup, and | |
| 281 | + | # /usr/share/nushell/vendor/autoload is the first one it looks in. Files | |
| 282 | + | # put here are picked up by every account with no per-user setup, which | |
| 283 | + | # is what an image with a read-only /usr wants. | |
| 284 | + | # | |
| 285 | + | # Generated at build time rather than on first shell start, for two | |
| 286 | + | # reasons that only showed up when this was tried the other way round. | |
| 287 | + | # `source` is a nushell *parse-time* keyword: it takes a path known while | |
| 288 | + | # the file is being parsed, so `let cache = ...; source $cache` fails with | |
| 289 | + | # "Value is not a parse-time constant" and, because the failure is a parse | |
| 290 | + | # error, nushell discards the whole config file. The account then gets | |
| 291 | + | # stock nushell: no theme, no vi mode, no history settings, no aliases, | |
| 292 | + | # and the banner that config.nu turns off. The second reason is ordering: | |
| 293 | + | # the autoload directories are read before env.nu's writes land, so a file | |
| 294 | + | # generated at shell start is not seen until the *next* shell. | |
| 295 | + | # | |
| 296 | + | # Guarded on the binaries so this step does not fail the build if either | |
| 297 | + | # package leaves the image; nushell simply autoloads whatever is here. | |
| 298 | + | RUN mkdir -p /usr/share/nushell/vendor/autoload \ | |
| 299 | + | && if command -v starship >/dev/null; then \ | |
| 300 | + | starship init nu > /usr/share/nushell/vendor/autoload/starship.nu; \ | |
| 301 | + | fi \ | |
| 302 | + | && if command -v zoxide >/dev/null; then \ | |
| 303 | + | zoxide init nushell > /usr/share/nushell/vendor/autoload/zoxide.nu; \ | |
| 304 | + | fi | |
| 305 | + | ||
| 277 | 306 | # ===================================================================== | |
| 278 | 307 | # Config tree — the etc/ and usr/ trees in the repo map 1:1 into | |
| 279 | 308 | # the image. Per-user defaults live under etc/skel/.config/ and |
| @@ -2,9 +2,10 @@ | |||
| 2 | 2 | //! | |
| 3 | 3 | //! Every command the console runs passes through here, which is what makes the | |
| 4 | 4 | //! log pane's promise honest: the pane cannot show a command the console did | |
| 5 | - | //! not run, and it cannot run one it does not show. docs/CONSOLE.md — "the | |
| 6 | - | //! console is not trying to hide the CLI, it's trying to make the CLI | |
| 7 | - | //! approachable" — is enforced structurally rather than by remembering to log. | |
| 5 | + | //! not run, and it cannot run one it does not show. The promise docs/CONSOLE.md | |
| 6 | + | //! makes, "the console is not trying to hide the CLI, it's trying to make the | |
| 7 | + | //! CLI approachable", is enforced structurally rather than by remembering to | |
| 8 | + | //! log. | |
| 8 | 9 | //! | |
| 9 | 10 | //! [`Invocation`] is the common case and [`Effect`] is the general one. Almost | |
| 10 | 11 | //! everything the console does is running someone else's CLI, but not quite |
| @@ -1590,7 +1590,7 @@ | |||
| 1590 | 1590 | impl View for InstallView { | |
| 1591 | 1591 | fn title(&self) -> String { | |
| 1592 | 1592 | format!( | |
| 1593 | - | "install ({}) — step {} of {}: {}", | |
| 1593 | + | "install ({}), step {} of {}: {}", | |
| 1594 | 1594 | self.backend.name(), | |
| 1595 | 1595 | self.steps.current() + 1, | |
| 1596 | 1596 | self.steps.len(), |
| @@ -140,8 +140,8 @@ | |||
| 140 | 140 | /// | |
| 141 | 141 | /// `Other` keeps the backend's own word rather than collapsing it. Podman's | |
| 142 | 142 | /// state vocabulary gains members (`paused`, `stopping`, `exited`), and showing | |
| 143 | - | /// an unfamiliar one beats mapping it to "unknown" — same reasoning as `mesh` | |
| 144 | - | /// reporting `BackendState` verbatim. | |
| 143 | + | /// an unfamiliar one beats mapping it to "unknown", the same reasoning as | |
| 144 | + | /// `mesh` reporting `BackendState` verbatim. | |
| 145 | 145 | #[derive(Debug, Clone, PartialEq, Eq)] | |
| 146 | 146 | pub enum BoxState { | |
| 147 | 147 | Running, | |
| @@ -1245,7 +1245,7 @@ | |||
| 1245 | 1245 | // check and same wording as `toggle`, for the same reason: the state | |
| 1246 | 1246 | // is the console's fact, not the backend's. | |
| 1247 | 1247 | if boxed.state == BoxState::Absent { | |
| 1248 | - | anyhow::bail!("{} does not exist yet — press c to create it", boxed.name); | |
| 1248 | + | anyhow::bail!("{} does not exist yet; press c to create it", boxed.name); | |
| 1249 | 1249 | } | |
| 1250 | 1250 | let (name, spec) = self.declared_spec(boxed, "exported")?; | |
| 1251 | 1251 | for effect in self.backends[index].export(name, spec)? { | |
| @@ -1272,7 +1272,7 @@ | |||
| 1272 | 1272 | // command that can only fail. The state is the console's fact to | |
| 1273 | 1273 | // check, not the backend's. | |
| 1274 | 1274 | if boxed.state == BoxState::Absent { | |
| 1275 | - | anyhow::bail!("{} does not exist yet — press c to create it", boxed.name); | |
| 1275 | + | anyhow::bail!("{} does not exist yet; press c to create it", boxed.name); | |
| 1276 | 1276 | } | |
| 1277 | 1277 | let backend = &self.backends[index]; | |
| 1278 | 1278 | let Some(invocation) = backend.stop(boxed).or_else(|| backend.start(boxed)) else { | |
| @@ -1322,7 +1322,7 @@ | |||
| 1322 | 1322 | }; | |
| 1323 | 1323 | if row.boxed.state == BoxState::Absent { | |
| 1324 | 1324 | self.error = Some(format!( | |
| 1325 | - | "{} does not exist yet — press c to create it", | |
| 1325 | + | "{} does not exist yet; press c to create it", | |
| 1326 | 1326 | row.boxed.name | |
| 1327 | 1327 | )); | |
| 1328 | 1328 | return Flow::Continue; |
| @@ -68,9 +68,9 @@ | |||
| 68 | 68 | /// The furthest step the user has reached, current or behind them. | |
| 69 | 69 | /// | |
| 70 | 70 | /// For the step indicator: steps at or below this are answered, the rest | |
| 71 | - | /// are not yet visited. Nothing draws that indicator yet — the title says | |
| 72 | - | /// "step 2 of 4" instead — so this is the last of the type still waiting on | |
| 73 | - | /// its consumer, and the allow comes off with it. | |
| 71 | + | /// are not yet visited. Nothing draws that indicator yet, since the title | |
| 72 | + | /// says "step 2 of 4" instead, so this is the last of the type still | |
| 73 | + | /// waiting on its consumer, and the allow comes off with it. | |
| 74 | 74 | #[allow(dead_code)] | |
| 75 | 75 | pub const fn furthest(&self) -> usize { | |
| 76 | 76 | self.furthest |
| @@ -4,7 +4,7 @@ | |||
| 4 | 4 | # reconsider whether the alias earned its place. | |
| 5 | 5 | ||
| 6 | 6 | # ------------------------------------------------------------------- | |
| 7 | - | # ls variants — nu's `ls` is already structured; these add flags | |
| 7 | + | # ls variants. nu's `ls` is already structured; these add flags | |
| 8 | 8 | # ------------------------------------------------------------------- | |
| 9 | 9 | alias ll = ls -la | |
| 10 | 10 | alias la = ls -a | |
| @@ -51,4 +51,4 @@ | |||
| 51 | 51 | # ------------------------------------------------------------------- | |
| 52 | 52 | # alias net = alloy net | |
| 53 | 53 | # alias audio = alloy audio | |
| 54 | - | # — deferred; enable once alloy console v0.5 ships. | |
| 54 | + | # Deferred; enable once alloy console v0.5 ships. |
| @@ -1,13 +1,13 @@ | |||
| 1 | 1 | # Alloy Nushell config | |
| 2 | 2 | # | |
| 3 | - | # Loaded on every nu shell start. Configures nu's own behavior — table style, | |
| 3 | + | # Loaded on every nu shell start. Configures nu's own behavior: table style, | |
| 4 | 4 | # history, completions, keybindings, color palette for nu's own output. | |
| 5 | 5 | # | |
| 6 | 6 | # Aliases live in aliases.nu (sourced at the bottom). | |
| 7 | 7 | # Environment lives in env.nu (loaded before this file by nu itself). | |
| 8 | 8 | ||
| 9 | 9 | # ------------------------------------------------------------------- | |
| 10 | - | # Alloy color palette — Akari Dawn (default light). | |
| 10 | + | # Alloy color palette, Akari Dawn (default light). | |
| 11 | 11 | # Source of truth: makeover's themes/akari-dawn.toml. | |
| 12 | 12 | # ------------------------------------------------------------------- | |
| 13 | 13 | let alloy = { | |
| @@ -90,9 +90,13 @@ | |||
| 90 | 90 | use_ls_colors: true | |
| 91 | 91 | } | |
| 92 | 92 | ||
| 93 | + | # `metric: true` and `format: "auto"` were this record's shape in an | |
| 94 | + | # older nushell and are rejected by 0.112 as unknown options. The intent | |
| 95 | + | # was metric units, which `unit` now carries. | |
| 93 | 96 | filesize: { | |
| 94 | - | metric: true | |
| 95 | - | format: "auto" | |
| 97 | + | unit: "metric" | |
| 98 | + | show_unit: true | |
| 99 | + | precision: 1 | |
| 96 | 100 | } | |
| 97 | 101 | ||
| 98 | 102 | cursor_shape: { | |
| @@ -172,30 +176,17 @@ | |||
| 172 | 176 | } | |
| 173 | 177 | ||
| 174 | 178 | # ------------------------------------------------------------------- | |
| 175 | - | # Integrations — conditionally loaded if the tool is present | |
| 179 | + | # Integrations | |
| 176 | 180 | # ------------------------------------------------------------------- | |
| 177 | - | ||
| 178 | - | # starship prompt | |
| 179 | - | if (which starship | is-not-empty) { | |
| 180 | - | let starship_cache = ($nu.cache-dir | path join "starship-init.nu") | |
| 181 | - | if not ($starship_cache | path exists) { | |
| 182 | - | mkdir ($starship_cache | path dirname) | |
| 183 | - | starship init nu | save -f $starship_cache | |
| 184 | - | } | |
| 185 | - | source $starship_cache | |
| 186 | - | } | |
| 187 | - | ||
| 188 | - | # zoxide directory jumper | |
| 189 | - | if (which zoxide | is-not-empty) { | |
| 190 | - | let zoxide_cache = ($nu.cache-dir | path join "zoxide-init.nu") | |
| 191 | - | if not ($zoxide_cache | path exists) { | |
| 192 | - | mkdir ($zoxide_cache | path dirname) | |
| 193 | - | zoxide init nushell | save -f $zoxide_cache | |
| 194 | - | } | |
| 195 | - | source $zoxide_cache | |
| 196 | - | } | |
| 181 | + | # starship and zoxide are not set up here. The image generates their init | |
| 182 | + | # files into /usr/share/nushell/vendor/autoload/, which nushell sources by | |
| 183 | + | # itself before this file runs. See the Containerfile for why: `source` is | |
| 184 | + | # a parse-time keyword, so it cannot take a path a `let` computed and it | |
| 185 | + | # cannot be gated behind a runtime `if`. Written that way it was a parse | |
| 186 | + | # error, and a parse error costs the whole file, not just its own line. | |
| 197 | 187 | ||
| 198 | 188 | # ------------------------------------------------------------------- | |
| 199 | - | # Aliases (small, curated — see aliases.nu) | |
| 189 | + | # Aliases (small, curated; see aliases.nu) | |
| 200 | 190 | # ------------------------------------------------------------------- | |
| 191 | + | # `$nu` is a parse-time constant, so this path is one `source` can take. | |
| 201 | 192 | source ($nu.default-config-dir | path join "aliases.nu") |
| @@ -50,7 +50,7 @@ | |||
| 50 | 50 | # a comment for future-Alloy debugging. | |
| 51 | 51 | ||
| 52 | 52 | # ------------------------------------------------------------------- | |
| 53 | - | # Cursor — Bibata Modern Classic, size 24. Also declared in | |
| 53 | + | # Cursor: Bibata Modern Classic, size 24. Also declared in | |
| 54 | 54 | # ~/.icons/default/index.theme and the GTK settings.ini; env vars here | |
| 55 | 55 | # cover apps and toolkits that read XCURSOR_* directly. | |
| 56 | 56 | # ------------------------------------------------------------------- |