Skip to content

Commit

Permalink
Now generates diagnostics
Browse files Browse the repository at this point in the history
  • Loading branch information
elijah-potter committed Jan 18, 2024
1 parent 5ff1b34 commit a2dffb1
Show file tree
Hide file tree
Showing 6 changed files with 76 additions and 27 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 1 addition & 2 deletions harper-ls/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@ name = "harper-ls"
version = "0.1.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
anyhow = "1.0.79"
ctrlc = "3.4.2"
Expand All @@ -14,3 +12,4 @@ serde = "1.0.195"
serde_json = "1.0.111"
tracing = "0.1.40"
tracing-subscriber = "0.3.18"
harper-core = { path = "../harper-core" }
61 changes: 61 additions & 0 deletions harper-ls/src/generate_diagnostics.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
use harper_core::{all_linters, Dictionary, Document, Lint, Span};
use lsp_types::{Diagnostic, Position, Range, Url};
use std::fs::read;

pub fn generate_diagnostics(file_uri: Url) -> anyhow::Result<Vec<Diagnostic>> {
let file = read(file_uri.path())?;
let file_str = String::from_utf8(file)?;

let document = Document::new(&file_str);
let dictionary = Dictionary::new();
let lints = all_linters(&document, dictionary);

let source_chars: Vec<_> = file_str.chars().collect();

let diagnostics = lints
.into_iter()
.map(|lint| lint_to_diagnostic(lint, &source_chars))
.collect();

Ok(diagnostics)
}

fn lint_to_diagnostic(lint: Lint, source: &[char]) -> Diagnostic {
let range = span_to_range(source, lint.span);

Diagnostic {
range,
severity: None,
code: None,
code_description: None,
source: Some("Harper".to_string()),
message: lint.message,
related_information: None,
tags: None,
data: None,
}
}

fn span_to_range(source: &[char], span: Span) -> Range {
let start = index_to_position(source, span.start);
let end = index_to_position(source, span.end);

Range { start, end }
}

fn index_to_position(source: &[char], index: usize) -> Position {
let before = &source[0..index];
let newline_indices: Vec<_> = before
.iter()
.enumerate()
.filter_map(|(idx, c)| if *c == '\n' { Some(idx) } else { None })
.collect();

let lines = newline_indices.len();
let cols = index - newline_indices.last().copied().unwrap_or(0);

Position {
line: lines as u32,
character: cols as u32,
}
}
3 changes: 2 additions & 1 deletion harper-ls/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
mod generate_diagnostics;
mod server;

use lsp_server::Connection;
Expand All @@ -12,7 +13,7 @@ fn main() -> anyhow::Result<()> {

tracing::subscriber::set_global_default(subscriber)?;

let (connection, io_threads) = Connection::listen("127.0.0.1:4000")?;
let (connection, io_threads) = Connection::stdio();
let mut server = Server::new(connection, io_threads)?;
server.main_loop()?;
server.join()?;
Expand Down
31 changes: 8 additions & 23 deletions harper-ls/src/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,13 @@ use lsp_types::{
PublishDiagnostics,
},
request::GotoDefinition,
Diagnostic, GotoDefinitionResponse, InitializedParams, Location, OneOf, Position,
Diagnostic, DiagnosticOptions, GotoDefinitionResponse, InitializedParams, Location, Position,
PublishDiagnosticsParams, Range, ServerCapabilities,
};
use tracing::{error, info};

use crate::generate_diagnostics::generate_diagnostics;

pub struct Server {
connection: Connection,
io_threads: IoThreads,
Expand All @@ -25,7 +27,9 @@ type NotificationHandler = fn(server: &Server, notif: &Notification) -> anyhow::
impl Server {
pub fn new(connection: Connection, io_threads: IoThreads) -> anyhow::Result<Self> {
let server_capabilities = serde_json::to_value(ServerCapabilities {
definition_provider: Some(OneOf::Left(true)),
diagnostic_provider: Some(lsp_types::DiagnosticServerCapabilities::Options(
DiagnosticOptions::default(),
)),
..Default::default()
})
.unwrap();
Expand Down Expand Up @@ -97,30 +101,11 @@ impl Server {
fn handle_save(&self, req: &Notification) -> anyhow::Result<()> {
let params = cast_notif::<DidSaveTextDocument>(req.clone())?;

dbg!(&params);
let diagnostics = generate_diagnostics(params.text_document.uri.clone())?;

let result = PublishDiagnosticsParams {
uri: params.text_document.uri,
diagnostics: vec![Diagnostic {
range: Range {
start: Position {
line: 0,
character: 0,
},
end: Position {
line: 0,
character: 0,
},
},
severity: None,
code: None,
code_description: None,
source: Some("Harper".to_string()),
message: "Testing testing 123".to_string(),
related_information: None,
tags: None,
data: None,
}],
diagnostics,
version: None,
};

Expand Down
4 changes: 3 additions & 1 deletion nvim.lua
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
-- This is a script used to debug `harper-ls` in NeoVim.

vim.lsp.start({
name = "example",
cmd = vim.lsp.rpc.connect("127.0.0.1", 4000),
cmd = { "harper-ls" },
root_dir = "."
})

0 comments on commit a2dffb1

Please sign in to comment.