Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'src/edi/lsp_impl.rs')
| -rw-r--r-- | src/edi/lsp_impl.rs | 159 |
1 files changed, 126 insertions, 33 deletions
diff --git a/src/edi/lsp_impl.rs b/src/edi/lsp_impl.rs index 269ddb0..6026a3d 100644 --- a/src/edi/lsp_impl.rs +++ b/src/edi/lsp_impl.rs @@ -2,8 +2,8 @@ use std::iter::repeat; use Default::default; use lsp_server::Request as LRq; -use lsp_types::request::*; use lsp_types::*; +use rust_analyzer::lsp::ext::CodeAction; use serde::{Deserialize, Serialize}; use ttools::{Tupl, With}; @@ -40,7 +40,7 @@ pub struct Requests { Box<[SemanticToken]>, Box<[SemanticToken]>, (), - RequestError<SemanticTokensFullRequest>, + RequestError<lsp_request!("textDocument/semanticTokens/full")>, >, pub diag: Rq< String, @@ -55,11 +55,11 @@ pub struct Requests { (), RequestError<lsp_request!("textDocument/inlayHint")>, >, - pub def: Rq< + pub def: crate::RqS< LocationLink, - Option<GotoDefinitionResponse>, + lsp_request!("textDocument/definition"), (usize, usize), - RequestError<lsp_request!("textDocument/definition")>, + // RequestError<lsp_request!("textDocument/definition")>, >, #[serde(skip)] pub document_symbols: Rq< @@ -71,6 +71,89 @@ pub struct Requests { #[serde(skip)] pub git_diff: Rq<imara_diff::Diff, imara_diff::Diff, (), ()>, } +use serde::ser::SerializeSeq; + +fn untokenr<'de, D>( + deserializer: D, +) -> Result<Vec<SemanticToken>, D::Error> +where + D: serde::Deserializer<'de>, +{ + let data = Vec::<u32>::deserialize(deserializer)?; + let chunks = data.chunks_exact(5); + + if !chunks.remainder().is_empty() { + return Result::Err(serde::de::Error::custom( + "Length is not divisible by 5", + )); + } + + Result::Ok( + chunks + .map(|chunk| SemanticToken { + delta_line: chunk[0], + delta_start: chunk[1], + length: chunk[2], + token_type: chunk[3], + token_modifiers_bitset: chunk[4], + }) + .collect(), + ) +} + +fn tokenr<S>( + tokens: &[SemanticToken], + serializer: S, +) -> Result<S::Ok, S::Error> +where + S: serde::Serializer, +{ + let mut seq = serializer.serialize_seq(Some(tokens.len() * 5))?; + for token in tokens.iter() { + seq.serialize_element(&token.delta_line)?; + seq.serialize_element(&token.delta_start)?; + seq.serialize_element(&token.length)?; + seq.serialize_element(&token.token_type)?; + seq.serialize_element(&token.token_modifiers_bitset)?; + } + seq.end() +} + +fn deserialize_tokens_opt<'de, D>( + deserializer: D, +) -> Result<Option<Vec<SemanticToken>>, D::Error> +where + D: serde::Deserializer<'de>, +{ + #[derive(Deserialize)] + #[serde(transparent)] + struct Wrapper { + #[serde(deserialize_with = "untokenr")] + tokens: Vec<SemanticToken>, + } + + Ok(Option::<Wrapper>::deserialize(deserializer)? + .map(|wrapper| wrapper.tokens)) +} + +fn serialize_tokens_opt<S>( + data: Option<&[SemanticToken]>, + serializer: S, +) -> Result<S::Ok, S::Error> +where + S: serde::Serializer, +{ + #[derive(Serialize)] + #[serde(transparent)] + struct Wrapper<'a> { + #[serde(serialize_with = "tokenr")] + tokens: &'a [SemanticToken], + } + + let opt = data.as_ref().map(|t| Wrapper { tokens: t }); + + opt.serialize(serializer) +} pub fn deserialize_tokens<'de, D: serde::Deserializer<'de>>( ser: D, ) -> Result< @@ -78,26 +161,44 @@ pub fn deserialize_tokens<'de, D: serde::Deserializer<'de>>( Box<[SemanticToken]>, Box<[SemanticToken]>, (), - RequestError<SemanticTokensFullRequest>, + RequestError<lsp_request!("textDocument/semanticTokens/full")>, >, D::Error, > { - SemanticToken::deserialize_tokens_opt(ser) - .map(|x| Rq { result: x.map(Into::into), request: None }) + { + #[derive(Deserialize)] + #[serde(transparent)] + struct Wrapper { + #[serde(deserialize_with = "untokenr")] + tokens: Vec<SemanticToken>, + } + + Ok(Option::<Wrapper>::deserialize(ser)? + .map(|wrapper| wrapper.tokens)) + } + .map(|x| Rq { result: x.map(Into::into), request: None }) } pub fn serialize_tokens<S: serde::Serializer>( s: &Rq< Box<[SemanticToken]>, Box<[SemanticToken]>, (), - RequestError<SemanticTokensFullRequest>, + RequestError<lsp_request!("textDocument/semanticTokens/full")>, >, ser: S, ) -> Result<S::Ok, S::Error> { - SemanticToken::serialize_tokens_opt( - &s.result.clone().map(|x| x.to_vec()), - ser, - ) + { + let data: &Option<Vec<SemanticToken>> = + &s.result.clone().map(|x| x.to_vec()); + #[derive(Serialize)] + #[serde(transparent)] + struct Wrapper { + #[serde(serialize_with = "tokenr")] + tokens: Vec<SemanticToken>, + } + let opt = data.as_ref().map(|t| Wrapper { tokens: t.to_vec() }); + opt.serialize(ser) + } } impl crate::edi::Editor { pub fn poll(&mut self) { @@ -149,14 +250,7 @@ impl crate::edi::Editor { } State::CodeAction(x) => { if x.poll(|x, _| { - let lems: Vec<CodeAction> = x - .ok()?? - .into_iter() - .map(|x| match x { - CodeActionOrCommand::CodeAction(x) => x, - _ => panic!("alas we dont like these"), - }) - .collect(); + let lems = x.ok()??; if lems.is_empty() { self.bar.last_action = "no code actions available".into(); @@ -218,18 +312,13 @@ impl crate::edi::Editor { x.ok().map(|x| { x.and_then(|x| try { z.data.0 = match x { - GotoDefinitionResponse::Scalar( - location, + ImplementationResponse::Definition( + Definition::Location(location), ) => vec![(GoTo::from( location, ),None)], - GotoDefinitionResponse::Array( - locations, - ) => locations - .into_iter() - .map(GoTo::from).zip(repeat(None)) - .collect(), - GotoDefinitionResponse::Link( + + ImplementationResponse::DefinitionLinkList( location_links, ) => location_links .into_iter() @@ -242,6 +331,7 @@ impl crate::edi::Editor { ) }).zip(repeat(None)) .collect(), + ImplementationResponse::Definition(Definition::LocationList(x)) => {unimplemented!()}, }; }); }) @@ -281,7 +371,10 @@ impl crate::edi::Editor { } self.requests.def.poll(|x, _| { x.ok().flatten().and_then(|x| match &x { - GotoDefinitionResponse::Link([x, ..]) => Some(x.clone()), + // DefinitionResponse::Definition(x) => Some(x.clone()), + DefinitionResponse::DefinitionLinkList([x, ..]) => + Some(x.clone()), + // DefinitionRequest::Definition([x, ..]) => Some(x.clone()), _ => None, }) }); @@ -303,8 +396,8 @@ impl crate::edi::Editor { self.requests.git_diff.poll(|x, _| x.ok()); self.requests.document_symbols.poll(|x, _| { x.ok().flatten().map(|x| match x { - DocumentSymbolResponse::Flat(_) => None, - DocumentSymbolResponse::Nested(x) => Some(x), + DocumentSymbolResponse::SymbolInformationList(_) => None, + DocumentSymbolResponse::DocumentSymbolList(x) => Some(x), }) }); } |