From 13e8aaddd56d5d3ffcebe65ea07fee500130cb6b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patrick=20F=C3=B6rster?= Date: Sun, 12 May 2019 12:21:26 +0200 Subject: [PATCH] Show BibTeX entry when completing citations --- src/completion/factory.rs | 23 +++++++---- src/completion/latex/citation.rs | 5 +-- src/formatting.rs | 70 +++++++++++++++++--------------- src/syntax/bibtex/ast.rs | 4 ++ 4 files changed, 57 insertions(+), 45 deletions(-) diff --git a/src/completion/factory.rs b/src/completion/factory.rs index 1fc0a3cc7..b604eff3c 100644 --- a/src/completion/factory.rs +++ b/src/completion/factory.rs @@ -1,4 +1,6 @@ -use lsp_types::{CompletionItem, CompletionItemKind, InsertTextFormat, Uri}; +use crate::formatting::{BibtexFormatter, BibtexFormattingOptions}; +use crate::syntax::bibtex::{BibtexEntry, BibtexToken}; +use lsp_types::*; use serde::{Deserialize, Serialize}; use std::borrow::Cow; use std::path::Path; @@ -36,11 +38,7 @@ pub enum CompletionItemData { Class, EntryKind, FieldName, - Citation { - #[serde(with = "url_serde")] - uri: Uri, - key: String, - }, + Citation, CommandSymbol, ArgumentSymbol, } @@ -162,11 +160,18 @@ pub fn create_class(name: Cow<'static, str>) -> CompletionItem { } } -pub fn create_citation(uri: Uri, key: String) -> CompletionItem { +pub fn create_citation(entry: &BibtexEntry, key: &str) -> CompletionItem { + let mut formatter = BibtexFormatter::new(BibtexFormattingOptions::new(2, true, 35)); + formatter.format_entry(entry); + let markdown = format!("```bibtex\n{}\n```", formatter.output); CompletionItem { - label: Cow::from(key.clone()), + label: Cow::from(key.to_owned()), kind: Some(CompletionItemKind::Field), - data: Some(CompletionItemData::Citation { uri, key }.into()), + data: Some(CompletionItemData::Citation.into()), + documentation: Some(Documentation::MarkupContent(MarkupContent { + kind: MarkupKind::Markdown, + value: Cow::from(markdown), + })), ..CompletionItem::default() } } diff --git a/src/completion/latex/citation.rs b/src/completion/latex/citation.rs index 45c24cb24..0cf3d90e2 100644 --- a/src/completion/latex/citation.rs +++ b/src/completion/latex/citation.rs @@ -21,10 +21,7 @@ impl LatexCitationCompletionProvider { for declaration in &tree.root.children { if let BibtexDeclaration::Entry(entry) = declaration { if let Some(key) = &entry.key { - items.push(factory::create_citation( - document.uri.clone(), - key.text().to_owned(), - )); + items.push(factory::create_citation(entry, key.text())); } } } diff --git a/src/formatting.rs b/src/formatting.rs index a5cad19e9..d2c9bd59e 100644 --- a/src/formatting.rs +++ b/src/formatting.rs @@ -33,7 +33,7 @@ impl Default for BibtexFormattingOptions { pub struct BibtexFormatter { pub options: BibtexFormattingOptions, indent: String, - output: String, + pub output: String, } impl BibtexFormatter { @@ -61,39 +61,45 @@ impl BibtexFormatter { let text = comment.token.text(); self.output.push_str(text); } - BibtexDeclaration::Preamble(preamble) => { - self.format_token(&preamble.kind); - self.output.push('{'); - if let Some(ref content) = preamble.content { - self.format_content(content, self.output.chars().count()); - self.output.push('}'); - } - } - BibtexDeclaration::String(string) => { - self.format_token(&string.kind); - self.output.push('{'); - if let Some(ref name) = string.name { - self.output.push_str(name.text()); - self.output.push_str(" = "); - if let Some(ref value) = string.value { - self.format_content(value, self.output.chars().count()); - self.output.push('}'); - } - } + BibtexDeclaration::Preamble(preamble) => self.format_preamble(preamble), + BibtexDeclaration::String(string) => self.format_string(string), + BibtexDeclaration::Entry(entry) => self.format_entry(entry), + } + } + + pub fn format_preamble(&mut self, preamble: &BibtexPreamble) { + self.format_token(&preamble.kind); + self.output.push('{'); + if let Some(ref content) = preamble.content { + self.format_content(content, self.output.chars().count()); + self.output.push('}'); + } + } + + pub fn format_string(&mut self, string: &BibtexString) { + self.format_token(&string.kind); + self.output.push('{'); + if let Some(ref name) = string.name { + self.output.push_str(name.text()); + self.output.push_str(" = "); + if let Some(ref value) = string.value { + self.format_content(value, self.output.chars().count()); + self.output.push('}'); } - BibtexDeclaration::Entry(entry) => { - self.format_token(&entry.kind); - self.output.push('{'); - if let Some(ref key) = entry.key { - self.output.push_str(key.text()); - self.output.push(','); - self.output.push('\n'); - for field in &entry.fields { - self.format_field(field); - } - self.output.push('}'); - } + } + } + + pub fn format_entry(&mut self, entry: &BibtexEntry) { + self.format_token(&entry.kind); + self.output.push('{'); + if let Some(ref key) = entry.key { + self.output.push_str(key.text()); + self.output.push(','); + self.output.push('\n'); + for field in &entry.fields { + self.format_field(field); } + self.output.push('}'); } } diff --git a/src/syntax/bibtex/ast.rs b/src/syntax/bibtex/ast.rs index 68853aebb..76da7bcc2 100644 --- a/src/syntax/bibtex/ast.rs +++ b/src/syntax/bibtex/ast.rs @@ -252,6 +252,10 @@ impl BibtexEntry { right, } } + + pub fn is_comment(&self) -> bool { + self.kind.text().to_lowercase() == "@comment" + } } impl SyntaxNode for BibtexEntry {