summaryrefslogtreecommitdiff
path: root/support/texlab/src/features/definition/command.rs
blob: 743a0f6d3c31ca1f8936c1cfa2f92c900bf0a72a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
use rowan::ast::AstNode;

use crate::{syntax::latex, util::cursor::CursorContext};

use super::DefinitionResult;

pub(super) fn goto_definition(context: &CursorContext) -> Option<Vec<DefinitionResult>> {
    let name = context
        .cursor
        .as_tex()
        .filter(|token| token.kind() == latex::COMMAND_NAME)?;

    let origin_selection_range = name.text_range();

    for document in context.related() {
        if let Some(data) = document.parse(context.db).as_tex() {
            let root = data.root(context.db);
            if let Some(result) = root
                .descendants()
                .filter_map(latex::CommandDefinition::cast)
                .filter(|def| {
                    def.name()
                        .and_then(|name| name.command())
                        .map_or(false, |node| node.text() == name.text())
                })
                .find_map(|def| {
                    Some(DefinitionResult {
                        origin_selection_range,
                        target: document,
                        target_range: latex::small_range(&def),
                        target_selection_range: def.name()?.command()?.text_range(),
                    })
                })
            {
                return Some(vec![result]);
            }
        }
    }

    None
}