feat(statusline): support display `relative path`

pull/11342/head
roadup 4 months ago
parent a1e20a3426
commit 1869e50999

@ -614,7 +614,13 @@ impl<T: 'static + Send + Sync, D: 'static + Send + Sync> Picker<T, D> {
(size, _) if size > MAX_FILE_SIZE_FOR_PREVIEW => {
CachedPreview::LargeFile
}
_ => Document::open(&path, None, None, editor.config.clone())
_ => Document::open(
&path,
None,
None,
editor.config.clone(),
&editor.diff_providers,
)
.map(|doc| {
// Asynchronously highlight the new document
helix_event::send_blocking(

@ -143,6 +143,7 @@ where
helix_view::editor::StatusLineElement::FileBaseName => render_file_base_name,
helix_view::editor::StatusLineElement::FileName => render_file_name,
helix_view::editor::StatusLineElement::FileAbsolutePath => render_file_absolute_path,
helix_view::editor::StatusLineElement::FileRelativePath => render_file_relative_path,
helix_view::editor::StatusLineElement::FileModificationIndicator => {
render_file_modification_indicator
}
@ -447,6 +448,27 @@ where
write(context, title, None);
}
fn render_file_relative_path<F>(context: &mut RenderContext, write: F)
where
F: Fn(&mut RenderContext, String, Option<Style>) + Copy,
{
let title = {
let path = context.doc.path();
let root = &context.doc.repo_root_dir;
let path = path
.as_ref()
.map(|p| {
p.strip_prefix(root.as_path())
.unwrap_or(p)
.to_string_lossy()
})
.unwrap_or_else(|| SCRATCH_BUFFER_NAME.into());
format!(" {} ", path)
};
write(context, title, None);
}
fn render_file_modification_indicator<F>(context: &mut RenderContext, write: F)
where
F: Fn(&mut RenderContext, String, Option<Style>) + Copy,

@ -1,8 +1,9 @@
use anyhow::{bail, Context, Result};
use arc_swap::ArcSwap;
use gix::filter::plumbing::driver::apply::Delay;
use gix::path::env;
use std::io::Read;
use std::path::Path;
use std::path::{Path, PathBuf};
use std::sync::Arc;
use gix::bstr::ByteSlice;
@ -117,6 +118,24 @@ fn open_repo(path: &Path) -> Result<ThreadSafeRepository> {
Ok(res)
}
pub fn get_repo_root_dir(file: &Path) -> Result<Arc<PathBuf>> {
debug_assert!(!file.exists() || file.is_file());
debug_assert!(file.is_absolute());
let repo_dir = file.parent().context("file has no parent directory")?;
Ok(Arc::new(match open_repo(repo_dir) {
Ok(repo) => repo
.work_dir()
.unwrap_or_else(|| Path::new("/"))
.to_path_buf(),
Err(_) => match env::home_dir() {
Some(p) => p,
None => PathBuf::from("/"),
},
}))
}
/// Emulates the result of running `git status` from the command line.
fn status(repo: &Repository, f: impl Fn(Result<FileChange>) -> bool) -> Result<()> {
let work_dir = repo

@ -66,6 +66,15 @@ impl DiffProviderRegistry {
}
});
}
pub fn get_repo_root(&self, cwd: &Path) -> Arc<PathBuf> {
self.providers
.iter()
.find_map(|provider| match provider.get_repo_root_dir(cwd) {
Ok(res) => Some(res),
Err(_) => None,
})
.unwrap_or_else(|| Arc::new(PathBuf::from("/")))
}
}
impl Default for DiffProviderRegistry {
@ -119,4 +128,12 @@ impl DiffProvider {
Self::None => bail!("No diff support compiled in"),
}
}
fn get_repo_root_dir(&self, cwd: &Path) -> Result<Arc<PathBuf>> {
match self {
#[cfg(feature = "git")]
DiffProvider::Git => git::get_repo_root_dir(cwd),
DiffProvider::None => bail!("No diff support compiled in"),
}
}
}

@ -191,6 +191,8 @@ pub struct Document {
pub focused_at: std::time::Instant,
pub readonly: bool,
pub repo_root_dir: Arc<PathBuf>,
}
/// Inlay hints for a single `(Document, View)` combo.
@ -683,6 +685,7 @@ impl Document {
focused_at: std::time::Instant::now(),
readonly: false,
jump_labels: HashMap::new(),
repo_root_dir: Arc::new(PathBuf::from("/")),
}
}
@ -700,6 +703,7 @@ impl Document {
encoding: Option<&'static Encoding>,
config_loader: Option<Arc<ArcSwap<syntax::Loader>>>,
config: Arc<dyn DynAccess<Config>>,
provider_registry: &DiffProviderRegistry,
) -> Result<Self, DocumentOpenError> {
// If the path is not a regular file (e.g.: /dev/random) it should not be opened.
if path
@ -729,6 +733,8 @@ impl Document {
doc.detect_indent_and_line_ending();
doc.repo_root_dir = provider_registry.get_repo_root(path);
Ok(doc)
}

@ -530,6 +530,9 @@ pub enum StatusLineElement {
/// The file absolute path
FileAbsolutePath,
/// The file relative path base on repo or home dir
FileRelativePath,
// The file modification indicator
FileModificationIndicator,
@ -1698,6 +1701,7 @@ impl Editor {
None,
Some(self.syn_loader.clone()),
self.config.clone(),
&self.diff_providers,
)?;
let diagnostics =

Loading…
Cancel
Save