mirror of
https://github.com/helix-editor/helix.git
synced 2024-11-22 17:36:19 +04:00
feat(statusline): support display relative path
This commit is contained in:
parent
a1e20a3426
commit
1869e50999
@ -614,7 +614,13 @@ fn get_preview<'picker, 'editor>(
|
|||||||
(size, _) if size > MAX_FILE_SIZE_FOR_PREVIEW => {
|
(size, _) if size > MAX_FILE_SIZE_FOR_PREVIEW => {
|
||||||
CachedPreview::LargeFile
|
CachedPreview::LargeFile
|
||||||
}
|
}
|
||||||
_ => Document::open(&path, None, None, editor.config.clone())
|
_ => Document::open(
|
||||||
|
&path,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
editor.config.clone(),
|
||||||
|
&editor.diff_providers,
|
||||||
|
)
|
||||||
.map(|doc| {
|
.map(|doc| {
|
||||||
// Asynchronously highlight the new document
|
// Asynchronously highlight the new document
|
||||||
helix_event::send_blocking(
|
helix_event::send_blocking(
|
||||||
|
@ -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::FileBaseName => render_file_base_name,
|
||||||
helix_view::editor::StatusLineElement::FileName => render_file_name,
|
helix_view::editor::StatusLineElement::FileName => render_file_name,
|
||||||
helix_view::editor::StatusLineElement::FileAbsolutePath => render_file_absolute_path,
|
helix_view::editor::StatusLineElement::FileAbsolutePath => render_file_absolute_path,
|
||||||
|
helix_view::editor::StatusLineElement::FileRelativePath => render_file_relative_path,
|
||||||
helix_view::editor::StatusLineElement::FileModificationIndicator => {
|
helix_view::editor::StatusLineElement::FileModificationIndicator => {
|
||||||
render_file_modification_indicator
|
render_file_modification_indicator
|
||||||
}
|
}
|
||||||
@ -447,6 +448,27 @@ fn render_file_absolute_path<F>(context: &mut RenderContext, write: F)
|
|||||||
write(context, title, None);
|
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)
|
fn render_file_modification_indicator<F>(context: &mut RenderContext, write: F)
|
||||||
where
|
where
|
||||||
F: Fn(&mut RenderContext, String, Option<Style>) + Copy,
|
F: Fn(&mut RenderContext, String, Option<Style>) + Copy,
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
use anyhow::{bail, Context, Result};
|
use anyhow::{bail, Context, Result};
|
||||||
use arc_swap::ArcSwap;
|
use arc_swap::ArcSwap;
|
||||||
use gix::filter::plumbing::driver::apply::Delay;
|
use gix::filter::plumbing::driver::apply::Delay;
|
||||||
|
use gix::path::env;
|
||||||
use std::io::Read;
|
use std::io::Read;
|
||||||
use std::path::Path;
|
use std::path::{Path, PathBuf};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use gix::bstr::ByteSlice;
|
use gix::bstr::ByteSlice;
|
||||||
@ -117,6 +118,24 @@ fn open_repo(path: &Path) -> Result<ThreadSafeRepository> {
|
|||||||
Ok(res)
|
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.
|
/// Emulates the result of running `git status` from the command line.
|
||||||
fn status(repo: &Repository, f: impl Fn(Result<FileChange>) -> bool) -> Result<()> {
|
fn status(repo: &Repository, f: impl Fn(Result<FileChange>) -> bool) -> Result<()> {
|
||||||
let work_dir = repo
|
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 {
|
impl Default for DiffProviderRegistry {
|
||||||
@ -119,4 +128,12 @@ fn for_each_changed_file(
|
|||||||
Self::None => bail!("No diff support compiled in"),
|
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 focused_at: std::time::Instant,
|
||||||
|
|
||||||
pub readonly: bool,
|
pub readonly: bool,
|
||||||
|
|
||||||
|
pub repo_root_dir: Arc<PathBuf>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Inlay hints for a single `(Document, View)` combo.
|
/// Inlay hints for a single `(Document, View)` combo.
|
||||||
@ -683,6 +685,7 @@ pub fn from(
|
|||||||
focused_at: std::time::Instant::now(),
|
focused_at: std::time::Instant::now(),
|
||||||
readonly: false,
|
readonly: false,
|
||||||
jump_labels: HashMap::new(),
|
jump_labels: HashMap::new(),
|
||||||
|
repo_root_dir: Arc::new(PathBuf::from("/")),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -700,6 +703,7 @@ pub fn open(
|
|||||||
encoding: Option<&'static Encoding>,
|
encoding: Option<&'static Encoding>,
|
||||||
config_loader: Option<Arc<ArcSwap<syntax::Loader>>>,
|
config_loader: Option<Arc<ArcSwap<syntax::Loader>>>,
|
||||||
config: Arc<dyn DynAccess<Config>>,
|
config: Arc<dyn DynAccess<Config>>,
|
||||||
|
provider_registry: &DiffProviderRegistry,
|
||||||
) -> Result<Self, DocumentOpenError> {
|
) -> Result<Self, DocumentOpenError> {
|
||||||
// If the path is not a regular file (e.g.: /dev/random) it should not be opened.
|
// If the path is not a regular file (e.g.: /dev/random) it should not be opened.
|
||||||
if path
|
if path
|
||||||
@ -729,6 +733,8 @@ pub fn open(
|
|||||||
|
|
||||||
doc.detect_indent_and_line_ending();
|
doc.detect_indent_and_line_ending();
|
||||||
|
|
||||||
|
doc.repo_root_dir = provider_registry.get_repo_root(path);
|
||||||
|
|
||||||
Ok(doc)
|
Ok(doc)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -530,6 +530,9 @@ pub enum StatusLineElement {
|
|||||||
/// The file absolute path
|
/// The file absolute path
|
||||||
FileAbsolutePath,
|
FileAbsolutePath,
|
||||||
|
|
||||||
|
/// The file relative path base on repo or home dir
|
||||||
|
FileRelativePath,
|
||||||
|
|
||||||
// The file modification indicator
|
// The file modification indicator
|
||||||
FileModificationIndicator,
|
FileModificationIndicator,
|
||||||
|
|
||||||
@ -1698,6 +1701,7 @@ pub fn open(&mut self, path: &Path, action: Action) -> Result<DocumentId, Docume
|
|||||||
None,
|
None,
|
||||||
Some(self.syn_loader.clone()),
|
Some(self.syn_loader.clone()),
|
||||||
self.config.clone(),
|
self.config.clone(),
|
||||||
|
&self.diff_providers,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
let diagnostics =
|
let diagnostics =
|
||||||
|
Loading…
Reference in New Issue
Block a user