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
Omnikar 3 years ago committed by GitHub
parent 7e6ade9290
commit 2505802d39
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -548,6 +548,8 @@ impl EditorView {
theme: &Theme,
is_focused: bool,
) {
use tui::text::{Span, Spans};
//-------------------------------
// Left side of the status line.
//-------------------------------
@ -566,17 +568,17 @@ impl EditorView {
})
.unwrap_or("");
let style = if is_focused {
let base_style = if is_focused {
theme.get("ui.statusline")
} else {
theme.get("ui.statusline.inactive")
};
// statusline
surface.set_style(viewport.with_height(1), style);
surface.set_style(viewport.with_height(1), base_style);
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() {
let path = path.to_string_lossy();
@ -587,7 +589,7 @@ impl EditorView {
viewport.y,
title,
viewport.width.saturating_sub(6) as usize,
style,
base_style,
);
}
@ -595,8 +597,50 @@ impl EditorView {
// Right side of the status line.
//-------------------------------
// Compute the individual info strings.
let diag_count = format!("{}", doc.diagnostics().len());
let mut right_side_text = Spans::default();
// 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 {
// IndentStyle::Tabs => "tabs",
// IndentStyle::Spaces(1) => "spaces:1",
@ -609,29 +653,28 @@ impl EditorView {
// IndentStyle::Spaces(8) => "spaces:8",
// _ => "indent:ERROR",
// };
let position_info = {
// Position
let pos = coords_at_pos(
doc.text().slice(..),
doc.selection(view.id)
.primary()
.cursor(doc.text().slice(..)),
);
format!("{}:{}", pos.row + 1, pos.col + 1) // convert to 1-indexing
};
// Render them to the status line together.
let right_side_text = format!(
"{} {} ",
&diag_count[..diag_count.len().min(4)],
// indent_info,
position_info
);
let text_len = right_side_text.len() as u16;
surface.set_string(
viewport.x + viewport.width.saturating_sub(text_len),
right_side_text.0.push(Span::styled(
format!(" {}:{} ", pos.row + 1, pos.col + 1), // Convert to 1-indexing.
base_style,
));
// Render to the statusline.
surface.set_spans(
viewport.x
+ viewport
.width
.saturating_sub(right_side_text.width() as u16),
viewport.y,
right_side_text,
style,
&right_side_text,
right_side_text.width() as u16,
);
}

Loading…
Cancel
Save