summaryrefslogtreecommitdiff
path: root/support/texlab/src/features/hover/citation.rs
diff options
context:
space:
mode:
Diffstat (limited to 'support/texlab/src/features/hover/citation.rs')
-rw-r--r--support/texlab/src/features/hover/citation.rs133
1 files changed, 133 insertions, 0 deletions
diff --git a/support/texlab/src/features/hover/citation.rs b/support/texlab/src/features/hover/citation.rs
new file mode 100644
index 0000000000..1fd6d6c06b
--- /dev/null
+++ b/support/texlab/src/features/hover/citation.rs
@@ -0,0 +1,133 @@
+use cancellation::CancellationToken;
+use lsp_types::{Hover, HoverContents, HoverParams};
+
+use crate::{citation, features::cursor::CursorContext, LineIndexExt};
+
+pub fn find_citation_hover(
+ context: &CursorContext<HoverParams>,
+ cancellation_token: &CancellationToken,
+) -> Option<Hover> {
+ cancellation_token.result().ok()?;
+ let main_document = context.request.main_document();
+
+ let (key_text, key_range) = context
+ .find_citation_key_word()
+ .or_else(|| context.find_citation_key_command())
+ .or_else(|| context.find_entry_key())?;
+
+ let contents = context
+ .request
+ .subset
+ .documents
+ .iter()
+ .find_map(|document| {
+ document
+ .data
+ .as_bibtex()
+ .and_then(|data| citation::render_citation(&data.root, &key_text))
+ })?;
+
+ Some(Hover {
+ range: Some(main_document.line_index.line_col_lsp_range(key_range)),
+ contents: HoverContents::Markup(contents),
+ })
+}
+
+#[cfg(test)]
+mod tests {
+ use lsp_types::{MarkupContent, MarkupKind, Range};
+
+ use crate::{features::testing::FeatureTester, RangeExt};
+
+ use super::*;
+
+ #[test]
+ fn test_empty_latex_document() {
+ let request = FeatureTester::builder()
+ .files(vec![("main.tex", "")])
+ .main("main.tex")
+ .line(0)
+ .character(0)
+ .build()
+ .hover();
+
+ let context = CursorContext::new(request);
+ let actual_hover = find_citation_hover(&context, CancellationToken::none());
+
+ assert_eq!(actual_hover, None);
+ }
+
+ #[test]
+ fn test_empty_bibtex_document() {
+ let request = FeatureTester::builder()
+ .files(vec![("main.bib", "")])
+ .main("main.bib")
+ .line(0)
+ .character(0)
+ .build()
+ .hover();
+
+ let context = CursorContext::new(request);
+ let actual_hover = find_citation_hover(&context, CancellationToken::none());
+
+ assert_eq!(actual_hover, None);
+ }
+
+ #[test]
+ fn test_inside_cite() {
+ let request = FeatureTester::builder()
+ .files(vec![
+ (
+ "main.bib",
+ "@article{foo, author = {Foo Bar}, title = {Baz Qux}, year = 1337}",
+ ),
+ ("main.tex", "\\addbibresource{main.bib}\n\\cite{foo}"),
+ ])
+ .main("main.tex")
+ .line(1)
+ .character(7)
+ .build()
+ .hover();
+
+ let context = CursorContext::new(request);
+ let actual_hover = find_citation_hover(&context, CancellationToken::none()).unwrap();
+
+ let expected_hover = Hover {
+ contents: HoverContents::Markup(MarkupContent {
+ kind: MarkupKind::Markdown,
+ value: "Bar, F. (1337). *Baz Qux*.".into(),
+ }),
+ range: Some(Range::new_simple(1, 6, 1, 9)),
+ };
+ assert_eq!(actual_hover, expected_hover);
+ }
+
+ #[test]
+ fn test_inside_entry() {
+ let request = FeatureTester::builder()
+ .files(vec![
+ (
+ "main.bib",
+ "@article{foo, author = {Foo Bar}, title = {Baz Qux}, year = 1337}",
+ ),
+ ("main.tex", "\\addbibresource{main.bib}\n\\cite{foo}"),
+ ])
+ .main("main.bib")
+ .line(0)
+ .character(11)
+ .build()
+ .hover();
+
+ let context = CursorContext::new(request);
+ let actual_hover = find_citation_hover(&context, CancellationToken::none()).unwrap();
+
+ let expected_hover = Hover {
+ contents: HoverContents::Markup(MarkupContent {
+ kind: MarkupKind::Markdown,
+ value: "Bar, F. (1337). *Baz Qux*.".into(),
+ }),
+ range: Some(Range::new_simple(0, 9, 0, 12)),
+ };
+ assert_eq!(actual_hover, expected_hover);
+ }
+}