texlab/features/definition/
entry.rs

1use std::sync::Arc;
2
3use lsp_types::GotoDefinitionParams;
4use rowan::ast::AstNode;
5
6use crate::{
7    features::cursor::CursorContext,
8    syntax::{
9        bibtex::{self, HasName},
10        latex,
11    },
12};
13
14use super::DefinitionResult;
15
16pub(super) fn goto_entry_definition(
17    context: &CursorContext<GotoDefinitionParams>,
18) -> Option<Vec<DefinitionResult>> {
19    let word = context
20        .cursor
21        .as_latex()
22        .filter(|token| token.kind() == latex::WORD)?;
23
24    let key = latex::Key::cast(word.parent()?)?;
25
26    latex::Citation::cast(key.syntax().parent()?.parent()?)?;
27
28    let origin_selection_range = latex::small_range(&key);
29
30    for document in context.request.workspace.iter() {
31        if let Some(data) = document.data().as_bibtex() {
32            for entry in bibtex::SyntaxNode::new_root(data.green.clone())
33                .children()
34                .filter_map(bibtex::Entry::cast)
35            {
36                if let Some(key) = entry.name_token().filter(|k| k.text() == word.text()) {
37                    return Some(vec![DefinitionResult {
38                        origin_selection_range,
39                        target_uri: Arc::clone(document.uri()),
40                        target_selection_range: key.text_range(),
41                        target_range: entry.syntax().text_range(),
42                    }]);
43                }
44            }
45        }
46    }
47
48    None
49}