1
0
mirror of https://github.com/Llewellynvdm/starship.git synced 2024-12-01 01:04:00 +00:00

feat: add typechange to git_status module (#4829)

Co-authored-by: David Knaack <davidkna@users.noreply.github.com>
This commit is contained in:
Chad Denyar 2023-04-13 15:02:08 -04:00 committed by GitHub
parent b2f902b3e9
commit edb96cad58
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 102 additions and 3 deletions

View File

@ -617,6 +617,7 @@
"staged": "+", "staged": "+",
"stashed": "\\$", "stashed": "\\$",
"style": "red bold", "style": "red bold",
"typechanged": "",
"untracked": "?", "untracked": "?",
"up_to_date": "" "up_to_date": ""
}, },
@ -3284,6 +3285,10 @@
"default": "?", "default": "?",
"type": "string" "type": "string"
}, },
"typechanged": {
"default": "",
"type": "string"
},
"ignore_submodules": { "ignore_submodules": {
"default": false, "default": false,
"type": "boolean" "type": "boolean"

View File

@ -1860,6 +1860,7 @@ You can disable the module or use the `windows_starship` option to use a Windows
| `staged` | `'+'` | The format of `staged` | | `staged` | `'+'` | The format of `staged` |
| `renamed` | `'»'` | The format of `renamed` | | `renamed` | `'»'` | The format of `renamed` |
| `deleted` | `'✘'` | The format of `deleted` | | `deleted` | `'✘'` | The format of `deleted` |
| `typechanged` | `""` | The format of `typechange` |
| `style` | `'bold red'` | The style for the module. | | `style` | `'bold red'` | The style for the module. |
| `ignore_submodules` | `false` | Ignore changes to submodules. | | `ignore_submodules` | `false` | Ignore changes to submodules. |
| `disabled` | `false` | Disables the `git_status` module. | | `disabled` | `false` | Disables the `git_status` module. |
@ -1880,6 +1881,7 @@ The following variables can be used in `format`:
| `staged` | Displays `staged` when a new file has been added to the staging area. | | `staged` | Displays `staged` when a new file has been added to the staging area. |
| `renamed` | Displays `renamed` when a renamed file has been added to the staging area. | | `renamed` | Displays `renamed` when a renamed file has been added to the staging area. |
| `deleted` | Displays `deleted` when a file's deletion has been added to the staging area. | | `deleted` | Displays `deleted` when a file's deletion has been added to the staging area. |
| `typechanged` | Displays `typechange` when a file's type has been changed in the staging area. |
| style\* | Mirrors the value of option `style` | | style\* | Mirrors the value of option `style` |
*: This variable can only be used as a part of a style string *: This variable can only be used as a part of a style string

View File

@ -21,6 +21,7 @@ pub struct GitStatusConfig<'a> {
pub modified: &'a str, pub modified: &'a str,
pub staged: &'a str, pub staged: &'a str,
pub untracked: &'a str, pub untracked: &'a str,
pub typechanged: &'a str,
pub ignore_submodules: bool, pub ignore_submodules: bool,
pub disabled: bool, pub disabled: bool,
#[serde(skip_serializing_if = "Option::is_none")] #[serde(skip_serializing_if = "Option::is_none")]
@ -43,6 +44,7 @@ impl<'a> Default for GitStatusConfig<'a> {
modified: "!", modified: "!",
staged: "+", staged: "+",
untracked: "?", untracked: "?",
typechanged: "",
ignore_submodules: false, ignore_submodules: false,
disabled: false, disabled: false,
windows_starship: None, windows_starship: None,

View File

@ -9,7 +9,8 @@ use crate::segment::Segment;
use std::ffi::OsStr; use std::ffi::OsStr;
use std::sync::Arc; use std::sync::Arc;
const ALL_STATUS_FORMAT: &str = "$conflicted$stashed$deleted$renamed$modified$staged$untracked"; const ALL_STATUS_FORMAT: &str =
"$conflicted$stashed$deleted$renamed$modified$typechanged$staged$untracked";
/// Creates a module with the Git branch in the current directory /// Creates a module with the Git branch in the current directory
/// ///
@ -98,6 +99,9 @@ pub fn module<'a>(context: &'a Context) -> Option<Module<'a>> {
"untracked" => info.get_untracked().and_then(|count| { "untracked" => info.get_untracked().and_then(|count| {
format_count(config.untracked, "git_status.untracked", context, count) format_count(config.untracked, "git_status.untracked", context, count)
}), }),
"typechanged" => info.get_typechanged().and_then(|count| {
format_count(config.typechanged, "git_status.typechanged", context, count)
}),
_ => None, _ => None,
}; };
segments.map(Ok) segments.map(Ok)
@ -188,6 +192,10 @@ impl<'a> GitStatusInfo<'a> {
pub fn get_untracked(&self) -> Option<usize> { pub fn get_untracked(&self) -> Option<usize> {
self.get_repo_status().map(|data| data.untracked) self.get_repo_status().map(|data| data.untracked)
} }
pub fn get_typechanged(&self) -> Option<usize> {
self.get_repo_status().map(|data| data.typechanged)
}
} }
/// Gets the number of files in various git states (staged, modified, deleted, etc...) /// Gets the number of files in various git states (staged, modified, deleted, etc...)
@ -259,6 +267,7 @@ struct RepoStatus {
renamed: usize, renamed: usize,
modified: usize, modified: usize,
staged: usize, staged: usize,
typechanged: usize,
untracked: usize, untracked: usize,
} }
@ -274,8 +283,14 @@ impl RepoStatus {
} }
fn is_staged(short_status: &str) -> bool { fn is_staged(short_status: &str) -> bool {
// is_index_modified || is_index_added // is_index_modified || is_index_added || is_index_typechanged
short_status.starts_with('M') || short_status.starts_with('A') short_status.starts_with('M')
|| short_status.starts_with('A')
|| short_status.starts_with('T')
}
fn is_typechanged(short_status: &str) -> bool {
short_status.ends_with('T')
} }
fn parse_normal_status(&mut self, short_status: &str) { fn parse_normal_status(&mut self, short_status: &str) {
@ -290,6 +305,10 @@ impl RepoStatus {
if Self::is_staged(short_status) { if Self::is_staged(short_status) {
self.staged += 1; self.staged += 1;
} }
if Self::is_typechanged(short_status) {
self.typechanged += 1;
}
} }
fn add(&mut self, s: &str) { fn add(&mut self, s: &str) {
@ -754,6 +773,25 @@ mod tests {
repo_dir.close() repo_dir.close()
} }
#[test]
fn shows_typechanged() -> io::Result<()> {
let repo_dir = fixture_repo(FixtureProvider::Git)?;
create_typechanged(repo_dir.path())?;
let actual = ModuleRenderer::new("git_status")
.config(toml::toml! {
[git_status]
typechanged = ""
})
.path(repo_dir.path())
.collect();
let expected = format_output("");
assert_eq!(expected, actual);
repo_dir.close()
}
#[test] #[test]
fn shows_modified() -> io::Result<()> { fn shows_modified() -> io::Result<()> {
let repo_dir = fixture_repo(FixtureProvider::Git)?; let repo_dir = fixture_repo(FixtureProvider::Git)?;
@ -844,6 +882,32 @@ mod tests {
repo_dir.close() repo_dir.close()
} }
#[test]
fn shows_staged_typechange_with_count() -> io::Result<()> {
let repo_dir = fixture_repo(FixtureProvider::Git)?;
create_staged_typechange(repo_dir.path())?;
let actual = ModuleRenderer::new("git_status")
.config(toml::toml! {
[git_status]
staged = "+[$count](green)"
})
.path(repo_dir.path())
.collect();
let expected = Some(format!(
"{} ",
AnsiStrings(&[
Color::Red.bold().paint("[+"),
Color::Green.paint("1"),
Color::Red.bold().paint("]"),
])
));
assert_eq!(expected, actual);
repo_dir.close()
}
#[test] #[test]
fn shows_staged_and_modified_file() -> io::Result<()> { fn shows_staged_and_modified_file() -> io::Result<()> {
let repo_dir = fixture_repo(FixtureProvider::Git)?; let repo_dir = fixture_repo(FixtureProvider::Git)?;
@ -1057,6 +1121,32 @@ mod tests {
Ok(()) Ok(())
} }
fn create_typechanged(repo_dir: &Path) -> io::Result<()> {
fs::remove_file(repo_dir.join("readme.md"))?;
#[cfg(not(target_os = "windows"))]
std::os::unix::fs::symlink(repo_dir.join("Cargo.toml"), repo_dir.join("readme.md"))?;
#[cfg(target_os = "windows")]
std::os::windows::fs::symlink_file(
repo_dir.join("Cargo.toml"),
repo_dir.join("readme.md"),
)?;
Ok(())
}
fn create_staged_typechange(repo_dir: &Path) -> io::Result<()> {
create_typechanged(repo_dir)?;
create_command("git")?
.args(["add", "."])
.current_dir(repo_dir)
.output()?;
Ok(())
}
fn create_conflict(repo_dir: &Path) -> io::Result<()> { fn create_conflict(repo_dir: &Path) -> io::Result<()> {
create_command("git")? create_command("git")?
.args(["reset", "--hard", "HEAD^"]) .args(["reset", "--hard", "HEAD^"])