diff options
Diffstat (limited to 'support/texlab/src/features/definition/command.rs')
-rw-r--r-- | support/texlab/src/features/definition/command.rs | 128 |
1 files changed, 26 insertions, 102 deletions
diff --git a/support/texlab/src/features/definition/command.rs b/support/texlab/src/features/definition/command.rs index 72cd4b5909..599c792dfd 100644 --- a/support/texlab/src/features/definition/command.rs +++ b/support/texlab/src/features/definition/command.rs @@ -1,123 +1,47 @@ -use lsp_types::{GotoDefinitionParams, LocationLink}; +use std::sync::Arc; + +use lsp_types::GotoDefinitionParams; use rowan::ast::AstNode; -use crate::{features::cursor::CursorContext, syntax::latex, LineIndexExt}; +use crate::{features::cursor::CursorContext, syntax::latex}; -pub fn goto_command_definition( - context: &CursorContext<GotoDefinitionParams>, -) -> Option<Vec<LocationLink>> { - let main_document = context.request.main_document(); +use super::DefinitionResult; +pub(super) fn goto_command_definition( + context: &CursorContext<GotoDefinitionParams>, +) -> Option<Vec<DefinitionResult>> { let name = context .cursor .as_latex() .filter(|token| token.kind().is_command_name())?; - let origin_selection_range = main_document - .line_index - .line_col_lsp_range(name.text_range()); + let origin_selection_range = name.text_range(); for document in context.request.workspace.documents_by_uri.values() { if let Some(data) = document.data.as_latex() { - for node in latex::SyntaxNode::new_root(data.green.clone()).descendants() { - if let Some(defintion) = latex::CommandDefinition::cast(node).filter(|def| { + let root = latex::SyntaxNode::new_root(data.green.clone()); + + 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()) - }) { - let target_selection_range = document - .line_index - .line_col_lsp_range(defintion.name()?.command()?.text_range()); - - let target_range = document - .line_index - .line_col_lsp_range(latex::small_range(&defintion)); - - return Some(vec![LocationLink { - origin_selection_range: Some(origin_selection_range), - target_uri: document.uri.as_ref().clone(), - target_range, - target_selection_range, - }]); - } + }) + .find_map(|def| { + Some(DefinitionResult { + origin_selection_range, + target_uri: Arc::clone(&document.uri), + target_range: latex::small_range(&def), + target_selection_range: def.name()?.command()?.text_range(), + }) + }) + { + return Some(vec![result]); } } } None } - -#[cfg(test)] -mod tests { - use indoc::indoc; - use lsp_types::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() - .definition(); - - let context = CursorContext::new(request); - - let actual_links = goto_command_definition(&context); - - assert!(actual_links.is_none()); - } - - #[test] - fn test_empty_bibtex_document() { - let request = FeatureTester::builder() - .files(vec![("main.bib", "")]) - .main("main.bib") - .line(0) - .character(0) - .build() - .definition(); - - let context = CursorContext::new(request); - let actual_links = goto_command_definition(&context); - - assert!(actual_links.is_none()); - } - - #[test] - fn test_command_definition() { - let tester = FeatureTester::builder() - .files(vec![( - "main.tex", - indoc! { - r#" - \DeclareMathOperator{\foo}{foo} - \foo - "# - }, - )]) - .main("main.tex") - .line(1) - .character(2) - .build(); - let target_uri = tester.uri("main.tex").as_ref().clone(); - - let request = tester.definition(); - let context = CursorContext::new(request); - let actual_links = goto_command_definition(&context).unwrap(); - - let expected_links = vec![LocationLink { - origin_selection_range: Some(Range::new_simple(1, 0, 1, 4)), - target_uri, - target_range: Range::new_simple(0, 0, 0, 31), - target_selection_range: Range::new_simple(0, 21, 0, 25), - }]; - - assert_eq!(actual_links, expected_links); - } -} |