Skip to content

Commit

Permalink
Add "Find all References" for commands (#1085)
Browse files Browse the repository at this point in the history
  • Loading branch information
pfoerster authored Apr 21, 2024
1 parent 68a30e8 commit 50a54f3
Show file tree
Hide file tree
Showing 8 changed files with 99 additions and 5 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Replace tilde (`~`), environment variables, `${userHome}`, `${workspaceFolder}` in options
- Replace tidle (`~`) with home directory in `\include`-like commands
- Add "Go To Definition" support for user-defined commands with `\def` and `\let` ([#1081](https://github.com/latex-lsp/texlab/issues/1081))
- Add "Find all References" for commands ([#1082](https://github.com/latex-lsp/texlab/issues/1082))

## [5.14.1] - 2024-03-27

Expand Down
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 9 additions & 0 deletions crates/base-db/src/semantics.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use rowan::{TextLen, TextRange};

pub mod auxiliary;
pub mod bib;
pub mod tex;
Expand All @@ -19,6 +21,13 @@ impl Span {
range: rowan::TextRange::empty(offset),
}
}

pub fn command<L: rowan::Language>(token: &rowan::SyntaxToken<L>) -> Self {
let range = token.text_range();
let range = TextRange::new(range.start() + "\\".text_len(), range.end());
let text = String::from(&token.text()[1..]);
Self::new(text, range)
}
}

impl std::fmt::Debug for Span {
Expand Down
7 changes: 2 additions & 5 deletions crates/base-db/src/semantics/tex.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use rowan::{ast::AstNode, TextLen, TextRange};
use rowan::{ast::AstNode, TextRange};
use rustc_hash::FxHashSet;
use syntax::latex::{self, HasBrack, HasCurly};

Expand Down Expand Up @@ -26,10 +26,7 @@ impl Semantics {
}
latex::SyntaxElement::Token(token) => {
if token.kind() == latex::COMMAND_NAME {
let range = token.text_range();
let range = TextRange::new(range.start() + "\\".text_len(), range.end());
let text = String::from(&token.text()[1..]);
self.commands.push(Span { range, text });
self.commands.push(Span::command(&token));
}
}
};
Expand Down
1 change: 1 addition & 0 deletions crates/references/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ rust-version.workspace = true
[dependencies]
base-db = { path = "../base-db" }
rowan = "0.15.15"
rustc-hash = "1.1.0"
syntax = { path = "../syntax" }

[dev-dependencies]
Expand Down
52 changes: 52 additions & 0 deletions crates/references/src/command.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
use base_db::{semantics::Span, DocumentLocation};
use rowan::ast::AstNode;
use rustc_hash::FxHashSet;
use syntax::latex;

use crate::{Reference, ReferenceContext, ReferenceKind};

pub(super) fn find_all(context: &mut ReferenceContext) -> Option<()> {
let data = context.params.feature.document.data.as_tex()?;
let token = data
.root_node()
.token_at_offset(context.params.offset)
.find(|token| token.kind() == latex::COMMAND_NAME)?;

let project = &context.params.feature.project;

for document in &project.documents {
if let Some(data) = document.data.as_tex() {
let defs: FxHashSet<Span> = data
.root_node()
.descendants()
.filter_map(|node| {
latex::OldCommandDefinition::cast(node.clone())
.and_then(|node| node.name())
.or_else(|| {
latex::NewCommandDefinition::cast(node)
.and_then(|node| node.name())
.and_then(|group| group.command())
})
.map(|name| Span::command(&name))
})
.collect();

for command in &data.semantics.commands {
if command.text == &token.text()[1..] {
let kind = if defs.contains(command) {
ReferenceKind::Definition
} else {
ReferenceKind::Reference
};

context.results.push(Reference {
location: DocumentLocation::new(document, command.range),
kind,
});
}
}
}
}

Some(())
}
2 changes: 2 additions & 0 deletions crates/references/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
mod command;
mod entry;
mod label;
mod string_def;
Expand Down Expand Up @@ -39,6 +40,7 @@ pub fn find_all<'a>(params: &ReferenceParams<'a>) -> Vec<DocumentLocation<'a>> {
entry::find_all(&mut context);
label::find_all(&mut context);
string_def::find_all(&mut context);
command::find_all(&mut context);

context
.results
Expand Down
31 changes: 31 additions & 0 deletions crates/references/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -229,3 +229,34 @@ fn test_string_definition_include_decl() {
true,
);
}

#[test]
fn test_new_command_definition() {
check(
r#"
%! main.tex
\foo
|
^^^
\newcommand{\foo}{foo}
"#,
false,
);
}

#[test]
fn test_new_command_definition_include_decl() {
check(
r#"
%! main.tex
\foo
|
^^^
\newcommand{\foo}{foo}
^^^
"#,
true,
);
}

0 comments on commit 50a54f3

Please sign in to comment.