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.rs159
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),
})
});
}