Skip to content

Commit

Permalink
Started work on LSP server
Browse files Browse the repository at this point in the history
  • Loading branch information
elijah-potter committed Jan 18, 2024
1 parent 7889402 commit dd0e4de
Show file tree
Hide file tree
Showing 5 changed files with 257 additions and 1 deletion.
138 changes: 138 additions & 0 deletions Cargo.lock

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

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
[workspace]
members = [ "harper-core", "harper-serve", "harper-wasm"]
members = [ "harper-core", "harper-ls", "harper-serve", "harper-wasm"]
resolver = "2"
16 changes: 16 additions & 0 deletions harper-ls/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
[package]
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"
lsp-server = "0.7.6"
lsp-types = "0.95.0"
serde = "1.0.195"
serde_json = "1.0.111"
tracing = "0.1.40"
tracing-subscriber = "0.3.18"
97 changes: 97 additions & 0 deletions harper-ls/src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
use lsp_types::{
request::GotoDefinition, GotoDefinitionResponse, InitializeParams, ServerCapabilities,
};
use lsp_types::{Location, OneOf, Position};

use lsp_server::{Connection, ExtractError, Message, Request, RequestId, Response};
use tracing::{info, Level};

fn main() -> anyhow::Result<()> {
let subscriber = tracing_subscriber::FmtSubscriber::builder()
.with_max_level(Level::DEBUG)
.finish();

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

let (connection, io_threads) = Connection::listen("127.0.0.1:4000")?;

let server_capabilities = serde_json::to_value(ServerCapabilities {
definition_provider: Some(OneOf::Left(true)),
..Default::default()
})
.unwrap();
let initialization_params = match connection.initialize(server_capabilities) {
Ok(it) => it,
Err(e) => {
if e.channel_is_disconnected() {
io_threads.join()?;
}
return Err(e.into());
}
};
main_loop(connection, initialization_params)?;
io_threads.join()?;

info!("Shutting down server.c");
Ok(())
}

fn main_loop(connection: Connection, params: serde_json::Value) -> anyhow::Result<()> {
let _params: InitializeParams = serde_json::from_value(params).unwrap();
info!("Starting example main loop");
for msg in &connection.receiver {
info!("Got msg: {msg:?}");
match msg {
Message::Request(req) => {
if connection.handle_shutdown(&req)? {
return Ok(());
}
info!("Got request: {req:?}");
match cast::<GotoDefinition>(req) {
Ok((id, params)) => {
info!("Got gotoDefinition request #{id}: {params:?}");
let result = Some(GotoDefinitionResponse::Array(vec![Location {
uri: params.text_document_position_params.text_document.uri,
range: lsp_types::Range {
start: Position {
line: 0,
character: 0,
},
end: Position {
line: 0,
character: 0,
},
},
}]));
let result = serde_json::to_value(&result).unwrap();
let resp = Response {
id,
result: Some(result),
error: None,
};
connection.sender.send(Message::Response(resp))?;
continue;
}
Err(err @ ExtractError::JsonError { .. }) => panic!("{err:?}"),
Err(ExtractError::MethodMismatch(req)) => req,
};
}
Message::Response(resp) => {
info!("Got response: {resp:?}");
}
Message::Notification(not) => {
info!("Got notification: {not:?}");
}
}
}

Ok(())
}

fn cast<R>(req: Request) -> Result<(RequestId, R::Params), ExtractError<Request>>
where
R: lsp_types::request::Request,
R::Params: serde::de::DeserializeOwned,
{
req.extract(R::METHOD)
}
5 changes: 5 additions & 0 deletions nvim.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
vim.lsp.start({
name = "example",
cmd = vim.lsp.rpc.connect("127.0.0.1", 4000),
root_dir = "."
})

0 comments on commit dd0e4de

Please sign in to comment.