From a5ae129f3aa3a3a0aeaa21c55b75a1d543fe4111 Mon Sep 17 00:00:00 2001 From: Norbert Preining Date: Fri, 4 Jun 2021 03:02:48 +0000 Subject: CTAN sync 202106040302 --- support/texlab/CHANGELOG.md | 18 ++++ support/texlab/Cargo.lock | 33 +++---- support/texlab/Cargo.toml | 22 +++-- support/texlab/README.md | 5 +- support/texlab/docs/options.md | 36 +++++++ support/texlab/src/citation.rs | 2 +- support/texlab/src/diagnostics/bibtex.rs | 12 +-- support/texlab/src/diagnostics/latex.rs | 22 +++-- support/texlab/src/features/completion.rs | 36 +++++-- .../texlab/src/features/completion/acronym_ref.rs | 16 +-- support/texlab/src/features/completion/citation.rs | 74 +++++++++++--- support/texlab/src/features/completion/color.rs | 11 +-- .../texlab/src/features/completion/color_model.rs | 31 ++---- .../features/completion/component_environment.rs | 20 +--- support/texlab/src/features/completion/field.rs | 2 +- .../texlab/src/features/completion/glossary_ref.rs | 18 +--- support/texlab/src/features/completion/import.rs | 13 +-- support/texlab/src/features/completion/include.rs | 11 +-- support/texlab/src/features/completion/label.rs | 60 ++++++----- support/texlab/src/features/completion/theorem.rs | 21 +--- .../texlab/src/features/completion/tikz_library.rs | 12 +-- support/texlab/src/features/completion/types.rs | 8 +- .../src/features/completion/user_environment.rs | 21 +--- support/texlab/src/features/cursor.rs | 110 ++++++++++++++++----- support/texlab/src/features/definition/entry.rs | 12 ++- support/texlab/src/features/definition/label.rs | 13 ++- support/texlab/src/features/formatting.rs | 6 +- .../src/features/formatting/bibtex_internal.rs | 2 +- .../texlab/src/features/formatting/latexindent.rs | 96 +++++++++++++----- support/texlab/src/features/highlight.rs | 7 +- support/texlab/src/features/highlight/label.rs | 61 +++++------- support/texlab/src/features/hover/label.rs | 4 +- support/texlab/src/features/reference/entry.rs | 10 +- support/texlab/src/features/reference/label.rs | 2 +- support/texlab/src/features/rename/entry.rs | 35 +++---- support/texlab/src/features/rename/label.rs | 37 +++---- support/texlab/src/features/symbol/bibtex.rs | 4 +- support/texlab/src/features/symbol/latex.rs | 22 ++--- support/texlab/src/label.rs | 13 +-- support/texlab/src/line_index.rs | 2 +- support/texlab/src/line_index_ext.rs | 2 +- support/texlab/src/options.rs | 28 ++++++ support/texlab/src/syntax/bibtex/cst.rs | 36 ++++++- support/texlab/src/syntax/bibtex/kind.rs | 1 + support/texlab/src/syntax/bibtex/parser.rs | 14 ++- ...btex__parser__tests__entry_complete_parens.snap | 3 +- ...ax__bibtex__parser__tests__entry_no_fields.snap | 3 +- ...rser__tests__entry_no_fields_missing_comma.snap | 3 +- ...ax__bibtex__parser__tests__entry_one_field.snap | 3 +- ..._parser__tests__entry_one_field_number_key.snap | 3 +- ...ser__tests__entry_one_field_trailing_comma.snap | 3 +- ...x__bibtex__parser__tests__entry_two_fields.snap | 3 +- ...parser__tests__entry_two_fields_incomplete.snap | 3 +- .../src/syntax/latex/analysis/environment.rs | 2 +- .../src/syntax/latex/analysis/explicit_link.rs | 20 ++-- .../texlab/src/syntax/latex/analysis/label_name.rs | 24 ++--- .../src/syntax/latex/analysis/label_number.rs | 2 +- .../texlab/src/syntax/latex/analysis/theorem.rs | 2 +- support/texlab/src/syntax/latex/analysis/types.rs | 6 +- support/texlab/src/syntax/latex/cst.rs | 52 +++++++--- support/texlab/src/syntax/latex/parser.rs | 108 +++++++++++--------- ..._latex__parser__tests__acronym_declaration.snap | 3 +- ..._parser__tests__acroynm_definition_options.snap | 3 +- ...__parser__tests__acroynm_definition_simple.snap | 3 +- ...__parser__tests__acroynm_reference_options.snap | 3 +- ...x__parser__tests__acroynm_reference_simple.snap | 3 +- ...x__parser__tests__biblatex_include_options.snap | 3 +- ...ex__parser__tests__biblatex_include_simple.snap | 3 +- ...atex__parser__tests__bibtex_include_simple.snap | 3 +- ...ntax__latex__parser__tests__caption_figure.snap | 6 +- ...tex__parser__tests__citation_missing_brace.snap | 3 +- ...tex__parser__tests__citation_multiple_keys.snap | 6 +- ...ax__latex__parser__tests__citation_prenote.snap | 3 +- ...__parser__tests__citation_prenote_postnote.snap | 3 +- ...x__parser__tests__citation_redundant_comma.snap | 3 +- ...tax__latex__parser__tests__citation_simple.snap | 3 +- ...yntax__latex__parser__tests__citation_star.snap | 3 +- ...atex__parser__tests__class_include_options.snap | 3 +- ...latex__parser__tests__class_include_simple.snap | 3 +- ...ex__parser__tests__color_definition_simple.snap | 6 +- ...tex__parser__tests__color_reference_simple.snap | 3 +- ...parser__tests__color_set_definition_error1.snap | 15 ++- ...parser__tests__color_set_definition_error2.snap | 9 +- ...parser__tests__color_set_definition_error3.snap | 6 +- ...parser__tests__color_set_definition_simple.snap | 18 ++-- ...__parser__tests__command_definition_simple.snap | 3 +- ...tex__parser__tests__environment_definition.snap | 6 +- ...__latex__parser__tests__environment_nested.snap | 12 ++- ...__tests__environment_nested_missing_braces.snap | 31 +++--- ...__latex__parser__tests__environment_simple.snap | 6 +- ...er__tests__equation_label_reference_simple.snap | 3 +- ...tex__parser__tests__equation_missing_begin.snap | 6 +- ...latex__parser__tests__equation_missing_end.snap | 6 +- ...r__tests__glossary_entry_definition_simple.snap | 3 +- ...r__tests__glossary_entry_reference_options.snap | 3 +- ...er__tests__glossary_entry_reference_simple.snap | 3 +- ...x__parser__tests__graphics_include_options.snap | 3 +- ...ex__parser__tests__graphics_include_simple.snap | 3 +- ...x__latex__parser__tests__import_incomplete.snap | 3 +- ...yntax__latex__parser__tests__import_simple.snap | 6 +- ...x__parser__tests__inkscape_include_options.snap | 3 +- ...ex__parser__tests__inkscape_include_simple.snap | 3 +- ...ex__parser__tests__label_definition_simple.snap | 3 +- ...syntax__latex__parser__tests__label_number.snap | 3 +- ...x__parser__tests__label_reference_multiple.snap | 6 +- ...parser__tests__label_reference_range_error.snap | 6 +- ...r__tests__label_reference_range_incomplete.snap | 3 +- ...arser__tests__label_reference_range_simple.snap | 6 +- ...tex__parser__tests__label_reference_simple.snap | 3 +- ...latex__parser__tests__latex_include_simple.snap | 3 +- ...__latex__parser__tests__latex_input_simple.snap | 3 +- ...x__parser__tests__package_include_multiple.snap | 6 +- ...ex__parser__tests__package_include_options.snap | 3 +- ...tex__parser__tests__package_include_simple.snap | 3 +- ...__parser__tests__pgf_library_import_simple.snap | 3 +- ..._latex__parser__tests__structure_enum_item.snap | 6 +- ..._latex__parser__tests__svg_include_options.snap | 3 +- ...__latex__parser__tests__svg_include_simple.snap | 3 +- ...ex__parser__tests__theorem_definition_full.snap | 9 +- ...ests__theorem_definition_name_with_counter.snap | 6 +- ...__theorem_definition_name_with_description.snap | 3 +- ...finition_name_with_description_and_counter.snap | 6 +- ...arser__tests__theorem_definition_only_name.snap | 3 +- ..._parser__tests__tikz_library_import_simple.snap | 3 +- ...ex__parser__tests__verbatim_include_simple.snap | 3 +- support/texlab/tests/integration/completion.rs | 34 +++++++ ...on__completion__latex__citation_multi_word.snap | 34 +++++++ support/texlab/texlab.pdf | Bin 84894 -> 26161 bytes support/texlab/texlab.tex | 78 +++++++++++++++ 129 files changed, 1097 insertions(+), 626 deletions(-) create mode 100644 support/texlab/tests/integration/snapshots/integration__completion__latex__citation_multi_word.snap create mode 100644 support/texlab/texlab.tex (limited to 'support/texlab') diff --git a/support/texlab/CHANGELOG.md b/support/texlab/CHANGELOG.md index df4134084d..885fa24bc5 100644 --- a/support/texlab/CHANGELOG.md +++ b/support/texlab/CHANGELOG.md @@ -5,6 +5,24 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [3.1.0] - 03.06.2021 + +### Added + +- Add `texlab.latexFormatter` setting to allow turning off `latexindent`. + At the moment, `texlab.latexFormatter: texlab` is not implemented yet and does nothing. +- Expose the `--local` flag of `latexindent` via `texlab.latexindent.local` setting ([#365](https://github.com/latex-lsp/texlab/issues/365)) +- Expose the `--modfiylinebreaks` flag of `latexindent` via `texlab.latexindent.modifyLineBreaks` setting ([#365](https://github.com/latex-lsp/texlab/issues/365)) +- Assign (unique) error codes to static analysis diagnostics. + +### Fixed + +- Avoid creating defunct `latexindent` processes which clear out the document ([#437](https://github.com/latex-lsp/texlab/issues/437)) +- Allow whitespace in LaTeX identifiers like labels ([#433](https://github.com/latex-lsp/texlab/issues/433)) +- Run CI on Ubuntu 18.04 to allow an older `glibc` version ([#439](https://github.com/latex-lsp/texlab/issues/439)). + +### Fixed + ## [3.0.1] - 22.05.2021 ### Fixed diff --git a/support/texlab/Cargo.lock b/support/texlab/Cargo.lock index c224bce2d3..8ae7d7e49d 100644 --- a/support/texlab/Cargo.lock +++ b/support/texlab/Cargo.lock @@ -604,21 +604,11 @@ dependencies = [ "percent-encoding", ] -[[package]] -name = "fsevent" -version = "2.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97f347202c95c98805c216f9e1df210e8ebaec9fdb2365700a43c10797a35e63" -dependencies = [ - "bitflags", - "fsevent-sys", -] - [[package]] name = "fsevent-sys" -version = "3.1.0" +version = "4.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca6f5e6817058771c10f0eb0f05ddf1e35844266f972004fe8e4b21fda295bd5" +checksum = "5c0e564d24da983c053beff1bb7178e237501206840a3e6bf4e267b9e8ae734a" dependencies = [ "libc", ] @@ -999,9 +989,9 @@ dependencies = [ [[package]] name = "lsp-types" -version = "0.89.0" +version = "0.89.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07731ecd4ee0654728359a5b95e2a254c857876c04b85225496a35d60345daa7" +checksum = "48b8a871b0a450bcec0e26d74a59583c8173cb9fb7d7f98889e18abb84838e0f" dependencies = [ "bitflags", "serde", @@ -1154,14 +1144,13 @@ dependencies = [ [[package]] name = "notify" -version = "5.0.0-pre.8" +version = "5.0.0-pre.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46bbbcd078f1f00ddb7a9abe70b96e91229b44b0b3afdec610f8e5137f8f014b" +checksum = "b89869d77edd64db917d7903abeadc166f93686b342c56cc0ca51acb68441d09" dependencies = [ "bitflags", "crossbeam-channel 0.5.1", "filetime", - "fsevent", "fsevent-sys", "inotify", "libc", @@ -1697,9 +1686,9 @@ dependencies = [ [[package]] name = "rayon" -version = "1.5.0" +version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b0d8e0819fadc20c74ea8373106ead0600e3a67ef1fe8da56e39b9ae7275674" +checksum = "c06aca804d41dbc8ba42dfd964f0d01334eceb64314b9ecf7c5fad5188a06d90" dependencies = [ "autocfg 1.0.1", "crossbeam-deque 0.8.0", @@ -1709,9 +1698,9 @@ dependencies = [ [[package]] name = "rayon-core" -version = "1.9.0" +version = "1.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ab346ac5921dc62ffa9f89b7a773907511cdfa5490c572ae9be1be33e8afa4a" +checksum = "d78120e2c850279833f1dd3582f730c4ab53ed95aeaaaa862a2a5c71b1656d8e" dependencies = [ "crossbeam-channel 0.5.1", "crossbeam-deque 0.8.0", @@ -2167,7 +2156,7 @@ dependencies = [ [[package]] name = "texlab" -version = "3.0.1" +version = "3.1.0" dependencies = [ "anyhow", "bibutils-sys", diff --git a/support/texlab/Cargo.toml b/support/texlab/Cargo.toml index 56317c7f9c..506b454b4a 100644 --- a/support/texlab/Cargo.toml +++ b/support/texlab/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "texlab" description = "LaTeX Language Server" -version = "3.0.1" +version = "3.1.0" license = "GPL-3.0" readme = "README.md" authors = [ @@ -17,7 +17,17 @@ doctest = false [features] default = ["citation", "completion"] completion = ["fuzzy-matcher"] -citation = ["bibutils-sys", "citeproc", "citeproc-db", "citeproc-io", "csl", "fnv", "html2md", "lalrpop-util", "lalrpop"] +citation = [ + "bibutils-sys", + "citeproc", + "citeproc-db", + "citeproc-io", + "csl", + "fnv", + "html2md", + "lalrpop-util", + "lalrpop", +] semantic = [] [dependencies] @@ -45,12 +55,12 @@ lalrpop-util = { version = "0.19.5", optional = true } log = "0.4.14" logos = "0.12.0" lsp-server = "0.5" -lsp-types = "0.89.0" +lsp-types = "0.89.1" multimap = "0.8.3" -notify = "5.0.0-pre.8" +notify = "5.0.0-pre.9" once_cell = "1.7.2" petgraph = "0.5.1" -rayon = "1.5.0" +rayon = "1.5.1" regex = "1.5.4" rustc-hash = "1.1.0" serde = "1.0.126" @@ -73,4 +83,4 @@ unindent = "0.1.7" lalrpop = { version = "0.19.5", features = ["lexer"], optional = true } [profile.release] -lto = true \ No newline at end of file +lto = true diff --git a/support/texlab/README.md b/support/texlab/README.md index b2edc3f2b4..57351b677b 100644 --- a/support/texlab/README.md +++ b/support/texlab/README.md @@ -1,7 +1,6 @@ [![CI](https://github.com/latex-lsp/texlab/workflows/CI/badge.svg)](https://github.com/latex-lsp/texlab/actions) [![Coverage](https://codecov.io/gh/latex-lsp/texlab/branch/master/graph/badge.svg)](https://codecov.io/gh/latex-lsp/texlab) -[![Rust](https://img.shields.io/badge/rustc-1.39%2B-blue)](https://blog.rust-lang.org/2019/11/07/Rust-1.39.0.html) -[![Dependabot](https://api.dependabot.com/badges/status?host=github&repo=latex-lsp/texlab)](https://dependabot.com) +[![Rust](https://img.shields.io/badge/rustc-1.51%2B-blue)](https://blog.rust-lang.org/2021/03/25/Rust-1.51.0.html) [![GitHub release](https://img.shields.io/github/release/latex-lsp/texlab?label=github)](https://github.com/latex-lsp/texlab/releases) [![CTAN](https://img.shields.io/ctan/v/texlab)](https://ctan.org/pkg/texlab) @@ -41,7 +40,7 @@ On Windows, you may need to install [Microsoft Visual C++ Redistributable for Vi You will need to install the following dependencies to compile the server: -- A recent, stable version of [Rust](https://rustup.rs/) +- A recent, stable version of [Rust](https://rustup.rs/) (>= 1.51) Then run the following command in the project folder: diff --git a/support/texlab/docs/options.md b/support/texlab/docs/options.md index 9cabd31062..3cc2edfd8a 100644 --- a/support/texlab/docs/options.md +++ b/support/texlab/docs/options.md @@ -143,3 +143,39 @@ Possible values are either `texlab` or `latexindent`. **Type:** `string` **Default value:** `texlab` + +--- + +## texlab.latexFormatter + +Defines the formatter to use for LaTeX formatting. +Possible values are either `texlab` or `latexindent`. +Note that `texlab` is not implemented yet. + +**Type:** `string` + +**Default value:** `latexindent` + +--- + +## texlab.latexindent.local + +Defines the path of a file containing the `latexindent` configuration. +This corresponds to the `--local=file.yaml` flag of `latexindent`. +By default the configuration inside the project root directory is used. + +**Type:** `string` + +**Default value:** `null` + +--- + +## texlab.latexindent.modifyLineBreaks + +Modifies linebreaks before, during, and at the end of code blocks +when formatting with `latexindent`. +This corresponds to the `--modifylinebreaks` flag of `latexindent`. + +**Type:** `boolean` + +**Default value:** `false` diff --git a/support/texlab/src/citation.rs b/support/texlab/src/citation.rs index e185c14b55..daa4b60997 100644 --- a/support/texlab/src/citation.rs +++ b/support/texlab/src/citation.rs @@ -67,7 +67,7 @@ fn convert_to_ris(root: &bibtex::SyntaxNode, key: &str) -> Option let entry = root .children() .filter_map(bibtex::Entry::cast) - .find(|entry| entry.key().map(|key| key.text()) == Some(key))?; + .find(|entry| entry.key().map(|key| key.to_string()).as_deref() == Some(key))?; bib_code.push_str(&entry.syntax().to_string()); bib_code = bib_code.replace("\\hypen", "-"); diff --git a/support/texlab/src/diagnostics/bibtex.rs b/support/texlab/src/diagnostics/bibtex.rs index efea141db0..d90bde0c8d 100644 --- a/support/texlab/src/diagnostics/bibtex.rs +++ b/support/texlab/src/diagnostics/bibtex.rs @@ -1,7 +1,7 @@ use std::sync::Arc; use cstree::TextRange; -use lsp_types::{Diagnostic, DiagnosticSeverity}; +use lsp_types::{Diagnostic, DiagnosticSeverity, NumberOrString}; use multimap::MultiMap; use crate::{ @@ -42,7 +42,7 @@ fn analyze_entry( .line_index .line_col_lsp_range(entry.ty()?.text_range()), severity: Some(DiagnosticSeverity::Error), - code: None, + code: Some(NumberOrString::Number(4)), code_description: None, source: Some("texlab".to_string()), message: "Expecting a curly bracket: \"{\"".to_string(), @@ -62,7 +62,7 @@ fn analyze_entry( .line_index .line_col_lsp_range(entry.left_delimiter()?.text_range()), severity: Some(DiagnosticSeverity::Error), - code: None, + code: Some(NumberOrString::Number(5)), code_description: None, source: Some("texlab".to_string()), message: "Expecting a key".to_string(), @@ -82,7 +82,7 @@ fn analyze_entry( .line_index .line_col_lsp_range(entry.right_delimiter()?.text_range()), severity: Some(DiagnosticSeverity::Error), - code: None, + code: Some(NumberOrString::Number(6)), code_description: None, source: Some("texlab".to_string()), message: "Expecting a curly bracket: \"}\"".to_string(), @@ -111,7 +111,7 @@ fn analyze_field( .line_index .line_col_lsp_range(TextRange::empty(field.name()?.text_range().end())), severity: Some(DiagnosticSeverity::Error), - code: None, + code: Some(NumberOrString::Number(7)), code_description: None, source: Some("texlab".to_string()), message: "Expecting an equality sign: \"=\"".to_string(), @@ -131,7 +131,7 @@ fn analyze_field( field.equality_sign()?.text_range().end(), )), severity: Some(DiagnosticSeverity::Error), - code: None, + code: Some(NumberOrString::Number(8)), code_description: None, source: Some("texlab".to_string()), message: "Expecting a field value".to_string(), diff --git a/support/texlab/src/diagnostics/latex.rs b/support/texlab/src/diagnostics/latex.rs index b835f88398..012e9b399f 100644 --- a/support/texlab/src/diagnostics/latex.rs +++ b/support/texlab/src/diagnostics/latex.rs @@ -1,7 +1,7 @@ use std::sync::Arc; use cstree::TextRange; -use lsp_types::{Diagnostic, DiagnosticSeverity}; +use lsp_types::{Diagnostic, DiagnosticSeverity, NumberOrString}; use multimap::MultiMap; use crate::{ @@ -31,7 +31,7 @@ pub fn analyze_latex_static( Diagnostic { range: document.line_index.line_col_lsp_range(node.text_range()), severity: Some(DiagnosticSeverity::Error), - code: None, + code: Some(NumberOrString::Number(1)), code_description: None, source: Some("texlab".to_string()), message: "Unexpected \"}\"".to_string(), @@ -56,15 +56,15 @@ fn analyze_environment( node: &latex::SyntaxNode, ) -> Option<()> { let environment = latex::Environment::cast(node)?; - let name1 = environment.begin()?.name()?.word()?; - let name2 = environment.end()?.name()?.word()?; - if name1.text() != name2.text() { + let name1 = environment.begin()?.name()?.key()?; + let name2 = environment.end()?.name()?.key()?; + if name1 != name2 { diagnostics_by_uri.insert( Arc::clone(&document.uri), Diagnostic { - range: document.line_index.line_col_lsp_range(name1.text_range()), + range: document.line_index.line_col_lsp_range(name1.small_range()), severity: Some(DiagnosticSeverity::Error), - code: None, + code: Some(NumberOrString::Number(3)), code_description: None, source: Some("texlab".to_string()), message: "Mismatched environment".to_string(), @@ -98,8 +98,10 @@ fn analyze_curly_group( .filter_map(latex::Environment::cast) .filter_map(|env| env.begin()) .filter_map(|begin| begin.name()) - .filter_map(|name| name.word()) - .any(|name| ["asy", "lstlisting", "minted", "verbatim"].contains(&name.text())); + .filter_map(|name| name.key()) + .any(|name| { + ["asy", "lstlisting", "minted", "verbatim"].contains(&name.to_string().as_str()) + }); if !is_inside_verbatim_environment && !node @@ -114,7 +116,7 @@ fn analyze_curly_group( .line_index .line_col_lsp_range(TextRange::empty(node.text_range().end())), severity: Some(DiagnosticSeverity::Error), - code: None, + code: Some(NumberOrString::Number(2)), code_description: None, source: Some("texlab".to_string()), message: "Missing \"}\" inserted".to_string(), diff --git a/support/texlab/src/features/completion.rs b/support/texlab/src/features/completion.rs index 13c7aad22b..29559bd808 100644 --- a/support/texlab/src/features/completion.rs +++ b/support/texlab/src/features/completion.rs @@ -19,6 +19,8 @@ mod user_command; mod user_environment; mod util; +use std::borrow::Cow; + use cancellation::CancellationToken; use fuzzy_matcher::{skim::SkimMatcherV2, FuzzyMatcher}; use lsp_types::{ @@ -144,15 +146,29 @@ fn dedup(items: Vec) -> Vec { } fn score(context: &CursorContext, items: &mut Vec) { - let pattern = match &context.cursor { - Cursor::Latex(token) if token.kind().is_command_name() => token.text().trim_end(), - Cursor::Latex(token) if token.kind() == latex::WORD => token.text(), - Cursor::Latex(_) => "", - Cursor::Bibtex(token) if token.kind().is_type() => token.text(), - Cursor::Bibtex(token) if token.kind() == bibtex::WORD => token.text(), - Cursor::Bibtex(token) if token.kind() == bibtex::COMMAND_NAME => token.text().trim_end(), - Cursor::Bibtex(_) => "", - Cursor::Nothing => "", + let pattern: Cow = match &context.cursor { + Cursor::Latex(token) if token.kind().is_command_name() => token.text().trim_end().into(), + Cursor::Latex(token) if token.kind() == latex::WORD => { + if let Some(key) = latex::Key::cast(token.parent()) { + key.to_string().into() + } else { + token.text().into() + } + } + Cursor::Latex(_) => "".into(), + Cursor::Bibtex(token) if token.kind().is_type() => token.text().into(), + Cursor::Bibtex(token) if token.kind() == bibtex::WORD => { + if let Some(key) = bibtex::Key::cast(token.parent()) { + key.to_string().into() + } else { + token.text().into() + } + } + Cursor::Bibtex(token) if token.kind() == bibtex::COMMAND_NAME => { + token.text().trim_end().into() + } + Cursor::Bibtex(_) => "".into(), + Cursor::Nothing => "".into(), }; let file_pattern = pattern.split('/').last().unwrap(); @@ -211,7 +227,7 @@ fn preselect( let group = latex::CurlyGroupWord::cast(name.parent())?; let end = latex::End::cast(group.syntax().parent()?)?; let environment = latex::Environment::cast(end.syntax().parent()?)?; - let name = environment.begin()?.name()?.word()?.text(); + let name = environment.begin()?.name()?.key()?.to_string(); for item in items { if item.data.label() == name { diff --git a/support/texlab/src/features/completion/acronym_ref.rs b/support/texlab/src/features/completion/acronym_ref.rs index 9d8bcc6c5f..db3e34f9eb 100644 --- a/support/texlab/src/features/completion/acronym_ref.rs +++ b/support/texlab/src/features/completion/acronym_ref.rs @@ -1,5 +1,4 @@ use cancellation::CancellationToken; -use cstree::TextRange; use lsp_types::CompletionParams; use crate::{ @@ -16,18 +15,9 @@ pub fn complete_acronyms<'a>( ) -> Option<()> { cancellation_token.result().ok()?; - let token = context.cursor.as_latex()?; - let group = latex::CurlyGroupWord::cast(token.parent()) - .filter(|group| context.is_inside_latex_curly(group))?; - + let (_, range, group) = context.find_curly_group_word()?; latex::AcronymReference::cast(group.syntax().parent()?)?; - let range = if token.kind() == latex::WORD { - token.text_range() - } else { - TextRange::empty(context.offset) - }; - for document in &context.request.subset.documents { if let Some(data) = document.data.as_latex() { for name in data @@ -35,8 +25,8 @@ pub fn complete_acronyms<'a>( .descendants() .filter_map(latex::AcronymDefinition::cast) .filter_map(|node| node.name()) - .filter_map(|name| name.word()) - .map(|name| name.text()) + .filter_map(|name| name.key()) + .map(|name| name.to_string()) { items.push(InternalCompletionItem::new( range, diff --git a/support/texlab/src/features/completion/citation.rs b/support/texlab/src/features/completion/citation.rs index 6df3364099..0a7cc26b10 100644 --- a/support/texlab/src/features/completion/citation.rs +++ b/support/texlab/src/features/completion/citation.rs @@ -26,12 +26,14 @@ pub fn complete_citations<'a>( let token = context.cursor.as_latex()?; let range = if token.kind() == latex::WORD { - token.text_range() + latex::Key::cast(token.parent()) + .map(|key| key.small_range()) + .or_else(|| latex::Text::cast(token.parent()).map(|text| text.small_range()))? } else { TextRange::empty(context.offset) }; - check_citation(context, token).or_else(|| check_acronym(token))?; + check_citation(context).or_else(|| check_acronym(context))?; for document in &context.request.subset.documents { if let Some(data) = document.data.as_bibtex() { for entry in data.root.children().filter_map(bibtex::Entry::cast) { @@ -46,20 +48,17 @@ pub fn complete_citations<'a>( Some(()) } -fn check_citation( - context: &CursorContext, - token: &latex::SyntaxToken, -) -> Option<()> { - let group = latex::CurlyGroupWordList::cast(token.parent()) - .filter(|group| context.is_inside_latex_curly(group))?; +fn check_citation(context: &CursorContext) -> Option<()> { + let (_, _, group) = context.find_curly_group_word_list()?; latex::Citation::cast(group.syntax().parent()?)?; Some(()) } -fn check_acronym(token: &latex::SyntaxToken) -> Option<()> { +fn check_acronym(context: &CursorContext) -> Option<()> { + let token = context.cursor.as_latex()?; + let pair = token.ancestors().find_map(latex::KeyValuePair::cast)?; - let mut key_words = pair.key()?.words(); - if key_words.next()?.text() != "cite" || key_words.next().is_some() { + if pair.key()?.to_string() != "cite" { return None; } @@ -72,7 +71,7 @@ fn make_item<'a>( entry: bibtex::Entry<'a>, range: TextRange, ) -> Option> { - let key = entry.key()?.text(); + let key = entry.key()?.to_string(); let ty = LANGUAGE_DATA .find_entry_type(&entry.ty()?.text()[1..]) .map(|ty| Structure::Entry(ty.category)) @@ -98,7 +97,7 @@ fn make_item<'a>( range, InternalCompletionItemData::Citation { uri: Arc::clone(&document.uri), - key: key.into(), + key, text, ty, }, @@ -170,6 +169,29 @@ mod tests { } } + #[test] + fn test_latex_two_words() { + let request = FeatureTester::builder() + .files(vec![ + ("main.tex", "\\addbibresource{main.bib}\n\\cite{foo}"), + ("main.bib", "@article{foo bar,}"), + ]) + .main("main.tex") + .line(1) + .character(6) + .build() + .completion(); + + let context = CursorContext::new(request); + let mut actual_items = Vec::new(); + complete_citations(&context, &mut actual_items, CancellationToken::none()); + + assert!(!actual_items.is_empty()); + for item in actual_items { + assert_eq!(item.range, TextRange::new(32.into(), 35.into())); + } + } + #[test] fn test_latex_open_brace() { let request = FeatureTester::builder() @@ -241,4 +263,30 @@ mod tests { assert_eq!(item.range, TextRange::new(54.into(), 54.into())); } } + + #[test] + fn test_latex_acronym_two_words() { + let request = FeatureTester::builder() + .files(vec![ + ( + "main.tex", + "\\addbibresource{main.bib}\n\\DeclareAcronym{foo}{cite={\na b}}", + ), + ("main.bib", "@article{foo,}"), + ]) + .main("main.tex") + .line(2) + .character(0) + .build() + .completion(); + + let context = CursorContext::new(request); + let mut actual_items = Vec::new(); + complete_citations(&context, &mut actual_items, CancellationToken::none()); + + assert!(!actual_items.is_empty()); + for item in actual_items { + assert_eq!(item.range, TextRange::new(54.into(), 57.into())); + } + } } diff --git a/support/texlab/src/features/completion/color.rs b/support/texlab/src/features/completion/color.rs index 0e94af15fe..15a7c341f5 100644 --- a/support/texlab/src/features/completion/color.rs +++ b/support/texlab/src/features/completion/color.rs @@ -1,5 +1,4 @@ use cancellation::CancellationToken; -use cstree::TextRange; use lsp_types::CompletionParams; use crate::{ @@ -17,15 +16,7 @@ pub fn complete_colors<'a>( ) -> Option<()> { cancellation_token.result().ok()?; - let token = context.cursor.as_latex()?; - let range = if token.kind() == latex::WORD { - token.text_range() - } else { - TextRange::empty(context.offset) - }; - - let group = latex::CurlyGroupWord::cast(token.parent()) - .filter(|group| context.is_inside_latex_curly(group))?; + let (_, range, group) = context.find_curly_group_word()?; latex::ColorReference::cast(group.syntax().parent()?)?; for name in &LANGUAGE_DATA.colors { diff --git a/support/texlab/src/features/completion/color_model.rs b/support/texlab/src/features/completion/color_model.rs index f7f09b6367..a24953caa5 100644 --- a/support/texlab/src/features/completion/color_model.rs +++ b/support/texlab/src/features/completion/color_model.rs @@ -18,15 +18,7 @@ pub fn complete_color_models<'a>( ) -> Option<()> { cancellation_token.result().ok()?; - let token = context.cursor.as_latex()?; - let range = if token.kind() == latex::WORD { - token.text_range() - } else { - TextRange::empty(context.offset) - }; - - check_color_definition(context, token) - .or_else(|| check_color_definition_set(context, token))?; + let range = check_color_definition(context).or_else(|| check_color_definition_set(context))?; for name in MODEL_NAMES { items.push(InternalCompletionItem::new( @@ -38,30 +30,23 @@ pub fn complete_color_models<'a>( Some(()) } -fn check_color_definition( - context: &CursorContext, - token: &latex::SyntaxToken, -) -> Option<()> { - let group = latex::CurlyGroupWord::cast(token.parent()) - .filter(|group| context.is_inside_latex_curly(group))?; +fn check_color_definition(context: &CursorContext) -> Option { + let (_, range, group) = context.find_curly_group_word()?; + let definition = latex::ColorDefinition::cast(group.syntax().parent()?)?; definition .model() .filter(|model| model.syntax().text_range() == group.syntax().text_range())?; - Some(()) + Some(range) } -fn check_color_definition_set( - context: &CursorContext, - token: &latex::SyntaxToken, -) -> Option<()> { - let group = latex::CurlyGroupWordList::cast(token.parent()) - .filter(|group| context.is_inside_latex_curly(group))?; +fn check_color_definition_set(context: &CursorContext) -> Option { + let (_, range, group) = context.find_curly_group_word_list()?; let definition = latex::ColorSetDefinition::cast(group.syntax().parent()?)?; definition .model_list() .filter(|model| model.syntax().text_range() == group.syntax().text_range())?; - Some(()) + Some(range) } #[cfg(test)] diff --git a/support/texlab/src/features/completion/component_environment.rs b/support/texlab/src/features/completion/component_environment.rs index fca9d03780..d4340a160a 100644 --- a/support/texlab/src/features/completion/component_environment.rs +++ b/support/texlab/src/features/completion/component_environment.rs @@ -1,12 +1,7 @@ use cancellation::CancellationToken; -use cstree::TextRange; use lsp_types::CompletionParams; -use crate::{ - component_db::COMPONENT_DATABASE, - features::cursor::CursorContext, - syntax::{latex, CstNode}, -}; +use crate::{component_db::COMPONENT_DATABASE, features::cursor::CursorContext}; use super::types::{InternalCompletionItem, InternalCompletionItemData}; @@ -17,18 +12,7 @@ pub fn complete_component_environments<'a>( ) -> Option<()> { cancellation_token.result().ok()?; - let token = context.cursor.as_latex()?; - let group = latex::CurlyGroupWord::cast(token.parent()) - .filter(|group| context.is_inside_latex_curly(group))?; - if !matches!(group.syntax().parent()?.kind(), latex::BEGIN | latex::END) { - return None; - } - - let range = if token.kind() == latex::WORD { - token.text_range() - } else { - TextRange::empty(context.offset) - }; + let (_, range) = context.find_environment_name()?; for component in COMPONENT_DATABASE.linked_components(&context.request.subset) { cancellation_token.result().ok()?; diff --git a/support/texlab/src/features/completion/field.rs b/support/texlab/src/features/completion/field.rs index d7297b481b..ad1042b04d 100644 --- a/support/texlab/src/features/completion/field.rs +++ b/support/texlab/src/features/completion/field.rs @@ -26,7 +26,7 @@ pub fn complete_fields<'a>( let parent = token.parent(); if let Some(entry) = bibtex::Entry::cast(parent) { - if entry.key()?.text_range() == token.text_range() { + if entry.key()?.small_range() == token.text_range() { return None; } } else { diff --git a/support/texlab/src/features/completion/glossary_ref.rs b/support/texlab/src/features/completion/glossary_ref.rs index 4529129fd7..66d20e46ff 100644 --- a/support/texlab/src/features/completion/glossary_ref.rs +++ b/support/texlab/src/features/completion/glossary_ref.rs @@ -1,5 +1,4 @@ use cancellation::CancellationToken; -use cstree::TextRange; use lsp_types::CompletionParams; use crate::{ @@ -16,15 +15,8 @@ pub fn complete_glossary_entries<'a>( ) -> Option<()> { cancellation_token.result().ok()?; - let token = context.cursor.as_latex()?; - let group = latex::CurlyGroupWord::cast(token.parent()) - .filter(|group| context.is_inside_latex_curly(group))?; + let (_, range, group) = context.find_curly_group_word()?; latex::GlossaryEntryReference::cast(group.syntax().parent()?)?; - let range = if token.kind() == latex::WORD { - token.text_range() - } else { - TextRange::empty(context.offset) - }; for document in &context.request.subset.documents { if let Some(data) = document.data.as_latex() { @@ -33,8 +25,8 @@ pub fn complete_glossary_entries<'a>( if let Some(name) = latex::GlossaryEntryDefinition::cast(node) .and_then(|entry| entry.name()) - .and_then(|name| name.word()) - .map(|name| name.text()) + .and_then(|name| name.key()) + .map(|name| name.to_string()) { items.push(InternalCompletionItem::new( range, @@ -42,8 +34,8 @@ pub fn complete_glossary_entries<'a>( )); } else if let Some(name) = latex::AcronymDefinition::cast(node) .and_then(|entry| entry.name()) - .and_then(|name| name.word()) - .map(|name| name.text()) + .and_then(|name| name.key()) + .map(|name| name.to_string()) { items.push(InternalCompletionItem::new( range, diff --git a/support/texlab/src/features/completion/import.rs b/support/texlab/src/features/completion/import.rs index ac5f2e6e40..da4c12c02b 100644 --- a/support/texlab/src/features/completion/import.rs +++ b/support/texlab/src/features/completion/import.rs @@ -1,5 +1,4 @@ use cancellation::CancellationToken; -use cstree::TextRange; use lsp_types::CompletionParams; use rustc_hash::FxHashSet; use smol_str::SmolStr; @@ -17,15 +16,7 @@ pub fn complete_imports<'a>( items: &mut Vec>, cancellation_token: &CancellationToken, ) -> Option<()> { - let token = context.cursor.as_latex()?; - let range = if token.kind() == latex::WORD { - token.text_range() - } else { - TextRange::empty(context.offset) - }; - - let group = latex::CurlyGroupWordList::cast(token.parent()) - .filter(|group| context.is_inside_latex_curly(group))?; + let (_, range, group) = context.find_curly_group_word_list()?; let (extension, mut factory): ( &str, @@ -76,6 +67,8 @@ pub fn complete_imports<'a>( #[cfg(test)] mod tests { + use cstree::TextRange; + use crate::features::testing::FeatureTester; use super::*; diff --git a/support/texlab/src/features/completion/include.rs b/support/texlab/src/features/completion/include.rs index c711ea5ce7..4a8e561866 100644 --- a/support/texlab/src/features/completion/include.rs +++ b/support/texlab/src/features/completion/include.rs @@ -25,15 +25,8 @@ pub fn complete_includes<'a>( return None; } - let token = context.cursor.as_latex()?; - let (path_text, path_range) = if token.kind() == latex::WORD { - (token.text(), token.text_range()) - } else { - ("", TextRange::empty(context.offset)) - }; + let (path_text, path_range, group) = context.find_curly_group_word_list()?; - let group = latex::CurlyGroupWordList::cast(token.parent()) - .filter(|group| context.is_inside_latex_curly(group))?; let include = group.syntax().parent()?; let (include_extension, extensions): (bool, &[&str]) = match include.kind() { latex::PACKAGE_INCLUDE => (false, &["sty"]), @@ -62,7 +55,7 @@ pub fn complete_includes<'a>( TextRange::new(start, path_range.end()) }; - let current_dir = current_dir(context, path_text)?; + let current_dir = current_dir(context, &path_text)?; for entry in fs::read_dir(current_dir).ok()?.filter_map(Result::ok) { let mut path = entry.path(); diff --git a/support/texlab/src/features/completion/label.rs b/support/texlab/src/features/completion/label.rs index 2f7e2d8f77..3efb168d0d 100644 --- a/support/texlab/src/features/completion/label.rs +++ b/support/texlab/src/features/completion/label.rs @@ -18,26 +18,7 @@ pub fn complete_labels<'a>( ) -> Option<()> { cancellation_token.result().ok()?; - let token = context.cursor.as_latex()?; - let is_math = latex::CurlyGroupWordList::cast(token.parent()) - .filter(|group| context.is_inside_latex_curly(group)) - .and_then(|group| group.syntax().parent()) - .and_then(|reference| latex::LabelReference::cast(reference)) - .and_then(|refernce| refernce.command()) - .map(|reference| reference.text() == "\\eqref") - .or_else(|| { - latex::CurlyGroupWord::cast(token.parent()) - .filter(|group| context.is_inside_latex_curly(group)) - .and_then(|group| group.syntax().parent()) - .and_then(|reference| latex::LabelReferenceRange::cast(reference)) - .map(|_| false) - })?; - - let range = if token.kind() == latex::WORD { - token.text_range() - } else { - TextRange::empty(context.offset) - }; + let (range, is_math) = find_reference(context).or_else(|| find_reference_range(context))?; for document in &context.request.subset.documents { if let Some(data) = document.data.as_latex() { @@ -49,10 +30,10 @@ pub fn complete_labels<'a>( { if let Some(name) = label .name() - .and_then(|name| name.word()) - .map(|name| name.text()) + .and_then(|name| name.key()) + .map(|name| name.to_string()) { - match render_label(&context.request.subset, name, Some(label)) { + match render_label(&context.request.subset, &name, Some(label)) { Some(rendered_label) => { let kind = match &rendered_label.object { LabelledObject::Section { .. } => Structure::Section, @@ -112,6 +93,19 @@ pub fn complete_labels<'a>( Some(()) } +fn find_reference(context: &CursorContext) -> Option<(TextRange, bool)> { + let (_, range, group) = context.find_curly_group_word_list()?; + let reference = latex::LabelReference::cast(group.syntax().parent()?)?; + let is_math = reference.command()?.text() == "\\eqref"; + Some((range, is_math)) +} + +fn find_reference_range(context: &CursorContext) -> Option<(TextRange, bool)> { + let (_, range, group) = context.find_curly_group_word()?; + latex::LabelReferenceRange::cast(group.syntax().parent()?)?; + Some((range, false)) +} + #[cfg(test)] mod tests { use cstree::TextRange; @@ -193,4 +187,24 @@ mod tests { assert_eq!(item.range, TextRange::new(11.into(), 11.into())); } } + + #[test] + fn test_multi_word() { + let request = FeatureTester::builder() + .files(vec![("main.tex", "\\ref{foo}\\label{foo bar}")]) + .main("main.tex") + .line(0) + .character(8) + .build() + .completion(); + + let context = CursorContext::new(request); + let mut actual_items = Vec::new(); + complete_labels(&context, &mut actual_items, CancellationToken::none()); + + assert!(!actual_items.is_empty()); + for item in actual_items { + assert_eq!(item.range, TextRange::new(5.into(), 8.into())); + } + } } diff --git a/support/texlab/src/features/completion/theorem.rs b/support/texlab/src/features/completion/theorem.rs index 54db031a4b..25eea87ab7 100644 --- a/support/texlab/src/features/completion/theorem.rs +++ b/support/texlab/src/features/completion/theorem.rs @@ -1,11 +1,7 @@ use cancellation::CancellationToken; -use cstree::TextRange; use lsp_types::CompletionParams; -use crate::{ - features::cursor::CursorContext, - syntax::{latex, CstNode}, -}; +use crate::features::cursor::CursorContext; use super::types::{InternalCompletionItem, InternalCompletionItemData}; @@ -18,18 +14,7 @@ pub fn complete_theorem_environments<'a>( return None; } - let token = context.cursor.as_latex()?; - let group = latex::CurlyGroupWord::cast(token.parent()) - .filter(|group| context.is_inside_latex_curly(group))?; - if !matches!(group.syntax().parent()?.kind(), latex::BEGIN | latex::END) { - return None; - } - - let range = if token.kind() == latex::WORD { - token.text_range() - } else { - TextRange::empty(context.offset) - }; + let (_, range) = context.find_environment_name()?; for document in &context.request.subset.documents { if let Some(data) = document.data.as_latex() { @@ -49,6 +34,8 @@ pub fn complete_theorem_environments<'a>( #[cfg(test)] mod tests { + use cstree::TextRange; + use crate::features::testing::FeatureTester; use super::*; diff --git a/support/texlab/src/features/completion/tikz_library.rs b/support/texlab/src/features/completion/tikz_library.rs index da2a26cc9b..b9c5e3ec7a 100644 --- a/support/texlab/src/features/completion/tikz_library.rs +++ b/support/texlab/src/features/completion/tikz_library.rs @@ -1,5 +1,4 @@ use cancellation::CancellationToken; -use cstree::TextRange; use lsp_types::CompletionParams; use crate::{ @@ -17,15 +16,8 @@ pub fn complete_tikz_libraries<'a>( ) -> Option<()> { cancellation_token.result().ok()?; - let token = context.cursor.as_latex()?; - let range = if token.kind() == latex::WORD { - token.text_range() - } else { - TextRange::empty(context.offset) - }; + let (_, range, group) = context.find_curly_group_word_list()?; - let group = latex::CurlyGroupWordList::cast(token.parent()) - .filter(|group| context.is_inside_latex_curly(group))?; let import = latex::TikzLibraryImport::cast(group.syntax().parent()?)?; if import.command()?.text() == "\\usepgflibrary" { @@ -49,6 +41,8 @@ pub fn complete_tikz_libraries<'a>( #[cfg(test)] mod tests { + use cstree::TextRange; + use crate::features::testing::FeatureTester; use super::*; diff --git a/support/texlab/src/features/completion/types.rs b/support/texlab/src/features/completion/types.rs index b58a155fc4..b7e5c09592 100644 --- a/support/texlab/src/features/completion/types.rs +++ b/support/texlab/src/features/completion/types.rs @@ -40,7 +40,7 @@ pub enum InternalCompletionItemData<'a> { BeginCommand, Citation { uri: Arc, - key: &'a str, + key: String, text: String, ty: Structure, }, @@ -67,10 +67,10 @@ pub enum InternalCompletionItemData<'a> { name: &'a str, }, Acronym { - name: &'a str, + name: String, }, GlossaryEntry { - name: &'a str, + name: String, }, File { name: SmolStr, @@ -79,7 +79,7 @@ pub enum InternalCompletionItemData<'a> { name: SmolStr, }, Label { - name: &'a str, + name: String, kind: Structure, header: Option, footer: Option, diff --git a/support/texlab/src/features/completion/user_environment.rs b/support/texlab/src/features/completion/user_environment.rs index a1a5701fac..5529143adc 100644 --- a/support/texlab/src/features/completion/user_environment.rs +++ b/support/texlab/src/features/completion/user_environment.rs @@ -1,11 +1,7 @@ use cancellation::CancellationToken; -use cstree::TextRange; use lsp_types::CompletionParams; -use crate::{ - features::cursor::CursorContext, - syntax::{latex, CstNode}, -}; +use crate::features::cursor::CursorContext; use super::types::{InternalCompletionItem, InternalCompletionItemData}; @@ -16,18 +12,7 @@ pub fn complete_user_environments<'a>( ) -> Option<()> { cancellation_token.result().ok()?; - let token = context.cursor.as_latex()?; - let group = latex::CurlyGroupWord::cast(token.parent()) - .filter(|group| context.is_inside_latex_curly(group))?; - if !matches!(group.syntax().parent()?.kind(), latex::BEGIN | latex::END) { - return None; - } - - let range = if token.kind() == latex::WORD { - token.text_range() - } else { - TextRange::empty(context.offset) - }; + let (name, range) = context.find_environment_name()?; for document in &context.request.subset.documents { if let Some(data) = document.data.as_latex() { @@ -35,7 +20,7 @@ pub fn complete_user_environments<'a>( .extras .environment_names .iter() - .filter(|name| name.as_str() != token.text()) + .filter(|n| n.as_str() != name) { cancellation_token.result().ok()?; items.push(InternalCompletionItem::new( diff --git a/support/texlab/src/features/cursor.rs b/support/texlab/src/features/cursor.rs index 19079b841b..6e8719987a 100644 --- a/support/texlab/src/features/cursor.rs +++ b/support/texlab/src/features/cursor.rs @@ -1,7 +1,7 @@ use cstree::{TextRange, TextSize}; use lsp_types::{ - CompletionParams, GotoDefinitionParams, HoverParams, Position, ReferenceParams, RenameParams, - TextDocumentPositionParams, + CompletionParams, DocumentHighlightParams, GotoDefinitionParams, HoverParams, Position, + ReferenceParams, RenameParams, TextDocumentPositionParams, }; use crate::{ @@ -42,6 +42,14 @@ impl Cursor { return Some(Self::Latex(right)); } + if left.kind() == latex::WHITESPACE && left.parent().kind() == latex::KEY { + return Some(Self::Latex(left)); + } + + if right.kind() == latex::WHITESPACE && right.parent().kind() == latex::KEY { + return Some(Self::Latex(right)); + } + Some(Self::Latex(right)) } @@ -149,66 +157,116 @@ impl CursorContext

{ group.small_range().contains(self.offset) || group.right_curly().is_none() } - pub fn find_citation_key_word(&self) -> Option<(&str, TextRange)> { - let key = self + pub fn find_citation_key_word(&self) -> Option<(String, TextRange)> { + let word = self .cursor .as_latex() .filter(|token| token.kind() == latex::WORD)?; - let group = latex::CurlyGroupWordList::cast(key.parent())?; + let key = latex::Key::cast(word.parent())?; + + let group = latex::CurlyGroupWordList::cast(key.syntax().parent()?)?; latex::Citation::cast(group.syntax().parent()?)?; - Some((key.text(), key.text_range())) + Some((key.to_string(), key.small_range())) } - pub fn find_citation_key_command(&self) -> Option<(&str, TextRange)> { + pub fn find_citation_key_command(&self) -> Option<(String, TextRange)> { let command = self.cursor.as_latex()?; let citation = latex::Citation::cast(command.parent())?; - let key = citation.key_list()?.words().next()?; - Some((key.text(), key.text_range())) + let key = citation.key_list()?.keys().next()?; + Some((key.to_string(), key.small_range())) } - pub fn find_entry_key(&self) -> Option<(&str, TextRange)> { - let key = self + pub fn find_entry_key(&self) -> Option<(String, TextRange)> { + let word = self .cursor .as_bibtex() .filter(|token| token.kind() == bibtex::WORD)?; - bibtex::Entry::cast(key.parent())?; - Some((key.text(), key.text_range())) + let key = bibtex::Key::cast(word.parent())?; + + bibtex::Entry::cast(key.syntax().parent()?)?; + Some((key.to_string(), key.small_range())) } - pub fn find_label_name_word(&self) -> Option<(&str, TextRange)> { + pub fn find_label_name_key(&self) -> Option<(String, TextRange)> { let name = self .cursor .as_latex() .filter(|token| token.kind() == latex::WORD)?; + let key = latex::Key::cast(name.parent())?; + if matches!( - name.parent().parent()?.kind(), + key.syntax().parent()?.parent()?.kind(), latex::LABEL_DEFINITION | latex::LABEL_REFERENCE | latex::LABEL_REFERENCE_RANGE ) { - Some((name.text(), name.text_range())) + Some((key.to_string(), key.small_range())) } else { None } } - pub fn find_label_name_command(&self) -> Option<(&str, TextRange)> { + pub fn find_label_name_command(&self) -> Option<(String, TextRange)> { let node = self.cursor.as_latex()?.parent(); if let Some(label) = latex::LabelDefinition::cast(node) { - let name = label.name()?.word()?; - Some((name.text(), name.text_range())) + let name = label.name()?.key()?; + Some((name.to_string(), name.small_range())) } else if let Some(label) = latex::LabelReference::cast(node) { - let name = label.name_list()?.words().next()?; - Some((name.text(), name.text_range())) + let name = label.name_list()?.keys().next()?; + Some((name.to_string(), name.small_range())) } else if let Some(label) = latex::LabelReferenceRange::cast(node) { - let name = label.from()?.word()?; - Some((name.text(), name.text_range())) + let name = label.from()?.key()?; + Some((name.to_string(), name.small_range())) } else { None } } + + pub fn find_environment_name(&self) -> Option<(String, TextRange)> { + let (name, range, group) = self.find_curly_group_word()?; + + if !matches!(group.syntax().parent()?.kind(), latex::BEGIN | latex::END) { + return None; + } + + Some((name, range)) + } + + pub fn find_curly_group_word(&self) -> Option<(String, TextRange, latex::CurlyGroupWord)> { + let token = self.cursor.as_latex()?; + let key = latex::Key::cast(token.parent()); + + let group = key + .as_ref() + .and_then(|key| key.syntax().parent()) + .unwrap_or(token.parent()); + + let group = + latex::CurlyGroupWord::cast(group).filter(|group| self.is_inside_latex_curly(group))?; + + key.map(|key| (key.to_string(), key.small_range(), group)) + .or_else(|| Some((String::new(), TextRange::empty(self.offset), group))) + } + + pub fn find_curly_group_word_list( + &self, + ) -> Option<(String, TextRange, latex::CurlyGroupWordList)> { + let token = self.cursor.as_latex()?; + let key = latex::Key::cast(token.parent()); + + let group = key + .as_ref() + .and_then(|key| key.syntax().parent()) + .unwrap_or(token.parent()); + + let group = latex::CurlyGroupWordList::cast(group) + .filter(|group| self.is_inside_latex_curly(group))?; + + key.map(|key| (key.to_string(), key.small_range(), group)) + .or_else(|| Some((String::new(), TextRange::empty(self.offset), group))) + } } pub trait HasPosition { @@ -250,3 +308,9 @@ impl HasPosition for GotoDefinitionParams { self.text_document_position_params.position } } + +impl HasPosition for DocumentHighlightParams { + fn position(&self) -> Position { + self.text_document_position_params.position + } +} diff --git a/support/texlab/src/features/definition/entry.rs b/support/texlab/src/features/definition/entry.rs index 7f489ec848..b04490dc32 100644 --- a/support/texlab/src/features/definition/entry.rs +++ b/support/texlab/src/features/definition/entry.rs @@ -13,29 +13,31 @@ pub fn goto_entry_definition( ) -> Option> { let main_document = context.request.main_document(); - let key = context + let word = context .cursor .as_latex() .filter(|token| token.kind() == latex::WORD)?; - latex::Citation::cast(key.parent().parent()?)?; + let key = latex::Key::cast(word.parent())?; + + latex::Citation::cast(key.syntax().parent()?.parent()?)?; let origin_selection_range = main_document .line_index - .line_col_lsp_range(key.text_range()); + .line_col_lsp_range(key.small_range()); for document in &context.request.subset.documents { if let Some(data) = document.data.as_bibtex() { for entry in data.root.children().filter_map(bibtex::Entry::cast) { cancellation_token.result().ok()?; - if let Some(key) = entry.key().filter(|k| k.text() == key.text()) { + if let Some(key) = entry.key().filter(|k| k.to_string() == key.to_string()) { return Some(vec![LocationLink { origin_selection_range: Some(origin_selection_range), target_uri: document.uri.as_ref().clone().into(), target_selection_range: document .line_index - .line_col_lsp_range(key.text_range()), + .line_col_lsp_range(key.small_range()), target_range: document.line_index.line_col_lsp_range(entry.small_range()), }]); } diff --git a/support/texlab/src/features/definition/label.rs b/support/texlab/src/features/definition/label.rs index 65f0981de0..fd30b1fbc5 100644 --- a/support/texlab/src/features/definition/label.rs +++ b/support/texlab/src/features/definition/label.rs @@ -1,7 +1,10 @@ use cancellation::CancellationToken; use lsp_types::{GotoDefinitionParams, LocationLink}; -use crate::{features::cursor::CursorContext, find_label_definition, render_label, LineIndexExt}; +use crate::{ + features::cursor::CursorContext, find_label_definition, render_label, syntax::CstNode, + LineIndexExt, +}; pub fn goto_label_definition( context: &CursorContext, @@ -10,7 +13,7 @@ pub fn goto_label_definition( let main_document = context.request.main_document(); let (name_text, name_range) = context - .find_label_name_word() + .find_label_name_key() .or_else(|| context.find_label_name_command())?; let origin_selection_range = main_document.line_index.line_col_lsp_range(name_range); @@ -18,10 +21,10 @@ pub fn goto_label_definition( for document in &context.request.subset.documents { cancellation_token.result().ok()?; if let Some(data) = document.data.as_latex() { - if let Some(definition) = find_label_definition(&data.root, name_text) { - let target_selection_range = definition.name()?.word()?.text_range(); + if let Some(definition) = find_label_definition(&data.root, &name_text) { + let target_selection_range = definition.name()?.key()?.small_range(); let target_range = - render_label(&context.request.subset, name_text, Some(definition)) + render_label(&context.request.subset, &name_text, Some(definition)) .map(|label| label.range) .unwrap_or(target_selection_range); diff --git a/support/texlab/src/features/formatting.rs b/support/texlab/src/features/formatting.rs index 4492a0532d..c7c2dc410a 100644 --- a/support/texlab/src/features/formatting.rs +++ b/support/texlab/src/features/formatting.rs @@ -4,7 +4,7 @@ mod latexindent; use cancellation::CancellationToken; use lsp_types::{DocumentFormattingParams, TextEdit}; -use crate::BibtexFormatter; +use crate::{BibtexFormatter, LatexFormatter}; use self::{bibtex_internal::format_bibtex_internal, latexindent::format_with_latexindent}; @@ -19,6 +19,10 @@ pub fn format_source_code( edits = edits.or_else(|| format_bibtex_internal(&request, cancellation_token)); } + if request.context.options.read().unwrap().latex_formatter == LatexFormatter::Texlab { + edits = edits.or_else(|| Some(vec![])); + } + edits = edits.or_else(|| format_with_latexindent(&request, cancellation_token)); edits } diff --git a/support/texlab/src/features/formatting/bibtex_internal.rs b/support/texlab/src/features/formatting/bibtex_internal.rs index 8481f561e7..641bee0cfe 100644 --- a/support/texlab/src/features/formatting/bibtex_internal.rs +++ b/support/texlab/src/features/formatting/bibtex_internal.rs @@ -148,7 +148,7 @@ impl<'a> Formatter<'a> { self.visit_token_lowercase(entry.ty().unwrap()); self.output.push('{'); if let Some(key) = entry.key() { - self.output.push_str(key.text()); + self.output.push_str(&key.to_string()); self.output.push(','); self.output.push('\n'); for field in entry.fields() { diff --git a/support/texlab/src/features/formatting/latexindent.rs b/support/texlab/src/features/formatting/latexindent.rs index f603728a5d..300f512578 100644 --- a/support/texlab/src/features/formatting/latexindent.rs +++ b/support/texlab/src/features/formatting/latexindent.rs @@ -1,50 +1,98 @@ use std::{ - io::{BufWriter, Write}, + fs, process::{Command, Stdio}, }; use cancellation::CancellationToken; use cstree::{TextLen, TextRange}; use lsp_types::{DocumentFormattingParams, TextEdit}; +use tempfile::tempdir; -use crate::{features::FeatureRequest, LineIndexExt}; +use crate::{features::FeatureRequest, DocumentLanguage, LineIndexExt}; pub fn format_with_latexindent( request: &FeatureRequest, _cancellation_token: &CancellationToken, ) -> Option> { + let directory = tempdir().ok()?; let document = request.main_document(); - let current_dir = &request.context.current_directory; let options = request.context.options.read().unwrap(); - let current_dir = match &options.root_directory { - Some(root_directory) => current_dir.join(root_directory), - None => current_dir.clone(), + let current_dir = options + .root_directory + .as_ref() + .cloned() + .or_else(|| { + if document.uri.scheme() == "file" { + document + .uri + .to_file_path() + .unwrap() + .parent() + .map(ToOwned::to_owned) + } else { + None + } + }) + .unwrap_or_else(|| ".".into()); + + let local = match &options.latexindent.local { + Some(local) => format!("--local={}", local), + None => "-l".to_string(), }; + + let modify_line_breaks = options.latexindent.modify_line_breaks; + drop(options); - let mut process = Command::new("latexindent") - .arg("-l") + let path = directory.path(); + let _ = fs::copy( + current_dir.join("localSettings.yaml"), + path.join("localSettings.yaml"), + ); + let _ = fs::copy( + current_dir.join(".localSettings.yaml"), + path.join(".localSettings.yaml"), + ); + let _ = fs::copy( + current_dir.join("latexindent.yaml"), + path.join("latexindent.yaml"), + ); + + let name = if document.language() == DocumentLanguage::Bibtex { + "file.bib" + } else { + "file.tex" + }; + + fs::write(directory.path().join(name), &document.text).ok()?; + + let mut args = Vec::new(); + if modify_line_breaks { + args.push("--modifylinebreaks"); + } + args.push(&local); + args.push(name); + + let output = Command::new("latexindent") + .args(&args) .current_dir(current_dir) - .stdin(Stdio::piped()) + .stdin(Stdio::null()) .stdout(Stdio::piped()) .stderr(Stdio::null()) - .spawn() + .current_dir(directory.path()) + .output() .ok()?; - let stdin = process.stdin.take()?; - let mut stdin = BufWriter::new(stdin); - stdin.write_all(document.text.as_bytes()).ok()?; - drop(stdin); - - let output = process.wait_with_output().ok()?; - let new_text = String::from_utf8_lossy(&output.stdout).into_owned(); - - Some(vec![TextEdit { - range: document - .line_index - .line_col_lsp_range(TextRange::new(0.into(), document.text.text_len())), - new_text, - }]) + if new_text.is_empty() { + None + } else { + Some(vec![TextEdit { + range: document + .line_index + .line_col_lsp_range(TextRange::new(0.into(), document.text.text_len())), + new_text, + }]) + } } diff --git a/support/texlab/src/features/highlight.rs b/support/texlab/src/features/highlight.rs index e1aea6e2ad..386018f353 100644 --- a/support/texlab/src/features/highlight.rs +++ b/support/texlab/src/features/highlight.rs @@ -5,11 +5,12 @@ use lsp_types::{DocumentHighlight, DocumentHighlightParams}; use self::label::find_label_highlights; -use super::FeatureRequest; +use super::{cursor::CursorContext, FeatureRequest}; pub fn find_document_highlights( request: FeatureRequest, - token: &CancellationToken, + cancellation_token: &CancellationToken, ) -> Option> { - find_label_highlights(&request, token) + let context = CursorContext::new(request); + find_label_highlights(&context, cancellation_token) } diff --git a/support/texlab/src/features/highlight/label.rs b/support/texlab/src/features/highlight/label.rs index 4c94180f2a..9694993033 100644 --- a/support/texlab/src/features/highlight/label.rs +++ b/support/texlab/src/features/highlight/label.rs @@ -2,48 +2,32 @@ use cancellation::CancellationToken; use lsp_types::{DocumentHighlight, DocumentHighlightKind, DocumentHighlightParams}; use crate::{ - features::FeatureRequest, + features::cursor::CursorContext, syntax::{latex, CstNode}, LineIndexExt, }; pub fn find_label_highlights( - request: &FeatureRequest, - token: &CancellationToken, + context: &CursorContext, + cancellation_token: &CancellationToken, ) -> Option> { - let main_document = request.main_document(); - - let offset = main_document - .line_index - .offset_lsp(request.params.text_document_position_params.position); + let (name_text, _) = context.find_label_name_key()?; + let main_document = context.request.main_document(); let data = main_document.data.as_latex()?; - let name = data.root.token_at_offset(offset).right_biased()?; - if name.kind() != latex::WORD { - return None; - } - - if !matches!( - name.parent().parent()?.kind(), - latex::LABEL_DEFINITION | latex::LABEL_REFERENCE | latex::LABEL_REFERENCE_RANGE - ) { - return None; - } let mut highlights = Vec::new(); for node in data.root.descendants() { - if token.is_canceled() { - return None; - } + cancellation_token.result().ok()?; if let Some(label_name) = latex::LabelDefinition::cast(node) .and_then(|label| label.name()) - .and_then(|label_name| label_name.word()) - .filter(|label_name| label_name.text() == name.text()) + .and_then(|label_name| label_name.key()) + .filter(|label_name| label_name.to_string() == name_text) { let range = main_document .line_index - .line_col_lsp_range(label_name.text_range()); + .line_col_lsp_range(label_name.small_range()); highlights.push(DocumentHighlight { range, @@ -53,12 +37,12 @@ pub fn find_label_highlights( for label_name in label .name_list() .into_iter() - .flat_map(|name| name.words()) - .filter(|label_name| label_name.text() == name.text()) + .flat_map(|name| name.keys()) + .filter(|label_name| label_name.to_string() == name_text) { let range = main_document .line_index - .line_col_lsp_range(label_name.text_range()); + .line_col_lsp_range(label_name.small_range()); highlights.push(DocumentHighlight { range, @@ -68,12 +52,12 @@ pub fn find_label_highlights( } else if let Some(label) = latex::LabelReferenceRange::cast(node) { if let Some(label_name) = label .from() - .and_then(|label_name| label_name.word()) - .filter(|label_name| label_name.text() == name.text()) + .and_then(|label_name| label_name.key()) + .filter(|label_name| label_name.to_string() == name_text) { let range = main_document .line_index - .line_col_lsp_range(label_name.text_range()); + .line_col_lsp_range(label_name.small_range()); highlights.push(DocumentHighlight { range, @@ -83,12 +67,12 @@ pub fn find_label_highlights( if let Some(label_name) = label .to() - .and_then(|label_name| label_name.word()) - .filter(|label_name| label_name.text() == name.text()) + .and_then(|label_name| label_name.key()) + .filter(|label_name| label_name.to_string() == name_text) { let range = main_document .line_index - .line_col_lsp_range(label_name.text_range()); + .line_col_lsp_range(label_name.small_range()); highlights.push(DocumentHighlight { range, @@ -118,8 +102,9 @@ mod tests { .character(0) .build() .highlight(); + let context = CursorContext::new(request); - let actual_links = find_label_highlights(&request, CancellationToken::none()); + let actual_links = find_label_highlights(&context, CancellationToken::none()); assert!(actual_links.is_none()); } @@ -133,8 +118,9 @@ mod tests { .character(0) .build() .highlight(); + let context = CursorContext::new(request); - let actual_links = find_label_highlights(&request, CancellationToken::none()); + let actual_links = find_label_highlights(&context, CancellationToken::none()); assert!(actual_links.is_none()); } @@ -148,8 +134,9 @@ mod tests { .character(7) .build(); let request = tester.highlight(); + let context = CursorContext::new(request); - let actual_highlights = find_label_highlights(&request, CancellationToken::none()).unwrap(); + let actual_highlights = find_label_highlights(&context, CancellationToken::none()).unwrap(); let expected_highlights = vec![ DocumentHighlight { diff --git a/support/texlab/src/features/hover/label.rs b/support/texlab/src/features/hover/label.rs index 79afe7d250..26477feb7c 100644 --- a/support/texlab/src/features/hover/label.rs +++ b/support/texlab/src/features/hover/label.rs @@ -10,10 +10,10 @@ pub fn find_label_hover( let main_document = context.request.main_document(); let (name_text, name_range) = context - .find_label_name_word() + .find_label_name_key() .or_else(|| context.find_label_name_command())?; - let label = render_label(&context.request.subset, name_text, None)?; + let label = render_label(&context.request.subset, &name_text, None)?; Some(Hover { range: Some(main_document.line_index.line_col_lsp_range(name_range)), diff --git a/support/texlab/src/features/reference/entry.rs b/support/texlab/src/features/reference/entry.rs index fbbcbdb4cc..a9e15ba5b6 100644 --- a/support/texlab/src/features/reference/entry.rs +++ b/support/texlab/src/features/reference/entry.rs @@ -26,9 +26,9 @@ pub fn find_entry_references( .descendants() .filter_map(latex::Citation::cast) .filter_map(|citation| citation.key_list()) - .flat_map(|keys| keys.words()) - .filter(|key| key.text() == key_text) - .map(|key| document.line_index.line_col_lsp_range(key.text_range())) + .flat_map(|keys| keys.keys()) + .filter(|key| key.to_string() == key_text) + .map(|key| document.line_index.line_col_lsp_range(key.small_range())) .for_each(|range| { references.push(Location::new(document.uri.as_ref().clone().into(), range)); }); @@ -38,8 +38,8 @@ pub fn find_entry_references( .children() .filter_map(bibtex::Entry::cast) .filter_map(|entry| entry.key()) - .filter(|key| key.text() == key_text) - .map(|key| document.line_index.line_col_lsp_range(key.text_range())) + .filter(|key| key.to_string() == key_text) + .map(|key| document.line_index.line_col_lsp_range(key.small_range())) .for_each(|range| { references.push(Location::new(document.uri.as_ref().clone().into(), range)); }); diff --git a/support/texlab/src/features/reference/label.rs b/support/texlab/src/features/reference/label.rs index e9aa3a8510..45c6b90137 100644 --- a/support/texlab/src/features/reference/label.rs +++ b/support/texlab/src/features/reference/label.rs @@ -11,7 +11,7 @@ pub fn find_label_references( cancellation_token.result().ok()?; let (name_text, _) = context - .find_label_name_word() + .find_label_name_key() .or_else(|| context.find_label_name_command())?; for document in &context.request.subset.documents { diff --git a/support/texlab/src/features/rename/entry.rs b/support/texlab/src/features/rename/entry.rs index 14fbfd42d7..35a77d926e 100644 --- a/support/texlab/src/features/rename/entry.rs +++ b/support/texlab/src/features/rename/entry.rs @@ -4,7 +4,7 @@ use cancellation::CancellationToken; use lsp_types::{Range, RenameParams, TextEdit, WorkspaceEdit}; use crate::{ - features::cursor::{Cursor, CursorContext, HasPosition}, + features::cursor::{CursorContext, HasPosition}, syntax::{bibtex, latex, CstNode}, DocumentData, LineIndexExt, }; @@ -13,18 +13,9 @@ pub fn prepare_entry_rename( context: &CursorContext

, _cancellation_token: &CancellationToken, ) -> Option { - let range = match &context.cursor { - Cursor::Latex(token) if token.kind() == latex::WORD => { - let group = latex::CurlyGroupWordList::cast(token.parent())?; - latex::Citation::cast(group.syntax().parent()?)?; - token.text_range() - } - Cursor::Bibtex(token) if token.kind() == bibtex::WORD => { - bibtex::Entry::cast(token.parent())?; - token.text_range() - } - _ => return None, - }; + let (_, range) = context + .find_citation_key_word() + .or_else(|| context.find_entry_key())?; Some( context @@ -41,11 +32,9 @@ pub fn rename_entry( ) -> Option { cancellation_token.result().ok()?; prepare_entry_rename(context, cancellation_token)?; - let key_text = context - .cursor - .as_latex() - .map(|token| token.text()) - .or_else(|| context.cursor.as_bibtex().map(|token| token.text()))?; + let (key_text, _) = context + .find_citation_key_word() + .or_else(|| context.find_entry_key())?; let mut changes = HashMap::new(); for document in &context.request.subset.documents { @@ -57,9 +46,9 @@ pub fn rename_entry( .descendants() .filter_map(latex::Citation::cast) .filter_map(|citation| citation.key_list()) - .flat_map(|keys| keys.words()) - .filter(|key| key.text() == key_text) - .map(|key| document.line_index.line_col_lsp_range(key.text_range())) + .flat_map(|keys| keys.keys()) + .filter(|key| key.to_string() == key_text) + .map(|key| document.line_index.line_col_lsp_range(key.small_range())) .map(|range| TextEdit::new(range, context.request.params.new_name.clone())) .collect(); changes.insert(document.uri.as_ref().clone().into(), edits); @@ -70,8 +59,8 @@ pub fn rename_entry( .descendants() .filter_map(bibtex::Entry::cast) .filter_map(|entry| entry.key()) - .filter(|key| key.text() == key_text) - .map(|key| document.line_index.line_col_lsp_range(key.text_range())) + .filter(|key| key.to_string() == key_text) + .map(|key| document.line_index.line_col_lsp_range(key.small_range())) .map(|range| TextEdit::new(range, context.request.params.new_name.clone())) .collect(); changes.insert(document.uri.as_ref().clone().into(), edits); diff --git a/support/texlab/src/features/rename/label.rs b/support/texlab/src/features/rename/label.rs index 11b414ccfa..a73a0064bf 100644 --- a/support/texlab/src/features/rename/label.rs +++ b/support/texlab/src/features/rename/label.rs @@ -13,20 +13,14 @@ pub fn prepare_label_rename( context: &CursorContext

, _cancellation_token: &CancellationToken, ) -> Option { - let name = context.cursor.as_latex()?; - name.parent().parent().filter(|node| { - matches!( - node.kind(), - latex::LABEL_DEFINITION | latex::LABEL_REFERENCE | latex::LABEL_REFERENCE_RANGE - ) - })?; + let (_, range) = context.find_label_name_key()?; Some( context .request .main_document() .line_index - .line_col_lsp_range(name.text_range()), + .line_col_lsp_range(range), ) } @@ -35,7 +29,8 @@ pub fn rename_label( cancellation_token: &CancellationToken, ) -> Option { prepare_label_rename(context, cancellation_token)?; - let name_text = context.cursor.as_latex()?.text(); + let (name_text, _) = context.find_label_name_key()?; + let mut changes = HashMap::new(); for document in &context.request.subset.documents { cancellation_token.result().ok()?; @@ -44,9 +39,9 @@ pub fn rename_label( for node in data.root.descendants() { if let Some(range) = latex::LabelDefinition::cast(node) .and_then(|label| label.name()) - .and_then(|name| name.word()) - .filter(|name| name.text() == name_text) - .map(|name| document.line_index.line_col_lsp_range(name.text_range())) + .and_then(|name| name.key()) + .filter(|name| name.to_string() == name_text) + .map(|name| document.line_index.line_col_lsp_range(name.small_range())) { edits.push(TextEdit::new( range, @@ -57,9 +52,9 @@ pub fn rename_label( latex::LabelReference::cast(node) .and_then(|label| label.name_list()) .into_iter() - .flat_map(|label| label.words()) - .filter(|name| name.text() == name_text) - .map(|name| document.line_index.line_col_lsp_range(name.text_range())) + .flat_map(|label| label.keys()) + .filter(|name| name.to_string() == name_text) + .map(|name| document.line_index.line_col_lsp_range(name.small_range())) .for_each(|range| { edits.push(TextEdit::new( range, @@ -70,22 +65,22 @@ pub fn rename_label( if let Some(label) = latex::LabelReferenceRange::cast(node) { if let Some(name1) = label .from() - .and_then(|name| name.word()) - .filter(|name| name.text() == name_text) + .and_then(|name| name.key()) + .filter(|name| name.to_string() == name_text) { edits.push(TextEdit::new( - document.line_index.line_col_lsp_range(name1.text_range()), + document.line_index.line_col_lsp_range(name1.small_range()), context.request.params.new_name.clone(), )); } if let Some(name2) = label .from() - .and_then(|name| name.word()) - .filter(|name| name.text() == name_text) + .and_then(|name| name.key()) + .filter(|name| name.to_string() == name_text) { edits.push(TextEdit::new( - document.line_index.line_col_lsp_range(name2.text_range()), + document.line_index.line_col_lsp_range(name2.small_range()), context.request.params.new_name.clone(), )); } diff --git a/support/texlab/src/features/symbol/bibtex.rs b/support/texlab/src/features/symbol/bibtex.rs index e030195880..db555a7176 100644 --- a/support/texlab/src/features/symbol/bibtex.rs +++ b/support/texlab/src/features/symbol/bibtex.rs @@ -68,7 +68,7 @@ pub fn find_bibtex_symbols( .unwrap_or(BibtexEntryTypeCategory::Misc); buf.push(InternalSymbol { - name: key.text().to_string(), + name: key.to_string(), label: None, kind: InternalSymbolKind::Entry(category), deprecated: false, @@ -77,7 +77,7 @@ pub fn find_bibtex_symbols( .line_col_lsp_range(entry.small_range()), selection_range: main_document .line_index - .line_col_lsp_range(key.text_range()), + .line_col_lsp_range(key.small_range()), children, }); } diff --git a/support/texlab/src/features/symbol/latex.rs b/support/texlab/src/features/symbol/latex.rs index ce584c0c76..ec549c87fe 100644 --- a/support/texlab/src/features/symbol/latex.rs +++ b/support/texlab/src/features/symbol/latex.rs @@ -59,25 +59,25 @@ fn visit(context: &mut Context, node: &latex::SyntaxNode) -> Vec latex::ENVIRONMENT => latex::Environment::cast(node) .and_then(|env| env.begin()) .and_then(|begin| begin.name()) - .and_then(|name| name.word()) - .map(|name| name.text()) + .and_then(|name| name.key()) + .map(|name| name.to_string()) .and_then(|name| { if LANGUAGE_DATA .math_environments .iter() - .any(|env| env == name) + .any(|env| env == &name) { visit_equation_environment(context, node) } else if LANGUAGE_DATA .enum_environments .iter() - .any(|env| env == name) + .any(|env| env == &name) { - visit_enumeration(context, node, name) - } else if let Ok(float_kind) = LabelledFloatKind::from_str(name) { + visit_enumeration(context, node, &name) + } else if let Ok(float_kind) = LabelledFloatKind::from_str(&name) { visit_float(context, node, float_kind) } else { - visit_theorem(context, node, name) + visit_theorem(context, node, &name) } }), _ => None, @@ -161,12 +161,12 @@ fn visit_enum_item(context: &mut Context, node: &latex::SyntaxNode) -> Option Option { let node = parent.children().find_map(latex::LabelDefinition::cast)?; - let name = node.name()?.word()?.text(); + let name = node.name()?.key()?.to_string(); let range = context .subset .documents @@ -479,7 +479,7 @@ fn find_label_by_parent( .line_index .line_col_lsp_range(node.small_range()); - let number = find_label_number(&context.subset, name); + let number = find_label_number(&context.subset, &name); Some(NumberedLabel { name: name.to_string(), range, diff --git a/support/texlab/src/label.rs b/support/texlab/src/label.rs index eead07814e..3d40b1620c 100644 --- a/support/texlab/src/label.rs +++ b/support/texlab/src/label.rs @@ -157,8 +157,9 @@ pub fn find_label_definition<'a>( .find(|label| { label .name() - .and_then(|name| name.word()) - .map(|name| name.text()) + .and_then(|name| name.key()) + .map(|name| name.to_string()) + .as_deref() == Some(label_name) }) } @@ -178,7 +179,7 @@ fn render_label_float( number: &mut Option, ) -> Option { let environment = latex::Environment::cast(parent)?; - let environment_name = environment.begin()?.name()?.word()?.text(); + let environment_name = environment.begin()?.name()?.key()?.to_string(); let kind = LabelledFloatKind::from_str(&environment_name).ok()?; let caption = find_caption_by_parent(&parent)?; Some(RenderedLabel { @@ -235,12 +236,12 @@ fn render_label_equation( number: &mut Option, ) -> Option { let environment = latex::Environment::cast(parent)?; - let environment_name = environment.begin()?.name()?.word()?.text(); + let environment_name = environment.begin()?.name()?.key()?.to_string(); if !LANGUAGE_DATA .math_environments .iter() - .any(|name| name == environment_name) + .any(|name| name == &environment_name) { return None; } @@ -261,7 +262,7 @@ fn render_label_theorem( let begin = environment.begin()?; let description = begin.options().and_then(|options| options.content_text()); - let environment_name = begin.name()?.word()?.text(); + let environment_name = begin.name()?.key()?.to_string(); let theorem = subset.documents.iter().find_map(|document| { document.data.as_latex().and_then(|data| { diff --git a/support/texlab/src/line_index.rs b/support/texlab/src/line_index.rs index 868fe41232..3b36cd6802 100644 --- a/support/texlab/src/line_index.rs +++ b/support/texlab/src/line_index.rs @@ -214,4 +214,4 @@ where } left -} \ No newline at end of file +} diff --git a/support/texlab/src/line_index_ext.rs b/support/texlab/src/line_index_ext.rs index 8e28207edd..8c8f83f7b4 100644 --- a/support/texlab/src/line_index_ext.rs +++ b/support/texlab/src/line_index_ext.rs @@ -30,7 +30,7 @@ impl LineIndexExt for LineIndex { fn line_col_lsp(&self, offset: TextSize) -> Position { let position = self.line_col(offset); - let LineColUtf16 { line , col } = self.to_utf16(position); + let LineColUtf16 { line, col } = self.to_utf16(position); Position::new(line, col) } diff --git a/support/texlab/src/options.rs b/support/texlab/src/options.rs index 09eea1110f..2626143e18 100644 --- a/support/texlab/src/options.rs +++ b/support/texlab/src/options.rs @@ -12,6 +12,9 @@ pub struct Options { #[serde(default)] pub bibtex_formatter: BibtexFormatter, + #[serde(default)] + pub latex_formatter: LatexFormatter, + pub formatter_line_length: Option, pub diagnostics_delay: Option, @@ -22,6 +25,9 @@ pub struct Options { #[serde(default)] pub chktex: ChktexOptions, + #[serde(default)] + pub latexindent: LatexindentOptions, + pub forward_search: Option, } @@ -38,6 +44,28 @@ impl Default for BibtexFormatter { } } +#[derive(Debug, PartialEq, Eq, Clone, Copy, Serialize, Deserialize)] +#[serde(rename_all = "kebab-case")] +pub enum LatexFormatter { + Texlab, + Latexindent, +} + +impl Default for LatexFormatter { + fn default() -> Self { + Self::Latexindent + } +} + +#[derive(Debug, PartialEq, Eq, Clone, Default, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct LatexindentOptions { + pub local: Option, + + #[serde(default)] + pub modify_line_breaks: bool, +} + #[derive(Debug, PartialEq, Eq, Clone, Default, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct BuildOptions { diff --git a/support/texlab/src/syntax/bibtex/cst.rs b/support/texlab/src/syntax/bibtex/cst.rs index 7f824681dc..ba860c1ee7 100644 --- a/support/texlab/src/syntax/bibtex/cst.rs +++ b/support/texlab/src/syntax/bibtex/cst.rs @@ -1,4 +1,5 @@ use cstree::TextRange; +use itertools::{EitherOrBoth, Itertools}; use crate::syntax::CstNode; @@ -159,15 +160,42 @@ impl<'a> HasType<'a> for Entry<'a> {} impl<'a> HasDelimiters<'a> for Entry<'a> {} impl<'a> Entry<'a> { - pub fn key(&self) -> Option<&'a SyntaxToken> { + pub fn key(&self) -> Option> { + self.syntax().children().find_map(Key::cast) + } + + pub fn fields(&self) -> impl Iterator> { + self.syntax().children().filter_map(Field::cast) + } +} + +cst_node!(Key, KEY); + +impl<'a> Key<'a> { + pub fn words(&self) -> impl Iterator { self.syntax() .children_with_tokens() .filter_map(|node| node.into_token()) - .find(|node| node.kind() == WORD) + .filter(|node| node.kind() == WORD) } +} - pub fn fields(&self) -> impl Iterator> { - self.syntax().children().filter_map(Field::cast) +impl<'a> PartialEq for Key<'a> { + fn eq(&self, other: &Self) -> bool { + self.words() + .zip_longest(other.words()) + .all(|result| match result { + EitherOrBoth::Both(left, right) => left.text() == right.text(), + EitherOrBoth::Left(_) | EitherOrBoth::Right(_) => false, + }) + } +} + +impl<'a> Eq for Key<'a> {} + +impl<'a> ToString for Key<'a> { + fn to_string(&self) -> std::string::String { + self.words().map(|word| word.text()).join(" ") } } diff --git a/support/texlab/src/syntax/bibtex/kind.rs b/support/texlab/src/syntax/bibtex/kind.rs index fcb26b69bd..91f62fd3b8 100644 --- a/support/texlab/src/syntax/bibtex/kind.rs +++ b/support/texlab/src/syntax/bibtex/kind.rs @@ -26,6 +26,7 @@ pub enum SyntaxKind { STRING, COMMENT, ENTRY, + KEY, FIELD, VALUE, TOKEN, diff --git a/support/texlab/src/syntax/bibtex/parser.rs b/support/texlab/src/syntax/bibtex/parser.rs index ffdb1c94a0..6e8c4b3b59 100644 --- a/support/texlab/src/syntax/bibtex/parser.rs +++ b/support/texlab/src/syntax/bibtex/parser.rs @@ -174,7 +174,7 @@ impl<'a> Parser<'a> { self.builder.finish_node(); return; } - self.eat(); + self.key(); while let Some(kind) = self.peek() { match kind { @@ -190,6 +190,18 @@ impl<'a> Parser<'a> { self.builder.finish_node(); } + fn key(&mut self) { + self.builder.start_node(KEY.into()); + while self + .peek() + .filter(|&kind| matches!(kind, WORD | WHITESPACE)) + .is_some() + { + self.eat(); + } + self.builder.finish_node(); + } + fn field(&mut self) { self.builder.start_node(FIELD.into()); self.eat(); diff --git a/support/texlab/src/syntax/bibtex/snapshots/texlab__syntax__bibtex__parser__tests__entry_complete_parens.snap b/support/texlab/src/syntax/bibtex/snapshots/texlab__syntax__bibtex__parser__tests__entry_complete_parens.snap index cfd469f161..d86d2fb035 100644 --- a/support/texlab/src/syntax/bibtex/snapshots/texlab__syntax__bibtex__parser__tests__entry_complete_parens.snap +++ b/support/texlab/src/syntax/bibtex/snapshots/texlab__syntax__bibtex__parser__tests__entry_complete_parens.snap @@ -7,7 +7,8 @@ ROOT@0..50 ENTRY@0..50 ENTRY_TYPE@0..8 "@article" L_PAREN@8..9 "(" - WORD@9..12 "foo" + KEY@9..12 + WORD@9..12 "foo" COMMA@12..13 "," WHITESPACE@13..14 " " FIELD@14..32 diff --git a/support/texlab/src/syntax/bibtex/snapshots/texlab__syntax__bibtex__parser__tests__entry_no_fields.snap b/support/texlab/src/syntax/bibtex/snapshots/texlab__syntax__bibtex__parser__tests__entry_no_fields.snap index a98df7e382..e5df412782 100644 --- a/support/texlab/src/syntax/bibtex/snapshots/texlab__syntax__bibtex__parser__tests__entry_no_fields.snap +++ b/support/texlab/src/syntax/bibtex/snapshots/texlab__syntax__bibtex__parser__tests__entry_no_fields.snap @@ -7,7 +7,8 @@ ROOT@0..14 ENTRY@0..14 ENTRY_TYPE@0..8 "@article" L_CURLY@8..9 "{" - WORD@9..12 "foo" + KEY@9..12 + WORD@9..12 "foo" COMMA@12..13 "," R_CURLY@13..14 "}" diff --git a/support/texlab/src/syntax/bibtex/snapshots/texlab__syntax__bibtex__parser__tests__entry_no_fields_missing_comma.snap b/support/texlab/src/syntax/bibtex/snapshots/texlab__syntax__bibtex__parser__tests__entry_no_fields_missing_comma.snap index b83037aae0..b15c871298 100644 --- a/support/texlab/src/syntax/bibtex/snapshots/texlab__syntax__bibtex__parser__tests__entry_no_fields_missing_comma.snap +++ b/support/texlab/src/syntax/bibtex/snapshots/texlab__syntax__bibtex__parser__tests__entry_no_fields_missing_comma.snap @@ -7,6 +7,7 @@ ROOT@0..13 ENTRY@0..13 ENTRY_TYPE@0..8 "@article" L_CURLY@8..9 "{" - WORD@9..12 "foo" + KEY@9..12 + WORD@9..12 "foo" R_CURLY@12..13 "}" diff --git a/support/texlab/src/syntax/bibtex/snapshots/texlab__syntax__bibtex__parser__tests__entry_one_field.snap b/support/texlab/src/syntax/bibtex/snapshots/texlab__syntax__bibtex__parser__tests__entry_one_field.snap index 704cbbbd47..0bd43ac612 100644 --- a/support/texlab/src/syntax/bibtex/snapshots/texlab__syntax__bibtex__parser__tests__entry_one_field.snap +++ b/support/texlab/src/syntax/bibtex/snapshots/texlab__syntax__bibtex__parser__tests__entry_one_field.snap @@ -7,7 +7,8 @@ ROOT@0..33 ENTRY@0..33 ENTRY_TYPE@0..8 "@article" L_CURLY@8..9 "{" - WORD@9..12 "foo" + KEY@9..12 + WORD@9..12 "foo" COMMA@12..13 "," WHITESPACE@13..14 " " FIELD@14..32 diff --git a/support/texlab/src/syntax/bibtex/snapshots/texlab__syntax__bibtex__parser__tests__entry_one_field_number_key.snap b/support/texlab/src/syntax/bibtex/snapshots/texlab__syntax__bibtex__parser__tests__entry_one_field_number_key.snap index 8f00c5ee1c..09bb00872f 100644 --- a/support/texlab/src/syntax/bibtex/snapshots/texlab__syntax__bibtex__parser__tests__entry_one_field_number_key.snap +++ b/support/texlab/src/syntax/bibtex/snapshots/texlab__syntax__bibtex__parser__tests__entry_one_field_number_key.snap @@ -7,7 +7,8 @@ ROOT@0..37 ENTRY@0..37 ENTRY_TYPE@0..8 "@article" L_CURLY@8..9 "{" - WORD@9..16 "foo2021" + KEY@9..16 + WORD@9..16 "foo2021" COMMA@16..17 "," WHITESPACE@17..18 " " FIELD@18..36 diff --git a/support/texlab/src/syntax/bibtex/snapshots/texlab__syntax__bibtex__parser__tests__entry_one_field_trailing_comma.snap b/support/texlab/src/syntax/bibtex/snapshots/texlab__syntax__bibtex__parser__tests__entry_one_field_trailing_comma.snap index af8b1593df..51adbbc275 100644 --- a/support/texlab/src/syntax/bibtex/snapshots/texlab__syntax__bibtex__parser__tests__entry_one_field_trailing_comma.snap +++ b/support/texlab/src/syntax/bibtex/snapshots/texlab__syntax__bibtex__parser__tests__entry_one_field_trailing_comma.snap @@ -7,7 +7,8 @@ ROOT@0..34 ENTRY@0..34 ENTRY_TYPE@0..8 "@article" L_CURLY@8..9 "{" - WORD@9..12 "foo" + KEY@9..12 + WORD@9..12 "foo" COMMA@12..13 "," WHITESPACE@13..14 " " FIELD@14..32 diff --git a/support/texlab/src/syntax/bibtex/snapshots/texlab__syntax__bibtex__parser__tests__entry_two_fields.snap b/support/texlab/src/syntax/bibtex/snapshots/texlab__syntax__bibtex__parser__tests__entry_two_fields.snap index f47b3b6917..384d582ef9 100644 --- a/support/texlab/src/syntax/bibtex/snapshots/texlab__syntax__bibtex__parser__tests__entry_two_fields.snap +++ b/support/texlab/src/syntax/bibtex/snapshots/texlab__syntax__bibtex__parser__tests__entry_two_fields.snap @@ -7,7 +7,8 @@ ROOT@0..56 ENTRY@0..56 ENTRY_TYPE@0..8 "@article" L_CURLY@8..9 "{" - WORD@9..12 "foo" + KEY@9..12 + WORD@9..12 "foo" COMMA@12..13 "," WHITESPACE@13..14 " " FIELD@14..32 diff --git a/support/texlab/src/syntax/bibtex/snapshots/texlab__syntax__bibtex__parser__tests__entry_two_fields_incomplete.snap b/support/texlab/src/syntax/bibtex/snapshots/texlab__syntax__bibtex__parser__tests__entry_two_fields_incomplete.snap index 34a9019582..cbe00beff5 100644 --- a/support/texlab/src/syntax/bibtex/snapshots/texlab__syntax__bibtex__parser__tests__entry_two_fields_incomplete.snap +++ b/support/texlab/src/syntax/bibtex/snapshots/texlab__syntax__bibtex__parser__tests__entry_two_fields_incomplete.snap @@ -7,7 +7,8 @@ ROOT@0..36 ENTRY@0..36 ENTRY_TYPE@0..8 "@article" L_CURLY@8..9 "{" - WORD@9..12 "foo" + KEY@9..12 + WORD@9..12 "foo" COMMA@12..13 "," WHITESPACE@13..14 " " FIELD@14..32 diff --git a/support/texlab/src/syntax/latex/analysis/environment.rs b/support/texlab/src/syntax/latex/analysis/environment.rs index 3b83b40b2f..7cda0c126b 100644 --- a/support/texlab/src/syntax/latex/analysis/environment.rs +++ b/support/texlab/src/syntax/latex/analysis/environment.rs @@ -4,7 +4,7 @@ use super::LatexAnalyzerContext; pub fn analyze_begin(context: &mut LatexAnalyzerContext, node: &latex::SyntaxNode) -> Option<()> { let begin = latex::Begin::cast(node)?; - let name = begin.name()?.word()?.text(); + let name = begin.name()?.key()?.to_string(); let extras = &mut context.extras; extras.environment_names.insert(name.into()); Some(()) diff --git a/support/texlab/src/syntax/latex/analysis/explicit_link.rs b/support/texlab/src/syntax/latex/analysis/explicit_link.rs index 363a576aaa..f177354ac7 100644 --- a/support/texlab/src/syntax/latex/analysis/explicit_link.rs +++ b/support/texlab/src/syntax/latex/analysis/explicit_link.rs @@ -23,22 +23,22 @@ pub fn analyze_include(context: &mut LatexAnalyzerContext, node: &latex::SyntaxN ExplicitLinkKind::Class => &["cls"], }; - for path in include.path_list()?.words() { - let stem = path.text(); - let mut targets = vec![Arc::new(context.base_uri.join(stem).ok()?.into())]; + for path in include.path_list()?.keys() { + let stem = path.to_string(); + let mut targets = vec![Arc::new(context.base_uri.join(&stem).ok()?.into())]; for extension in extensions { let path = format!("{}.{}", stem, extension); targets.push(Arc::new(context.base_uri.join(&path).ok()?.into())); } - resolve_distro_file(&context.inner.resolver.lock().unwrap(), stem, extensions) + resolve_distro_file(&context.inner.resolver.lock().unwrap(), &stem, extensions) .into_iter() .for_each(|target| targets.push(Arc::new(target))); context.extras.explicit_links.push(ExplicitLink { kind, stem: stem.into(), - stem_range: path.text_range(), + stem_range: path.small_range(), targets, }); } @@ -52,19 +52,19 @@ pub fn analyze_import(context: &mut LatexAnalyzerContext, node: &latex::SyntaxNo let mut targets = Vec::new(); let directory = context .base_uri - .join(import.directory()?.word()?.text()) + .join(&import.directory()?.key()?.to_string()) .ok()?; - let file = import.file()?.word()?; - let stem = file.text(); - targets.push(Arc::new(directory.join(stem).ok()?.into())); + let file = import.file()?.key()?; + let stem = file.to_string(); + targets.push(Arc::new(directory.join(&stem).ok()?.into())); targets.push(Arc::new( directory.join(&format!("{}.tex", stem)).ok()?.into(), )); context.extras.explicit_links.push(ExplicitLink { stem: stem.into(), - stem_range: file.text_range(), + stem_range: file.small_range(), targets, kind: ExplicitLinkKind::Latex, }); diff --git a/support/texlab/src/syntax/latex/analysis/label_name.rs b/support/texlab/src/syntax/latex/analysis/label_name.rs index d0410b953c..e5ff6829cd 100644 --- a/support/texlab/src/syntax/latex/analysis/label_name.rs +++ b/support/texlab/src/syntax/latex/analysis/label_name.rs @@ -18,10 +18,10 @@ fn analyze_label_definition_name( node: &latex::SyntaxNode, ) -> Option<()> { let label = latex::LabelDefinition::cast(node)?; - let name = label.name()?.word()?; + let name = label.name()?.key()?; context.extras.label_names.push(LabelName { - text: name.text().into(), - range: name.text_range(), + text: name.to_string().into(), + range: name.small_range(), is_definition: true, }); Some(()) @@ -32,10 +32,10 @@ fn analyze_label_reference_name( node: &latex::SyntaxNode, ) -> Option<()> { let label = latex::LabelReference::cast(node)?; - for name in label.name_list()?.words() { + for name in label.name_list()?.keys() { context.extras.label_names.push(LabelName { - text: name.text().into(), - range: name.text_range(), + text: name.to_string().into(), + range: name.small_range(), is_definition: false, }); } @@ -47,18 +47,18 @@ fn analyze_label_reference_range_name( node: &latex::SyntaxNode, ) -> Option<()> { let label = LabelReferenceRange::cast(node)?; - if let Some(name1) = label.from().and_then(|name| name.word()) { + if let Some(name1) = label.from().and_then(|name| name.key()) { context.extras.label_names.push(LabelName { - text: name1.text().into(), - range: name1.text_range(), + text: name1.to_string().into(), + range: name1.small_range(), is_definition: false, }); } - if let Some(name2) = label.to().and_then(|name| name.word()) { + if let Some(name2) = label.to().and_then(|name| name.key()) { context.extras.label_names.push(LabelName { - text: name2.text().into(), - range: name2.text_range(), + text: name2.to_string().into(), + range: name2.small_range(), is_definition: false, }); } diff --git a/support/texlab/src/syntax/latex/analysis/label_number.rs b/support/texlab/src/syntax/latex/analysis/label_number.rs index de8d0dc1e1..93ad09523f 100644 --- a/support/texlab/src/syntax/latex/analysis/label_number.rs +++ b/support/texlab/src/syntax/latex/analysis/label_number.rs @@ -7,7 +7,7 @@ pub fn analyze_label_number( node: &latex::SyntaxNode, ) -> Option<()> { let number = latex::LabelNumber::cast(node)?; - let name = number.name()?.word()?.text().into(); + let name = number.name()?.key()?.to_string(); let text = number .text()? .syntax() diff --git a/support/texlab/src/syntax/latex/analysis/theorem.rs b/support/texlab/src/syntax/latex/analysis/theorem.rs index 0c365f0ef5..50236e24a5 100644 --- a/support/texlab/src/syntax/latex/analysis/theorem.rs +++ b/support/texlab/src/syntax/latex/analysis/theorem.rs @@ -10,7 +10,7 @@ pub fn analyze_theorem_definition( node: &latex::SyntaxNode, ) -> Option<()> { let theorem = latex::TheoremDefinition::cast(node)?; - let name = theorem.name()?.word()?.text().into(); + let name = theorem.name()?.key()?.to_string(); let description = theorem.description()?; let description = description.content_text()?; diff --git a/support/texlab/src/syntax/latex/analysis/types.rs b/support/texlab/src/syntax/latex/analysis/types.rs index f089721397..bd2789b3b7 100644 --- a/support/texlab/src/syntax/latex/analysis/types.rs +++ b/support/texlab/src/syntax/latex/analysis/types.rs @@ -20,9 +20,9 @@ pub struct Extras { pub explicit_links: Vec, pub has_document_environment: bool, pub command_names: FxHashSet, - pub environment_names: FxHashSet, + pub environment_names: FxHashSet, pub label_names: Vec, - pub label_numbers_by_name: FxHashMap, + pub label_numbers_by_name: FxHashMap, pub theorem_environments: Vec, } @@ -61,7 +61,7 @@ impl ExplicitLink { #[derive(Debug, PartialEq, Eq, Clone, Default, Hash)] pub struct TheoremEnvironment { - pub name: SmolStr, + pub name: String, pub description: String, } diff --git a/support/texlab/src/syntax/latex/cst.rs b/support/texlab/src/syntax/latex/cst.rs index 0b839b706d..a800236ebf 100644 --- a/support/texlab/src/syntax/latex/cst.rs +++ b/support/texlab/src/syntax/latex/cst.rs @@ -1,4 +1,5 @@ use cstree::TextRange; +use itertools::{EitherOrBoth, Itertools}; use crate::syntax::CstNode; @@ -6,7 +7,7 @@ use super::{Language, SyntaxKind::*, SyntaxNode, SyntaxToken}; macro_rules! cst_node { ($name:ident, $($kind:pat),+) => { - #[derive(Clone)] + #[derive(Clone, Copy)] #[repr(transparent)] pub struct $name<'a>(&'a SyntaxNode); @@ -45,6 +46,15 @@ macro_rules! cst_node { cst_node!(Text, TEXT); +impl<'a> Text<'a> { + pub fn words(&self) -> impl Iterator { + self.syntax() + .children_with_tokens() + .filter_map(|node| node.into_token()) + .filter(|node| node.kind() == WORD) + } +} + pub trait HasCurly<'a>: CstNode<'a, Lang = Language> { fn left_curly(&self) -> Option<&'a SyntaxToken> { self.syntax() @@ -168,11 +178,8 @@ cst_node!(CurlyGroupWord, CURLY_GROUP_WORD); impl<'a> HasCurly<'a> for CurlyGroupWord<'a> {} impl<'a> CurlyGroupWord<'a> { - pub fn word(&self) -> Option<&'a SyntaxToken> { - self.syntax() - .children_with_tokens() - .filter_map(|node| node.into_token()) - .find(|node| node.kind() == WORD) + pub fn key(&self) -> Option> { + self.syntax().children().find_map(Key::cast) } } @@ -181,11 +188,8 @@ cst_node!(BrackGroupWord, BRACK_GROUP_WORD); impl<'a> HasBrack<'a> for BrackGroupWord<'a> {} impl<'a> BrackGroupWord<'a> { - pub fn word(&self) -> Option<&'a SyntaxToken> { - self.syntax() - .children_with_tokens() - .filter_map(|node| node.into_token()) - .find(|node| node.kind() == WORD) + pub fn key(&self) -> Option> { + self.syntax().children().find_map(Key::cast) } } @@ -194,11 +198,8 @@ cst_node!(CurlyGroupWordList, CURLY_GROUP_WORD_LIST); impl<'a> HasCurly<'a> for CurlyGroupWordList<'a> {} impl<'a> CurlyGroupWordList<'a> { - pub fn words(&self) -> impl Iterator { - self.syntax() - .children_with_tokens() - .filter_map(|node| node.into_token()) - .filter(|node| node.kind() == WORD) + pub fn keys(&self) -> impl Iterator> { + self.syntax().children().filter_map(Key::cast) } } @@ -226,6 +227,25 @@ impl<'a> Key<'a> { } } +impl<'a> PartialEq for Key<'a> { + fn eq(&self, other: &Self) -> bool { + self.words() + .zip_longest(other.words()) + .all(|result| match result { + EitherOrBoth::Both(left, right) => left.text() == right.text(), + EitherOrBoth::Left(_) | EitherOrBoth::Right(_) => false, + }) + } +} + +impl<'a> Eq for Key<'a> {} + +impl<'a> ToString for Key<'a> { + fn to_string(&self) -> String { + self.words().map(|word| word.text()).join(" ") + } +} + cst_node!(Value, VALUE); cst_node!(KeyValuePair, KEY_VALUE_PAIR); diff --git a/support/texlab/src/syntax/latex/parser.rs b/support/texlab/src/syntax/latex/parser.rs index 4333235ba5..a21674f51d 100644 --- a/support/texlab/src/syntax/latex/parser.rs +++ b/support/texlab/src/syntax/latex/parser.rs @@ -173,20 +173,6 @@ impl<'a> Parser<'a> { self.builder.finish_node(); } - fn group_with_token( - &mut self, - node_kind: SyntaxKind, - content_kind: SyntaxKind, - right_kind: SyntaxKind, - ) { - self.builder.start_node(node_kind.into()); - self.eat(); - self.trivia(); - self.expect(content_kind); - self.expect(right_kind); - self.builder.finish_node(); - } - fn curly_group(&mut self) { self.builder.start_node(CURLY_GROUP.into()); self.eat(); @@ -219,7 +205,23 @@ impl<'a> Parser<'a> { } fn curly_group_word(&mut self) { - self.group_with_token(CURLY_GROUP_WORD, WORD, R_CURLY); + self.builder.start_node(CURLY_GROUP_WORD.into()); + self.eat(); + self.trivia(); + match self.peek() { + Some(WORD) => { + self.key(); + } + Some(PARAMETER) => { + self.eat(); + self.trivia(); + } + Some(_) | None => { + self.builder.token(MISSING.into(), ""); + } + } + self.expect(R_CURLY); + self.builder.finish_node(); } fn curly_group_word_list(&mut self) { @@ -228,10 +230,14 @@ impl<'a> Parser<'a> { while self .peek() - .filter(|&kind| matches!(kind, WHITESPACE | COMMENT | WORD | COMMA)) + .filter(|&kind| matches!(kind, WHITESPACE | COMMENT | WORD | COMMA | PARAMETER)) .is_some() { - self.eat(); + if self.peek() == Some(WORD) { + self.key(); + } else { + self.eat(); + } } self.expect(R_CURLY); @@ -239,7 +245,24 @@ impl<'a> Parser<'a> { } fn curly_group_command(&mut self) { - self.group_with_token(CURLY_GROUP_COMMAND, GENERIC_COMMAND_NAME, R_CURLY); + self.builder.start_node(CURLY_GROUP_COMMAND.into()); + self.eat(); + self.trivia(); + match self.peek() { + Some(kind) if kind.is_command_name() => { + self.eat(); + self.trivia(); + } + Some(PARAMETER) => { + self.eat(); + self.trivia(); + } + Some(_) | None => { + self.builder.token(MISSING.into(), ""); + } + } + self.expect(R_CURLY); + self.builder.finish_node(); } fn brack_group(&mut self) { @@ -271,37 +294,24 @@ impl<'a> Parser<'a> { } fn brack_group_word(&mut self) { - self.group_with_token(BRACK_GROUP_WORD, WORD, R_BRACK); - } - - // fn paren_group(&mut self) { - // self.builder.start_node(PAREN_GROUP.into()); - // self.eat(); - // while self - // .peek() - // .filter(|&kind| { - // !matches!( - // kind, - // R_CURLY - // | R_BRACK - // | R_PAREN - // | PART_NAME - // | CHAPTER_NAME - // | SECTION_NAME - // | SUBSECTION_NAME - // | PARAGRAPH_NAME - // | SUBPARAGRAPH_NAME - // | ENUM_ITEM_NAME - // | END_ENVIRONMENT_NAME - // ) - // }) - // .is_some() - // { - // self.content(); - // } - // self.expect(R_PAREN); - // self.builder.finish_node(); - // } + self.builder.start_node(BRACK_GROUP_WORD.into()); + self.eat(); + self.trivia(); + match self.peek() { + Some(WORD) => { + self.key(); + } + Some(PARAMETER) => { + self.eat(); + self.trivia(); + } + Some(_) | None => { + self.builder.token(MISSING.into(), ""); + } + } + self.expect(R_BRACK); + self.builder.finish_node(); + } fn mixed_group(&mut self) { self.builder.start_node(MIXED_GROUP.into()); diff --git a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__acronym_declaration.snap b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__acronym_declaration.snap index dfd05750d3..a92180efb3 100644 --- a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__acronym_declaration.snap +++ b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__acronym_declaration.snap @@ -9,7 +9,8 @@ ROOT@0..64 ACRONYM_DECLARATION_NAME@0..15 "\\DeclareAcronym" CURLY_GROUP_WORD@15..19 L_CURLY@15..16 "{" - WORD@16..18 "eg" + KEY@16..18 + WORD@16..18 "eg" R_CURLY@18..19 "}" CURLY_GROUP_KEY_VALUE@19..64 L_CURLY@19..20 "{" diff --git a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__acroynm_definition_options.snap b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__acroynm_definition_options.snap index 1838e80f9a..80043c18e7 100644 --- a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__acroynm_definition_options.snap +++ b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__acroynm_definition_options.snap @@ -27,7 +27,8 @@ ROOT@0..76 R_BRACK@42..43 "]" CURLY_GROUP_WORD@43..53 L_CURLY@43..44 "{" - WORD@44..52 "fpsLabel" + KEY@44..52 + WORD@44..52 "fpsLabel" R_CURLY@52..53 "}" CURLY_GROUP@53..58 L_CURLY@53..54 "{" diff --git a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__acroynm_definition_simple.snap b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__acroynm_definition_simple.snap index 1d32bed249..74ae2219de 100644 --- a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__acroynm_definition_simple.snap +++ b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__acroynm_definition_simple.snap @@ -9,7 +9,8 @@ ROOT@0..44 ACRONYM_DEFINITION_NAME@0..11 "\\newacronym" CURLY_GROUP_WORD@11..21 L_CURLY@11..12 "{" - WORD@12..20 "fpsLabel" + KEY@12..20 + WORD@12..20 "fpsLabel" R_CURLY@20..21 "}" CURLY_GROUP@21..26 L_CURLY@21..22 "{" diff --git a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__acroynm_reference_options.snap b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__acroynm_reference_options.snap index ce5b85c1cf..6a1c2cdcbe 100644 --- a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__acroynm_reference_options.snap +++ b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__acroynm_reference_options.snap @@ -24,6 +24,7 @@ ROOT@0..32 R_BRACK@21..22 "]" CURLY_GROUP_WORD@22..32 L_CURLY@22..23 "{" - WORD@23..31 "fpsLabel" + KEY@23..31 + WORD@23..31 "fpsLabel" R_CURLY@31..32 "}" diff --git a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__acroynm_reference_simple.snap b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__acroynm_reference_simple.snap index 5df8059f1b..9924c7175c 100644 --- a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__acroynm_reference_simple.snap +++ b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__acroynm_reference_simple.snap @@ -9,6 +9,7 @@ ROOT@0..19 ACRONYM_REFERENCE_NAME@0..9 "\\acrshort" CURLY_GROUP_WORD@9..19 L_CURLY@9..10 "{" - WORD@10..18 "fpsLabel" + KEY@10..18 + WORD@10..18 "fpsLabel" R_CURLY@18..19 "}" diff --git a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__biblatex_include_options.snap b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__biblatex_include_options.snap index c910699363..3189cabd46 100644 --- a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__biblatex_include_options.snap +++ b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__biblatex_include_options.snap @@ -25,6 +25,7 @@ ROOT@0..42 R_BRACK@28..29 "]" CURLY_GROUP_WORD_LIST@29..42 L_CURLY@29..30 "{" - WORD@30..41 "foo/bar.bib" + KEY@30..41 + WORD@30..41 "foo/bar.bib" R_CURLY@41..42 "}" diff --git a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__biblatex_include_simple.snap b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__biblatex_include_simple.snap index 3549b985c4..3166d13aff 100644 --- a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__biblatex_include_simple.snap +++ b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__biblatex_include_simple.snap @@ -9,6 +9,7 @@ ROOT@0..28 BIBLATEX_INCLUDE_NAME@0..15 "\\addbibresource" CURLY_GROUP_WORD_LIST@15..28 L_CURLY@15..16 "{" - WORD@16..27 "foo/bar.bib" + KEY@16..27 + WORD@16..27 "foo/bar.bib" R_CURLY@27..28 "}" diff --git a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__bibtex_include_simple.snap b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__bibtex_include_simple.snap index f0d30ebfa3..db58621c75 100644 --- a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__bibtex_include_simple.snap +++ b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__bibtex_include_simple.snap @@ -9,6 +9,7 @@ ROOT@0..22 BIBTEX_INCLUDE_NAME@0..13 "\\bibliography" CURLY_GROUP_WORD_LIST@13..22 L_CURLY@13..14 "{" - WORD@14..21 "foo/bar" + KEY@14..21 + WORD@14..21 "foo/bar" R_CURLY@21..22 "}" diff --git a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__caption_figure.snap b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__caption_figure.snap index 4b963caabd..b3bf7589d8 100644 --- a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__caption_figure.snap +++ b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__caption_figure.snap @@ -10,7 +10,8 @@ ROOT@0..39 BEGIN_ENVIRONMENT_NAME@0..6 "\\begin" CURLY_GROUP_WORD@6..14 L_CURLY@6..7 "{" - WORD@7..13 "figure" + KEY@7..13 + WORD@7..13 "figure" R_CURLY@13..14 "}" CAPTION@14..27 CAPTION_NAME@14..22 "\\caption" @@ -23,6 +24,7 @@ ROOT@0..39 END_ENVIRONMENT_NAME@27..31 "\\end" CURLY_GROUP_WORD@31..39 L_CURLY@31..32 "{" - WORD@32..38 "figure" + KEY@32..38 + WORD@32..38 "figure" R_CURLY@38..39 "}" diff --git a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__citation_missing_brace.snap b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__citation_missing_brace.snap index 363f8b0142..61cd6d8f0b 100644 --- a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__citation_missing_brace.snap +++ b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__citation_missing_brace.snap @@ -9,6 +9,7 @@ ROOT@0..9 CITATION_NAME@0..5 "\\cite" CURLY_GROUP_WORD_LIST@5..9 L_CURLY@5..6 "{" - WORD@6..9 "foo" + KEY@6..9 + WORD@6..9 "foo" MISSING@9..9 "" diff --git a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__citation_multiple_keys.snap b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__citation_multiple_keys.snap index dafc826a97..7195e8992e 100644 --- a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__citation_multiple_keys.snap +++ b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__citation_multiple_keys.snap @@ -9,9 +9,11 @@ ROOT@0..15 CITATION_NAME@0..5 "\\cite" CURLY_GROUP_WORD_LIST@5..15 L_CURLY@5..6 "{" - WORD@6..9 "foo" + KEY@6..9 + WORD@6..9 "foo" COMMA@9..10 "," WHITESPACE@10..11 " " - WORD@11..14 "bar" + KEY@11..14 + WORD@11..14 "bar" R_CURLY@14..15 "}" diff --git a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__citation_prenote.snap b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__citation_prenote.snap index 93d83bb448..b5d92886aa 100644 --- a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__citation_prenote.snap +++ b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__citation_prenote.snap @@ -14,6 +14,7 @@ ROOT@0..15 R_BRACK@9..10 "]" CURLY_GROUP_WORD_LIST@10..15 L_CURLY@10..11 "{" - WORD@11..14 "bar" + KEY@11..14 + WORD@11..14 "bar" R_CURLY@14..15 "}" diff --git a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__citation_prenote_postnote.snap b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__citation_prenote_postnote.snap index 3acaafea3b..ba99b66e35 100644 --- a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__citation_prenote_postnote.snap +++ b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__citation_prenote_postnote.snap @@ -19,6 +19,7 @@ ROOT@0..20 R_BRACK@14..15 "]" CURLY_GROUP_WORD_LIST@15..20 L_CURLY@15..16 "{" - WORD@16..19 "baz" + KEY@16..19 + WORD@16..19 "baz" R_CURLY@19..20 "}" diff --git a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__citation_redundant_comma.snap b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__citation_redundant_comma.snap index 12f34f16ae..9062479f7a 100644 --- a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__citation_redundant_comma.snap +++ b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__citation_redundant_comma.snap @@ -10,7 +10,8 @@ ROOT@0..12 CURLY_GROUP_WORD_LIST@5..12 L_CURLY@5..6 "{" COMMA@6..7 "," - WORD@7..10 "foo" + KEY@7..10 + WORD@7..10 "foo" COMMA@10..11 "," R_CURLY@11..12 "}" diff --git a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__citation_simple.snap b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__citation_simple.snap index a22129f85f..335b9d461c 100644 --- a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__citation_simple.snap +++ b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__citation_simple.snap @@ -9,6 +9,7 @@ ROOT@0..10 CITATION_NAME@0..5 "\\cite" CURLY_GROUP_WORD_LIST@5..10 L_CURLY@5..6 "{" - WORD@6..9 "foo" + KEY@6..9 + WORD@6..9 "foo" R_CURLY@9..10 "}" diff --git a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__citation_star.snap b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__citation_star.snap index 4388596dfd..e6d5dad128 100644 --- a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__citation_star.snap +++ b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__citation_star.snap @@ -9,6 +9,7 @@ ROOT@0..10 CITATION_NAME@0..7 "\\nocite" CURLY_GROUP_WORD_LIST@7..10 L_CURLY@7..8 "{" - WORD@8..9 "*" + KEY@8..9 + WORD@8..9 "*" R_CURLY@9..10 "}" diff --git a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__class_include_options.snap b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__class_include_options.snap index 0d0eb1b250..ac20c4b8ac 100644 --- a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__class_include_options.snap +++ b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__class_include_options.snap @@ -32,6 +32,7 @@ ROOT@0..44 R_BRACK@34..35 "]" CURLY_GROUP_WORD_LIST@35..44 L_CURLY@35..36 "{" - WORD@36..43 "article" + KEY@36..43 + WORD@36..43 "article" R_CURLY@43..44 "}" diff --git a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__class_include_simple.snap b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__class_include_simple.snap index 85e21b47a8..07c426101e 100644 --- a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__class_include_simple.snap +++ b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__class_include_simple.snap @@ -9,6 +9,7 @@ ROOT@0..23 CLASS_INCLUDE_NAME@0..14 "\\documentclass" CURLY_GROUP_WORD_LIST@14..23 L_CURLY@14..15 "{" - WORD@15..22 "article" + KEY@15..22 + WORD@15..22 "article" R_CURLY@22..23 "}" diff --git a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__color_definition_simple.snap b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__color_definition_simple.snap index e4adfd534c..64eee4351b 100644 --- a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__color_definition_simple.snap +++ b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__color_definition_simple.snap @@ -9,11 +9,13 @@ ROOT@0..33 COLOR_DEFINITION_NAME@0..12 "\\definecolor" CURLY_GROUP_WORD@12..17 L_CURLY@12..13 "{" - WORD@13..16 "foo" + KEY@13..16 + WORD@13..16 "foo" R_CURLY@16..17 "}" CURLY_GROUP_WORD@17..22 L_CURLY@17..18 "{" - WORD@18..21 "rgb" + KEY@18..21 + WORD@18..21 "rgb" R_CURLY@21..22 "}" CURLY_GROUP@22..33 L_CURLY@22..23 "{" diff --git a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__color_reference_simple.snap b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__color_reference_simple.snap index 41a3700122..cb0ee151b9 100644 --- a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__color_reference_simple.snap +++ b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__color_reference_simple.snap @@ -9,6 +9,7 @@ ROOT@0..13 COLOR_REFERENCE_NAME@0..6 "\\color" CURLY_GROUP_WORD@6..13 L_CURLY@6..7 "{" - WORD@7..12 "black" + KEY@7..12 + WORD@7..12 "black" R_CURLY@12..13 "}" diff --git a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__color_set_definition_error1.snap b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__color_set_definition_error1.snap index 42095ff974..59688f0902 100644 --- a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__color_set_definition_error1.snap +++ b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__color_set_definition_error1.snap @@ -9,21 +9,26 @@ ROOT@0..39 COLOR_SET_DEFINITION_NAME@0..15 "\\definecolorset" BRACK_GROUP_WORD@15..19 L_BRACK@15..16 "[" - WORD@16..18 "ty" + KEY@16..18 + WORD@16..18 "ty" R_BRACK@18..19 "]" CURLY_GROUP_WORD_LIST@19..29 L_CURLY@19..20 "{" - WORD@20..23 "rgb" + KEY@20..23 + WORD@20..23 "rgb" COMMA@23..24 "," - WORD@24..28 "HTML" + KEY@24..28 + WORD@24..28 "HTML" R_CURLY@28..29 "}" CURLY_GROUP_WORD@29..34 L_CURLY@29..30 "{" - WORD@30..33 "foo" + KEY@30..33 + WORD@30..33 "foo" R_CURLY@33..34 "}" CURLY_GROUP_WORD@34..39 L_CURLY@34..35 "{" - WORD@35..38 "bar" + KEY@35..38 + WORD@35..38 "bar" R_CURLY@38..39 "}" MISSING@39..39 "" diff --git a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__color_set_definition_error2.snap b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__color_set_definition_error2.snap index 718d49a3e3..cbbeacb649 100644 --- a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__color_set_definition_error2.snap +++ b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__color_set_definition_error2.snap @@ -9,13 +9,16 @@ ROOT@0..30 COLOR_SET_DEFINITION_NAME@0..15 "\\definecolorset" CURLY_GROUP_WORD_LIST@15..25 L_CURLY@15..16 "{" - WORD@16..19 "rgb" + KEY@16..19 + WORD@16..19 "rgb" COMMA@19..20 "," - WORD@20..24 "HTML" + KEY@20..24 + WORD@20..24 "HTML" R_CURLY@24..25 "}" CURLY_GROUP_WORD@25..30 L_CURLY@25..26 "{" - WORD@26..29 "foo" + KEY@26..29 + WORD@26..29 "foo" R_CURLY@29..30 "}" MISSING@30..30 "" MISSING@30..30 "" diff --git a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__color_set_definition_error3.snap b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__color_set_definition_error3.snap index f92d813123..826bea28b6 100644 --- a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__color_set_definition_error3.snap +++ b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__color_set_definition_error3.snap @@ -9,9 +9,11 @@ ROOT@0..25 COLOR_SET_DEFINITION_NAME@0..15 "\\definecolorset" CURLY_GROUP_WORD_LIST@15..25 L_CURLY@15..16 "{" - WORD@16..19 "rgb" + KEY@16..19 + WORD@16..19 "rgb" COMMA@19..20 "," - WORD@20..24 "HTML" + KEY@20..24 + WORD@20..24 "HTML" R_CURLY@24..25 "}" MISSING@25..25 "" MISSING@25..25 "" diff --git a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__color_set_definition_simple.snap b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__color_set_definition_simple.snap index f9a736c65f..9d32e127ef 100644 --- a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__color_set_definition_simple.snap +++ b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__color_set_definition_simple.snap @@ -9,24 +9,30 @@ ROOT@0..44 COLOR_SET_DEFINITION_NAME@0..15 "\\definecolorset" BRACK_GROUP_WORD@15..19 L_BRACK@15..16 "[" - WORD@16..18 "ty" + KEY@16..18 + WORD@16..18 "ty" R_BRACK@18..19 "]" CURLY_GROUP_WORD_LIST@19..29 L_CURLY@19..20 "{" - WORD@20..23 "rgb" + KEY@20..23 + WORD@20..23 "rgb" COMMA@23..24 "," - WORD@24..28 "HTML" + KEY@24..28 + WORD@24..28 "HTML" R_CURLY@28..29 "}" CURLY_GROUP_WORD@29..34 L_CURLY@29..30 "{" - WORD@30..33 "foo" + KEY@30..33 + WORD@30..33 "foo" R_CURLY@33..34 "}" CURLY_GROUP_WORD@34..39 L_CURLY@34..35 "{" - WORD@35..38 "bar" + KEY@35..38 + WORD@35..38 "bar" R_CURLY@38..39 "}" CURLY_GROUP_WORD@39..44 L_CURLY@39..40 "{" - WORD@40..43 "baz" + KEY@40..43 + WORD@40..43 "baz" R_CURLY@43..44 "}" diff --git a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__command_definition_simple.snap b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__command_definition_simple.snap index e5f2377fcf..b0d9b225d0 100644 --- a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__command_definition_simple.snap +++ b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__command_definition_simple.snap @@ -10,7 +10,8 @@ ROOT@0..23 MISSING@11..11 "" BRACK_GROUP_WORD@11..14 L_BRACK@11..12 "[" - WORD@12..13 "1" + KEY@12..13 + WORD@12..13 "1" R_BRACK@13..14 "]" CURLY_GROUP@14..19 L_CURLY@14..15 "{" diff --git a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__environment_definition.snap b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__environment_definition.snap index df3c0d56fb..982d3b8667 100644 --- a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__environment_definition.snap +++ b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__environment_definition.snap @@ -9,11 +9,13 @@ ROOT@0..47 ENVIRONMENT_DEFINIITION_NAME@0..15 "\\newenvironment" CURLY_GROUP_WORD@15..20 L_CURLY@15..16 "{" - WORD@16..19 "bar" + KEY@16..19 + WORD@16..19 "bar" R_CURLY@19..20 "}" BRACK_GROUP_WORD@20..23 L_BRACK@20..21 "[" - WORD@21..22 "1" + KEY@21..22 + WORD@21..22 "1" R_BRACK@22..23 "]" CURLY_GROUP@23..36 L_CURLY@23..24 "{" diff --git a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__environment_nested.snap b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__environment_nested.snap index a5c566f773..3a65af3a2b 100644 --- a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__environment_nested.snap +++ b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__environment_nested.snap @@ -10,7 +10,8 @@ ROOT@0..43 BEGIN_ENVIRONMENT_NAME@0..6 "\\begin" CURLY_GROUP_WORD@6..12 L_CURLY@6..7 "{" - WORD@7..10 "foo" + KEY@7..10 + WORD@7..10 "foo" R_CURLY@10..11 "}" WHITESPACE@11..12 " " ENVIRONMENT@12..34 @@ -18,20 +19,23 @@ ROOT@0..43 BEGIN_ENVIRONMENT_NAME@12..18 "\\begin" CURLY_GROUP_WORD@18..24 L_CURLY@18..19 "{" - WORD@19..22 "qux" + KEY@19..22 + WORD@19..22 "qux" R_CURLY@22..23 "}" WHITESPACE@23..24 " " END@24..34 END_ENVIRONMENT_NAME@24..28 "\\end" CURLY_GROUP_WORD@28..34 L_CURLY@28..29 "{" - WORD@29..32 "baz" + KEY@29..32 + WORD@29..32 "baz" R_CURLY@32..33 "}" WHITESPACE@33..34 " " END@34..43 END_ENVIRONMENT_NAME@34..38 "\\end" CURLY_GROUP_WORD@38..43 L_CURLY@38..39 "{" - WORD@39..42 "bar" + KEY@39..42 + WORD@39..42 "bar" R_CURLY@42..43 "}" diff --git a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__environment_nested_missing_braces.snap b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__environment_nested_missing_braces.snap index 9ff76605d6..973e6e9a9f 100644 --- a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__environment_nested_missing_braces.snap +++ b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__environment_nested_missing_braces.snap @@ -10,33 +10,36 @@ ROOT@0..52 BEGIN_ENVIRONMENT_NAME@0..6 "\\begin" CURLY_GROUP_WORD@6..11 L_CURLY@6..7 "{" - WORD@7..10 "foo" - WHITESPACE@10..11 " " + KEY@7..11 + WORD@7..10 "foo" + WHITESPACE@10..11 " " MISSING@11..11 "" ENVIRONMENT@11..44 - BEGIN@11..22 + BEGIN@11..34 BEGIN_ENVIRONMENT_NAME@11..17 "\\begin" - CURLY_GROUP_WORD@17..22 + CURLY_GROUP_WORD@17..34 L_CURLY@17..18 "{" - WORD@18..21 "qux" - WHITESPACE@21..22 " " - MISSING@22..22 "" - TEXT@22..34 - WORD@22..27 "Hello" - WHITESPACE@27..28 " " - WORD@28..33 "World" - WHITESPACE@33..34 " " + KEY@18..34 + WORD@18..21 "qux" + WHITESPACE@21..22 " " + WORD@22..27 "Hello" + WHITESPACE@27..28 " " + WORD@28..33 "World" + WHITESPACE@33..34 " " + MISSING@34..34 "" END@34..44 END_ENVIRONMENT_NAME@34..38 "\\end" CURLY_GROUP_WORD@38..44 L_CURLY@38..39 "{" - WORD@39..42 "baz" + KEY@39..42 + WORD@39..42 "baz" R_CURLY@42..43 "}" WHITESPACE@43..44 " " END@44..52 END_ENVIRONMENT_NAME@44..48 "\\end" CURLY_GROUP_WORD@48..52 L_CURLY@48..49 "{" - WORD@49..52 "bar" + KEY@49..52 + WORD@49..52 "bar" MISSING@52..52 "" diff --git a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__environment_simple.snap b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__environment_simple.snap index d58f5b26c4..b8b85f1348 100644 --- a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__environment_simple.snap +++ b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__environment_simple.snap @@ -10,7 +10,8 @@ ROOT@0..33 BEGIN_ENVIRONMENT_NAME@0..6 "\\begin" CURLY_GROUP_WORD@6..12 L_CURLY@6..7 "{" - WORD@7..10 "foo" + KEY@7..10 + WORD@7..10 "foo" R_CURLY@10..11 "}" WHITESPACE@11..12 " " TEXT@12..24 @@ -22,6 +23,7 @@ ROOT@0..33 END_ENVIRONMENT_NAME@24..28 "\\end" CURLY_GROUP_WORD@28..33 L_CURLY@28..29 "{" - WORD@29..32 "bar" + KEY@29..32 + WORD@29..32 "bar" R_CURLY@32..33 "}" diff --git a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__equation_label_reference_simple.snap b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__equation_label_reference_simple.snap index 7a851233ef..9123fafcf2 100644 --- a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__equation_label_reference_simple.snap +++ b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__equation_label_reference_simple.snap @@ -9,6 +9,7 @@ ROOT@0..11 LABEL_REFERENCE_NAME@0..6 "\\eqref" CURLY_GROUP_WORD_LIST@6..11 L_CURLY@6..7 "{" - WORD@7..10 "foo" + KEY@7..10 + WORD@7..10 "foo" R_CURLY@10..11 "}" diff --git a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__equation_missing_begin.snap b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__equation_missing_begin.snap index fe065667c3..9a2af78417 100644 --- a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__equation_missing_begin.snap +++ b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__equation_missing_begin.snap @@ -10,7 +10,8 @@ ROOT@0..28 BEGIN_ENVIRONMENT_NAME@0..6 "\\begin" CURLY_GROUP_WORD@6..10 L_CURLY@6..7 "{" - WORD@7..8 "a" + KEY@7..8 + WORD@7..8 "a" R_CURLY@8..9 "}" WHITESPACE@9..10 " " TEXT@10..18 @@ -25,6 +26,7 @@ ROOT@0..28 END_ENVIRONMENT_NAME@21..25 "\\end" CURLY_GROUP_WORD@25..28 L_CURLY@25..26 "{" - WORD@26..27 "b" + KEY@26..27 + WORD@26..27 "b" R_CURLY@27..28 "}" diff --git a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__equation_missing_end.snap b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__equation_missing_end.snap index f7b6205ffb..3085037fac 100644 --- a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__equation_missing_end.snap +++ b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__equation_missing_end.snap @@ -10,7 +10,8 @@ ROOT@0..28 BEGIN_ENVIRONMENT_NAME@0..6 "\\begin" CURLY_GROUP_WORD@6..10 L_CURLY@6..7 "{" - WORD@7..8 "a" + KEY@7..8 + WORD@7..8 "a" R_CURLY@8..9 "}" WHITESPACE@9..10 " " EQUATION@10..21 @@ -26,6 +27,7 @@ ROOT@0..28 END_ENVIRONMENT_NAME@21..25 "\\end" CURLY_GROUP_WORD@25..28 L_CURLY@25..26 "{" - WORD@26..27 "b" + KEY@26..27 + WORD@26..27 "b" R_CURLY@27..28 "}" diff --git a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__glossary_entry_definition_simple.snap b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__glossary_entry_definition_simple.snap index d1b31e275a..519abf75e8 100644 --- a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__glossary_entry_definition_simple.snap +++ b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__glossary_entry_definition_simple.snap @@ -9,7 +9,8 @@ ROOT@0..39 GLOSSARY_ENTRY_DEFINITION_NAME@0..17 "\\newglossaryentry" CURLY_GROUP_WORD@17..22 L_CURLY@17..18 "{" - WORD@18..21 "foo" + KEY@18..21 + WORD@18..21 "foo" R_CURLY@21..22 "}" CURLY_GROUP_KEY_VALUE@22..39 L_CURLY@22..23 "{" diff --git a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__glossary_entry_reference_options.snap b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__glossary_entry_reference_options.snap index ad5c44885a..494c0be0a0 100644 --- a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__glossary_entry_reference_options.snap +++ b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__glossary_entry_reference_options.snap @@ -27,6 +27,7 @@ ROOT@0..25 R_BRACK@19..20 "]" CURLY_GROUP_WORD@20..25 L_CURLY@20..21 "{" - WORD@21..24 "baz" + KEY@21..24 + WORD@21..24 "baz" R_CURLY@24..25 "}" diff --git a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__glossary_entry_reference_simple.snap b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__glossary_entry_reference_simple.snap index 2a6b845733..94af3796fc 100644 --- a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__glossary_entry_reference_simple.snap +++ b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__glossary_entry_reference_simple.snap @@ -9,6 +9,7 @@ ROOT@0..9 GLOSSARY_ENTRY_REFERENCE_NAME@0..4 "\\gls" CURLY_GROUP_WORD@4..9 L_CURLY@4..5 "{" - WORD@5..8 "foo" + KEY@5..8 + WORD@5..8 "foo" R_CURLY@8..9 "}" diff --git a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__graphics_include_options.snap b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__graphics_include_options.snap index 910a4848ef..14e2413323 100644 --- a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__graphics_include_options.snap +++ b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__graphics_include_options.snap @@ -20,6 +20,7 @@ ROOT@0..39 R_BRACK@25..26 "]" CURLY_GROUP_WORD_LIST@26..39 L_CURLY@26..27 "{" - WORD@27..38 "foo/bar.pdf" + KEY@27..38 + WORD@27..38 "foo/bar.pdf" R_CURLY@38..39 "}" diff --git a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__graphics_include_simple.snap b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__graphics_include_simple.snap index fa6fbf1a14..f4c640bca8 100644 --- a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__graphics_include_simple.snap +++ b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__graphics_include_simple.snap @@ -9,6 +9,7 @@ ROOT@0..29 GRAPHICS_INCLUDE_NAME@0..16 "\\includegraphics" CURLY_GROUP_WORD_LIST@16..29 L_CURLY@16..17 "{" - WORD@17..28 "foo/bar.pdf" + KEY@17..28 + WORD@17..28 "foo/bar.pdf" R_CURLY@28..29 "}" diff --git a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__import_incomplete.snap b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__import_incomplete.snap index 3dae1f433a..c8634d6269 100644 --- a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__import_incomplete.snap +++ b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__import_incomplete.snap @@ -9,7 +9,8 @@ ROOT@0..11 IMPORT_NAME@0..7 "\\import" CURLY_GROUP_WORD@7..11 L_CURLY@7..8 "{" - WORD@8..11 "foo" + KEY@8..11 + WORD@8..11 "foo" MISSING@11..11 "" MISSING@11..11 "" diff --git a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__import_simple.snap b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__import_simple.snap index 6e21f65cbf..c94f34eb3f 100644 --- a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__import_simple.snap +++ b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__import_simple.snap @@ -9,10 +9,12 @@ ROOT@0..17 IMPORT_NAME@0..7 "\\import" CURLY_GROUP_WORD@7..12 L_CURLY@7..8 "{" - WORD@8..11 "foo" + KEY@8..11 + WORD@8..11 "foo" R_CURLY@11..12 "}" CURLY_GROUP_WORD@12..17 L_CURLY@12..13 "{" - WORD@13..16 "bar" + KEY@13..16 + WORD@13..16 "bar" R_CURLY@16..17 "}" diff --git a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__inkscape_include_options.snap b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__inkscape_include_options.snap index d1fd2df652..8b95509be6 100644 --- a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__inkscape_include_options.snap +++ b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__inkscape_include_options.snap @@ -20,6 +20,7 @@ ROOT@0..30 R_BRACK@20..21 "]" CURLY_GROUP_WORD_LIST@21..30 L_CURLY@21..22 "{" - WORD@22..29 "foo/bar" + KEY@22..29 + WORD@22..29 "foo/bar" R_CURLY@29..30 "}" diff --git a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__inkscape_include_simple.snap b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__inkscape_include_simple.snap index 59f50c36d3..e3d1f9bdfd 100644 --- a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__inkscape_include_simple.snap +++ b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__inkscape_include_simple.snap @@ -9,6 +9,7 @@ ROOT@0..20 SVG_INCLUDE_NAME@0..11 "\\includesvg" CURLY_GROUP_WORD_LIST@11..20 L_CURLY@11..12 "{" - WORD@12..19 "foo/bar" + KEY@12..19 + WORD@12..19 "foo/bar" R_CURLY@19..20 "}" diff --git a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__label_definition_simple.snap b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__label_definition_simple.snap index 7eacd65c59..2d15533f87 100644 --- a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__label_definition_simple.snap +++ b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__label_definition_simple.snap @@ -9,6 +9,7 @@ ROOT@0..11 LABEL_DEFINITION_NAME@0..6 "\\label" CURLY_GROUP_WORD@6..11 L_CURLY@6..7 "{" - WORD@7..10 "foo" + KEY@7..10 + WORD@7..10 "foo" R_CURLY@10..11 "}" diff --git a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__label_number.snap b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__label_number.snap index 46392d7574..a63752d80e 100644 --- a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__label_number.snap +++ b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__label_number.snap @@ -9,7 +9,8 @@ ROOT@0..21 LABEL_NUMBER_NAME@0..9 "\\newlabel" CURLY_GROUP_WORD@9..14 L_CURLY@9..10 "{" - WORD@10..13 "foo" + KEY@10..13 + WORD@10..13 "foo" R_CURLY@13..14 "}" CURLY_GROUP@14..21 L_CURLY@14..15 "{" diff --git a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__label_reference_multiple.snap b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__label_reference_multiple.snap index e399397e09..0176c770e8 100644 --- a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__label_reference_multiple.snap +++ b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__label_reference_multiple.snap @@ -9,9 +9,11 @@ ROOT@0..14 LABEL_REFERENCE_NAME@0..4 "\\ref" CURLY_GROUP_WORD_LIST@4..14 L_CURLY@4..5 "{" - WORD@5..8 "foo" + KEY@5..8 + WORD@5..8 "foo" COMMA@8..9 "," WHITESPACE@9..10 " " - WORD@10..13 "bar" + KEY@10..13 + WORD@10..13 "bar" R_CURLY@13..14 "}" diff --git a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__label_reference_range_error.snap b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__label_reference_range_error.snap index 2894a9c2ec..ee65f8a02f 100644 --- a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__label_reference_range_error.snap +++ b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__label_reference_range_error.snap @@ -9,10 +9,12 @@ ROOT@0..19 LABEL_REFERENCE_RANGE_NAME@0..10 "\\crefrange" CURLY_GROUP_WORD@10..14 L_CURLY@10..11 "{" - WORD@11..14 "foo" + KEY@11..14 + WORD@11..14 "foo" MISSING@14..14 "" CURLY_GROUP_WORD@14..19 L_CURLY@14..15 "{" - WORD@15..18 "bar" + KEY@15..18 + WORD@15..18 "bar" R_CURLY@18..19 "}" diff --git a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__label_reference_range_incomplete.snap b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__label_reference_range_incomplete.snap index 0a1753867e..3dbe4bbab6 100644 --- a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__label_reference_range_incomplete.snap +++ b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__label_reference_range_incomplete.snap @@ -9,7 +9,8 @@ ROOT@0..15 LABEL_REFERENCE_RANGE_NAME@0..10 "\\crefrange" CURLY_GROUP_WORD@10..15 L_CURLY@10..11 "{" - WORD@11..14 "foo" + KEY@11..14 + WORD@11..14 "foo" R_CURLY@14..15 "}" MISSING@15..15 "" diff --git a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__label_reference_range_simple.snap b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__label_reference_range_simple.snap index c06c31c1b7..094d0e2870 100644 --- a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__label_reference_range_simple.snap +++ b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__label_reference_range_simple.snap @@ -9,10 +9,12 @@ ROOT@0..20 LABEL_REFERENCE_RANGE_NAME@0..10 "\\crefrange" CURLY_GROUP_WORD@10..15 L_CURLY@10..11 "{" - WORD@11..14 "foo" + KEY@11..14 + WORD@11..14 "foo" R_CURLY@14..15 "}" CURLY_GROUP_WORD@15..20 L_CURLY@15..16 "{" - WORD@16..19 "bar" + KEY@16..19 + WORD@16..19 "bar" R_CURLY@19..20 "}" diff --git a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__label_reference_simple.snap b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__label_reference_simple.snap index ed06f5dfc1..9b6e622ef9 100644 --- a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__label_reference_simple.snap +++ b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__label_reference_simple.snap @@ -9,6 +9,7 @@ ROOT@0..9 LABEL_REFERENCE_NAME@0..4 "\\ref" CURLY_GROUP_WORD_LIST@4..9 L_CURLY@4..5 "{" - WORD@5..8 "foo" + KEY@5..8 + WORD@5..8 "foo" R_CURLY@8..9 "}" diff --git a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__latex_include_simple.snap b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__latex_include_simple.snap index 34565aa072..dbdeaad2f7 100644 --- a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__latex_include_simple.snap +++ b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__latex_include_simple.snap @@ -9,6 +9,7 @@ ROOT@0..17 LATEX_INCLUDE_NAME@0..8 "\\include" CURLY_GROUP_WORD_LIST@8..17 L_CURLY@8..9 "{" - WORD@9..16 "foo/bar" + KEY@9..16 + WORD@9..16 "foo/bar" R_CURLY@16..17 "}" diff --git a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__latex_input_simple.snap b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__latex_input_simple.snap index 208e898407..efa0d9b675 100644 --- a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__latex_input_simple.snap +++ b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__latex_input_simple.snap @@ -9,6 +9,7 @@ ROOT@0..19 LATEX_INCLUDE_NAME@0..6 "\\input" CURLY_GROUP_WORD_LIST@6..19 L_CURLY@6..7 "{" - WORD@7..18 "foo/bar.tex" + KEY@7..18 + WORD@7..18 "foo/bar.tex" R_CURLY@18..19 "}" diff --git a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__package_include_multiple.snap b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__package_include_multiple.snap index e68b98d1b5..2df92fd909 100644 --- a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__package_include_multiple.snap +++ b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__package_include_multiple.snap @@ -9,9 +9,11 @@ ROOT@0..28 PACKAGE_INCLUDE_NAME@0..11 "\\usepackage" CURLY_GROUP_WORD_LIST@11..28 L_CURLY@11..12 "{" - WORD@12..19 "amsmath" + KEY@12..19 + WORD@12..19 "amsmath" COMMA@19..20 "," WHITESPACE@20..21 " " - WORD@21..27 "lipsum" + KEY@21..27 + WORD@21..27 "lipsum" R_CURLY@27..28 "}" diff --git a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__package_include_options.snap b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__package_include_options.snap index a33c4e0bd7..0f87570023 100644 --- a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__package_include_options.snap +++ b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__package_include_options.snap @@ -32,6 +32,7 @@ ROOT@0..41 R_BRACK@31..32 "]" CURLY_GROUP_WORD_LIST@32..41 L_CURLY@32..33 "{" - WORD@33..40 "amsmath" + KEY@33..40 + WORD@33..40 "amsmath" R_CURLY@40..41 "}" diff --git a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__package_include_simple.snap b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__package_include_simple.snap index 00c075fdfe..a28dd39a13 100644 --- a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__package_include_simple.snap +++ b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__package_include_simple.snap @@ -9,6 +9,7 @@ ROOT@0..20 PACKAGE_INCLUDE_NAME@0..11 "\\usepackage" CURLY_GROUP_WORD_LIST@11..20 L_CURLY@11..12 "{" - WORD@12..19 "amsmath" + KEY@12..19 + WORD@12..19 "amsmath" R_CURLY@19..20 "}" diff --git a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__pgf_library_import_simple.snap b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__pgf_library_import_simple.snap index 8f289f97a4..c36bf857bb 100644 --- a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__pgf_library_import_simple.snap +++ b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__pgf_library_import_simple.snap @@ -9,6 +9,7 @@ ROOT@0..19 TIKZ_LIBRARY_IMPORT_NAME@0..14 "\\usepgflibrary" CURLY_GROUP_WORD_LIST@14..19 L_CURLY@14..15 "{" - WORD@15..18 "foo" + KEY@15..18 + WORD@15..18 "foo" R_CURLY@18..19 "}" diff --git a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__structure_enum_item.snap b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__structure_enum_item.snap index 43dcae1987..0ca7421ac6 100644 --- a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__structure_enum_item.snap +++ b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__structure_enum_item.snap @@ -10,7 +10,8 @@ ROOT@0..60 BEGIN_ENVIRONMENT_NAME@0..6 "\\begin" CURLY_GROUP_WORD@6..18 L_CURLY@6..7 "{" - WORD@7..16 "enumerate" + KEY@7..16 + WORD@7..16 "enumerate" R_CURLY@16..17 "}" WHITESPACE@17..18 " " ENUM_ITEM@18..26 @@ -40,6 +41,7 @@ ROOT@0..60 END_ENVIRONMENT_NAME@45..49 "\\end" CURLY_GROUP_WORD@49..60 L_CURLY@49..50 "{" - WORD@50..59 "enumerate" + KEY@50..59 + WORD@50..59 "enumerate" R_CURLY@59..60 "}" diff --git a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__svg_include_options.snap b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__svg_include_options.snap index 863f27cf56..3140282630 100644 --- a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__svg_include_options.snap +++ b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__svg_include_options.snap @@ -20,6 +20,7 @@ ROOT@0..34 R_BRACK@20..21 "]" CURLY_GROUP_WORD_LIST@21..34 L_CURLY@21..22 "{" - WORD@22..33 "foo/bar.svg" + KEY@22..33 + WORD@22..33 "foo/bar.svg" R_CURLY@33..34 "}" diff --git a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__svg_include_simple.snap b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__svg_include_simple.snap index 02db942d99..2cf133b4d0 100644 --- a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__svg_include_simple.snap +++ b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__svg_include_simple.snap @@ -9,6 +9,7 @@ ROOT@0..24 SVG_INCLUDE_NAME@0..11 "\\includesvg" CURLY_GROUP_WORD_LIST@11..24 L_CURLY@11..12 "{" - WORD@12..23 "foo/bar.svg" + KEY@12..23 + WORD@12..23 "foo/bar.svg" R_CURLY@23..24 "}" diff --git a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__theorem_definition_full.snap b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__theorem_definition_full.snap index d8fe3816ad..7f21c0ef52 100644 --- a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__theorem_definition_full.snap +++ b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__theorem_definition_full.snap @@ -9,11 +9,13 @@ ROOT@0..31 THEOREM_DEFINITION_NAME@0..11 "\\newtheorem" CURLY_GROUP_WORD@11..16 L_CURLY@11..12 "{" - WORD@12..15 "foo" + KEY@12..15 + WORD@12..15 "foo" R_CURLY@15..16 "}" BRACK_GROUP_WORD@16..21 L_BRACK@16..17 "[" - WORD@17..20 "bar" + KEY@17..20 + WORD@17..20 "bar" R_BRACK@20..21 "]" CURLY_GROUP@21..26 L_CURLY@21..22 "{" @@ -22,6 +24,7 @@ ROOT@0..31 R_CURLY@25..26 "}" BRACK_GROUP_WORD@26..31 L_BRACK@26..27 "[" - WORD@27..30 "baz" + KEY@27..30 + WORD@27..30 "baz" R_BRACK@30..31 "]" diff --git a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__theorem_definition_name_with_counter.snap b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__theorem_definition_name_with_counter.snap index 9e550b19a4..d7bb29bf58 100644 --- a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__theorem_definition_name_with_counter.snap +++ b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__theorem_definition_name_with_counter.snap @@ -9,11 +9,13 @@ ROOT@0..21 THEOREM_DEFINITION_NAME@0..11 "\\newtheorem" CURLY_GROUP_WORD@11..16 L_CURLY@11..12 "{" - WORD@12..15 "foo" + KEY@12..15 + WORD@12..15 "foo" R_CURLY@15..16 "}" BRACK_GROUP_WORD@16..21 L_BRACK@16..17 "[" - WORD@17..20 "bar" + KEY@17..20 + WORD@17..20 "bar" R_BRACK@20..21 "]" MISSING@21..21 "" diff --git a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__theorem_definition_name_with_description.snap b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__theorem_definition_name_with_description.snap index 356dc079f1..7c8b49efa1 100644 --- a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__theorem_definition_name_with_description.snap +++ b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__theorem_definition_name_with_description.snap @@ -9,7 +9,8 @@ ROOT@0..21 THEOREM_DEFINITION_NAME@0..11 "\\newtheorem" CURLY_GROUP_WORD@11..16 L_CURLY@11..12 "{" - WORD@12..15 "foo" + KEY@12..15 + WORD@12..15 "foo" R_CURLY@15..16 "}" CURLY_GROUP@16..21 L_CURLY@16..17 "{" diff --git a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__theorem_definition_name_with_description_and_counter.snap b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__theorem_definition_name_with_description_and_counter.snap index cc6e34d378..3322a9a116 100644 --- a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__theorem_definition_name_with_description_and_counter.snap +++ b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__theorem_definition_name_with_description_and_counter.snap @@ -9,11 +9,13 @@ ROOT@0..26 THEOREM_DEFINITION_NAME@0..11 "\\newtheorem" CURLY_GROUP_WORD@11..16 L_CURLY@11..12 "{" - WORD@12..15 "foo" + KEY@12..15 + WORD@12..15 "foo" R_CURLY@15..16 "}" BRACK_GROUP_WORD@16..21 L_BRACK@16..17 "[" - WORD@17..20 "bar" + KEY@17..20 + WORD@17..20 "bar" R_BRACK@20..21 "]" CURLY_GROUP@21..26 L_CURLY@21..22 "{" diff --git a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__theorem_definition_only_name.snap b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__theorem_definition_only_name.snap index 27a040b7ff..0ba62df76c 100644 --- a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__theorem_definition_only_name.snap +++ b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__theorem_definition_only_name.snap @@ -9,7 +9,8 @@ ROOT@0..16 THEOREM_DEFINITION_NAME@0..11 "\\newtheorem" CURLY_GROUP_WORD@11..16 L_CURLY@11..12 "{" - WORD@12..15 "foo" + KEY@12..15 + WORD@12..15 "foo" R_CURLY@15..16 "}" MISSING@16..16 "" diff --git a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__tikz_library_import_simple.snap b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__tikz_library_import_simple.snap index 4915306c55..4cd63e6728 100644 --- a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__tikz_library_import_simple.snap +++ b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__tikz_library_import_simple.snap @@ -9,6 +9,7 @@ ROOT@0..20 TIKZ_LIBRARY_IMPORT_NAME@0..15 "\\usetikzlibrary" CURLY_GROUP_WORD_LIST@15..20 L_CURLY@15..16 "{" - WORD@16..19 "foo" + KEY@16..19 + WORD@16..19 "foo" R_CURLY@19..20 "}" diff --git a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__verbatim_include_simple.snap b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__verbatim_include_simple.snap index 399e16d791..48d6b816f3 100644 --- a/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__verbatim_include_simple.snap +++ b/support/texlab/src/syntax/latex/snapshots/texlab__syntax__latex__parser__tests__verbatim_include_simple.snap @@ -9,6 +9,7 @@ ROOT@0..27 VERBATIM_INCLUDE_NAME@0..14 "\\verbatiminput" CURLY_GROUP_WORD_LIST@14..27 L_CURLY@14..15 "{" - WORD@15..26 "foo/bar.txt" + KEY@15..26 + WORD@15..26 "foo/bar.txt" R_CURLY@26..27 "}" diff --git a/support/texlab/tests/integration/completion.rs b/support/texlab/tests/integration/completion.rs index 33af77f003..488415e2d6 100644 --- a/support/texlab/tests/integration/completion.rs +++ b/support/texlab/tests/integration/completion.rs @@ -238,6 +238,40 @@ mod latex { Ok(()) } + #[test] + fn test_citation_multi_word() -> Result<()> { + let server = ServerTester::launch_new_instance()?; + server.initialize(ClientCapabilities::default(), None)?; + let tex_uri = server.open( + "main.tex", + r#" + \documentclass{article} + \bibliography{main} + \begin{document} + \cite{foo 2 + \end{document} + "#, + "latex", + false, + )?; + server.open( + "main.bib", + r#" + @article{foo 2019, + author = {Foo Bar}, + title = {Baz Qux}, + year = {2019}, + } + + @article{bar:2005,} + "#, + "bibtex", + false, + )?; + assert_json_snapshot!(complete_and_resolve(&server, tex_uri, 3, 6)?); + Ok(()) + } + #[test] fn test_citation_after() -> Result<()> { let server = ServerTester::launch_new_instance()?; diff --git a/support/texlab/tests/integration/snapshots/integration__completion__latex__citation_multi_word.snap b/support/texlab/tests/integration/snapshots/integration__completion__latex__citation_multi_word.snap new file mode 100644 index 0000000000..2ce23ae3fa --- /dev/null +++ b/support/texlab/tests/integration/snapshots/integration__completion__latex__citation_multi_word.snap @@ -0,0 +1,34 @@ +--- +source: tests/integration/completion.rs +expression: "complete_and_resolve(&server, tex_uri, 3, 6)?" + +--- +{ + "isIncomplete": false, + "items": [ + { + "label": "foo 2019", + "kind": 1, + "documentation": { + "kind": "markdown", + "value": "Bar, F. (2019). *Baz Qux*." + }, + "preselect": false, + "sortText": "00 foo 2019 @articlefoo 2019 author Foo Bar title Baz Qux year 2019", + "filterText": "foo 2019 @articlefoo 2019 author Foo Bar title Baz Qux year 2019", + "textEdit": { + "range": { + "start": { + "line": 3, + "character": 6 + }, + "end": { + "line": 3, + "character": 11 + } + }, + "newText": "foo 2019" + } + } + ] +} diff --git a/support/texlab/texlab.pdf b/support/texlab/texlab.pdf index bf485f9295..27f915c944 100644 Binary files a/support/texlab/texlab.pdf and b/support/texlab/texlab.pdf differ diff --git a/support/texlab/texlab.tex b/support/texlab/texlab.tex new file mode 100644 index 0000000000..7faff8b122 --- /dev/null +++ b/support/texlab/texlab.tex @@ -0,0 +1,78 @@ +\documentclass{article} +\usepackage[utf8]{inputenc} +\usepackage{hyperref} + +\date{\today} +\author{Eric Förster \and Patrick Förster} +\title{\TeX{}Lab} + +\begin{document} + +\maketitle{} + +\section{Introduction} + +TexLab is a cross-platform implementation of the +\href{https://microsoft.github.io/language-server-protocol/specifications/specification-current/}{Language Server Protocol} +for the \LaTeX{} typesetting system. +It aims to produce high quality code completion results. +The server may be used with any editor that implements the Language Server Protocol. +It is written in Rust, a blazingly fast systems programming language. + +\section{Features} + +The language server implements most of the Language Server Protocol specification. +In addition to that, it implements additional functionality like +building and forward search. + +\section{Availability} + +TexLab is available on \href{https://github.com/latex-lsp/texlab}{GitHub}, +various package managers and CTAN\@. +Pre-compiled binaries are available on the +\href{https://github.com/latex-lsp/texlab/releases}{GitHub Releases} page. +Some editor extensions are able to automatically download TexLab. + +\section{Installation} + +There are various ways to install TexLab: +\begin{itemize} + \item + TexLab is included in some package managers like \texttt{brew}, + \texttt{pacman} and \texttt{scoop}. + Please refer to the badges in the README to see if your package manager + includes TexLab. + \item + You can download a pre-compiled binary from our + \href{https://github.com/latex-lsp/texlab/releases}{GitHub Releases} page. + \item + Some extensions like the Visual Studio Code extension or + \texttt{coc-texlab} can automatically download the server for you. + \item + You can download the sources from either GitHub or CTAN + and compile the server with \texttt{cargo build --release}. + The \texttt{texlab} binary can be found inside \texttt{target/release}. +\end{itemize} + +\section{Usage} + +\subsection{Synopsis} + +\texttt{texlab [FLAGS] [OPTIONS]} + +\subsection{Flags} + +\begin{itemize} + \item \texttt{-h}, \texttt{--help} Prints help information + \item \texttt{-q}, \texttt{--quiet} No output printed to stderr + \item \texttt{-V}, \texttt{--version} Prints version information + \item \texttt{-v}, \texttt{--verbosity} Increase message verbosity (\texttt{-vvvv} for max verbosity) +\end{itemize} + +\subsection{Options} + +\begin{itemize} + \item \texttt{--log-file } WRite the logging output to \texttt{FILE} +\end{itemize} + +\end{document} \ No newline at end of file -- cgit v1.2.3