feat(git_branch): add 'only_attached' config bool (#1910)
* feat(git_branch): add 'only_attached' config bool This adds a new boolean, `only_attached`, to the configuration for the `git_branch` module. This mirrors the `only_detached` config value for the `git_commit` module: setting the value to true causes the module to suppress its output when the user is not on a branch. This allows users to have either a branch name or a commit hash in their prompt, as opposed to having either a branch name or the overly-wordy "HEAD (sha1)". * Fix formatting
This commit is contained in:
parent
29117c4817
commit
4b85b40cb0
|
@ -1030,6 +1030,7 @@ The `git_branch` module shows the active branch of the repo in your current dire
|
||||||
| `style` | `"bold purple"` | The style for the module. |
|
| `style` | `"bold purple"` | The style for the module. |
|
||||||
| `truncation_length` | `2^63 - 1` | Truncates a git branch to X graphemes. |
|
| `truncation_length` | `2^63 - 1` | Truncates a git branch to X graphemes. |
|
||||||
| `truncation_symbol` | `"…"` | The symbol used to indicate a branch name was truncated. You can use `""` for no symbol. |
|
| `truncation_symbol` | `"…"` | The symbol used to indicate a branch name was truncated. You can use `""` for no symbol. |
|
||||||
|
| `only_attached` | `false` | Only show the branch name when not in a detached HEAD state. |
|
||||||
| `disabled` | `false` | Disables the `git_branch` module. |
|
| `disabled` | `false` | Disables the `git_branch` module. |
|
||||||
|
|
||||||
### Variables
|
### Variables
|
||||||
|
|
|
@ -9,6 +9,7 @@ pub struct GitBranchConfig<'a> {
|
||||||
pub style: &'a str,
|
pub style: &'a str,
|
||||||
pub truncation_length: i64,
|
pub truncation_length: i64,
|
||||||
pub truncation_symbol: &'a str,
|
pub truncation_symbol: &'a str,
|
||||||
|
pub only_attached: bool,
|
||||||
pub disabled: bool,
|
pub disabled: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -20,6 +21,7 @@ impl<'a> RootModuleConfig<'a> for GitBranchConfig<'a> {
|
||||||
style: "bold purple",
|
style: "bold purple",
|
||||||
truncation_length: std::i64::MAX,
|
truncation_length: std::i64::MAX,
|
||||||
truncation_symbol: "…",
|
truncation_symbol: "…",
|
||||||
|
only_attached: false,
|
||||||
disabled: false,
|
disabled: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
use unicode_segmentation::UnicodeSegmentation;
|
use unicode_segmentation::UnicodeSegmentation;
|
||||||
|
|
||||||
use super::{Context, Module, RootModuleConfig};
|
use super::{Context, Module, RootModuleConfig};
|
||||||
|
use git2::Repository;
|
||||||
|
|
||||||
use crate::configs::git_branch::GitBranchConfig;
|
use crate::configs::git_branch::GitBranchConfig;
|
||||||
use crate::formatter::StringFormatter;
|
use crate::formatter::StringFormatter;
|
||||||
|
@ -25,6 +26,14 @@ pub fn module<'a>(context: &'a Context) -> Option<Module<'a>> {
|
||||||
};
|
};
|
||||||
|
|
||||||
let repo = context.get_repo().ok()?;
|
let repo = context.get_repo().ok()?;
|
||||||
|
|
||||||
|
let repo_root = repo.root.as_ref()?;
|
||||||
|
let git_repo = Repository::open(repo_root).ok()?;
|
||||||
|
let is_detached = git_repo.head_detached().ok()?;
|
||||||
|
if config.only_attached && is_detached {
|
||||||
|
return None;
|
||||||
|
};
|
||||||
|
|
||||||
let branch_name = repo.branch.as_ref()?;
|
let branch_name = repo.branch.as_ref()?;
|
||||||
|
|
||||||
let mut graphemes: Vec<&str> = branch_name.graphemes(true).collect();
|
let mut graphemes: Vec<&str> = branch_name.graphemes(true).collect();
|
||||||
|
@ -246,6 +255,57 @@ mod tests {
|
||||||
repo_dir.close()
|
repo_dir.close()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_render_branch_only_attached_on_branch() -> io::Result<()> {
|
||||||
|
let repo_dir = fixture_repo(FixtureProvider::GIT)?;
|
||||||
|
|
||||||
|
Command::new("git")
|
||||||
|
.args(&["checkout", "-b", "test_branch"])
|
||||||
|
.current_dir(repo_dir.path())
|
||||||
|
.output()?;
|
||||||
|
|
||||||
|
let actual = ModuleRenderer::new("git_branch")
|
||||||
|
.config(toml::toml! {
|
||||||
|
[git_branch]
|
||||||
|
only_attached = true
|
||||||
|
})
|
||||||
|
.path(&repo_dir.path())
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
let expected = Some(format!(
|
||||||
|
"on {} ",
|
||||||
|
Color::Purple
|
||||||
|
.bold()
|
||||||
|
.paint(format!("\u{e0a0} {}", "test_branch")),
|
||||||
|
));
|
||||||
|
|
||||||
|
assert_eq!(expected, actual);
|
||||||
|
repo_dir.close()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_render_branch_only_attached_on_detached() -> io::Result<()> {
|
||||||
|
let repo_dir = fixture_repo(FixtureProvider::GIT)?;
|
||||||
|
|
||||||
|
Command::new("git")
|
||||||
|
.args(&["checkout", "@~1"])
|
||||||
|
.current_dir(&repo_dir.path())
|
||||||
|
.output()?;
|
||||||
|
|
||||||
|
let actual = ModuleRenderer::new("git_branch")
|
||||||
|
.config(toml::toml! {
|
||||||
|
[git_branch]
|
||||||
|
only_attached = true
|
||||||
|
})
|
||||||
|
.path(&repo_dir.path())
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
let expected = None;
|
||||||
|
|
||||||
|
assert_eq!(expected, actual);
|
||||||
|
repo_dir.close()
|
||||||
|
}
|
||||||
|
|
||||||
// This test is not possible until we switch to `git status --porcelain`
|
// This test is not possible until we switch to `git status --porcelain`
|
||||||
// where we can mock the env for the specific git process. This is because
|
// where we can mock the env for the specific git process. This is because
|
||||||
// git2 does not care about our mocking and when we set the real `GIT_DIR`
|
// git2 does not care about our mocking and when we set the real `GIT_DIR`
|
||||||
|
|
Loading…
Reference in New Issue