mirror of
https://github.com/latex-lsp/texlab.git
synced 2025-07-07 21:25:32 +00:00
Handle command definitions without curly braces (#1422)
Parse structures like \newcommand\foo{bar} correctly.
This commit is contained in:
parent
6013783776
commit
7f09abcd0f
7 changed files with 58 additions and 11 deletions
|
@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||
### Fixed
|
||||
|
||||
- Make sort order of workspace symbols deterministic ([#1421](https://github.com/latex-lsp/texlab/issues/1421))
|
||||
- Parse command definitions without curly braces correctly, e. g. `\newcommand\foo{bar}` ([#1409](https://github.com/latex-lsp/texlab/issues/1409))
|
||||
|
||||
## [5.23.0] - 2025-06-14
|
||||
|
||||
|
|
|
@ -49,6 +49,6 @@ fn process_old_definition(node: latex::SyntaxNode) -> Option<(TextRange, latex::
|
|||
|
||||
fn process_new_definition(node: latex::SyntaxNode) -> Option<(TextRange, latex::SyntaxToken)> {
|
||||
let node = latex::NewCommandDefinition::cast(node)?;
|
||||
let name = node.name()?.command()?;
|
||||
let name = node.name()?;
|
||||
Some((latex::small_range(&node), name))
|
||||
}
|
||||
|
|
|
@ -63,6 +63,20 @@ fn test_new_command_definition() {
|
|||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_new_command_definition_without_curly() {
|
||||
check(
|
||||
r#"
|
||||
%! main.tex
|
||||
\newcommand\foo{foo}
|
||||
^^^^
|
||||
^^^^^^^^^^^^^^^^^^^^
|
||||
\foo
|
||||
|
|
||||
^^^^"#,
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_document() {
|
||||
check(
|
||||
|
|
|
@ -946,7 +946,11 @@ impl<'a> Parser<'a> {
|
|||
self.eat();
|
||||
self.trivia();
|
||||
|
||||
if self.lexer.peek() == Some(Token::LCurly) {
|
||||
let token = self.lexer.peek();
|
||||
if matches!(token, Some(Token::CommandName(_))) {
|
||||
self.eat();
|
||||
self.trivia();
|
||||
} else if token == Some(Token::LCurly) {
|
||||
self.curly_group_command();
|
||||
}
|
||||
|
||||
|
|
|
@ -718,6 +718,26 @@ fn test_command_definition_with_begin() {
|
|||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_command_definition_without_curly() {
|
||||
check(
|
||||
r#"\newcommand\foo{bar}"#,
|
||||
expect![[r#"
|
||||
ROOT@0..20
|
||||
PREAMBLE@0..20
|
||||
NEW_COMMAND_DEFINITION@0..20
|
||||
COMMAND_NAME@0..11 "\\newcommand"
|
||||
COMMAND_NAME@11..15 "\\foo"
|
||||
CURLY_GROUP@15..20
|
||||
L_CURLY@15..16 "{"
|
||||
TEXT@16..19
|
||||
WORD@16..19 "bar"
|
||||
R_CURLY@19..20 "}"
|
||||
|
||||
"#]],
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_math_operator_no_impl() {
|
||||
check(
|
||||
|
@ -2681,9 +2701,8 @@ fn test_issue_857() {
|
|||
expect![[r#"
|
||||
ROOT@0..55
|
||||
PREAMBLE@0..55
|
||||
NEW_COMMAND_DEFINITION@0..11
|
||||
NEW_COMMAND_DEFINITION@0..17
|
||||
COMMAND_NAME@0..11 "\\newcommand"
|
||||
GENERIC_COMMAND@11..17
|
||||
COMMAND_NAME@11..14 "\\ö"
|
||||
CURLY_GROUP@14..17
|
||||
L_CURLY@14..15 "{"
|
||||
|
@ -2699,9 +2718,8 @@ fn test_issue_857() {
|
|||
L_CURLY@35..36 "{"
|
||||
R_CURLY@36..37 "}"
|
||||
WHITESPACE@37..38 "\n"
|
||||
NEW_COMMAND_DEFINITION@38..49
|
||||
NEW_COMMAND_DEFINITION@38..55
|
||||
COMMAND_NAME@38..49 "\\newcommand"
|
||||
GENERIC_COMMAND@49..55
|
||||
COMMAND_NAME@49..53 "\\123"
|
||||
CURLY_GROUP@53..55
|
||||
L_CURLY@53..54 "{"
|
||||
|
|
|
@ -23,9 +23,7 @@ pub(super) fn find_all(context: &mut ReferenceContext) -> Option<()> {
|
|||
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())
|
||||
latex::NewCommandDefinition::cast(node).and_then(|node| node.name())
|
||||
})
|
||||
.map(|name| Span::command(&name))
|
||||
})
|
||||
|
|
|
@ -615,8 +615,20 @@ impl NewCommandDefinition {
|
|||
self.syntax().first_token()
|
||||
}
|
||||
|
||||
pub fn name(&self) -> Option<CurlyGroupCommand> {
|
||||
self.syntax().children().find_map(CurlyGroupCommand::cast)
|
||||
pub fn name(&self) -> Option<SyntaxToken> {
|
||||
let token = self
|
||||
.syntax()
|
||||
.children_with_tokens()
|
||||
.skip(1)
|
||||
.filter_map(|elem| elem.into_token())
|
||||
.find(|token| token.kind() == COMMAND_NAME);
|
||||
|
||||
token.or_else(|| {
|
||||
self.syntax()
|
||||
.children()
|
||||
.find_map(CurlyGroupCommand::cast)
|
||||
.and_then(|x| x.command())
|
||||
})
|
||||
}
|
||||
|
||||
pub fn implementation(&self) -> Option<CurlyGroup> {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue