Total mess but it works: diagnostic marking.

pull/5/head
Blaž Hrastnik 4 years ago
parent f9bfba4d96
commit 49254d7180

@ -1 +1,7 @@
pub struct Diagnostic {} use crate::Range;
pub struct Diagnostic {
pub range: (usize, usize),
pub line: usize,
pub message: String,
}

@ -10,6 +10,9 @@ use serde_json::Value;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
pub use lsp::Position;
pub use lsp::Url;
use smol::prelude::*; use smol::prelude::*;
use smol::{ use smol::{
channel::{Receiver, Sender}, channel::{Receiver, Sender},

@ -29,10 +29,10 @@ use tui::{
backend::CrosstermBackend, backend::CrosstermBackend,
buffer::Buffer as Surface, buffer::Buffer as Surface,
layout::Rect, layout::Rect,
style::{Color, Style}, style::{Color, Modifier, Style},
}; };
const OFFSET: u16 = 6; // 5 linenr + 1 gutter const OFFSET: u16 = 7; // 1 diagnostic + 5 linenr + 1 gutter
type Terminal = tui::Terminal<CrosstermBackend<std::io::Stdout>>; type Terminal = tui::Terminal<CrosstermBackend<std::io::Stdout>>;
@ -205,6 +205,16 @@ impl Renderer {
style style
}; };
// ugh, improve with a traverse method
// or interleave highlight spans with selection and diagnostic spans
let style = if view.state.diagnostics.iter().any(|diagnostic| {
diagnostic.range.0 <= char_index && diagnostic.range.1 > char_index
}) {
style.clone().add_modifier(Modifier::UNDERLINED)
} else {
style
};
// TODO: paint cursor heads except primary // TODO: paint cursor heads except primary
self.surface self.surface
@ -212,18 +222,23 @@ impl Renderer {
visual_x += width; visual_x += width;
} }
// if grapheme == "\t"
char_index += 1; char_index += 1;
} }
} }
} }
} }
let style: Style = theme.get("ui.linenr"); let style: Style = theme.get("ui.linenr");
let warning: Style = theme.get("warning");
let last_line = view.last_line(); let last_line = view.last_line();
for (i, line) in (view.first_line..last_line).enumerate() { for (i, line) in (view.first_line..last_line).enumerate() {
if view.state.diagnostics.iter().any(|d| d.line == line) {
self.surface.set_stringn(0, i as u16, "●", 1, warning);
}
self.surface self.surface
.set_stringn(0, i as u16, format!("{:>5}", line + 1), 5, style); .set_stringn(1, i as u16, format!("{:>5}", line + 1), 5, style);
} }
} }
@ -240,6 +255,13 @@ impl Renderer {
); );
self.surface self.surface
.set_string(1, self.size.1 - 2, mode, self.text_color); .set_string(1, self.size.1 - 2, mode, self.text_color);
self.surface.set_string(
self.size.0 - 10,
self.size.1 - 2,
format!("{}", view.state.diagnostics.len()),
self.text_color,
);
} }
pub fn render_prompt(&mut self, view: &View, prompt: &Prompt, theme: &Theme) { pub fn render_prompt(&mut self, view: &View, prompt: &Prompt, theme: &Theme) {
@ -545,7 +567,59 @@ impl<'a> Application<'a> {
pub async fn handle_lsp_notification(&mut self, notification: Option<helix_lsp::Notification>) { pub async fn handle_lsp_notification(&mut self, notification: Option<helix_lsp::Notification>) {
use helix_lsp::Notification; use helix_lsp::Notification;
match notification { match notification {
Some(Notification::PublishDiagnostics(params)) => unimplemented!("{:?}", params), Some(Notification::PublishDiagnostics(params)) => {
let view = self.editor.views.iter_mut().find(|view| {
let path = view
.state
.path
.as_ref()
.map(|path| helix_lsp::Url::from_file_path(path).unwrap());
eprintln!("{:?} {} {}", path, params.uri, params.diagnostics.len());
// HAXX
path == Some(params.uri.clone())
});
fn lsp_pos_to_pos(doc: &helix_core::RopeSlice, pos: helix_lsp::Position) -> usize {
let line = doc.line_to_char(pos.line as usize);
let line_start = doc.char_to_utf16_cu(line);
doc.utf16_cu_to_char(pos.character as usize + line_start)
}
if let Some(view) = view {
let doc = view.state.doc().slice(..);
let diagnostics = params
.diagnostics
.into_iter()
.map(|diagnostic| {
let start = lsp_pos_to_pos(&doc, diagnostic.range.start);
let end = lsp_pos_to_pos(&doc, diagnostic.range.end);
// eprintln!(
// "{:?}-{:?} {}-{} {}",
// diagnostic.range.start,
// diagnostic.range.end,
// start,
// end,
// diagnostic.message
// );
helix_core::Diagnostic {
range: (start, end),
line: diagnostic.range.start.line as usize,
message: diagnostic.message,
// severity
// code
// source
}
})
.collect();
view.state.diagnostics = diagnostics;
self.render();
}
}
_ => unreachable!(), _ => unreachable!(),
} }
} }

@ -157,6 +157,8 @@ impl Default for Theme {
"ui.background" => Style::default().bg(Color::Rgb(59, 34, 76)), // midnight "ui.background" => Style::default().bg(Color::Rgb(59, 34, 76)), // midnight
"ui.linenr" => Style::default().fg(Color::Rgb(90, 89, 119)), // comet "ui.linenr" => Style::default().fg(Color::Rgb(90, 89, 119)), // comet
"ui.statusline" => Style::default().bg(Color::Rgb(40, 23, 51)), // revolver "ui.statusline" => Style::default().bg(Color::Rgb(40, 23, 51)), // revolver
"warning" => Style::default().fg(Color::Rgb(255, 205, 28)),
}; };
let scopes = mapping.keys().map(ToString::to_string).collect(); let scopes = mapping.keys().map(ToString::to_string).collect();

Loading…
Cancel
Save