@@ -196,6 +196,12 @@ impl Client {
196196 root_uri: None, // set to project root in the future
197197 initialization_options: None,
198198 capabilities: lsp::ClientCapabilities {
199+ // text_document:
200+ // { completion: {
201+ // dynamic_registration: bool
202+ // completion_item: { snippet, documentation_format, ... }
203+ // completion_item_kind: { }
204+ // } }
199205 ..Default::default()
200206 },
201207 trace: None,
@@ -358,4 +364,41 @@ impl Client {
358364 pub async fn text_document_did_save(&self) -> anyhow::Result<()> {
359365 unimplemented!()
360366 }
367+
368+ pub async fn completion(&self, doc: &Document) -> anyhow::Result<Vec<lsp::CompletionItem>> {
369+ // TODO: figure out what should happen when you complete with multiple cursors
370+
371+ let params = lsp::CompletionParams {
372+ text_document_position: lsp::TextDocumentPositionParams {
373+ text_document: text_document_identifier(doc),
374+ position: crate::util::pos_to_lsp_pos(
375+ &doc.text().slice(..),
376+ doc.selection().cursor(),
377+ ),
378+ },
379+ // TODO: support these tokens by async receiving and updating the choice list
380+ work_done_progress_params: lsp::WorkDoneProgressParams {
381+ work_done_token: None,
382+ },
383+ partial_result_params: lsp::PartialResultParams {
384+ partial_result_token: None,
385+ },
386+ context: None,
387+ // lsp::CompletionContext { trigger_kind: , trigger_character: Some(), }
388+ };
389+
390+ let response = self.request::<lsp::request::Completion>(params).await?;
391+
392+ let items = match response {
393+ Some(lsp::CompletionResponse::Array(items)) => items,
394+ // TODO: do something with is_incomplete
395+ Some(lsp::CompletionResponse::List(lsp::CompletionList {
396+ is_incomplete: _is_incomplete,
397+ items,
398+ })) => items,
399+ None => Vec::new(),
400+ };
401+
402+ Ok(items)
403+ }
361404}