Merge branch 'master' into conditional-style

This commit is contained in:
Filip Bachul 2023-01-02 15:03:34 +01:00
commit a8a0b1524f
22 changed files with 529 additions and 105 deletions

View File

@ -757,7 +757,7 @@
"hg_branch": {
"default": {
"disabled": true,
"format": "on [$symbol$branch]($style) ",
"format": "on [$symbol$branch(:$topic)]($style) ",
"style": "bold purple",
"symbol": " ",
"truncation_length": 9223372036854775807,
@ -1222,6 +1222,21 @@
}
]
},
"pijul_channel": {
"default": {
"disabled": true,
"format": "on [$symbol$channel]($style) ",
"style": "bold purple",
"symbol": " ",
"truncation_length": 9223372036854775807,
"truncation_symbol": "…"
},
"allOf": [
{
"$ref": "#/definitions/PijulConfig"
}
]
},
"pulumi": {
"default": {
"disabled": false,
@ -3619,7 +3634,7 @@
"type": "string"
},
"format": {
"default": "on [$symbol$branch]($style) ",
"default": "on [$symbol$branch(:$topic)]($style) ",
"type": "string"
},
"truncation_length": {
@ -4577,6 +4592,37 @@
},
"additionalProperties": false
},
"PijulConfig": {
"type": "object",
"properties": {
"symbol": {
"default": " ",
"type": "string"
},
"style": {
"default": "bold purple",
"type": "string"
},
"format": {
"default": "on [$symbol$channel]($style) ",
"type": "string"
},
"truncation_length": {
"default": 9223372036854775807,
"type": "integer",
"format": "int64"
},
"truncation_symbol": {
"default": "…",
"type": "string"
},
"disabled": {
"default": true,
"type": "boolean"
}
},
"additionalProperties": false
},
"PulumiConfig": {
"type": "object",
"properties": {

92
Cargo.lock generated
View File

@ -885,9 +885,9 @@ dependencies = [
[[package]]
name = "git-actor"
version = "0.15.0"
version = "0.16.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7def29b46f25f95a2e196323cfb336eae9965e0a3c7c35ad9506f295c3a8e234"
checksum = "599cb75eb7c3bf03149b7ab70c66bc0b9a432a092b1154b49d21b49fc7e4bd93"
dependencies = [
"bstr",
"btoi",
@ -899,9 +899,9 @@ dependencies = [
[[package]]
name = "git-attributes"
version = "0.7.0"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f0affaed361598fdd06b2a184a566c823d0b5817b09f576018248fb267193a96"
checksum = "f8013dfce47c1e29236d732308933e2c77af5355ec5105755d26faf7764d3f7b"
dependencies = [
"bstr",
"compact_str",
@ -933,18 +933,18 @@ dependencies = [
[[package]]
name = "git-command"
version = "0.2.0"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a6b98a6312fef79b326c0a6e15d576c2bd30f7f9d0b7964998d166049e0d7b9e"
checksum = "215145cc1686a45bc6f9872b153a0d3f3c40a1b94173a928325e1b53dfa5e2af"
dependencies = [
"bstr",
]
[[package]]
name = "git-config"
version = "0.13.0"
version = "0.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5ff189268cfb19d5151529ac30b6b708072ebfa1075643d785232675456ec320"
checksum = "d1b95089db62159d7d24c13ddfb4bf949c508521d0bb25331744ef500295ceb8"
dependencies = [
"bstr",
"git-config-value",
@ -976,9 +976,9 @@ dependencies = [
[[package]]
name = "git-credentials"
version = "0.8.0"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "28da3d029be10258007699d002321a3b1ebe45e67b0e140a4cf464ba3ee79b32"
checksum = "97cd6bbe001afd6356b35ef13f2a6b0f0abc0133d1b2ecaec1033bdd769616d6"
dependencies = [
"bstr",
"git-command",
@ -1004,9 +1004,9 @@ dependencies = [
[[package]]
name = "git-diff"
version = "0.24.0"
version = "0.25.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f30011a43908645c492dfbea7b004e10528be6bd667bf5cdc12ff4297fe1e3c"
checksum = "a8ae775956f509fe115b173d79e539f97539d40c1d5c5c63a61d10eaf79c857a"
dependencies = [
"git-hash",
"git-object",
@ -1016,9 +1016,9 @@ dependencies = [
[[package]]
name = "git-discover"
version = "0.10.0"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "93c244b1cf7cf45501116e948506c25324e33ddc613f00557ff5bfded2132009"
checksum = "aab20ca6af631c2bb10d59e63377ca9c9c74908586e6018ab15377967432e68b"
dependencies = [
"bstr",
"git-hash",
@ -1030,9 +1030,9 @@ dependencies = [
[[package]]
name = "git-features"
version = "0.25.1"
version = "0.26.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0f98e6ede7b790dfba16bf3c62861ae75c3719485d675b522cf7d7e748a4011c"
checksum = "5ff74064fa007c5beefa89a64bb72834f32b3c497750a56c79c6802bbdb311f9"
dependencies = [
"crc32fast",
"crossbeam-channel",
@ -1083,9 +1083,9 @@ dependencies = [
[[package]]
name = "git-index"
version = "0.10.0"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "20627f71f3a884b0ae50f9f3abb3a07d9b117d06e16110d25b85da4d71d478c0"
checksum = "430f5d9302a2dd5e50b6b04a3b9d0df6b3423e55908fde18333fe9cd51312027"
dependencies = [
"atoi",
"bitflags",
@ -1116,9 +1116,9 @@ dependencies = [
[[package]]
name = "git-mailmap"
version = "0.7.0"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f90e3ee2eaeebda8a12d17f4d99dff5b19d81536476020bcebb99ee121820466"
checksum = "396cef08d4ec18ea35fed043f5b003e46957603a01349dd429a4773c146fefca"
dependencies = [
"bstr",
"git-actor",
@ -1127,9 +1127,9 @@ dependencies = [
[[package]]
name = "git-object"
version = "0.24.0"
version = "0.25.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "35b658f1e3e149d88cb3e0a2234be749bb0cab65887405975dbe6f3190cf6571"
checksum = "fad6c2ddb376b99172dc8b651e11be4cb49cef423de4fad563ebbda4fee3fcf6"
dependencies = [
"bstr",
"btoi",
@ -1146,9 +1146,9 @@ dependencies = [
[[package]]
name = "git-odb"
version = "0.38.1"
version = "0.39.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "55333419bbb25aa6d39e29155f747ad8e1777fe385f70f447be9d680824d23dd"
checksum = "84ea84e47ae48b95e108664d2991013507694b1b722e4183ed1c9309251b9b10"
dependencies = [
"arc-swap",
"git-features",
@ -1164,9 +1164,9 @@ dependencies = [
[[package]]
name = "git-pack"
version = "0.28.0"
version = "0.29.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9ed3c9af66949553af9795b9eac9d450a5bdceee9959352cda468997ddce0d2f"
checksum = "692e9c78c57212aa76c71be9a319f80d42fe8191735b3aff5b97b8f034295774"
dependencies = [
"bytesize",
"clru",
@ -1223,9 +1223,9 @@ dependencies = [
[[package]]
name = "git-ref"
version = "0.21.0"
version = "0.22.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c97b7d719e4320179fb64d081016e7faca56fed4a8ee4cf84e4697faad9235a3"
checksum = "b351af399166a5506369e36389d6b9aee744cfa672d0e2ea93d2b01223b1cfbe"
dependencies = [
"git-actor",
"git-features",
@ -1242,9 +1242,9 @@ dependencies = [
[[package]]
name = "git-refspec"
version = "0.5.0"
version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d478e9db0956d60cd386d3348b5ec093e3ae613105a7a75ff6084b886254eba8"
checksum = "fcf699f310ba8530708f599b1ce730eb557ebc0af1a1a57b882ce3d685571092"
dependencies = [
"bstr",
"git-hash",
@ -1256,9 +1256,9 @@ dependencies = [
[[package]]
name = "git-repository"
version = "0.30.2"
version = "0.31.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1925a65a9fea6587e969a7a85cb239c8e1e438cf6dc520406df1b4c9d0e83bdc"
checksum = "d9e21852e326233c5f3f034a44b66215c166506e5ccf227de7e28ccdfbcfb47a"
dependencies = [
"git-actor",
"git-attributes",
@ -1299,9 +1299,9 @@ dependencies = [
[[package]]
name = "git-revision"
version = "0.8.0"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f7516b1db551756b4d3176c4b7d18ccc4b79d35dcc5e74f768c90f5bb11bb6c9"
checksum = "8b64c0d2e37eb24c8897d11a2f77371a817c3d40dc744d4a2f048f33236eef6b"
dependencies = [
"bstr",
"git-date",
@ -1340,9 +1340,9 @@ dependencies = [
[[package]]
name = "git-traverse"
version = "0.20.0"
version = "0.21.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5e5141dde56d0c4861193c760e01fb61c7e03a32d0840ba93a0ac1c597588d4d"
checksum = "43b91ed45b561161ba56b85a83865825b7d17a6b1c6f981e831a78b93cf2cc5f"
dependencies = [
"git-hash",
"git-hashtable",
@ -1352,9 +1352,9 @@ dependencies = [
[[package]]
name = "git-url"
version = "0.12.2"
version = "0.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8651924c9692a778f09141ca44d1bf2dada229fe9b240f1ff1bdecd9621a1a93"
checksum = "c85af407ed0dbb8d8da2a7241827d2fd5681186d9dab3570fc8dd8d6152ec48f"
dependencies = [
"bstr",
"git-features",
@ -1376,9 +1376,9 @@ dependencies = [
[[package]]
name = "git-worktree"
version = "0.10.0"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "17d748c54c3d904c914b987654a1416c7abe7cf048fdc83eeae69e6ac3d76f20"
checksum = "ffc45b5ac445d0f8719def12303f037966f810cf399ebe0daf29217865df9a49"
dependencies = [
"bstr",
"git-attributes",
@ -1956,9 +1956,9 @@ dependencies = [
[[package]]
name = "once_cell"
version = "1.16.0"
version = "1.17.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "86f0b0d4bf799edbc74508c1e8bf170ff5f41238e5f8225603ca7caaae2b7860"
checksum = "6f61fba1741ea2b3d6a1e3178721804bb716a68a6aeba1149b5d52e3d464ea66"
[[package]]
name = "opaque-debug"
@ -2318,9 +2318,9 @@ dependencies = [
[[package]]
name = "prodash"
version = "22.1.0"
version = "23.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "38e2b91fcc982d0d8ae5e9d477561c73e09c24c5c19bac4858e202f6f065a13e"
checksum = "5d8c414345b4a98cbcd0e8d8829c8f54b47a7ed4fb771c45b7c5c6c0ae23dc4c"
dependencies = [
"bytesize",
"dashmap",
@ -2711,9 +2711,9 @@ dependencies = [
[[package]]
name = "shadow-rs"
version = "0.19.0"
version = "0.20.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6c401e795850edb4e9fdde5940f856364f0fbab573e8dea58f6ee5f85fcf471d"
checksum = "8da90bd2a722461267a2c5d20b2c6de76dba087348e60484fd6c3fbb48b766d6"
dependencies = [
"const_format",
"is_debug",

View File

@ -48,16 +48,16 @@ clap_complete = "4.0.7"
dirs-next = "2.0.0"
dunce = "1.0.3"
gethostname = "0.4.1"
git-features = { version = "0.25.1", optional = true }
git-features = { version = "0.26.0", optional = true }
# default feature restriction addresses https://github.com/starship/starship/issues/4251
git-repository = { version = "0.30.2", default-features = false, features = ["max-performance-safe"] }
git-repository = { version = "0.31.0", default-features = false, features = ["max-performance-safe"] }
indexmap = { version = "1.9.2", features = ["serde"] }
log = { version = "0.4.17", features = ["std"] }
# nofity-rust is optional (on by default) because the crate doesn't currently build for darwin with nix
# see: https://github.com/NixOS/nixpkgs/issues/160876
notify-rust = { version = "4.6.0", optional = true }
nu-ansi-term = "0.46.0"
once_cell = "1.16.0"
once_cell = "1.17.0"
open = "3.2.0"
# update os module config and tests when upgrading os_info
os_info = "3.5.1"
@ -73,7 +73,7 @@ semver = "1.0.16"
serde = { version = "1.0.152", features = ["derive"] }
serde_json = "1.0.91"
sha1 = "0.10.5"
shadow-rs = { version = "0.19.0", default-features = false }
shadow-rs = { version = "0.20.0", default-features = false }
# battery is optional (on by default) because the crate doesn't currently build for Termux
# see: https://github.com/svartalf/rust-battery/issues/33
starship-battery = { version = "0.7.9", optional = true }
@ -117,7 +117,7 @@ features = [
nix = { version = "0.26.1", default-features = false, features = ["feature", "fs", "user"] }
[build-dependencies]
shadow-rs = { version = "0.19.0", default-features = false }
shadow-rs = { version = "0.20.0", default-features = false }
dunce = "1.0.3"
[target.'cfg(windows)'.build-dependencies]

View File

@ -332,7 +332,7 @@ Add the following to the end of your Nushell env file (find it by running `$nu.e
```sh
mkdir ~/.cache/starship
starship init nu | save ~/.cache/starship/init.nu
starship init nu | save -f ~/.cache/starship/init.nu
```
And add the following to the end of your Nushell configuration (find it by running `$nu.config-path`):
@ -341,7 +341,7 @@ And add the following to the end of your Nushell configuration (find it by runni
source ~/.cache/starship/init.nu
```
Note: Only Nushell v0.61+ is supported
Note: Only Nushell v0.73+ is supported
</details>

View File

@ -130,6 +130,9 @@ format = '\[[$symbol($version)]($style)\]'
[php]
format = '\[[$symbol($version)]($style)\]'
[pijul_channel]
format = '\[[$symbol$channel]($style)\]'
[pulumi]
format = '\[[$symbol$stack]($style)\]'

View File

@ -108,6 +108,9 @@ Windows = " "
[package]
symbol = " "
[pijul_channel]
symbol = "🪺 "
[python]
symbol = " "

View File

@ -156,6 +156,9 @@ symbol = "pl "
[php]
symbol = "php "
[pijul_channel]
symbol = "pijul "
[pulumi]
symbol = "pulumi "
@ -180,6 +183,9 @@ symbol = "scala "
[spack]
symbol = "spack "
[status]
symbol = "[x](bold red) "
[sudo]
symbol = "sudo "

View File

@ -138,14 +138,14 @@ description: Starship is the minimal, blazing fast, and extremely customizable p
::: warning
This will change in the future.
Only Nushell v0.61+ is supported.
Only Nushell v0.73+ is supported.
:::
Add the following to the end of your Nushell env file (find it by running `$nu.env-path` in Nushell):
```sh
mkdir ~/.cache/starship
starship init nu | save ~/.cache/starship/init.nu
starship init nu | save -f ~/.cache/starship/init.nu
```
And add the following to the end of your Nushell configuration (find it by running `$nu.config-path`):

View File

@ -271,6 +271,7 @@ $git_state\
$git_metrics\
$git_status\
$hg_branch\
$pijul_channel\
$docker_context\
$package\
$c\
@ -2643,26 +2644,27 @@ style = 'bold dimmed green'
## Mercurial Branch
The `hg_branch` module shows the active branch of the repo in your current directory.
The `hg_branch` module shows the active branch and topic of the repo in your current directory.
### Options
| Option | Default | Description |
| ------------------- | -------------------------------- | -------------------------------------------------------------------------------------------- |
| `symbol` | `' '` | The symbol used before the hg bookmark or branch name of the repo in your current directory. |
| `style` | `'bold purple'` | The style for the module. |
| `format` | `'on [$symbol$branch]($style) '` | The format for the module. |
| `truncation_length` | `2^63 - 1` | Truncates the hg branch name to `N` graphemes |
| `truncation_symbol` | `'…'` | The symbol used to indicate a branch name was truncated. |
| `disabled` | `true` | Disables the `hg_branch` module. |
| Option | Default | Description |
| ------------------- | ----------------------------------------- | -------------------------------------------------------------------------------------------- |
| `symbol` | `' '` | The symbol used before the hg bookmark or branch name of the repo in your current directory. |
| `style` | `'bold purple'` | The style for the module. |
| `format` | `'on [$symbol$branch(:$topic)]($style) '` | The format for the module. |
| `truncation_length` | `2^63 - 1` | Truncates the hg branch / topic name to `N` graphemes |
| `truncation_symbol` | `'…'` | The symbol used to indicate a branch name was truncated. |
| `disabled` | `true` | Disables the `hg_branch` module. |
### Variables
| Variable | Example | Description |
| -------- | -------- | ------------------------------------ |
| branch | `master` | The active mercurial branch |
| symbol | | Mirrors the value of option `symbol` |
| style\* | | Mirrors the value of option `style` |
| Variable | Example | Description |
| -------- | --------- | ------------------------------------ |
| branch | `master` | The active mercurial branch |
| topic | `feature` | The active mercurial topic |
| symbol | | Mirrors the value of option `symbol` |
| style\* | | Mirrors the value of option `style` |
*: This variable can only be used as a part of a style string
@ -3174,6 +3176,21 @@ By default the module will be shown if any of the following conditions are met:
format = 'via [🔹 $version](147 bold) '
```
## Pijul Channel
The `pijul_channel` module shows the active channel of the repo in your current directory.
### Options
| Option | Default | Description |
| ------------------- | --------------------------------- | ------------------------------------------------------------------------------------ |
| `symbol` | `' '` | The symbol used before the pijul channel name of the repo in your current directory. |
| `style` | `'bold purple'` | The style for the module. |
| `format` | `'on [$symbol$channel]($style) '` | The format for the module. |
| `truncation_length` | `2^63 - 1` | Truncates the pijul channel name to `N` graphemes |
| `truncation_symbol` | `'…'` | The symbol used to indicate a branch name was truncated. |
| `disabled` | `true` | Disables the `pijul` module. |
## Pulumi
The `pulumi` module shows the current username, selected [Pulumi Stack](https://www.pulumi.com/docs/intro/concepts/stack/), and version.

View File

@ -338,10 +338,10 @@ print_install() {
# shellcheck disable=SC2088
config_file="${BOLD}your nu config file${NO_COLOR} (find it by running ${BOLD}\$nu.config-path${NO_COLOR} in Nushell)"
config_cmd="mkdir ~/.cache/starship
starship init nu | save ~/.cache/starship/init.nu
starship init nu | save -f ~/.cache/starship/init.nu
source ~/.cache/starship/init.nu"
warning="${warning} This will change in the future.
Only Nushell v0.61 or higher is supported.
Only Nushell v0.73 or higher is supported.
Add the following to the end of ${BOLD}your Nushell env file${NO_COLOR} (find it by running ${BOLD}\$nu.env-path${NO_COLOR} in Nushell): \"mkdir ~/.cache/starship; starship init nu | save ~/.cache/starship/init.nu\""
;;
esac

View File

@ -21,7 +21,7 @@ impl<'a> Default for HgBranchConfig<'a> {
HgBranchConfig {
symbol: "",
style: "bold purple",
format: "on [$symbol$branch]($style) ",
format: "on [$symbol$branch(:$topic)]($style) ",
truncation_length: std::i64::MAX,
truncation_symbol: "",
disabled: true,

View File

@ -61,6 +61,7 @@ pub mod os;
pub mod package;
pub mod perl;
pub mod php;
pub mod pijul_channel;
pub mod pulumi;
pub mod purescript;
pub mod python;
@ -221,6 +222,8 @@ pub struct FullConfig<'a> {
#[serde(borrow)]
php: php::PhpConfig<'a>,
#[serde(borrow)]
pijul_channel: pijul_channel::PijulConfig<'a>,
#[serde(borrow)]
pulumi: pulumi::PulumiConfig<'a>,
#[serde(borrow)]
purescript: purescript::PureScriptConfig<'a>,

View File

@ -0,0 +1,30 @@
use serde::{Deserialize, Serialize};
#[derive(Clone, Deserialize, Serialize)]
#[cfg_attr(
feature = "config-schema",
derive(schemars::JsonSchema),
schemars(deny_unknown_fields)
)]
#[serde(default)]
pub struct PijulConfig<'a> {
pub symbol: &'a str,
pub style: &'a str,
pub format: &'a str,
pub truncation_length: i64,
pub truncation_symbol: &'a str,
pub disabled: bool,
}
impl<'a> Default for PijulConfig<'a> {
fn default() -> Self {
PijulConfig {
symbol: "",
style: "bold purple",
format: "on [$symbol$channel]($style) ",
truncation_length: std::i64::MAX,
truncation_symbol: "",
disabled: true,
}
}
}

View File

@ -42,6 +42,7 @@ pub const PROMPT_ORDER: &[&str] = &[
"git_metrics",
"git_status",
"hg_branch",
"pijul_channel",
"docker_context",
"package",
// ↓ Toolchain version modules ↓

View File

@ -68,6 +68,7 @@ pub const ALL_MODULES: &[&str] = &[
"package",
"perl",
"php",
"pijul_channel",
"pulumi",
"purescript",
"python",

View File

@ -1,20 +1,18 @@
use unicode_segmentation::UnicodeSegmentation;
use std::io::{Error, ErrorKind};
use std::path::Path;
use super::utils::truncate::truncate_text;
use super::{Context, Module, ModuleConfig};
use crate::configs::hg_branch::HgBranchConfig;
use crate::formatter::StringFormatter;
use crate::modules::utils::path::PathExt;
use crate::utils::read_file;
/// Creates a module with the Hg bookmark or branch in the current directory
///
/// Will display the bookmark or branch name if the current directory is an hg repo
pub fn module<'a>(context: &'a Context) -> Option<Module<'a>> {
let is_hg_repo = context.try_begin_scan()?.set_folders(&[".hg"]).is_match();
if !is_hg_repo {
return None;
}
let mut module = context.new_module("hg_branch");
let config: HgBranchConfig = HgBranchConfig::try_load(module.config);
@ -34,16 +32,16 @@ pub fn module<'a>(context: &'a Context) -> Option<Module<'a>> {
config.truncation_length as usize
};
let branch_name =
get_hg_current_bookmark(context).unwrap_or_else(|| get_hg_branch_name(context));
let repo_root = get_hg_repo_root(context).ok()?;
let branch_name = get_hg_current_bookmark(repo_root).unwrap_or_else(|_| {
get_hg_branch_name(repo_root).unwrap_or_else(|_| String::from("default"))
});
let truncated_graphemes = get_graphemes(&branch_name, len);
// The truncation symbol should only be added if we truncated
let truncated_and_symbol = if len < graphemes_len(&branch_name) {
let truncation_symbol = get_graphemes(config.truncation_symbol, 1);
truncated_graphemes + truncation_symbol.as_str()
let branch_graphemes = truncate_text(&branch_name, len, config.truncation_symbol);
let topic_graphemes = if let Ok(topic) = get_hg_topic_name(repo_root) {
truncate_text(&topic, len, config.truncation_symbol)
} else {
truncated_graphemes
String::from("")
};
let parsed = StringFormatter::new(config.format).and_then(|formatter| {
@ -57,7 +55,8 @@ pub fn module<'a>(context: &'a Context) -> Option<Module<'a>> {
_ => None,
})
.map(|variable| match variable {
"branch" => Some(Ok(truncated_and_symbol.as_str())),
"branch" => Some(Ok(branch_graphemes.as_str())),
"topic" => Some(Ok(topic_graphemes.as_str())),
_ => None,
})
.parse(None, Some(context))
@ -74,26 +73,33 @@ pub fn module<'a>(context: &'a Context) -> Option<Module<'a>> {
Some(module)
}
fn get_hg_branch_name(ctx: &Context) -> String {
std::fs::read_to_string(ctx.current_dir.join(".hg").join("branch"))
.map_or_else(|_| "default".to_string(), |s| s.trim().into())
fn get_hg_repo_root<'a>(ctx: &'a Context) -> Result<&'a Path, Error> {
let dir = ctx.current_dir.as_path();
let dev_id = dir.device_id();
for root_dir in dir.ancestors() {
if dev_id != root_dir.device_id() {
break;
}
if root_dir.join(".hg").is_dir() {
return Ok(root_dir);
}
}
Err(Error::new(ErrorKind::Other, "No .hg found!"))
}
fn get_hg_current_bookmark(ctx: &Context) -> Option<String> {
std::fs::read_to_string(ctx.current_dir.join(".hg").join("bookmarks.current"))
.map(|s| s.trim().into())
.ok()
fn get_hg_branch_name(hg_root: &Path) -> Result<String, Error> {
match read_file(hg_root.join(".hg").join("branch")) {
Ok(b) => Ok(b.trim().to_string()),
Err(e) => Err(e),
}
}
fn get_graphemes(text: &str, length: usize) -> String {
UnicodeSegmentation::graphemes(text, true)
.take(length)
.collect::<Vec<&str>>()
.concat()
fn get_hg_current_bookmark(hg_root: &Path) -> Result<String, Error> {
read_file(hg_root.join(".hg").join("bookmarks.current"))
}
fn graphemes_len(text: &str) -> usize {
UnicodeSegmentation::graphemes(text, true).count()
fn get_hg_topic_name(hg_root: &Path) -> Result<String, Error> {
read_file(hg_root.join(".hg").join("topic"))
}
#[cfg(test)]
@ -186,6 +192,26 @@ mod tests {
tempdir.close()
}
#[test]
#[ignore]
fn test_hg_topic() -> io::Result<()> {
let tempdir = fixture_repo(FixtureProvider::Hg)?;
let repo_dir = tempdir.path();
fs::write(repo_dir.join(".hg").join("topic"), "feature")?;
let actual = ModuleRenderer::new("hg_branch")
.path(repo_dir.to_str().unwrap())
.config(toml::toml! {
[hg_branch]
format = "$topic"
disabled = false
})
.collect();
assert_eq!(Some(String::from("feature")), actual);
tempdir.close()
}
#[test]
#[ignore]
fn test_default_truncation_symbol() -> io::Result<()> {

View File

@ -58,6 +58,7 @@ mod os;
mod package;
mod perl;
mod php;
mod pijul_channel;
mod pulumi;
mod purescript;
mod python;
@ -159,6 +160,7 @@ pub fn handle<'a>(module: &str, context: &'a Context) -> Option<Module<'a>> {
"package" => package::module(context),
"perl" => perl::module(context),
"php" => php::module(context),
"pijul_channel" => pijul_channel::module(context),
"pulumi" => pulumi::module(context),
"purescript" => purescript::module(context),
"python" => python::module(context),
@ -249,7 +251,7 @@ pub fn description(module: &str) -> &'static str {
"haskell" => "The selected version of the Haskell toolchain",
"haxe" => "The currently installed version of Haxe",
"helm" => "The currently installed version of Helm",
"hg_branch" => "The active branch of the repo in your current directory",
"hg_branch" => "The active branch and topic of the repo in your current directory",
"hostname" => "The system hostname",
"java" => "The currently installed version of Java",
"jobs" => "The current number of jobs running",
@ -273,6 +275,7 @@ pub fn description(module: &str) -> &'static str {
"package" => "The package version of the current directory's project",
"perl" => "The currently installed version of Perl",
"php" => "The currently installed version of PHP",
"pijul_channel" => "The current channel of the repo in the current directory",
"pulumi" => "The current username, stack, and installed version of Pulumi",
"purescript" => "The currently installed version of PureScript",
"python" => "The currently installed version of Python",

View File

@ -0,0 +1,220 @@
use super::utils::truncate::truncate_text;
use super::{Context, Module, ModuleConfig};
use crate::configs::pijul_channel::PijulConfig;
use crate::formatter::StringFormatter;
/// Creates a module with the Pijul channel in the current directory
///
/// Will display the channel lame if the current directory is a pijul repo
pub fn module<'a>(context: &'a Context) -> Option<Module<'a>> {
let is_repo = context
.try_begin_scan()?
.set_folders(&[".pijul"])
.is_match();
if !is_repo {
return None;
}
let mut module = context.new_module("pijul_channel");
let config: PijulConfig = PijulConfig::try_load(module.config);
// We default to disabled=true, so we have to check after loading our config module.
if config.disabled {
return None;
};
let channel_name = get_pijul_current_channel(context)?;
let truncated_text = truncate_text(
&channel_name,
config.truncation_length as usize,
config.truncation_symbol,
);
let parsed = StringFormatter::new(config.format).and_then(|formatter| {
formatter
.map_meta(|variable, _| match variable {
"symbol" => Some(config.symbol),
_ => None,
})
.map_style(|variable| match variable {
"style" => Some(Ok(config.style)),
_ => None,
})
.map(|variable| match variable {
"channel" => Some(Ok(&truncated_text)),
_ => None,
})
.parse(None, Some(context))
});
module.set_segments(match parsed {
Ok(segments) => segments,
Err(error) => {
log::warn!("Error in module `pijul_channel`:\n{}", error);
return None;
}
});
Some(module)
}
fn get_pijul_current_channel(ctx: &Context) -> Option<String> {
let output = ctx.exec_cmd("pijul", &["channel"])?.stdout;
output
.lines()
.find_map(|l| l.strip_prefix("* "))
.map(str::to_owned)
}
#[cfg(test)]
mod tests {
use nu_ansi_term::{Color, Style};
use std::io;
use std::path::Path;
use crate::test::{fixture_repo, FixtureProvider, ModuleRenderer};
enum Expect<'a> {
ChannelName(&'a str),
Empty,
NoTruncation,
Symbol(&'a str),
Style(Style),
TruncationSymbol(&'a str),
}
#[test]
fn show_nothing_on_empty_dir() -> io::Result<()> {
let repo_dir = tempfile::tempdir()?;
let actual = ModuleRenderer::new("pijul_channel")
.path(repo_dir.path())
.collect();
let expected = None;
assert_eq!(expected, actual);
repo_dir.close()
}
#[test]
fn test_pijul_disabled_per_default() -> io::Result<()> {
let tempdir = fixture_repo(FixtureProvider::Pijul)?;
let repo_dir = tempdir.path();
expect_pijul_with_config(
repo_dir,
Some(toml::toml! {
[pijul_channel]
truncation_length = 14
}),
&[Expect::Empty],
);
tempdir.close()
}
#[test]
fn test_pijul_autodisabled() -> io::Result<()> {
let tempdir = tempfile::tempdir()?;
expect_pijul_with_config(tempdir.path(), None, &[Expect::Empty]);
tempdir.close()
}
#[test]
fn test_pijul_channel() -> io::Result<()> {
let tempdir = fixture_repo(FixtureProvider::Pijul)?;
let repo_dir = tempdir.path();
run_pijul(&["channel", "new", "tributary-48198"], repo_dir)?;
run_pijul(&["channel", "switch", "tributary-48198"], repo_dir)?;
expect_pijul_with_config(
repo_dir,
None,
&[Expect::ChannelName("tributary-48198"), Expect::NoTruncation],
);
tempdir.close()
}
#[test]
fn test_pijul_configured() -> io::Result<()> {
let tempdir = fixture_repo(FixtureProvider::Pijul)?;
let repo_dir = tempdir.path();
run_pijul(&["channel", "new", "tributary-48198"], repo_dir)?;
run_pijul(&["channel", "switch", "tributary-48198"], repo_dir)?;
expect_pijul_with_config(
repo_dir,
Some(toml::toml! {
[pijul_channel]
style = "underline blue"
symbol = "P "
truncation_length = 14
truncation_symbol = "%"
disabled = false
}),
&[
Expect::ChannelName("tributary-4819"),
Expect::Style(Color::Blue.underline()),
Expect::Symbol("P"),
Expect::TruncationSymbol("%"),
],
);
tempdir.close()
}
fn expect_pijul_with_config(
repo_dir: &Path,
config: Option<toml::Value>,
expectations: &[Expect],
) {
let actual = ModuleRenderer::new("pijul_channel")
.path(repo_dir.to_str().unwrap())
.config(config.unwrap_or_else(|| {
toml::toml! {
[pijul_channel]
disabled = false
}
}))
.collect();
let mut expect_channel_name = "main";
let mut expect_style = Color::Purple.bold();
let mut expect_symbol = "\u{e0a0}";
let mut expect_truncation_symbol = "";
for expect in expectations {
match expect {
Expect::Empty => {
assert_eq!(None, actual);
return;
}
Expect::Symbol(symbol) => {
expect_symbol = symbol;
}
Expect::TruncationSymbol(truncation_symbol) => {
expect_truncation_symbol = truncation_symbol;
}
Expect::NoTruncation => {
expect_truncation_symbol = "";
}
Expect::ChannelName(channel_name) => {
expect_channel_name = channel_name;
}
Expect::Style(style) => expect_style = *style,
}
}
let expected = Some(format!(
"on {} ",
expect_style.paint(format!(
"{expect_symbol} {expect_channel_name}{expect_truncation_symbol}"
)),
));
assert_eq!(expected, actual);
}
fn run_pijul(args: &[&str], _repo_dir: &Path) -> io::Result<()> {
crate::utils::mock_cmd("pijul", args).ok_or(io::ErrorKind::Unsupported)?;
Ok(())
}
}

View File

@ -337,6 +337,27 @@ mod tests {
}
}
#[test]
fn failure_plaintext_status() {
let exit_values = [1, 2, 130];
for status in &exit_values {
let expected = Some(format!(
"{} ",
Color::Red.bold().paint(format!("x {status}"))
));
let actual = ModuleRenderer::new("status")
.config(toml::toml! {
[status]
symbol = "[x](bold red) "
disabled = false
})
.status(*status)
.collect();
assert_eq!(expected, actual);
}
}
#[test]
fn failure_hex_status() {
let exit_values = [1, 2, 130, -2_147_467_260, 2_147_500_036];

View File

@ -13,6 +13,8 @@ pub trait PathExt {
/// E.g. `\\?\UNC\server\share\foo` => `\foo`
/// E.g. `/foo/bar` => `/foo/bar`
fn without_prefix(&self) -> &Path;
/// Get device / volume info
fn device_id(&self) -> Option<u64>;
}
#[cfg(windows)]
@ -80,6 +82,11 @@ impl PathExt for Path {
let (_, path) = normalize::normalize_path(self);
path
}
fn device_id(&self) -> Option<u64> {
// Maybe it should use unimplemented!
Some(42u64)
}
}
// NOTE: Windows path prefixes are only parsed on Windows.
@ -100,6 +107,24 @@ impl PathExt for Path {
fn without_prefix(&self) -> &Path {
self
}
#[cfg(target_os = "linux")]
fn device_id(&self) -> Option<u64> {
use std::os::linux::fs::MetadataExt;
match self.metadata() {
Ok(m) => Some(m.st_dev()),
Err(_) => None,
}
}
#[cfg(all(unix, not(target_os = "linux")))]
fn device_id(&self) -> Option<u64> {
use std::os::unix::fs::MetadataExt;
match self.metadata() {
Ok(m) => Some(m.dev()),
Err(_) => None,
}
}
}
#[cfg(test)]

View File

@ -7,6 +7,7 @@ use crate::{
};
use log::{Level, LevelFilter};
use once_cell::sync::Lazy;
use std::fs;
use std::io;
use std::path::{Path, PathBuf};
use tempfile::TempDir;
@ -165,6 +166,7 @@ impl<'a> ModuleRenderer<'a> {
pub enum FixtureProvider {
Git,
Hg,
Pijul,
}
pub fn fixture_repo(provider: FixtureProvider) -> io::Result<TempDir> {
@ -223,5 +225,10 @@ pub fn fixture_repo(provider: FixtureProvider) -> io::Result<TempDir> {
Ok(path)
}
FixtureProvider::Pijul => {
let path = tempfile::tempdir()?;
fs::create_dir(path.path().join(".pijul"))?;
Ok(path)
}
}
}

View File

@ -337,6 +337,18 @@ WebAssembly: unavailable
stderr: String::default(),
})
},
"pijul channel" => Some(CommandOutput{
stdout: String::from(" main\n* tributary-48198"),
stderr: String::default(),
}),
"pijul channel new tributary-48198" => Some(CommandOutput{
stdout: String::default(),
stderr: String::default(),
}),
"pijul channel switch tributary-48198" => Some(CommandOutput{
stdout: String::from("Outputting repository ↖"),
stderr: String::default(),
}),
"pulumi version" => Some(CommandOutput{
stdout: String::from("1.2.3-ver.1631311768+e696fb6c"),
stderr: String::default(),