mirror of
https://github.com/helix-editor/helix.git
synced 2024-11-22 09:26:19 +04:00
feat(statusline): support display relative path
This commit is contained in:
parent
a1e20a3426
commit
1869e50999
@ -614,16 +614,22 @@ fn get_preview<'picker, 'editor>(
|
||||
(size, _) if size > MAX_FILE_SIZE_FOR_PREVIEW => {
|
||||
CachedPreview::LargeFile
|
||||
}
|
||||
_ => Document::open(&path, None, None, editor.config.clone())
|
||||
.map(|doc| {
|
||||
// Asynchronously highlight the new document
|
||||
helix_event::send_blocking(
|
||||
&self.preview_highlight_handler,
|
||||
path.clone(),
|
||||
);
|
||||
CachedPreview::Document(Box::new(doc))
|
||||
})
|
||||
.unwrap_or(CachedPreview::NotFound),
|
||||
_ => Document::open(
|
||||
&path,
|
||||
None,
|
||||
None,
|
||||
editor.config.clone(),
|
||||
&editor.diff_providers,
|
||||
)
|
||||
.map(|doc| {
|
||||
// Asynchronously highlight the new document
|
||||
helix_event::send_blocking(
|
||||
&self.preview_highlight_handler,
|
||||
path.clone(),
|
||||
);
|
||||
CachedPreview::Document(Box::new(doc))
|
||||
})
|
||||
.unwrap_or(CachedPreview::NotFound),
|
||||
},
|
||||
)
|
||||
.unwrap_or(CachedPreview::NotFound);
|
||||
|
@ -143,6 +143,7 @@ fn get_render_function<F>(element_id: StatusLineElementID) -> impl Fn(&mut Rende
|
||||
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 @@ fn render_file_absolute_path<F>(context: &mut RenderContext, write: F)
|
||||
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 @@ pub fn for_each_changed_file(
|
||||
}
|
||||
});
|
||||
}
|
||||
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 @@ fn for_each_changed_file(
|
||||
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 @@ pub fn from(
|
||||
focused_at: std::time::Instant::now(),
|
||||
readonly: false,
|
||||
jump_labels: HashMap::new(),
|
||||
repo_root_dir: Arc::new(PathBuf::from("/")),
|
||||
}
|
||||
}
|
||||
|
||||
@ -700,6 +703,7 @@ pub fn open(
|
||||
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 @@ pub fn open(
|
||||
|
||||
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 @@ pub fn open(&mut self, path: &Path, action: Action) -> Result<DocumentId, Docume
|
||||
None,
|
||||
Some(self.syn_loader.clone()),
|
||||
self.config.clone(),
|
||||
&self.diff_providers,
|
||||
)?;
|
||||
|
||||
let diagnostics =
|
||||
|
Loading…
Reference in New Issue
Block a user