From 5237560b6192e6a8647c9ae02e6037fc66d6c482 Mon Sep 17 00:00:00 2001 From: PoiScript Date: Thu, 21 Dec 2023 02:57:13 +0800 Subject: [PATCH] feat(lsp): completion support --- orgize-lsp/src/completion.rs | 75 ++++++++++++++++++++++++++++++++++++ orgize-lsp/src/main.rs | 15 ++++++-- 2 files changed, 87 insertions(+), 3 deletions(-) create mode 100644 orgize-lsp/src/completion.rs diff --git a/orgize-lsp/src/completion.rs b/orgize-lsp/src/completion.rs new file mode 100644 index 0000000..5b48c9c --- /dev/null +++ b/orgize-lsp/src/completion.rs @@ -0,0 +1,75 @@ +use tower_lsp::lsp_types::{ + CompletionItem, CompletionItemKind, CompletionParams, CompletionResponse, CompletionTextEdit, + Position, Range, TextEdit, +}; + +use crate::Backend; + +pub fn completion(params: CompletionParams, backend: &Backend) -> Option { + let uri = params.text_document_position.text_document.uri.to_string(); + + let Some(doc) = backend.documents.get(&uri) else { + return None; + }; + + let offset = doc.offset_of(params.text_document_position.position) as usize; + + if offset < 2 { + return None; + } + + let filter_text = doc.text.get((offset - 2)..offset)?; + + let (label, new_text) = match filter_text { + " ( + "ASCI export block", + "#+BEGIN_EXPORT ascii\n\n#+END_EXPORT\n", + ), + " ("Center block", "#+BEGIN_CENTER\n\n#+END_CENTER\n"), + " ("Comment block", "#+BEGIN_COMMENT\n\n#+END_COMMENT\n"), + " ("Example block", "#+BEGIN_EXAMPLE\n\n#+END_EXAMPLE\n"), + " ("Export block", "#+BEGIN_EXPORT\n\n#+END_EXPORT\n"), + " ("HTML export block", "#+BEGIN_EXPORT html\n\n#+END_EXPORT\n"), + " ( + "LaTeX export block", + "#+BEGIN_EXPORT latex\n\n#+END_EXPORT\n", + ), + " ("Quote block", "#+BEGIN_QUOTE\n\n#+END_QUOTE\n"), + " ("Source block", "#+BEGIN_SRC\n\n#+END_SRC\n"), + " ("Verse block", "#+BEGIN_VERSE\n\n#+END_VERSE\n"), + _ => return None, + }; + + let end = params.text_document_position.position; + + Some(CompletionResponse::Array(vec![CompletionItem { + label: label.into(), + kind: Some(CompletionItemKind::TEXT), + insert_text: Some(new_text.into()), + filter_text: Some(filter_text.into()), + text_edit: Some(CompletionTextEdit::Edit(TextEdit { + new_text: new_text.into(), + range: Range { + start: Position::new(end.line, end.character - 2), + end, + }, + })), + ..Default::default() + }])) +} + +pub fn trigger_characters() -> Vec { + vec![ + " Result> { - Ok(None) + async fn completion(&self, params: CompletionParams) -> Result> { + Ok(completion::completion(params, &self)) + } + + async fn completion_resolve(&self, params: CompletionItem) -> Result { + Ok(params) } async fn semantic_tokens_full( @@ -265,7 +275,6 @@ impl LanguageServer for Backend { let mut t = DocumentSymbolTraverser::new(&doc); doc.traverse(&mut t); - dbg!(&t.symbols); Ok(Some(DocumentSymbolResponse::Nested(t.symbols))) } }