Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'src/lsp/client.rs')
| -rw-r--r-- | src/lsp/client.rs | 272 |
1 files changed, 145 insertions, 127 deletions
diff --git a/src/lsp/client.rs b/src/lsp/client.rs index a0db994..ddbe7c4 100644 --- a/src/lsp/client.rs +++ b/src/lsp/client.rs @@ -14,15 +14,15 @@ use log::debug; use lsp_server::{ Message, Notification as N, Request as LRq, Response as Re, }; -use lsp_types::notification::*; -use lsp_types::request::*; use lsp_types::*; use rootcause::option_ext::OptionExt; use rust_analyzer::lsp::ext::*; use tokio::sync::oneshot; use ttools::*; +use url::Url; use crate::lsp::BehaviourAfter::{self, *}; +use crate::lsp::communication::{WorkDoneProgress, send}; use crate::lsp::{RequestError, Require, Requiring, Rq, RqSendError}; use crate::text::cursor::ceach; use crate::text::{LOADER, RopeExt, SortTedits, TextArea}; @@ -55,7 +55,7 @@ pub struct Client { ProgressToken, Option<(WorkDoneProgress, WorkDoneProgressBegin)>, >, - pub diagnostics: &'static papaya::HashMap<Url, Vec<Diagnostic>>, + pub diagnostics: &'static papaya::HashMap<url::Url, Vec<Diagnostic>>, #[allow(dead_code)] // TODO: handle notifications from the server pub not_rx: Receiver<N>, @@ -70,7 +70,7 @@ pub struct Client { impl Drop for Client { fn drop(&mut self) { - _ = self.notify::<Exit>(&()); + _ = self.notify::<ExitNotification>(&()); println!( "dropped lsp({}) @ {}", self.lsp_data.1.name, self.workspace.uri @@ -90,22 +90,25 @@ impl Client { l: helix_core::Language, ) -> Result<(), SendError<Message>> { let l = LOADER.language(l).config(); - self.notify::<DidOpenTextDocument>(&DidOpenTextDocumentParams { - text_document: TextDocumentItem { - uri: url::Url::from_file_path(f).unwrap(), - language_id: l - .language_server_language_id - .clone() - .unwrap_or(l.language_id.clone()), - version: 0, - text, + self.notify::<DidOpenTextDocumentNotification>( + &DidOpenTextDocumentParams { + text_document: TextDocumentItem { + uri: url::Url::from_file_path(f).unwrap(), + language_id: l + .language_server_language_id + .clone() + .unwrap_or(l.language_id.clone()) + .into(), + version: 0, + text, + }, }, - }) + ) } pub fn close(&self, f: &Path) -> Result<(), SendError<Message>> { - self.notify::<DidCloseTextDocument>(&DidCloseTextDocumentParams { - text_document: f.tid(), - }) + self.notify::<DidCloseTextDocumentNotification>( + &DidCloseTextDocumentParams { text_document: f.tid() }, + ) } pub fn edit( &self, @@ -113,17 +116,16 @@ impl Client { text: String, ) -> Result<(), SendError<Message>> { static V: AtomicI32 = AtomicI32::new(0); - self.notify::<lsp_types::notification::DidChangeTextDocument>( + self.notify::<lsp_types::DidChangeTextDocumentNotification>( &DidChangeTextDocumentParams { text_document: VersionedTextDocumentIdentifier { - uri: url::Url::from_file_path(f).unwrap(), + text_document_identifier: f.tid(), version: V.fetch_add(1, Relaxed), }, - content_changes: vec![TextDocumentContentChangeEvent { - range: None, - range_length: None, - text, - }], + content_changes: vec![ + (TextDocumentContentChangeWholeDocument { text }) + .into(), + ], }, ) } @@ -131,8 +133,13 @@ impl Client { pub fn resolve( &self, x: CompletionItem, - ) -> Result<CompletionItem, RequestError<ResolveCompletionItem>> { - self.request_immediate::<ResolveCompletionItem>(&x) + ) -> Result< + CompletionItem, + RequestError<lsp_request!("completionItem/resolve")>, + > { + self.request_immediate::<lsp_request!("completionItem/resolve")>( + &x, + ) } pub fn request_complete<'me>( @@ -145,18 +152,15 @@ impl Client { impl Future< Output = Result< Option<CompletionResponse>, - RequestError<Completion>, + RequestError<lsp_request!("textDocument/completion")>, >, > + use<>, > { self.caps().completion_provider.require()?; let (rx, _) = self - .request_::<Completion, { Redraw }>(&CompletionParams { - text_document_position: TextDocumentPositionParams { - text_document: f.tid(), - position: Position { line: y as _, character: x as _ }, - }, + .request_::<lsp_request!("textDocument/completion"), { Redraw }>(&CompletionParams { + text_document_position_params: TextDocumentPositionParams::new(f.tid(), Position { line: y as _, character: x as _ }), work_done_progress_params: default(), partial_result_params: default(), context: Some(c), @@ -268,7 +272,7 @@ impl Client { .diagnostic_provider .as_ref()? { - DiagnosticServerCapabilities::RegistrationOptions( + DiagnosticProvider::DiagnosticRegistrationOptions( x, ) => x.diagnostic_options.identifier.clone()?, _ => None?, @@ -293,8 +297,8 @@ impl Client { }; // dbg!(&x); match x.clone() { - DocumentDiagnosticReportResult::Report( - DocumentDiagnosticReport::Full( + // DocumentDiagnosticReport::DocumentDiagnosticReport( + DocumentDiagnosticReport::RelatedFullDocumentDiagnosticReport( RelatedFullDocumentDiagnosticReport { related_documents, full_document_diagnostic_report: @@ -303,7 +307,7 @@ impl Client { result_id, }, }, - ), + ) => { let l = self.diagnostics.guard(); self.diagnostics.insert(f.tid().uri, items, &l); @@ -311,14 +315,14 @@ impl Client { related_documents.into_iter().flatten() { match rel { - DocumentDiagnosticReportKind::Full( + RelatedDocument::FullDocumentDiagnosticReport( FullDocumentDiagnosticReport { items, .. }, ) => { self.diagnostics.insert(uri, items, &l); } - DocumentDiagnosticReportKind::Unchanged(_) => { + RelatedDocument::UnchangedDocumentDiagnosticReport(_) => { } } } @@ -343,15 +347,14 @@ impl Client { > + use<>, > { self.caps().document_highlight_provider.require()?; - let p = DocumentHighlightParams { + Ok(send!(self.request_::<{Redraw}>, "textDocument/documentHighlight", _ { text_document_position_params: TextDocumentPositionParams { text_document: f.tid(), position: cursor, }, work_done_progress_params: default(), partial_result_params: default(), - }; - Ok(self.request_::<lsp_request!("textDocument/documentHighlight"), {Redraw}>(&p) + }) .unwrap() .0 .map(|x| x.map(|x| x.unwrap_or_default()))) @@ -369,8 +372,7 @@ impl Client { > + use<>, > { self.caps().document_symbol_provider.require()?; - Ok(self.request_::<lsp_request!("textDocument/documentSymbol"), { Redraw }>( - &DocumentSymbolParams { + Ok(send!(self.request_::<{ Redraw }>, "textDocument/documentSymbol", _ { text_document: p.tid(), work_done_progress_params: default(), partial_result_params: default(), @@ -387,20 +389,22 @@ impl Client { impl Future< Output = Result< Option<WorkspaceSymbolResponse>, - RequestError<lsp_request!("workspace/symbol")>, + RequestError< + rust_analyzer::lsp::ext::WorkspaceSymbolRequest, + >, >, > + use<>, > { self.caps().workspace_symbol_provider.require()?; Ok(self - .request_::<lsp_request!("workspace/symbol"), { Redraw }>( - &lsp_types::WorkspaceSymbolParams { + .request_::<rust_analyzer::lsp::ext::WorkspaceSymbolRequest, { Redraw }>( + &rust_analyzer::lsp::ext::WorkspaceSymbolParams { query: f, search_scope: Some( - lsp_types::WorkspaceSymbolSearchScope::Workspace, + WorkspaceSymbolSearchScope::Workspace, ), search_kind: Some( - lsp_types::WorkspaceSymbolSearchKind::AllSymbols, + WorkspaceSymbolSearchKind::AllSymbols, ), ..Default::default() }, @@ -413,11 +417,10 @@ impl Client { &self, f: &Path, x: Vec<Position>, - ) -> Result<Vec<Option<Position>>, RequestError<MatchingBrace>> { - self.request_immediate::<MatchingBrace>(&MatchingBraceParams { - text_document: f.tid(), - positions: x, - }) + ) -> Result<Vec<[Position;2]>, RequestError<MatchingBraceRequest>> { + self.request_immediate::<MatchingBraceRequest>( + &MatchingBraceParams { text_document: f.tid(), positions: x }, + ) } pub fn matching_brace<'a>(&self, f: &Path, t: &'a mut TextArea) { @@ -425,16 +428,23 @@ impl Client { self.matching_brace_at(f, t.cursor.positions(&t.rope)) { for (c, p) in t.cursor.inner.iter_mut().zip(x) { - if let Some(p) = p { - c.position = t.rope.l_position(p).unwrap(); - } + // if let Some(p) = p { + c.position = t.rope.l_position(p[1]).unwrap(); + // } } } } pub fn legend(&self) -> Option<&SemanticTokensLegend> { - match &self.caps(){ - ServerCapabilities {semantic_tokens_provider:Some(SemanticTokensServerCapabilities::SemanticTokensOptions(SemanticTokensOptions{legend,..})), ..}=> {Some(legend)},_ => None, + match &self.caps() { + ServerCapabilities { + semantic_tokens_provider: + Some(SemanticTokensProvider::SemanticTokensOptions( + SemanticTokensOptions { legend, .. }, + )), + .. + } => Some(legend), + _ => None, } } pub fn inlay( @@ -451,7 +461,7 @@ impl Client { > + use<>, > { self.caps().inlay_hint_provider.require()?; - Ok(self.request_::<lsp_request!("textDocument/inlayHint"), { Redraw }>(&InlayHintParams { + Ok(send!(self.request_::<{ Redraw }>, "textDocument/inlayHint", _ { work_done_progress_params: default(), text_document: f.tid(), range: t.to_l_range(lower::saturating::math!{ @@ -481,28 +491,26 @@ impl Client { impl Future< Output = Result< Option<Vec<TextEdit>>, - RequestError<Formatting>, + RequestError<lsp_request!("textDocument/formatting")>, >, >, > { self.caps().document_formatting_provider.require()?; - Ok(self - .request::<lsp_request!("textDocument/formatting")>( - &DocumentFormattingParams { - text_document: f.tid(), - options: FormattingOptions { - tab_size: 4, - insert_spaces: false, - properties: default(), - trim_trailing_whitespace: Some(true), - insert_final_newline: Some(true), - trim_final_newlines: Some(false), - }, - work_done_progress_params: default(), - }, - ) - .unwrap() - .0) + Ok(send!(self.request, "textDocument/formatting", + _ { + text_document: f.tid(), + options: FormattingOptions { + tab_size: 4, + insert_spaces: false, + // properties: default(), + trim_trailing_whitespace: Some(true), + insert_final_newline: Some(true), + trim_final_newlines: Some(false), + }, + work_done_progress_params: default(), + }) + .unwrap() + .0) } pub fn rq_semantic_tokens( &self, @@ -510,12 +518,15 @@ impl Client { Box<[SemanticToken]>, Box<[SemanticToken]>, (), - RequestError<SemanticTokensFullRequest>, + RequestError<lsp_request!("textDocument/semanticTokens/full")>, >, f: &Path, ) -> Requiring< "semantic_tokens", - Result<(), RequestError<SemanticTokensFullRequest>>, + Result< + (), + RequestError<lsp_request!("textDocument/semanticTokens/full")>, + >, > { self.caps().semantic_tokens_provider.require()?; debug!("requested semantic tokens"); @@ -524,25 +535,23 @@ impl Client { // return Ok(()); // }; Ok(try bikeshed Result<(), RequestError<_>> { - let (rx, _) = self.request::<SemanticTokensFullRequest>( - &SemanticTokensParams { - work_done_progress_params: default(), - partial_result_params: default(), - text_document: f.tid(), - }, - )?; + let (rx, _) = send!(self.request, "textDocument/semanticTokens/full", _ { + work_done_progress_params: default(), + partial_result_params: default(), + text_document: f.tid(), + })?; let x = self.runtime.spawn(async move { let t = rx.await; let y = t?.ok_or(RequestError::Rx(std::marker::PhantomData))?; debug!("received semantic tokens"); - let r = match y { - SemanticTokensResult::Partial(_) => - panic!("i told the lsp i dont support this"), - SemanticTokensResult::Tokens(x) => - x.data.into_boxed_slice(), - }; - Ok(r) + // let r = match y { + // SemanticTokensResult::Partial(_) => + // panic!("i told the lsp i dont support this"), + // SemanticTokensResult::Tokens(x) => + // x.data.into_boxed_slice(), + // }; + Ok(y.data.into_boxed_slice()) }); to.request(x); }) @@ -555,7 +564,7 @@ impl Client { ) -> rootcause::Result<()> { ceach!(t.cursor, |c| try bikeshed rootcause::Result<()> { let r = self - .request_by::<OnEnter>( + .request_by::<OnEnterRequest>( &TextDocumentPositionParams { text_document: f.tid(), position: t.to_l_position(*c).unwrap(), @@ -580,11 +589,12 @@ impl Client { t: &Path, c: Option<Position>, ) -> Result< - impl Future<Output = Result<Vec<Runnable>, RequestError<Runnables>>> - + use<>, - RqSendError<Runnables>, + impl Future< + Output = Result<Vec<Runnable>, RequestError<RunnablesRequest>>, + > + use<>, + RqSendError<RunnablesRequest>, > { - self.request::<Runnables>(&RunnablesParams { + self.request::<RunnablesRequest>(&RunnablesParams { text_document: t.tid(), position: c, }) @@ -598,13 +608,13 @@ impl Client { ) -> Result< impl Future< Output = Result< - <ChildModules as Request>::Result, - RequestError<ChildModules>, + <ChildModulesRequest as Request>::Result, + RequestError<ChildModulesRequest>, >, >, - RqSendError<ChildModules>, + RqSendError<ChildModulesRequest>, > { - self.request::<ChildModules>(&TextDocumentPositionParams { + self.request::<ChildModulesRequest>(&TextDocumentPositionParams { position: p, text_document: t.tid(), }) @@ -616,17 +626,19 @@ impl Client { ) -> Result< impl Future< Output = Result< - <GotoImplementation as Request>::Result, - RequestError<GotoImplementation>, + <lsp_request!("textDocument/implementation") as Request>::Result, + RequestError<lsp_request!("textDocument/implementation")>, >, > + use<>, - RqSendError<GotoImplementation>, - > { - self.request::<GotoImplementation>(&GotoImplementationParams { - text_document_position_params: tdpp, - work_done_progress_params: default(), - partial_result_params: default(), - }) + RqSendError<lsp_request!("textDocument/implementation")>, + >{ + send!(self.request, "textDocument/implementation", + _ { + text_document_position_params: tdpp, + work_done_progress_params: default(), + partial_result_params: default(), + }, + ) .map(fst) } @@ -637,17 +649,19 @@ impl Client { impl Future< Output = Result< Option<Vec<Location>>, - RequestError<References>, + RequestError<lsp_request!("textDocument/references")>, >, > + use<>, - RqSendError<References>, + RqSendError<lsp_request!("textDocument/references")>, > { - self.request::<References>(&ReferenceParams { - text_document_position: tdpp, - work_done_progress_params: default(), - partial_result_params: default(), - context: ReferenceContext { include_declaration: false }, - }) + send!(self.request, "textDocument/references", + _ { + text_document_position_params: tdpp, + work_done_progress_params: default(), + partial_result_params: default(), + context: ReferenceContext { include_declaration: false }, + }, + ) .map(fst) } @@ -666,15 +680,19 @@ impl Client { impl Future< Output = Result< Option<CallHierarchyItem>, - RequestError<CallHierarchyPrepare>, + RequestError< + lsp_request!("textDocument/prepareCallHierarchy"), + >, >, > + use<>, - RqSendError<CallHierarchyPrepare>, + RqSendError<lsp_request!("textDocument/prepareCallHierarchy")>, > { - self.request::<CallHierarchyPrepare>(&CallHierarchyPrepareParams { - text_document_position_params: at, - work_done_progress_params: default(), - }) + send!(self.request, "textDocument/prepareCallHierarchy", + _ { + text_document_position_params: at, + work_done_progress_params: default(), + } + ) .map(fst) .map(|x| x.map(|x| x.map(|x| x.and_then(|mut x| x.try_remove(0))))) } @@ -683,7 +701,7 @@ impl Client { at: TextDocumentPositionParams, ) -> rootcause::Result<Vec<CallHierarchyIncomingCall>> { let calls = self - .request::<CallHierarchyIncomingCalls>( + .request::<CallHierarchyIncomingCallsRequest>( &CallHierarchyIncomingCallsParams { item: self .find_function(at)? @@ -703,7 +721,7 @@ impl Client { at: TextDocumentPositionParams, ) -> rootcause::Result<Vec<CallHierarchyOutgoingCall>> { let calls = self - .request::<CallHierarchyOutgoingCalls>( + .request::<CallHierarchyOutgoingCallsRequest>( &CallHierarchyOutgoingCallsParams { item: self .find_function(at)? |