From 1661e4b5e1d8ebfef28f798fcb86ba2656373ba0 Mon Sep 17 00:00:00 2001 From: Dimitar Gyurov Date: Fri, 10 Mar 2023 23:42:42 +0100 Subject: Add a version-control statusline element (#5682) --- helix-vcs/Cargo.toml | 1 + helix-vcs/src/git.rs | 17 +++++++++++++++++ helix-vcs/src/lib.rs | 14 +++++++++++++- 3 files changed, 31 insertions(+), 1 deletion(-) (limited to 'helix-vcs') diff --git a/helix-vcs/Cargo.toml b/helix-vcs/Cargo.toml index 789ee795..58c078b4 100644 --- a/helix-vcs/Cargo.toml +++ b/helix-vcs/Cargo.toml @@ -15,6 +15,7 @@ helix-core = { version = "0.6", path = "../helix-core" } tokio = { version = "1", features = ["rt", "rt-multi-thread", "time", "sync", "parking_lot", "macros"] } parking_lot = "0.12" +arc-swap = { version = "1.6.0" } gix = { version = "0.39.0", default-features = false , optional = true } imara-diff = "0.1.5" diff --git a/helix-vcs/src/git.rs b/helix-vcs/src/git.rs index 2a540c8d..1732bdd0 100644 --- a/helix-vcs/src/git.rs +++ b/helix-vcs/src/git.rs @@ -1,4 +1,6 @@ +use arc_swap::ArcSwap; use std::path::Path; +use std::sync::Arc; use gix::objs::tree::EntryMode; use gix::sec::trust::DefaultForLevel; @@ -87,6 +89,21 @@ impl DiffProvider for Git { } Some(data) } + + fn get_current_head_name(&self, file: &Path) -> Option>>> { + debug_assert!(!file.exists() || file.is_file()); + debug_assert!(file.is_absolute()); + let repo = Git::open_repo(file.parent()?, None)?.to_thread_local(); + let head_ref = repo.head_ref().ok()?; + let head_commit = repo.head_commit().ok()?; + + let name = match head_ref { + Some(reference) => reference.name().shorten().to_string(), + None => head_commit.id.to_hex_with_len(8).to_string(), + }; + + Some(Arc::new(ArcSwap::from_pointee(name.into_boxed_str()))) + } } /// Finds the object that contains the contents of a file at a specific commit. diff --git a/helix-vcs/src/lib.rs b/helix-vcs/src/lib.rs index 97320d32..6f5e40d0 100644 --- a/helix-vcs/src/lib.rs +++ b/helix-vcs/src/lib.rs @@ -1,4 +1,5 @@ -use std::path::Path; +use arc_swap::ArcSwap; +use std::{path::Path, sync::Arc}; #[cfg(feature = "git")] pub use git::Git; @@ -18,6 +19,7 @@ pub trait DiffProvider { /// The data is returned as raw byte without any decoding or encoding performed /// to ensure all file encodings are handled correctly. fn get_diff_base(&self, file: &Path) -> Option>; + fn get_current_head_name(&self, file: &Path) -> Option>>>; } #[doc(hidden)] @@ -26,6 +28,10 @@ impl DiffProvider for Dummy { fn get_diff_base(&self, _file: &Path) -> Option> { None } + + fn get_current_head_name(&self, _file: &Path) -> Option>>> { + None + } } pub struct DiffProviderRegistry { @@ -38,6 +44,12 @@ impl DiffProviderRegistry { .iter() .find_map(|provider| provider.get_diff_base(file)) } + + pub fn get_current_head_name(&self, file: &Path) -> Option>>> { + self.providers + .iter() + .find_map(|provider| provider.get_current_head_name(file)) + } } impl Default for DiffProviderRegistry { -- cgit v1.2.3-70-g09d2