Skip to content

Commit

Permalink
Show BibTeX entry when hovering over citations
Browse files Browse the repository at this point in the history
  • Loading branch information
pfoerster committed May 12, 2019
1 parent e2afe54 commit 90e512e
Show file tree
Hide file tree
Showing 2 changed files with 81 additions and 2 deletions.
73 changes: 73 additions & 0 deletions src/hover/latex_citation.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
use crate::feature::FeatureRequest;
use crate::formatting::{BibtexFormatter, BibtexFormattingOptions};
use crate::syntax::bibtex::{BibtexDeclaration, BibtexEntry};
use crate::syntax::latex::{LatexCitationAnalyzer, LatexToken, LatexVisitor};
use crate::syntax::text::SyntaxNode;
use crate::workspace::SyntaxTree;
use lsp_types::{Hover, HoverContents, MarkupContent, MarkupKind, TextDocumentPositionParams};
use std::borrow::Cow;

pub struct LatexCitationHoverProvider;

impl LatexCitationHoverProvider {
pub async fn execute(request: &FeatureRequest<TextDocumentPositionParams>) -> Option<Hover> {
let entry = Self::get_entry(request)?;
if entry.is_comment() {
None
} else {
let mut formatter = BibtexFormatter::new(BibtexFormattingOptions::new(4, true, 80));
formatter.format_entry(entry);
Some(Hover {
contents: HoverContents::Markup(MarkupContent {
kind: MarkupKind::Markdown,
value: Cow::from(format!("```bibtex\n{}\n```", formatter.output)),
}),
range: None,
})
}
}

fn get_entry(request: &FeatureRequest<TextDocumentPositionParams>) -> Option<&BibtexEntry> {
let key = Self::get_key(request)?;
for document in &request.related_documents {
if let SyntaxTree::Bibtex(tree) = &document.tree {
for declaration in &tree.root.children {
if let BibtexDeclaration::Entry(entry) = &declaration {
if let Some(current_key) = &entry.key {
if current_key.text() == key {
return Some(entry);
}
}
}
}
}
}
None
}

fn get_key(request: &FeatureRequest<TextDocumentPositionParams>) -> Option<&str> {
match &request.document.tree {
SyntaxTree::Latex(tree) => {
let mut analyzer = LatexCitationAnalyzer::new();
analyzer.visit_root(&tree.root);
analyzer
.citations
.iter()
.find(|citation| citation.command.range.contains(request.params.position))
.map(|citation| citation.key.text())
}
SyntaxTree::Bibtex(tree) => {
for declaration in &tree.root.children {
if let BibtexDeclaration::Entry(entry) = &declaration {
if let Some(key) = &entry.key {
if key.range().contains(request.params.position) {
return Some(key.text());
}
}
}
}
None
}
}
}
}
10 changes: 8 additions & 2 deletions src/hover/mod.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,20 @@
mod bibtex_field;
mod latex_citation;

use self::bibtex_field::BibtexFieldHoverProvider;
use self::latex_citation::LatexCitationHoverProvider;
use crate::choice_feature;
use crate::feature::FeatureRequest;
use crate::hover::bibtex_field::BibtexFieldHoverProvider;
use lsp_types::{Hover, TextDocumentPositionParams};

pub struct HoverProvider;

impl HoverProvider {
pub async fn execute(request: &FeatureRequest<TextDocumentPositionParams>) -> Option<Hover> {
choice_feature!(&request, BibtexFieldHoverProvider)
choice_feature!(
&request,
BibtexFieldHoverProvider,
LatexCitationHoverProvider
)
}
}

0 comments on commit 90e512e

Please sign in to comment.