1
0
mirror of https://github.com/Llewellynvdm/starship.git synced 2024-12-26 19:40:20 +00:00

Add the Git branch segment (#32)

Added
- Repository to Context for reuse in directory and git_branch
- git_branch to prompt

Changed
- Made segments bold to match spaceship
This commit is contained in:
Matan Kushner 2019-04-26 22:07:07 -04:00 committed by GitHub
parent 85e4b11f0b
commit 9a352c0acc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 62 additions and 20 deletions

View File

@ -1,4 +1,5 @@
use clap::ArgMatches; use clap::ArgMatches;
use git2::Repository;
use std::env; use std::env;
use std::fs; use std::fs;
use std::path::PathBuf; use std::path::PathBuf;
@ -7,6 +8,7 @@ pub struct Context<'a> {
pub current_dir: PathBuf, pub current_dir: PathBuf,
pub dir_files: Vec<PathBuf>, pub dir_files: Vec<PathBuf>,
pub arguments: ArgMatches<'a>, pub arguments: ArgMatches<'a>,
pub repository: Option<Repository>,
} }
impl<'a> Context<'a> { impl<'a> Context<'a> {
@ -34,10 +36,13 @@ impl<'a> Context<'a> {
.map(|entry| entry.path()) .map(|entry| entry.path())
.collect::<Vec<PathBuf>>(); .collect::<Vec<PathBuf>>();
let repository: Option<Repository> = Repository::discover(&current_dir).ok();
Context { Context {
current_dir,
arguments, arguments,
current_dir,
dir_files, dir_files,
repository,
} }
} }

View File

@ -1,5 +1,4 @@
use ansi_term::Color; use ansi_term::Color;
use git2::Repository;
use std::path::Path; use std::path::Path;
use super::Segment; use super::Segment;
@ -23,17 +22,17 @@ pub fn segment(context: &Context) -> Option<Segment> {
let current_dir = &context.current_dir; let current_dir = &context.current_dir;
let dir_string; let dir_string;
if let Ok(repo) = git2::Repository::discover(current_dir) { if let Some(repo) = &context.repository {
// Contract the path to the git repo root // Contract the path to the git repo root
let repo_root = get_repo_root(&repo); let repo_root = repo.workdir().unwrap();
let repo_folder_name = repo_root.file_name().unwrap().to_str().unwrap(); let repo_folder_name = repo_root.file_name().unwrap().to_str().unwrap();
dir_string = contract_path(current_dir, repo_root, repo_folder_name); dir_string = contract_path(&current_dir, repo_root, repo_folder_name);
} else { } else {
// Contract the path to the home directory // Contract the path to the home directory
let home_dir = dirs::home_dir().unwrap(); let home_dir = dirs::home_dir().unwrap();
dir_string = contract_path(current_dir, &home_dir, HOME_SYMBOL); dir_string = contract_path(&current_dir, &home_dir, HOME_SYMBOL);
} }
// Truncate the dir string to the maximum number of path components // Truncate the dir string to the maximum number of path components
@ -46,17 +45,6 @@ pub fn segment(context: &Context) -> Option<Segment> {
Some(segment) Some(segment)
} }
/// Get the root directory of a git repo
fn get_repo_root(repo: &Repository) -> &Path {
if repo.is_bare() {
// Bare repos will return the repo root
repo.path()
} else {
// Non-bare repos will return the path of `.git`
repo.path().parent().unwrap()
}
}
/// Contract the root component of a path /// Contract the root component of a path
/// ///
/// Replaces the `top_level_path` in a given `full_path` with the provided /// Replaces the `top_level_path` in a given `full_path` with the provided

46
src/modules/git_branch.rs Normal file
View File

@ -0,0 +1,46 @@
use ansi_term::Color;
use git2::Repository;
use super::Segment;
use crate::context::Context;
/// Creates a segment with the Git branch in the current directory
///
/// Will display the branch name if the current directory is a git repo
pub fn segment(context: &Context) -> Option<Segment> {
if context.repository.is_none() {
return None;
}
let repository = context.repository.as_ref().unwrap();
match get_current_branch(repository) {
Ok(branch_name) => {
const GIT_BRANCH_CHAR: &str = "";
const SEGMENT_COLOR: Color = Color::Purple;
// TODO: Make the prefix for the module "in "
let mut segment_prefix = Segment::new("git_branch_prefix");
segment_prefix
.set_value(GIT_BRANCH_CHAR)
.set_style(SEGMENT_COLOR.bold());
let mut segment = Segment::new("git_branch");
segment
.set_prefix(Some(Box::new(segment_prefix)))
.set_style(SEGMENT_COLOR.bold())
.set_value(branch_name);
Some(segment)
}
Err(_e) => None,
}
}
fn get_current_branch(repository: &Repository) -> Result<String, git2::Error> {
let head = repository.head()?;
let head_name = head.shorthand();
match head_name {
Some(name) => Ok(name.to_string()),
None => Err(git2::Error::from_str("No branch name found")),
}
}

View File

@ -1,5 +1,6 @@
mod character; mod character;
mod directory; mod directory;
mod git_branch;
mod line_break; mod line_break;
mod nodejs; mod nodejs;
mod python; mod python;
@ -16,6 +17,7 @@ pub fn handle(module: &str, context: &Context) -> Option<Segment> {
"rust" | "rustlang" => rust::segment(context), "rust" | "rustlang" => rust::segment(context),
"python" => python::segment(context), "python" => python::segment(context),
"line_break" => line_break::segment(context), "line_break" => line_break::segment(context),
"git_branch" => git_branch::segment(context),
_ => panic!("Unknown module: {}", module), _ => panic!("Unknown module: {}", module),
} }

View File

@ -23,7 +23,7 @@ pub fn segment(context: &Context) -> Option<Segment> {
const SEGMENT_COLOR: Color = Color::Green; const SEGMENT_COLOR: Color = Color::Green;
let mut segment = Segment::new("node"); let mut segment = Segment::new("node");
segment.set_style(SEGMENT_COLOR); segment.set_style(SEGMENT_COLOR.bold());
let formatted_version = node_version.trim(); let formatted_version = node_version.trim();
segment.set_value(format!("{} {}", NODE_CHAR, formatted_version)); segment.set_value(format!("{} {}", NODE_CHAR, formatted_version));

View File

@ -23,7 +23,7 @@ pub fn segment(context: &Context) -> Option<Segment> {
const SEGMENT_COLOR: Color = Color::Yellow; const SEGMENT_COLOR: Color = Color::Yellow;
let mut segment = Segment::new("python"); let mut segment = Segment::new("python");
segment.set_style(SEGMENT_COLOR); segment.set_style(SEGMENT_COLOR.bold());
let formatted_version = format_python_version(python_version); let formatted_version = format_python_version(python_version);
segment.set_value(format!("{} {}", PYTHON_CHAR, formatted_version)); segment.set_value(format!("{} {}", PYTHON_CHAR, formatted_version));

View File

@ -21,7 +21,7 @@ pub fn segment(context: &Context) -> Option<Segment> {
const SEGMENT_COLOR: Color = Color::Red; const SEGMENT_COLOR: Color = Color::Red;
let mut segment = Segment::new("rust"); let mut segment = Segment::new("rust");
segment.set_style(SEGMENT_COLOR); segment.set_style(SEGMENT_COLOR.bold());
let formatted_version = format_rustc_version(rust_version); let formatted_version = format_rustc_version(rust_version);
segment.set_value(format!("{} {}", RUST_CHAR, formatted_version)); segment.set_value(format!("{} {}", RUST_CHAR, formatted_version));

View File

@ -7,6 +7,7 @@ use crate::modules;
pub fn prompt(args: ArgMatches) { pub fn prompt(args: ArgMatches) {
let prompt_order = vec![ let prompt_order = vec![
"directory", "directory",
"git_branch",
"nodejs", "nodejs",
"rust", "rust",
"python", "python",