|
|
|
@ -4,6 +4,7 @@ use helix_view::document::DEFAULT_LANGUAGE_NAME;
|
|
|
|
|
use helix_view::{
|
|
|
|
|
document::{Mode, SCRATCH_BUFFER_NAME},
|
|
|
|
|
graphics::Rect,
|
|
|
|
|
icons::Icon,
|
|
|
|
|
theme::Style,
|
|
|
|
|
Document, Editor, View,
|
|
|
|
|
};
|
|
|
|
@ -21,6 +22,7 @@ pub struct RenderContext<'a> {
|
|
|
|
|
pub focused: bool,
|
|
|
|
|
pub spinners: &'a ProgressSpinners,
|
|
|
|
|
pub parts: RenderBuffer<'a>,
|
|
|
|
|
pub icons: RenderContextIcons<'a>,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl<'a> RenderContext<'a> {
|
|
|
|
@ -31,6 +33,25 @@ impl<'a> RenderContext<'a> {
|
|
|
|
|
focused: bool,
|
|
|
|
|
spinners: &'a ProgressSpinners,
|
|
|
|
|
) -> Self {
|
|
|
|
|
// Determine icon based on language name if possible
|
|
|
|
|
let mut filetype_icon = None;
|
|
|
|
|
if let Some(language_config) = doc.language_config() {
|
|
|
|
|
for filetype in &language_config.file_types {
|
|
|
|
|
let filetype_str = match filetype {
|
|
|
|
|
helix_core::syntax::FileType::Extension(s) => s,
|
|
|
|
|
helix_core::syntax::FileType::Suffix(s) => s,
|
|
|
|
|
};
|
|
|
|
|
filetype_icon = editor.icons.icon_from_filetype(filetype_str);
|
|
|
|
|
if filetype_icon.is_some() {
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
// Otherwise based on filetype
|
|
|
|
|
if filetype_icon.is_none() {
|
|
|
|
|
filetype_icon = editor.icons.icon_from_path(doc.path())
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
RenderContext {
|
|
|
|
|
editor,
|
|
|
|
|
doc,
|
|
|
|
@ -38,10 +59,21 @@ impl<'a> RenderContext<'a> {
|
|
|
|
|
focused,
|
|
|
|
|
spinners,
|
|
|
|
|
parts: RenderBuffer::default(),
|
|
|
|
|
icons: RenderContextIcons {
|
|
|
|
|
enabled: editor.config().icons.statusline,
|
|
|
|
|
filetype_icon,
|
|
|
|
|
vcs_icon: editor.icons.ui.as_ref().and_then(|ui| ui.get("vcs_branch")),
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub struct RenderContextIcons<'a> {
|
|
|
|
|
pub enabled: bool,
|
|
|
|
|
pub filetype_icon: Option<&'a Icon>,
|
|
|
|
|
pub vcs_icon: Option<&'a Icon>,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[derive(Default)]
|
|
|
|
|
pub struct RenderBuffer<'a> {
|
|
|
|
|
pub left: Spans<'a>,
|
|
|
|
@ -148,6 +180,7 @@ where
|
|
|
|
|
helix_view::editor::StatusLineElement::FileEncoding => render_file_encoding,
|
|
|
|
|
helix_view::editor::StatusLineElement::FileLineEnding => render_file_line_ending,
|
|
|
|
|
helix_view::editor::StatusLineElement::FileType => render_file_type,
|
|
|
|
|
helix_view::editor::StatusLineElement::FileTypeIcon => render_file_type_icon,
|
|
|
|
|
helix_view::editor::StatusLineElement::Diagnostics => render_diagnostics,
|
|
|
|
|
helix_view::editor::StatusLineElement::WorkspaceDiagnostics => render_workspace_diagnostics,
|
|
|
|
|
helix_view::editor::StatusLineElement::Selections => render_selections,
|
|
|
|
@ -240,7 +273,13 @@ where
|
|
|
|
|
if warnings > 0 {
|
|
|
|
|
write(
|
|
|
|
|
context,
|
|
|
|
|
"●".to_string(),
|
|
|
|
|
context
|
|
|
|
|
.editor
|
|
|
|
|
.icons
|
|
|
|
|
.diagnostic
|
|
|
|
|
.warning
|
|
|
|
|
.icon_char
|
|
|
|
|
.to_string(),
|
|
|
|
|
Some(context.editor.theme.get("warning")),
|
|
|
|
|
);
|
|
|
|
|
write(context, format!(" {} ", warnings), None);
|
|
|
|
@ -249,7 +288,7 @@ where
|
|
|
|
|
if errors > 0 {
|
|
|
|
|
write(
|
|
|
|
|
context,
|
|
|
|
|
"●".to_string(),
|
|
|
|
|
context.editor.icons.diagnostic.error.icon_char.to_string(),
|
|
|
|
|
Some(context.editor.theme.get("error")),
|
|
|
|
|
);
|
|
|
|
|
write(context, format!(" {} ", errors), None);
|
|
|
|
@ -282,7 +321,13 @@ where
|
|
|
|
|
if warnings > 0 {
|
|
|
|
|
write(
|
|
|
|
|
context,
|
|
|
|
|
"●".to_string(),
|
|
|
|
|
context
|
|
|
|
|
.editor
|
|
|
|
|
.icons
|
|
|
|
|
.diagnostic
|
|
|
|
|
.warning
|
|
|
|
|
.icon_char
|
|
|
|
|
.to_string(),
|
|
|
|
|
Some(context.editor.theme.get("warning")),
|
|
|
|
|
);
|
|
|
|
|
write(context, format!(" {} ", warnings), None);
|
|
|
|
@ -291,7 +336,7 @@ where
|
|
|
|
|
if errors > 0 {
|
|
|
|
|
write(
|
|
|
|
|
context,
|
|
|
|
|
"●".to_string(),
|
|
|
|
|
context.editor.icons.diagnostic.error.icon_char.to_string(),
|
|
|
|
|
Some(context.editor.theme.get("error")),
|
|
|
|
|
);
|
|
|
|
|
write(context, format!(" {} ", errors), None);
|
|
|
|
@ -412,6 +457,21 @@ where
|
|
|
|
|
write(context, format!(" {} ", file_type), None);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn render_file_type_icon<F>(context: &mut RenderContext, write: F)
|
|
|
|
|
where
|
|
|
|
|
F: Fn(&mut RenderContext, String, Option<Style>) + Copy,
|
|
|
|
|
{
|
|
|
|
|
if context.icons.enabled {
|
|
|
|
|
if let Some(icon) = context.icons.filetype_icon {
|
|
|
|
|
write(
|
|
|
|
|
context,
|
|
|
|
|
format!("{}", icon.icon_char),
|
|
|
|
|
icon.style.map(|icons_style| icons_style.into()),
|
|
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn render_file_name<F>(context: &mut RenderContext, write: F)
|
|
|
|
|
where
|
|
|
|
|
F: Fn(&mut RenderContext, String, Option<Style>) + Copy,
|
|
|
|
@ -482,11 +542,12 @@ fn render_version_control<F>(context: &mut RenderContext, write: F)
|
|
|
|
|
where
|
|
|
|
|
F: Fn(&mut RenderContext, String, Option<Style>) + Copy,
|
|
|
|
|
{
|
|
|
|
|
let head = context
|
|
|
|
|
.doc
|
|
|
|
|
.version_control_head()
|
|
|
|
|
.unwrap_or_default()
|
|
|
|
|
.to_string();
|
|
|
|
|
let head = context.doc.version_control_head().unwrap_or_default();
|
|
|
|
|
|
|
|
|
|
write(context, head, None);
|
|
|
|
|
if !head.is_empty() && context.icons.enabled {
|
|
|
|
|
if let Some(vcs_icon) = context.icons.vcs_icon {
|
|
|
|
|
return write(context, format!("{} {head}", vcs_icon.icon_char), None);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
write(context, head.to_string(), None);
|
|
|
|
|
}
|
|
|
|
|