git.delta.rocks / jrsonnet / refs/commits / dacee201fa00

difftreelog

source

cmds/jrsonnet-lsp/src/main.rs5.9 KiBsourcehistory
1use std::{fs::File, io::Write, path::PathBuf, str::FromStr};23use lsp_server::{Connection, ErrorCode, Message, Request, RequestId, Response};4use lsp_types::{5	notification::{DidChangeTextDocument, DidOpenTextDocument, Notification},6	request::{DocumentLinkRequest, HoverRequest},7	CompletionOptions, DidChangeTextDocumentParams, DidOpenTextDocumentParams, DocumentLink,8	DocumentLinkOptions, ServerCapabilities, TextDocumentSyncCapability, TextDocumentSyncKind,9	TextDocumentSyncOptions, Url, WorkDoneProgressOptions,10};1112fn main() {13	let mut log = File::create("test").unwrap();14	writeln!(log, "start").unwrap();15	let (connection, io_threads) = Connection::stdio();16	let capabilities = serde_json::to_value(&ServerCapabilities {17		completion_provider: Some(CompletionOptions::default()),18		definition_provider: Some(lsp_types::OneOf::Left(true)),19		document_link_provider: Some(DocumentLinkOptions {20			resolve_provider: Some(false),21			work_done_progress_options: WorkDoneProgressOptions::default(),22		}),23		hover_provider: Some(lsp_types::HoverProviderCapability::Simple(true)),24		text_document_sync: Some(TextDocumentSyncCapability::Options(25			TextDocumentSyncOptions {26				change: Some(TextDocumentSyncKind::FULL),27				open_close: Some(true),28				..TextDocumentSyncOptions::default()29			},30		)),31		..ServerCapabilities::default()32	})33	.expect("failed to convert capabilities to json");3435	connection36		.initialize(capabilities)37		.expect("failed to initialize connection");3839	writeln!(log, "initialized").unwrap();4041	main_loop(&mut log, &connection).expect("main loop failed");4243	io_threads.join().expect("failed to join io_threads");44}45fn main_loop(log: &mut File, connection: &Connection) -> anyhow::Result<()> {46	// let mut es = EvaluationState::default();47	// es.set_import_resolver(Box::new(FileImportResolver::default()));4849	let reply = |response: Response| {50		connection51			.sender52			.send(Message::Response(response))53			.expect("failed to respond");54	};5556	for msg in &connection.receiver {57		match msg {58			Message::Response(_) => (),59			Message::Request(req) => {60				if connection.handle_shutdown(&req)? {61					return Ok(());62				}63				if let Some((id, params)) = cast::<DocumentLinkRequest>(&req) {64					reply(Response::new_ok(id, <Vec<DocumentLink>>::new()));65				} else if let Some((id, params)) = cast::<HoverRequest>(&req) {66					let pos = params67						.text_document_position_params68						.text_document69						.uri70						.path();71					let buf = PathBuf::from_str(pos).unwrap();72				// let pos = es73				// 	.map_from_source_location(74				// 		&buf,75				// 		params.text_document_position_params.position.line as usize + 1,76				// 		params.text_document_position_params.position.character as usize + 1,77				// 	)78				// 	.unwrap();79				// let el = ExprLocation(buf.clone().into(), pos as usize, pos as usize);80				// let es2 = es.clone();81				// reply(Response::new_ok(82				// 	id,83				// 	Some(Hover {84				// 		range: None,85				// 		contents: HoverContents::Markup(MarkupContent {86				// 			kind: MarkupKind::Markdown,87				// 			value: es88				// 				.run_in_state_with_breakpoint(el, move || {89				// 					es2.reset_evaluation_state(&buf);90				// 					es2.import_file(&PathBuf::new(), &buf)?91				// 						.to_string()92				// 						.map(|_| ())93				// 				})94				// 				.unwrap()95				// 				.unwrap_or_else(|| Val::Null)96				// 				.value_type()97				// 				.to_string(),98				// 		}),99				// 	}),100				// ));101				} else {102					reply(Response::new_err(103						req.id,104						ErrorCode::MethodNotFound as i32,105						format!("unrecognized request {}", req.method),106					))107				}108				/*109				if let Some((id, params)) = cast::<DocumentLinkRequest>(&req) {110					 let links = handle_links(&files, params).unwrap_or_default();111					 reply(Response::new_ok(id, links));112				} else if let Some((id, params)) = cast::<GotoDefinition>(&req) {113					 if let Some(loc) = handle_goto(&files, params) {114						  reply(Response::new_ok(id, loc))115					 } else {116						  reply(Response::new_ok(id, ()))117					 }118				} else if let Some((id, params)) = cast::<HoverRequest>(&req) {119					 match handle_hover(&files, params) {120						  Some((range, markdown)) => {121								reply(Response::new_ok(122									 id,123									 Hover {124										  contents: HoverContents::Markup(MarkupContent {125												kind: MarkupKind::Markdown,126												value: markdown,127										  }),128										  range,129									 },130								));131						  }132						  None => {133								reply(Response::new_ok(id, ()));134						  }135					 }136				} else if let Some((id, params)) = cast::<Completion>(&req) {137					 let completions = handle_completion(&files, params.text_document_position)138						  .unwrap_or_default();139					 reply(Response::new_ok(id, completions));140				} else141				*/142			}143			Message::Notification(req) => {144				let mut handle = |text: String, uri: Url| {145					writeln!(log, "updated file: {:?}", uri).unwrap();146					let path = match PathBuf::from_str(uri.path()) {147						Ok(x) => x,148						Err(_) => return,149					};150					let (ast, errors) = jrsonnet_rowan_parser::parse(&text);151					// es.add_parsed_file(path.into(), text.into(), parsed)152					// 	.unwrap();153					writeln!(log, "parsed: {:?}", uri).unwrap();154				};155156				match &*req.method {157					DidOpenTextDocument::METHOD => {158						let params: DidOpenTextDocumentParams =159							match serde_json::from_value(req.params) {160								Ok(x) => x,161								Err(_) => continue,162							};163						handle(params.text_document.text, params.text_document.uri);164					}165					DidChangeTextDocument::METHOD => {166						let params: DidChangeTextDocumentParams =167							match serde_json::from_value(req.params) {168								Ok(x) => x,169								Err(_) => continue,170							};171						for change in params.content_changes.into_iter() {172							handle(change.text, params.text_document.uri.clone());173						}174					}175					_ => continue,176				}177			}178		}179	}180	Ok(())181}182fn cast<R>(req: &Request) -> Option<(RequestId, R::Params)>183where184	R: lsp_types::request::Request,185	R::Params: serde::de::DeserializeOwned,186{187	req.clone().extract(R::METHOD).ok()188}