@@ -13,7 +13,10 @@ use std::sync::atomic::{AtomicU64, Ordering};
1313use tokio::{
1414 io::{BufReader, BufWriter},
1515 process::{Child, Command},
16− sync::mpsc::{channel, UnboundedReceiver, UnboundedSender},
16+ sync::{
17+ mpsc::{channel, UnboundedReceiver, UnboundedSender},
18+ OnceCell,
19+ },
1720};
1821
1922#[derive(Debug)]
@@ -22,7 +25,7 @@ pub struct Client {
2225 _process: Child,
2326 server_tx: UnboundedSender<Payload>,
2427 request_counter: AtomicU64,
25− capabilities: Option<lsp::ServerCapabilities>,
28+ pub(crate) capabilities: OnceCell<lsp::ServerCapabilities>,
2629 offset_encoding: OffsetEncoding,
2730 config: Option<Value>,
2831}
@@ -57,14 +60,11 @@ impl Client {
5760 _process: process,
5861 server_tx,
5962 request_counter: AtomicU64::new(0),
60− capabilities: None,
63+ capabilities: OnceCell::new(),
6164 offset_encoding: OffsetEncoding::Utf8,
6265 config,
6366 };
6467
65− // TODO: async client.initialize()
66− // maybe use an arc<atomic> flag
67−
6868 Ok((client, server_rx))
6969 }
7070
@@ -90,7 +90,7 @@ impl Client {
9090
9191 pub fn capabilities(&self) -> &lsp::ServerCapabilities {
9292 self.capabilities
93− .as_ref()
93+ .get()
9494 .expect("language server not yet initialized!")
9595 }
9696
@@ -151,7 +151,7 @@ impl Client {
151151 }
152152
153153 /// Send a RPC notification to the language server.
154− fn notify<R: lsp::notification::Notification>(
154+ pub fn notify<R: lsp::notification::Notification>(
155155 &self,
156156 params: R::Params,
157157 ) -> impl Future<Output = Result<()>>
@@ -213,7 +213,7 @@ impl Client {
213213 // General messages
214214 // -------------------------------------------------------------------------------------------
215215
216− pub(crate) async fn initialize(&mut self) -> Result<()> {
216+ pub(crate) async fn initialize(&self) -> Result<lsp::InitializeResult> {
217217 // TODO: delay any requests that are triggered prior to initialize
218218 let root = find_root(None).and_then(|root| lsp::Url::from_file_path(root).ok());
219219
@@ -281,14 +281,7 @@ impl Client {
281281 locale: None, // TODO
282282 };
283283
284− let response = self.request::<lsp::request::Initialize>(params).await?;
285− self.capabilities = Some(response.capabilities);
286−
287− // next up, notify<initialized>
288− self.notify::<lsp::notification::Initialized>(lsp::InitializedParams {})
289− .await?;
290−
291− Ok(())
284+ self.request::<lsp::request::Initialize>(params).await
292285 }
293286
294287 pub async fn shutdown(&self) -> Result<()> {
@@ -445,7 +438,7 @@ impl Client {
445438 ) -> Option<impl Future<Output = Result<()>>> {
446439 // figure out what kind of sync the server supports
447440
448− let capabilities = self.capabilities.as_ref().unwrap();
441+ let capabilities = self.capabilities.get().unwrap();
449442
450443 let sync_capabilities = match capabilities.text_document_sync {
451444 Some(lsp::TextDocumentSyncCapability::Kind(kind))
@@ -496,7 +489,7 @@ impl Client {
496489 text_document: lsp::TextDocumentIdentifier,
497490 text: &Rope,
498491 ) -> Result<()> {
499− let capabilities = self.capabilities.as_ref().unwrap();
492+ let capabilities = self.capabilities.get().unwrap();
500493
501494 let include_text = match &capabilities.text_document_sync {
502495 Some(lsp::TextDocumentSyncCapability::Options(lsp::TextDocumentSyncOptions {
@@ -590,7 +583,7 @@ impl Client {
590583 options: lsp::FormattingOptions,
591584 work_done_token: Option<lsp::ProgressToken>,
592585 ) -> anyhow::Result<Vec<lsp::TextEdit>> {
593− let capabilities = self.capabilities.as_ref().unwrap();
586+ let capabilities = self.capabilities.get().unwrap();
594587
595588 // check if we're able to format
596589 match capabilities.document_formatting_provider {
@@ -618,7 +611,7 @@ impl Client {
618611 options: lsp::FormattingOptions,
619612 work_done_token: Option<lsp::ProgressToken>,
620613 ) -> anyhow::Result<Vec<lsp::TextEdit>> {
621− let capabilities = self.capabilities.as_ref().unwrap();
614+ let capabilities = self.capabilities.get().unwrap();
622615
623616 // check if we're able to format
624617 match capabilities.document_range_formatting_provider {