mirror of https://github.com/helix-editor/helix
Improve statusline (#916)
* Improve statusline * Change diagnostic count display to show counts of individual diagnostic types next to their corresponding gutter dots. * Add selection count to the statusline. * Do not display info or hint count in statusline * Reduce padding Co-authored-by: Blaž Hrastnik <blaz@mxxn.io> * Reduce padding Co-authored-by: Blaž Hrastnik <blaz@mxxn.io> * Use `Span::styled` * Reduce padding * Use `Style::patch` * Remove unnecessary `Cow` creation Co-authored-by: Blaž Hrastnik <blaz@mxxn.io>pull/924/head
parent
7e6ade9290
commit
2505802d39
|
@ -548,6 +548,8 @@ impl EditorView {
|
||||||
theme: &Theme,
|
theme: &Theme,
|
||||||
is_focused: bool,
|
is_focused: bool,
|
||||||
) {
|
) {
|
||||||
|
use tui::text::{Span, Spans};
|
||||||
|
|
||||||
//-------------------------------
|
//-------------------------------
|
||||||
// Left side of the status line.
|
// Left side of the status line.
|
||||||
//-------------------------------
|
//-------------------------------
|
||||||
|
@ -566,17 +568,17 @@ impl EditorView {
|
||||||
})
|
})
|
||||||
.unwrap_or("");
|
.unwrap_or("");
|
||||||
|
|
||||||
let style = if is_focused {
|
let base_style = if is_focused {
|
||||||
theme.get("ui.statusline")
|
theme.get("ui.statusline")
|
||||||
} else {
|
} else {
|
||||||
theme.get("ui.statusline.inactive")
|
theme.get("ui.statusline.inactive")
|
||||||
};
|
};
|
||||||
// statusline
|
// statusline
|
||||||
surface.set_style(viewport.with_height(1), style);
|
surface.set_style(viewport.with_height(1), base_style);
|
||||||
if is_focused {
|
if is_focused {
|
||||||
surface.set_string(viewport.x + 1, viewport.y, mode, style);
|
surface.set_string(viewport.x + 1, viewport.y, mode, base_style);
|
||||||
}
|
}
|
||||||
surface.set_string(viewport.x + 5, viewport.y, progress, style);
|
surface.set_string(viewport.x + 5, viewport.y, progress, base_style);
|
||||||
|
|
||||||
if let Some(path) = doc.relative_path() {
|
if let Some(path) = doc.relative_path() {
|
||||||
let path = path.to_string_lossy();
|
let path = path.to_string_lossy();
|
||||||
|
@ -587,7 +589,7 @@ impl EditorView {
|
||||||
viewport.y,
|
viewport.y,
|
||||||
title,
|
title,
|
||||||
viewport.width.saturating_sub(6) as usize,
|
viewport.width.saturating_sub(6) as usize,
|
||||||
style,
|
base_style,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -595,8 +597,50 @@ impl EditorView {
|
||||||
// Right side of the status line.
|
// Right side of the status line.
|
||||||
//-------------------------------
|
//-------------------------------
|
||||||
|
|
||||||
// Compute the individual info strings.
|
let mut right_side_text = Spans::default();
|
||||||
let diag_count = format!("{}", doc.diagnostics().len());
|
|
||||||
|
// Compute the individual info strings and add them to `right_side_text`.
|
||||||
|
|
||||||
|
// Diagnostics
|
||||||
|
let diags = doc.diagnostics().iter().fold((0, 0), |mut counts, diag| {
|
||||||
|
use helix_core::diagnostic::Severity;
|
||||||
|
match diag.severity {
|
||||||
|
Some(Severity::Warning) => counts.0 += 1,
|
||||||
|
Some(Severity::Error) | None => counts.1 += 1,
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
counts
|
||||||
|
});
|
||||||
|
let (warnings, errors) = diags;
|
||||||
|
let warning_style = theme.get("warning");
|
||||||
|
let error_style = theme.get("error");
|
||||||
|
for i in 0..2 {
|
||||||
|
let (count, style) = match i {
|
||||||
|
0 => (warnings, warning_style),
|
||||||
|
1 => (errors, error_style),
|
||||||
|
_ => unreachable!(),
|
||||||
|
};
|
||||||
|
if count == 0 {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
let style = base_style.patch(style);
|
||||||
|
right_side_text.0.push(Span::styled("●", style));
|
||||||
|
right_side_text
|
||||||
|
.0
|
||||||
|
.push(Span::styled(format!(" {} ", count), base_style));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Selections
|
||||||
|
let sels_count = doc.selection(view.id).len();
|
||||||
|
right_side_text.0.push(Span::styled(
|
||||||
|
format!(
|
||||||
|
" {} sel{} ",
|
||||||
|
sels_count,
|
||||||
|
if sels_count == 1 { "" } else { "s" }
|
||||||
|
),
|
||||||
|
base_style,
|
||||||
|
));
|
||||||
|
|
||||||
// let indent_info = match doc.indent_style {
|
// let indent_info = match doc.indent_style {
|
||||||
// IndentStyle::Tabs => "tabs",
|
// IndentStyle::Tabs => "tabs",
|
||||||
// IndentStyle::Spaces(1) => "spaces:1",
|
// IndentStyle::Spaces(1) => "spaces:1",
|
||||||
|
@ -609,29 +653,28 @@ impl EditorView {
|
||||||
// IndentStyle::Spaces(8) => "spaces:8",
|
// IndentStyle::Spaces(8) => "spaces:8",
|
||||||
// _ => "indent:ERROR",
|
// _ => "indent:ERROR",
|
||||||
// };
|
// };
|
||||||
let position_info = {
|
|
||||||
|
// Position
|
||||||
let pos = coords_at_pos(
|
let pos = coords_at_pos(
|
||||||
doc.text().slice(..),
|
doc.text().slice(..),
|
||||||
doc.selection(view.id)
|
doc.selection(view.id)
|
||||||
.primary()
|
.primary()
|
||||||
.cursor(doc.text().slice(..)),
|
.cursor(doc.text().slice(..)),
|
||||||
);
|
);
|
||||||
format!("{}:{}", pos.row + 1, pos.col + 1) // convert to 1-indexing
|
right_side_text.0.push(Span::styled(
|
||||||
};
|
format!(" {}:{} ", pos.row + 1, pos.col + 1), // Convert to 1-indexing.
|
||||||
|
base_style,
|
||||||
|
));
|
||||||
|
|
||||||
// Render them to the status line together.
|
// Render to the statusline.
|
||||||
let right_side_text = format!(
|
surface.set_spans(
|
||||||
"{} {} ",
|
viewport.x
|
||||||
&diag_count[..diag_count.len().min(4)],
|
+ viewport
|
||||||
// indent_info,
|
.width
|
||||||
position_info
|
.saturating_sub(right_side_text.width() as u16),
|
||||||
);
|
|
||||||
let text_len = right_side_text.len() as u16;
|
|
||||||
surface.set_string(
|
|
||||||
viewport.x + viewport.width.saturating_sub(text_len),
|
|
||||||
viewport.y,
|
viewport.y,
|
||||||
right_side_text,
|
&right_side_text,
|
||||||
style,
|
right_side_text.width() as u16,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue