summaryrefslogtreecommitdiff
path: root/support/texlab
diff options
context:
space:
mode:
Diffstat (limited to 'support/texlab')
-rw-r--r--support/texlab/CHANGELOG.md16
-rw-r--r--support/texlab/Cargo.lock86
-rw-r--r--support/texlab/crates/base-db/Cargo.toml6
-rw-r--r--support/texlab/crates/base-db/src/diagnostics/bib.rs4
-rw-r--r--support/texlab/crates/base-db/src/graph.rs4
-rw-r--r--support/texlab/crates/base-db/src/semantics/tex.rs14
-rw-r--r--support/texlab/crates/base-db/src/workspace.rs3
-rw-r--r--support/texlab/crates/citeproc/Cargo.toml2
-rw-r--r--support/texlab/crates/commands/Cargo.toml7
-rw-r--r--support/texlab/crates/commands/src/find_envs.rs65
-rw-r--r--support/texlab/crates/commands/src/fwd_search.rs4
-rw-r--r--support/texlab/crates/commands/src/lib.rs2
-rw-r--r--support/texlab/crates/commands/src/placeholders.rs2
-rw-r--r--support/texlab/crates/commands/src/snapshots/commands__find_envs__tests__test.snap27
-rw-r--r--support/texlab/crates/distro/Cargo.toml2
-rw-r--r--support/texlab/crates/parser/Cargo.toml2
-rw-r--r--support/texlab/crates/parser/src/latex.rs55
-rw-r--r--support/texlab/crates/parser/src/latex/lexer/commands.rs11
-rw-r--r--support/texlab/crates/parser/src/latex/lexer/types.rs10
-rw-r--r--support/texlab/crates/parser/src/snapshots/parser__latex__tests__parse@structure__paragraphs.txt.snap67
-rw-r--r--support/texlab/crates/parser/src/snapshots/parser__latex__tests__parse@theorem_definition__theorem_definition_full.txt.snap2
-rw-r--r--support/texlab/crates/parser/src/snapshots/parser__latex__tests__parse@theorem_definition__theorem_definition_name_with_counter.txt.snap2
-rw-r--r--support/texlab/crates/parser/src/snapshots/parser__latex__tests__parse@theorem_definition__theorem_definition_name_with_description.txt.snap2
-rw-r--r--support/texlab/crates/parser/src/snapshots/parser__latex__tests__parse@theorem_definition__theorem_definition_name_with_description_and_counter.txt.snap2
-rw-r--r--support/texlab/crates/parser/src/snapshots/parser__latex__tests__parse@theorem_definition__theorem_definition_only_name.txt.snap2
-rw-r--r--support/texlab/crates/parser/src/snapshots/parser__latex__tests__parse@theorem_definition__theorem_definition_thmtools.txt.snap35
-rw-r--r--support/texlab/crates/parser/src/test_data/latex/structure/paragraphs.txt11
-rw-r--r--support/texlab/crates/parser/src/test_data/latex/theorem_definition/theorem_definition_thmtools.txt1
-rw-r--r--support/texlab/crates/symbols/Cargo.toml2
-rw-r--r--support/texlab/crates/symbols/src/document.rs1
-rw-r--r--support/texlab/crates/symbols/src/document/snapshots/symbols__document__tests__theorem_amsthm.snap (renamed from support/texlab/crates/symbols/src/document/snapshots/symbols__document__tests__theorem.snap)0
-rw-r--r--support/texlab/crates/symbols/src/document/snapshots/symbols__document__tests__theorem_thmtools.snap53
-rw-r--r--support/texlab/crates/symbols/src/document/tests.rs42
-rw-r--r--support/texlab/crates/symbols/src/types.rs2
-rw-r--r--support/texlab/crates/syntax/src/latex/cst.rs36
-rw-r--r--support/texlab/crates/syntax/src/latex/kind.rs3
-rw-r--r--support/texlab/crates/texlab/Cargo.toml20
-rw-r--r--support/texlab/crates/texlab/src/features/completion/builder.rs10
-rw-r--r--support/texlab/crates/texlab/src/features/completion/label.rs2
-rw-r--r--support/texlab/crates/texlab/src/features/completion/matcher.rs2
-rw-r--r--support/texlab/crates/texlab/src/features/formatting/latexindent.rs8
-rw-r--r--support/texlab/crates/texlab/src/features/inlay_hint.rs2
-rw-r--r--support/texlab/crates/texlab/src/features/inlay_hint/label.rs2
-rw-r--r--support/texlab/crates/texlab/src/server.rs42
-rw-r--r--support/texlab/crates/texlab/src/server/extensions.rs17
-rw-r--r--support/texlab/crates/texlab/src/util/cursor.rs15
-rw-r--r--support/texlab/crates/texlab/tests/lsp/text_document/snapshots/lsp__text_document__inlay_hint__label_definition.snap18
-rw-r--r--support/texlab/texlab.14
-rw-r--r--support/texlab/texlab.pdfbin26324 -> 26404 bytes
49 files changed, 556 insertions, 171 deletions
diff --git a/support/texlab/CHANGELOG.md b/support/texlab/CHANGELOG.md
index b165ced68e..cca502b4d3 100644
--- a/support/texlab/CHANGELOG.md
+++ b/support/texlab/CHANGELOG.md
@@ -5,6 +5,22 @@ 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).
+## [5.7.0] - 2023-06-07
+
+### Added
+
+- Add symbol support for `thmtools` package ([#894](https://github.com/latex-lsp/texlab/issues/894))
+- Add `texlab.findEnvironments` command to return the list of environments containing a position ([#892](https://github.com/latex-lsp/texlab/issues/892))
+
+### Changed
+
+- Show inlay hints for labels after the command instead of inside the argument ([#890](https://github.com/latex-lsp/texlab/issues/890))
+
+### Fixed
+
+- Prevent adding trailing newline after formatting with `latexmk` ([#895](https://github.com/latex-lsp/texlab/issues/895))
+- Improving `\paragraph` parsing
+
## [5.6.0] - 2023-05-20
### Added
diff --git a/support/texlab/Cargo.lock b/support/texlab/Cargo.lock
index aceaaf083a..b69b6e82e8 100644
--- a/support/texlab/Cargo.lock
+++ b/support/texlab/Cargo.lock
@@ -106,17 +106,6 @@ dependencies = [
]
[[package]]
-name = "atty"
-version = "0.2.14"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
-dependencies = [
- "hermit-abi 0.1.19",
- "libc",
- "winapi",
-]
-
-[[package]]
name = "autocfg"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -256,18 +245,6 @@ dependencies = [
[[package]]
name = "clap"
-version = "3.2.25"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4ea181bf566f71cb9a5d17a59e1871af638180a18fb0035c92ae62b705207123"
-dependencies = [
- "bitflags",
- "clap_lex 0.2.4",
- "indexmap",
- "textwrap",
-]
-
-[[package]]
-name = "clap"
version = "4.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "93aae7a4192245f70fe75dd9157fc7b4a5bf53e88d30bd4396f7d8f9284d5acc"
@@ -286,7 +263,7 @@ dependencies = [
"anstream",
"anstyle",
"bitflags",
- "clap_lex 0.5.0",
+ "clap_lex",
"strsim",
]
@@ -304,15 +281,6 @@ dependencies = [
[[package]]
name = "clap_lex"
-version = "0.2.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2850f2f5a82cbf437dd5af4d49848fbdfc27c157c3d010345776f952765261c5"
-dependencies = [
- "os_str_bytes",
-]
-
-[[package]]
-name = "clap_lex"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2da6da31387c7e4ef160ffab6d5e7f00c42626fe39aea70a7b0f1773f7dd6c1b"
@@ -331,12 +299,15 @@ dependencies = [
"base-db",
"bstr",
"crossbeam-channel",
+ "distro",
+ "insta",
"itertools",
"libc",
"log",
"rowan",
"rustc-hash",
"syntax",
+ "test-utils",
"thiserror",
"url",
]
@@ -379,19 +350,19 @@ dependencies = [
[[package]]
name = "criterion"
-version = "0.4.0"
+version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e7c76e09c1aae2bc52b3d2f29e13c6572553b30c4aa1b8a49fd70de6412654cb"
+checksum = "f2b12d017a929603d80db1831cd3a24082f8137ce19c69e6447f54f5fc8d692f"
dependencies = [
"anes",
- "atty",
"cast",
"ciborium",
- "clap 3.2.25",
+ "clap",
"criterion-plot",
+ "is-terminal",
"itertools",
- "lazy_static",
"num-traits",
+ "once_cell",
"oorandom",
"plotters",
"rayon",
@@ -683,15 +654,6 @@ checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8"
[[package]]
name = "hermit-abi"
-version = "0.1.19"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33"
-dependencies = [
- "libc",
-]
-
-[[package]]
-name = "hermit-abi"
version = "0.2.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ee512640fe35acbfb4bb779db6f0d80704c2cacfa2e39b601ef3e3f47d1ae4c7"
@@ -735,16 +697,6 @@ dependencies = [
]
[[package]]
-name = "indexmap"
-version = "1.9.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99"
-dependencies = [
- "autocfg",
- "hashbrown",
-]
-
-[[package]]
name = "inotify"
version = "0.9.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1012,9 +964,9 @@ dependencies = [
[[package]]
name = "notify"
-version = "5.2.0"
+version = "6.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "729f63e1ca555a43fe3efa4f3efdf4801c479da85b432242a7b726f353c88486"
+checksum = "4d9ba6c734de18ca27c8cef5cd7058aa4ac9f63596131e4c7e41e579319032a2"
dependencies = [
"bitflags",
"crossbeam-channel",
@@ -1076,12 +1028,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d"
[[package]]
-name = "os_str_bytes"
-version = "6.5.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ceedf44fb00f2d1984b0bc98102627ce622e083e49a5bacdb3e514fa4238e267"
-
-[[package]]
name = "parking_lot"
version = "0.12.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1566,13 +1512,13 @@ dependencies = [
[[package]]
name = "texlab"
-version = "5.6.0"
+version = "5.7.0"
dependencies = [
"anyhow",
"assert_unordered",
"base-db",
"citeproc",
- "clap 4.3.0",
+ "clap",
"commands",
"criterion",
"crossbeam-channel",
@@ -1614,12 +1560,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "288cb548dbe72b652243ea797201f3d481a0609a967980fcc5b2315ea811560a"
[[package]]
-name = "textwrap"
-version = "0.16.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "222a222a5bfe1bba4a77b45ec488a741b3cb8872e5e499451fd7d0129c9c7c3d"
-
-[[package]]
name = "thiserror"
version = "1.0.40"
source = "registry+https://github.com/rust-lang/crates.io-index"
diff --git a/support/texlab/crates/base-db/Cargo.toml b/support/texlab/crates/base-db/Cargo.toml
index c968cefac9..2b44acaf3c 100644
--- a/support/texlab/crates/base-db/Cargo.toml
+++ b/support/texlab/crates/base-db/Cargo.toml
@@ -7,15 +7,15 @@ edition.workspace = true
rust-version.workspace = true
[dependencies]
-dirs = "5.0.0"
+dirs = "5.0.1"
distro = { path = "../distro" }
itertools = "0.10.5"
log = "0.4.17"
-notify = "5.1.0"
+notify = "6.0.0"
once_cell = "1.17.1"
parser = { path = "../parser" }
percent-encoding = "2.2.0"
-regex = "1.7.3"
+regex = "1.8.1"
rowan = "0.15.11"
rustc-hash = "1.1.0"
syntax = { path = "../syntax" }
diff --git a/support/texlab/crates/base-db/src/diagnostics/bib.rs b/support/texlab/crates/base-db/src/diagnostics/bib.rs
index f931a43c51..67fcf412ad 100644
--- a/support/texlab/crates/base-db/src/diagnostics/bib.rs
+++ b/support/texlab/crates/base-db/src/diagnostics/bib.rs
@@ -41,8 +41,6 @@ fn analyze_entry(document: &mut Document, entry: bibtex::Entry) {
range: TextRange::empty(entry.syntax().text_range().end()),
code: ErrorCode::ExpectingRCurly,
});
-
- return;
}
}
@@ -63,7 +61,5 @@ fn analyze_field(document: &mut Document, field: bibtex::Field) {
range: field.name_token().unwrap().text_range(),
code,
});
-
- return;
}
}
diff --git a/support/texlab/crates/base-db/src/graph.rs b/support/texlab/crates/base-db/src/graph.rs
index b16245e011..5e727d2bd2 100644
--- a/support/texlab/crates/base-db/src/graph.rs
+++ b/support/texlab/crates/base-db/src/graph.rs
@@ -108,7 +108,7 @@ impl<'a> Graph<'a> {
let new_base_dir = link
.base_dir
.as_deref()
- .and_then(|path| base_dir.join(&path).ok())
+ .and_then(|path| base_dir.join(path).ok())
.unwrap_or_else(|| base_dir.clone());
let weight = Some(EdgeWeight {
@@ -148,7 +148,7 @@ impl<'a> Graph<'a> {
path.set_extension(extension);
let Some(target_uri) = path.file_name()
.and_then(OsStr::to_str)
- .and_then(|name| self.workspace.output_dir(base_dir).join(&name).ok()) else { return };
+ .and_then(|name| self.workspace.output_dir(base_dir).join(name).ok()) else { return };
match self.workspace.lookup(&target_uri) {
Some(target) => {
diff --git a/support/texlab/crates/base-db/src/semantics/tex.rs b/support/texlab/crates/base-db/src/semantics/tex.rs
index 46c805ba8a..1445ae12e7 100644
--- a/support/texlab/crates/base-db/src/semantics/tex.rs
+++ b/support/texlab/crates/base-db/src/semantics/tex.rs
@@ -105,6 +105,7 @@ impl Semantics {
fn process_label_definition(&mut self, label: latex::LabelDefinition) {
let Some(name) = label.name().and_then(|group| group.key()) else { return };
+ let full_range = latex::small_range(&label);
let mut objects = Vec::new();
for node in label.syntax().ancestors() {
if let Some(section) = latex::Section::cast(node.clone()) {
@@ -169,27 +170,32 @@ impl Semantics {
kind: LabelKind::Definition,
name: Span::from(&name),
targets: objects,
+ full_range,
});
}
fn process_label_reference(&mut self, label: latex::LabelReference) {
let Some(name_list) = label.name_list() else { return };
+ let full_range = latex::small_range(&label);
for name in name_list.keys() {
self.labels.push(Label {
kind: LabelKind::Reference,
name: Span::from(&name),
targets: Vec::new(),
+ full_range,
});
}
}
fn process_label_reference_range(&mut self, label: latex::LabelReferenceRange) {
+ let full_range = latex::small_range(&label);
if let Some(from) = label.from().and_then(|group| group.key()) {
self.labels.push(Label {
kind: LabelKind::ReferenceRange,
name: Span::from(&from),
targets: Vec::new(),
+ full_range,
});
}
@@ -198,6 +204,7 @@ impl Semantics {
kind: LabelKind::ReferenceRange,
name: Span::from(&to),
targets: Vec::new(),
+ full_range,
});
}
}
@@ -216,13 +223,11 @@ impl Semantics {
fn process_theorem_definition(&mut self, theorem_def: latex::TheoremDefinition) {
let Some(name) = theorem_def.name().and_then(|name| name.key()) else { return };
- let Some(description) = theorem_def
- .heading()
- .and_then(|group| group.content_text()) else { return };
+ let Some(heading) = theorem_def.heading() else { return };
self.theorem_definitions.push(TheoremDefinition {
name: Span::from(&name),
- heading: description,
+ heading,
});
}
}
@@ -265,6 +270,7 @@ pub struct Label {
pub kind: LabelKind,
pub name: Span,
pub targets: Vec<LabelTarget>,
+ pub full_range: TextRange,
}
#[derive(Debug, Clone)]
diff --git a/support/texlab/crates/base-db/src/workspace.rs b/support/texlab/crates/base-db/src/workspace.rs
index 581d93cfc3..58c7567f9d 100644
--- a/support/texlab/crates/base-db/src/workspace.rs
+++ b/support/texlab/crates/base-db/src/workspace.rs
@@ -75,7 +75,8 @@ impl Workspace {
Cow::Owned(text) => text,
};
- Ok(self.open(uri, text, language, owner, LineCol { line: 0, col: 0 }))
+ self.open(uri, text, language, owner, LineCol { line: 0, col: 0 });
+ Ok(())
}
pub fn edit(&mut self, uri: &Url, delete: TextRange, insert: &str) -> Option<()> {
diff --git a/support/texlab/crates/citeproc/Cargo.toml b/support/texlab/crates/citeproc/Cargo.toml
index 353292c484..fb230323b0 100644
--- a/support/texlab/crates/citeproc/Cargo.toml
+++ b/support/texlab/crates/citeproc/Cargo.toml
@@ -8,7 +8,7 @@ rust-version.workspace = true
[dependencies]
chrono = { version = "0.4.24", default-features = false, features = ["std"] }
-human_name = "2.0.1"
+human_name = "2.0.2"
isocountry = "0.3.2"
itertools = "0.10.5"
rowan = "0.15.11"
diff --git a/support/texlab/crates/commands/Cargo.toml b/support/texlab/crates/commands/Cargo.toml
index 68d034675e..1f3a1bddd9 100644
--- a/support/texlab/crates/commands/Cargo.toml
+++ b/support/texlab/crates/commands/Cargo.toml
@@ -7,7 +7,7 @@ edition.workspace = true
rust-version.workspace = true
[dependencies]
-anyhow = "1.0.70"
+anyhow = "1.0.71"
base-db = { path = "../base-db" }
bstr = "1.4.0"
crossbeam-channel = "0.5.8"
@@ -20,5 +20,10 @@ syntax = { path = "../syntax" }
thiserror = "1.0.40"
url = "2.3.1"
+[dev-dependencies]
+distro = { path = "../distro" }
+insta = { version = "1.29.0", features = ["json"] }
+test-utils = { path = "../test-utils" }
+
[lib]
doctest = false
diff --git a/support/texlab/crates/commands/src/find_envs.rs b/support/texlab/crates/commands/src/find_envs.rs
new file mode 100644
index 0000000000..20b11c9e37
--- /dev/null
+++ b/support/texlab/crates/commands/src/find_envs.rs
@@ -0,0 +1,65 @@
+use base_db::{semantics::Span, Document, DocumentData};
+use rowan::{ast::AstNode, TextRange, TextSize};
+use syntax::latex;
+
+#[derive(Debug, PartialEq, Eq, Clone)]
+pub struct EnvironmentMatch {
+ pub name: Span,
+ pub full_range: TextRange,
+}
+
+pub fn find_environments(document: &Document, offset: TextSize) -> Vec<EnvironmentMatch> {
+ let DocumentData::Tex(data) = &document.data else { return Vec::new() };
+
+ let root = latex::SyntaxNode::new_root(data.green.clone());
+
+ let Some(token) = root.token_at_offset(offset).right_biased() else { return Vec::new() };
+
+ let mut results = Vec::new();
+ for environment in token
+ .parent_ancestors()
+ .filter_map(latex::Environment::cast)
+ {
+ let Some(name) = environment
+ .begin()
+ .and_then(|begin| begin.name())
+ .and_then(|group| group.key())
+ .map(|name| Span::from(&name)) else { continue };
+
+ let full_range = latex::small_range(&environment);
+ results.push(EnvironmentMatch { name, full_range });
+ }
+
+ results.reverse();
+ results
+}
+
+#[cfg(test)]
+mod tests {
+ use insta::assert_debug_snapshot;
+ use test_utils::fixture::Fixture;
+
+ use crate::find_environments;
+
+ #[test]
+ fn test() {
+ let fixture = Fixture::parse(
+ r#"
+%! main.tex
+\begin{a}
+ \begin{b}
+ \begin{c}
+ |
+ \end{c}
+ \end{b}
+ \begin{d}
+ \end{d}
+\end{a}"#,
+ );
+
+ let workspace = fixture.workspace;
+ let document = workspace.iter().next().unwrap();
+ let results = find_environments(&document, fixture.documents[0].cursor.unwrap());
+ assert_debug_snapshot!(results);
+ }
+}
diff --git a/support/texlab/crates/commands/src/fwd_search.rs b/support/texlab/crates/commands/src/fwd_search.rs
index fc0a130f86..55c2df59a0 100644
--- a/support/texlab/crates/commands/src/fwd_search.rs
+++ b/support/texlab/crates/commands/src/fwd_search.rs
@@ -75,12 +75,12 @@ impl ForwardSearch {
};
if !pdf_path.exists() {
- return Err(ForwardSearchError::PdfNotFound(pdf_path.clone()));
+ return Err(ForwardSearchError::PdfNotFound(pdf_path));
}
let tex_path = tex_path.to_string_lossy().into_owned();
let pdf_path = pdf_path.to_string_lossy().into_owned();
- let line = line.unwrap_or_else(|| child.cursor.line);
+ let line = line.unwrap_or(child.cursor.line);
let line = (line + 1).to_string();
let program = config.program.clone();
diff --git a/support/texlab/crates/commands/src/lib.rs b/support/texlab/crates/commands/src/lib.rs
index bcf4c8538f..8023c8d66c 100644
--- a/support/texlab/crates/commands/src/lib.rs
+++ b/support/texlab/crates/commands/src/lib.rs
@@ -2,6 +2,7 @@ mod build;
mod change_env;
mod clean;
mod dep_graph;
+mod find_envs;
mod fwd_search;
mod placeholders;
@@ -10,5 +11,6 @@ pub use self::{
change_env::{change_environment, ChangeEnvironmentResult},
clean::{CleanCommand, CleanTarget},
dep_graph::show_dependency_graph,
+ find_envs::find_environments,
fwd_search::{ForwardSearch, ForwardSearchError},
};
diff --git a/support/texlab/crates/commands/src/placeholders.rs b/support/texlab/crates/commands/src/placeholders.rs
index 913af33edf..9994420f5d 100644
--- a/support/texlab/crates/commands/src/placeholders.rs
+++ b/support/texlab/crates/commands/src/placeholders.rs
@@ -17,7 +17,7 @@ pub fn replace_placeholders(args: &[String], pairs: &[(char, &str)]) -> Vec<Stri
if ch == '%' {
match chars.next() {
Some(key) => match map.get(&key) {
- Some(value) => output.push_str(&value),
+ Some(value) => output.push_str(value),
None => output.push(key),
},
None => output.push('%'),
diff --git a/support/texlab/crates/commands/src/snapshots/commands__find_envs__tests__test.snap b/support/texlab/crates/commands/src/snapshots/commands__find_envs__tests__test.snap
new file mode 100644
index 0000000000..fa532f125a
--- /dev/null
+++ b/support/texlab/crates/commands/src/snapshots/commands__find_envs__tests__test.snap
@@ -0,0 +1,27 @@
+---
+source: crates/commands/src/find_envs.rs
+expression: results
+---
+[
+ EnvironmentMatch {
+ name: Span(
+ "a",
+ 7..8,
+ ),
+ full_range: 0..87,
+ },
+ EnvironmentMatch {
+ name: Span(
+ "b",
+ 19..20,
+ ),
+ full_range: 12..57,
+ },
+ EnvironmentMatch {
+ name: Span(
+ "c",
+ 33..34,
+ ),
+ full_range: 26..47,
+ },
+]
diff --git a/support/texlab/crates/distro/Cargo.toml b/support/texlab/crates/distro/Cargo.toml
index b450aa2631..d7c336a041 100644
--- a/support/texlab/crates/distro/Cargo.toml
+++ b/support/texlab/crates/distro/Cargo.toml
@@ -7,7 +7,7 @@ edition.workspace = true
rust-version.workspace = true
[dependencies]
-anyhow = "1.0.70"
+anyhow = "1.0.71"
rustc-hash = "1.1.0"
[lib]
diff --git a/support/texlab/crates/parser/Cargo.toml b/support/texlab/crates/parser/Cargo.toml
index 8e8b88841f..1b57d5aec1 100644
--- a/support/texlab/crates/parser/Cargo.toml
+++ b/support/texlab/crates/parser/Cargo.toml
@@ -9,7 +9,7 @@ rust-version.workspace = true
[dependencies]
logos = "0.13.0"
once_cell = "1.17.1"
-regex = "1.7.3"
+regex = "1.8.1"
rowan = "0.15.11"
rustc-hash = "1.1.0"
syntax = { path = "../syntax" }
diff --git a/support/texlab/crates/parser/src/latex.rs b/support/texlab/crates/parser/src/latex.rs
index c42031dcf1..63c160d4e2 100644
--- a/support/texlab/crates/parser/src/latex.rs
+++ b/support/texlab/crates/parser/src/latex.rs
@@ -6,7 +6,7 @@ use syntax::latex::SyntaxKind::{self, *};
use crate::SyntaxConfig;
use self::lexer::{
- types::{CommandName, SectionLevel, Token},
+ types::{CommandName, ParagraphLevel, SectionLevel, Token},
Lexer,
};
@@ -114,6 +114,7 @@ impl<'a> Parser<'a> {
CommandName::BeginEquation => self.equation(),
CommandName::EndEquation => self.generic_command(),
CommandName::Section(level) => self.section(level),
+ CommandName::Paragraph(level) => self.paragraph(level),
CommandName::EnumItem => self.enum_item(),
CommandName::Caption => self.caption(),
CommandName::Citation => self.citation(),
@@ -138,7 +139,8 @@ impl<'a> Parser<'a> {
CommandName::AcronymDefinition => self.acronym_definition(),
CommandName::AcronymDeclaration => self.acronym_declaration(),
CommandName::AcronymReference => self.acronym_reference(),
- CommandName::TheoremDefinition => self.theorem_definition(),
+ CommandName::TheoremDefinitionAmsThm => self.theorem_definition_amsthm(),
+ CommandName::TheoremDefinitionThmTools => self.theorem_definition_thmtools(),
CommandName::ColorReference => self.color_reference(),
CommandName::ColorDefinition => self.color_definition(),
CommandName::ColorSetDefinition => self.color_set_definition(),
@@ -559,8 +561,6 @@ impl<'a> Parser<'a> {
SectionLevel::Section => SECTION,
SectionLevel::Subsection => SUBSECTION,
SectionLevel::Subsubsection => SUBSUBSECTION,
- SectionLevel::Paragraph => PARAGRAPH,
- SectionLevel::Subparagraph => SUBPARAGRAPH,
};
self.builder.start_node(node_kind.into());
@@ -583,6 +583,33 @@ impl<'a> Parser<'a> {
self.builder.finish_node();
}
+ fn paragraph(&mut self, level: ParagraphLevel) {
+ let node_kind = match level {
+ ParagraphLevel::Paragraph => PARAGRAPH,
+ ParagraphLevel::Subparagraph => SUBPARAGRAPH,
+ };
+
+ self.builder.start_node(node_kind.into());
+ self.eat();
+ self.trivia();
+
+ if self.peek() == Some(Token::LCurly) {
+ self.curly_group();
+ }
+
+ while let Some(kind) = self.peek() {
+ match kind {
+ Token::RCurly => break,
+ Token::CommandName(CommandName::EndEnvironment) => break,
+ Token::CommandName(CommandName::Section(_)) => break,
+ Token::CommandName(CommandName::Paragraph(nested)) if nested <= level => break,
+ _ => self.content(ParserContext::default()),
+ }
+ }
+
+ self.builder.finish_node();
+ }
+
fn enum_item(&mut self) {
self.builder.start_node(ENUM_ITEM.into());
self.eat();
@@ -978,8 +1005,8 @@ impl<'a> Parser<'a> {
self.builder.finish_node();
}
- fn theorem_definition(&mut self) {
- self.builder.start_node(THEOREM_DEFINITION.into());
+ fn theorem_definition_amsthm(&mut self) {
+ self.builder.start_node(THEOREM_DEFINITION_AMSTHM.into());
self.eat();
self.trivia();
@@ -1002,6 +1029,22 @@ impl<'a> Parser<'a> {
self.builder.finish_node();
}
+ fn theorem_definition_thmtools(&mut self) {
+ self.builder.start_node(THEOREM_DEFINITION_THMTOOLS.into());
+ self.eat();
+ self.trivia();
+
+ if self.lexer.peek() == Some(Token::LBrack) {
+ self.brack_group_key_value();
+ }
+
+ if self.lexer.peek() == Some(Token::LCurly) {
+ self.curly_group_word();
+ }
+
+ self.builder.finish_node();
+ }
+
fn color_reference(&mut self) {
self.builder.start_node(COLOR_REFERENCE.into());
self.eat();
diff --git a/support/texlab/crates/parser/src/latex/lexer/commands.rs b/support/texlab/crates/parser/src/latex/lexer/commands.rs
index c5fe48e0c9..b6e1d11737 100644
--- a/support/texlab/crates/parser/src/latex/lexer/commands.rs
+++ b/support/texlab/crates/parser/src/latex/lexer/commands.rs
@@ -1,6 +1,6 @@
use crate::SyntaxConfig;
-use super::types::{CommandName, SectionLevel};
+use super::types::{CommandName, ParagraphLevel, SectionLevel};
pub fn classify(name: &str, config: &SyntaxConfig) -> CommandName {
match name {
@@ -13,8 +13,8 @@ pub fn classify(name: &str, config: &SyntaxConfig) -> CommandName {
"section" | "section*" => CommandName::Section(SectionLevel::Section),
"subsection" | "subsection*" => CommandName::Section(SectionLevel::Subsection),
"subsubsection" | "subsubsection*" => CommandName::Section(SectionLevel::Subsubsection),
- "paragraph" | "paragraph*" => CommandName::Section(SectionLevel::Paragraph),
- "subparagraph" | "subparagraph*" => CommandName::Section(SectionLevel::Subparagraph),
+ "paragraph" | "paragraph*" => CommandName::Paragraph(ParagraphLevel::Paragraph),
+ "subparagraph" | "subparagraph*" => CommandName::Paragraph(ParagraphLevel::Subparagraph),
"item" => CommandName::EnumItem,
"caption" => CommandName::Caption,
"usepackage" | "RequirePackage" => CommandName::PackageInclude,
@@ -67,9 +67,8 @@ pub fn classify(name: &str, config: &SyntaxConfig) -> CommandName {
| "Glsentrylong" | "glsentrylongpl" | "Glsentrylongpl" | "glsentryshort"
| "Glsentryshort" | "glsentryshortpl" | "Glsentryshortpl" | "glsentryfullpl"
| "Glsentryfullpl" => CommandName::AcronymReference,
- "newtheorem" | "newtheorem*" | "declaretheorem" | "declaretheorem*" => {
- CommandName::TheoremDefinition
- }
+ "newtheorem" | "newtheorem*" => CommandName::TheoremDefinitionAmsThm,
+ "declaretheorem" | "declaretheorem*" => CommandName::TheoremDefinitionThmTools,
"color" | "colorbox" | "textcolor" | "pagecolor" => CommandName::ColorReference,
"definecolor" => CommandName::ColorDefinition,
"definecolorset" => CommandName::ColorSetDefinition,
diff --git a/support/texlab/crates/parser/src/latex/lexer/types.rs b/support/texlab/crates/parser/src/latex/lexer/types.rs
index eea6ea3b44..607138a448 100644
--- a/support/texlab/crates/parser/src/latex/lexer/types.rs
+++ b/support/texlab/crates/parser/src/latex/lexer/types.rs
@@ -58,7 +58,7 @@ fn lex_command_name(lexer: &mut logos::Lexer<Token>) -> CommandName {
return CommandName::Generic;
}
- while let Some(c) = chars.next() {
+ for c in chars {
match c {
'*' => {
lexer.bump(c.len_utf8());
@@ -87,6 +87,7 @@ pub enum CommandName {
BeginEquation,
EndEquation,
Section(SectionLevel),
+ Paragraph(ParagraphLevel),
EnumItem,
Caption,
Citation,
@@ -111,7 +112,8 @@ pub enum CommandName {
AcronymDefinition,
AcronymDeclaration,
AcronymReference,
- TheoremDefinition,
+ TheoremDefinitionAmsThm,
+ TheoremDefinitionThmTools,
ColorReference,
ColorDefinition,
ColorSetDefinition,
@@ -130,6 +132,10 @@ pub enum SectionLevel {
Section,
Subsection,
Subsubsection,
+}
+
+#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Copy, Hash)]
+pub enum ParagraphLevel {
Paragraph,
Subparagraph,
}
diff --git a/support/texlab/crates/parser/src/snapshots/parser__latex__tests__parse@structure__paragraphs.txt.snap b/support/texlab/crates/parser/src/snapshots/parser__latex__tests__parse@structure__paragraphs.txt.snap
new file mode 100644
index 0000000000..7c3e7fae57
--- /dev/null
+++ b/support/texlab/crates/parser/src/snapshots/parser__latex__tests__parse@structure__paragraphs.txt.snap
@@ -0,0 +1,67 @@
+---
+source: crates/parser/src/latex.rs
+expression: root
+input_file: crates/parser/src/test_data/latex/structure/paragraphs.txt
+---
+ROOT@0..134
+ PREAMBLE@0..134
+ SECTION@0..105
+ COMMAND_NAME@0..8 "\\section"
+ CURLY_GROUP@8..20
+ L_CURLY@8..9 "{"
+ TEXT@9..18
+ WORD@9..16 "Section"
+ WHITESPACE@16..17 " "
+ WORD@17..18 "1"
+ R_CURLY@18..19 "}"
+ LINE_BREAK@19..20 "\n"
+ TEXT@20..31
+ WORD@20..27 "Section"
+ WHITESPACE@27..28 " "
+ WORD@28..29 "1"
+ LINE_BREAK@29..31 "\n\n"
+ PARAGRAPH@31..68
+ COMMAND_NAME@31..41 "\\paragraph"
+ CURLY_GROUP@41..55
+ L_CURLY@41..42 "{"
+ TEXT@42..53
+ WORD@42..51 "Paragraph"
+ WHITESPACE@51..52 " "
+ WORD@52..53 "1"
+ R_CURLY@53..54 "}"
+ LINE_BREAK@54..55 "\n"
+ TEXT@55..68
+ WORD@55..64 "Paragraph"
+ WHITESPACE@64..65 " "
+ WORD@65..66 "1"
+ LINE_BREAK@66..68 "\n\n"
+ PARAGRAPH@68..105
+ COMMAND_NAME@68..78 "\\paragraph"
+ CURLY_GROUP@78..92
+ L_CURLY@78..79 "{"
+ TEXT@79..90
+ WORD@79..88 "Paragraph"
+ WHITESPACE@88..89 " "
+ WORD@89..90 "2"
+ R_CURLY@90..91 "}"
+ LINE_BREAK@91..92 "\n"
+ TEXT@92..105
+ WORD@92..101 "Paragraph"
+ WHITESPACE@101..102 " "
+ WORD@102..103 "2"
+ LINE_BREAK@103..105 "\n\n"
+ SECTION@105..134
+ COMMAND_NAME@105..113 "\\section"
+ CURLY_GROUP@113..125
+ L_CURLY@113..114 "{"
+ TEXT@114..123
+ WORD@114..121 "Section"
+ WHITESPACE@121..122 " "
+ WORD@122..123 "2"
+ R_CURLY@123..124 "}"
+ LINE_BREAK@124..125 "\n"
+ TEXT@125..134
+ WORD@125..132 "Section"
+ WHITESPACE@132..133 " "
+ WORD@133..134 "2"
+
diff --git a/support/texlab/crates/parser/src/snapshots/parser__latex__tests__parse@theorem_definition__theorem_definition_full.txt.snap b/support/texlab/crates/parser/src/snapshots/parser__latex__tests__parse@theorem_definition__theorem_definition_full.txt.snap
index c21f26976e..ce42bde1d3 100644
--- a/support/texlab/crates/parser/src/snapshots/parser__latex__tests__parse@theorem_definition__theorem_definition_full.txt.snap
+++ b/support/texlab/crates/parser/src/snapshots/parser__latex__tests__parse@theorem_definition__theorem_definition_full.txt.snap
@@ -5,7 +5,7 @@ input_file: crates/parser/src/test_data/latex/theorem_definition/theorem_definit
---
ROOT@0..31
PREAMBLE@0..31
- THEOREM_DEFINITION@0..31
+ THEOREM_DEFINITION_AMSTHM@0..31
COMMAND_NAME@0..11 "\\newtheorem"
CURLY_GROUP_WORD@11..16
L_CURLY@11..12 "{"
diff --git a/support/texlab/crates/parser/src/snapshots/parser__latex__tests__parse@theorem_definition__theorem_definition_name_with_counter.txt.snap b/support/texlab/crates/parser/src/snapshots/parser__latex__tests__parse@theorem_definition__theorem_definition_name_with_counter.txt.snap
index d4c5d787b5..c1e7ad5387 100644
--- a/support/texlab/crates/parser/src/snapshots/parser__latex__tests__parse@theorem_definition__theorem_definition_name_with_counter.txt.snap
+++ b/support/texlab/crates/parser/src/snapshots/parser__latex__tests__parse@theorem_definition__theorem_definition_name_with_counter.txt.snap
@@ -5,7 +5,7 @@ input_file: crates/parser/src/test_data/latex/theorem_definition/theorem_definit
---
ROOT@0..21
PREAMBLE@0..21
- THEOREM_DEFINITION@0..21
+ THEOREM_DEFINITION_AMSTHM@0..21
COMMAND_NAME@0..11 "\\newtheorem"
CURLY_GROUP_WORD@11..16
L_CURLY@11..12 "{"
diff --git a/support/texlab/crates/parser/src/snapshots/parser__latex__tests__parse@theorem_definition__theorem_definition_name_with_description.txt.snap b/support/texlab/crates/parser/src/snapshots/parser__latex__tests__parse@theorem_definition__theorem_definition_name_with_description.txt.snap
index b269ac10d0..13c043c94f 100644
--- a/support/texlab/crates/parser/src/snapshots/parser__latex__tests__parse@theorem_definition__theorem_definition_name_with_description.txt.snap
+++ b/support/texlab/crates/parser/src/snapshots/parser__latex__tests__parse@theorem_definition__theorem_definition_name_with_description.txt.snap
@@ -5,7 +5,7 @@ input_file: crates/parser/src/test_data/latex/theorem_definition/theorem_definit
---
ROOT@0..21
PREAMBLE@0..21
- THEOREM_DEFINITION@0..21
+ THEOREM_DEFINITION_AMSTHM@0..21
COMMAND_NAME@0..11 "\\newtheorem"
CURLY_GROUP_WORD@11..16
L_CURLY@11..12 "{"
diff --git a/support/texlab/crates/parser/src/snapshots/parser__latex__tests__parse@theorem_definition__theorem_definition_name_with_description_and_counter.txt.snap b/support/texlab/crates/parser/src/snapshots/parser__latex__tests__parse@theorem_definition__theorem_definition_name_with_description_and_counter.txt.snap
index 230f1fac29..57f4f7ce1b 100644
--- a/support/texlab/crates/parser/src/snapshots/parser__latex__tests__parse@theorem_definition__theorem_definition_name_with_description_and_counter.txt.snap
+++ b/support/texlab/crates/parser/src/snapshots/parser__latex__tests__parse@theorem_definition__theorem_definition_name_with_description_and_counter.txt.snap
@@ -5,7 +5,7 @@ input_file: crates/parser/src/test_data/latex/theorem_definition/theorem_definit
---
ROOT@0..26
PREAMBLE@0..26
- THEOREM_DEFINITION@0..26
+ THEOREM_DEFINITION_AMSTHM@0..26
COMMAND_NAME@0..11 "\\newtheorem"
CURLY_GROUP_WORD@11..16
L_CURLY@11..12 "{"
diff --git a/support/texlab/crates/parser/src/snapshots/parser__latex__tests__parse@theorem_definition__theorem_definition_only_name.txt.snap b/support/texlab/crates/parser/src/snapshots/parser__latex__tests__parse@theorem_definition__theorem_definition_only_name.txt.snap
index b01de34857..22674fbbba 100644
--- a/support/texlab/crates/parser/src/snapshots/parser__latex__tests__parse@theorem_definition__theorem_definition_only_name.txt.snap
+++ b/support/texlab/crates/parser/src/snapshots/parser__latex__tests__parse@theorem_definition__theorem_definition_only_name.txt.snap
@@ -5,7 +5,7 @@ input_file: crates/parser/src/test_data/latex/theorem_definition/theorem_definit
---
ROOT@0..16
PREAMBLE@0..16
- THEOREM_DEFINITION@0..16
+ THEOREM_DEFINITION_AMSTHM@0..16
COMMAND_NAME@0..11 "\\newtheorem"
CURLY_GROUP_WORD@11..16
L_CURLY@11..12 "{"
diff --git a/support/texlab/crates/parser/src/snapshots/parser__latex__tests__parse@theorem_definition__theorem_definition_thmtools.txt.snap b/support/texlab/crates/parser/src/snapshots/parser__latex__tests__parse@theorem_definition__theorem_definition_thmtools.txt.snap
new file mode 100644
index 0000000000..8b00bb4b59
--- /dev/null
+++ b/support/texlab/crates/parser/src/snapshots/parser__latex__tests__parse@theorem_definition__theorem_definition_thmtools.txt.snap
@@ -0,0 +1,35 @@
+---
+source: crates/parser/src/latex.rs
+expression: root
+input_file: crates/parser/src/test_data/latex/theorem_definition/theorem_definition_thmtools.txt
+---
+ROOT@0..41
+ PREAMBLE@0..41
+ THEOREM_DEFINITION_THMTOOLS@0..41
+ COMMAND_NAME@0..15 "\\declaretheorem"
+ BRACK_GROUP_KEY_VALUE@15..36
+ L_BRACK@15..16 "["
+ KEY_VALUE_BODY@16..35
+ KEY_VALUE_PAIR@16..25
+ KEY@16..21
+ WORD@16..21 "style"
+ EQUALITY_SIGN@21..22 "="
+ VALUE@22..25
+ TEXT@22..25
+ WORD@22..25 "foo"
+ COMMA@25..26 ","
+ WHITESPACE@26..27 " "
+ KEY_VALUE_PAIR@27..35
+ KEY@27..31
+ WORD@27..31 "name"
+ EQUALITY_SIGN@31..32 "="
+ VALUE@32..35
+ TEXT@32..35
+ WORD@32..35 "bar"
+ R_BRACK@35..36 "]"
+ CURLY_GROUP_WORD@36..41
+ L_CURLY@36..37 "{"
+ KEY@37..40
+ WORD@37..40 "baz"
+ R_CURLY@40..41 "}"
+
diff --git a/support/texlab/crates/parser/src/test_data/latex/structure/paragraphs.txt b/support/texlab/crates/parser/src/test_data/latex/structure/paragraphs.txt
new file mode 100644
index 0000000000..a7e32353bb
--- /dev/null
+++ b/support/texlab/crates/parser/src/test_data/latex/structure/paragraphs.txt
@@ -0,0 +1,11 @@
+\section{Section 1}
+Section 1
+
+\paragraph{Paragraph 1}
+Paragraph 1
+
+\paragraph{Paragraph 2}
+Paragraph 2
+
+\section{Section 2}
+Section 2 \ No newline at end of file
diff --git a/support/texlab/crates/parser/src/test_data/latex/theorem_definition/theorem_definition_thmtools.txt b/support/texlab/crates/parser/src/test_data/latex/theorem_definition/theorem_definition_thmtools.txt
new file mode 100644
index 0000000000..2662a5ca8c
--- /dev/null
+++ b/support/texlab/crates/parser/src/test_data/latex/theorem_definition/theorem_definition_thmtools.txt
@@ -0,0 +1 @@
+\declaretheorem[style=foo, name=bar]{baz} \ No newline at end of file
diff --git a/support/texlab/crates/symbols/Cargo.toml b/support/texlab/crates/symbols/Cargo.toml
index d1d5bd2d8b..b79e671597 100644
--- a/support/texlab/crates/symbols/Cargo.toml
+++ b/support/texlab/crates/symbols/Cargo.toml
@@ -20,5 +20,5 @@ url = "2.3.1"
[dev-dependencies]
insta = "1.29.0"
-regex = "1.7.3"
+regex = "1.8.1"
test-utils = { path = "../test-utils" }
diff --git a/support/texlab/crates/symbols/src/document.rs b/support/texlab/crates/symbols/src/document.rs
index eb3d8d339f..b34974e019 100644
--- a/support/texlab/crates/symbols/src/document.rs
+++ b/support/texlab/crates/symbols/src/document.rs
@@ -37,7 +37,6 @@ fn filter_symbols(container: &mut Vec<Symbol>, config: &SymbolConfig) {
while i < container.len() {
let symbol = &mut container[i];
if symbol.name.is_empty() || !util::filter_regex_patterns(&symbol.name, allowed, ignored) {
- drop(symbol);
let mut symbol = container.remove(i);
container.append(&mut symbol.children);
} else {
diff --git a/support/texlab/crates/symbols/src/document/snapshots/symbols__document__tests__theorem.snap b/support/texlab/crates/symbols/src/document/snapshots/symbols__document__tests__theorem_amsthm.snap
index 9d897532b1..9d897532b1 100644
--- a/support/texlab/crates/symbols/src/document/snapshots/symbols__document__tests__theorem.snap
+++ b/support/texlab/crates/symbols/src/document/snapshots/symbols__document__tests__theorem_amsthm.snap
diff --git a/support/texlab/crates/symbols/src/document/snapshots/symbols__document__tests__theorem_thmtools.snap b/support/texlab/crates/symbols/src/document/snapshots/symbols__document__tests__theorem_thmtools.snap
new file mode 100644
index 0000000000..cb5d344965
--- /dev/null
+++ b/support/texlab/crates/symbols/src/document/snapshots/symbols__document__tests__theorem_thmtools.snap
@@ -0,0 +1,53 @@
+---
+source: crates/symbols/src/document/tests.rs
+expression: "document_symbols(&fixture.workspace, document)"
+---
+[
+ Symbol {
+ name: "Lemma 1 (Foo)",
+ kind: Theorem,
+ label: Some(
+ Span(
+ "thm:foo",
+ 147..162,
+ ),
+ ),
+ full_range: 129..182,
+ selection_range: 147..162,
+ children: [],
+ },
+ Symbol {
+ name: "Lemma 2",
+ kind: Theorem,
+ label: Some(
+ Span(
+ "thm:bar",
+ 197..212,
+ ),
+ ),
+ full_range: 184..232,
+ selection_range: 197..212,
+ children: [],
+ },
+ Symbol {
+ name: "Lemma",
+ kind: Theorem,
+ label: Some(
+ Span(
+ "thm:baz",
+ 247..262,
+ ),
+ ),
+ full_range: 234..282,
+ selection_range: 247..262,
+ children: [],
+ },
+ Symbol {
+ name: "Lemma (Qux)",
+ kind: Theorem,
+ label: None,
+ full_range: 284..322,
+ selection_range: 284..322,
+ children: [],
+ },
+]
diff --git a/support/texlab/crates/symbols/src/document/tests.rs b/support/texlab/crates/symbols/src/document/tests.rs
index dcb3c17a7c..355a8a5719 100644
--- a/support/texlab/crates/symbols/src/document/tests.rs
+++ b/support/texlab/crates/symbols/src/document/tests.rs
@@ -138,7 +138,7 @@ fn test_section() {
}
#[test]
-fn test_theorem() {
+fn test_theorem_amsthm() {
let fixture = Fixture::parse(
r#"
%! main.tex
@@ -178,6 +178,46 @@ fn test_theorem() {
}
#[test]
+fn test_theorem_thmtools() {
+ let fixture = Fixture::parse(
+ r#"
+%! main.tex
+\documentclass{article}
+\declaretheoremstyle{lemmastyle}
+\declaretheorem[style=lemmastyle, name=Lemma]{lemma}
+
+\begin{document}
+
+\begin{lemma}[Foo]\label{thm:foo}
+ Foo
+\end{lemma}
+
+\begin{lemma}\label{thm:bar}
+ Bar
+\end{lemma}
+
+\begin{lemma}\label{thm:baz}
+ Baz
+\end{lemma}
+
+\begin{lemma}[Qux]
+ Qux
+\end{lemma}
+
+\end{document}
+|
+
+%! main.aux
+\relax
+\newlabel{thm:foo}{{1}{1}}
+\newlabel{thm:bar}{{2}{1}}"#,
+ );
+
+ let document = fixture.workspace.lookup(&fixture.documents[0].uri).unwrap();
+ assert_debug_snapshot!(document_symbols(&fixture.workspace, document));
+}
+
+#[test]
fn test_allowed_patterns() {
let mut fixture = Fixture::parse(
r#"
diff --git a/support/texlab/crates/symbols/src/types.rs b/support/texlab/crates/symbols/src/types.rs
index d78f9af200..5d31c98143 100644
--- a/support/texlab/crates/symbols/src/types.rs
+++ b/support/texlab/crates/symbols/src/types.rs
@@ -54,7 +54,7 @@ impl Symbol {
}
}
- pub fn keywords<'a>(&'a self) -> Vec<&'a str> {
+ pub fn keywords(&self) -> Vec<&str> {
match self.kind {
SymbolKind::Section => vec![&self.name, "latex", "section"],
SymbolKind::Figure => vec![&self.name, "latex", "float", "figure"],
diff --git a/support/texlab/crates/syntax/src/latex/cst.rs b/support/texlab/crates/syntax/src/latex/cst.rs
index be64557886..a2945c3e7a 100644
--- a/support/texlab/crates/syntax/src/latex/cst.rs
+++ b/support/texlab/crates/syntax/src/latex/cst.rs
@@ -265,6 +265,15 @@ impl ToString for Key {
cst_node!(Value, VALUE);
+impl Value {
+ pub fn text(&self) -> Option<String> {
+ match CurlyGroup::cast(self.syntax().clone()) {
+ Some(group) => group.content_text(),
+ None => Some(self.syntax().text().to_string()),
+ }
+ }
+}
+
cst_node!(KeyValuePair, KEY_VALUE_PAIR);
impl KeyValuePair {
@@ -528,7 +537,11 @@ impl LabelNumber {
}
}
-cst_node!(TheoremDefinition, THEOREM_DEFINITION);
+cst_node!(
+ TheoremDefinition,
+ THEOREM_DEFINITION_AMSTHM,
+ THEOREM_DEFINITION_THMTOOLS
+);
impl TheoremDefinition {
pub fn command(&self) -> Option<SyntaxToken> {
@@ -539,8 +552,25 @@ impl TheoremDefinition {
self.syntax().children().find_map(CurlyGroupWord::cast)
}
- pub fn heading(&self) -> Option<CurlyGroup> {
- self.syntax().children().find_map(CurlyGroup::cast)
+ pub fn heading(&self) -> Option<String> {
+ if self.0.kind() == THEOREM_DEFINITION_THMTOOLS {
+ let options = self
+ .syntax()
+ .children()
+ .find_map(BrackGroupKeyValue::cast)
+ .and_then(|group| group.body())?;
+
+ options
+ .pairs()
+ .find(|pair| pair.key().map_or(false, |key| key.to_string() == "name"))
+ .and_then(|pair| pair.value())
+ .and_then(|name| name.text())
+ } else {
+ self.syntax()
+ .children()
+ .find_map(CurlyGroup::cast)
+ .and_then(|group| group.content_text())
+ }
}
}
diff --git a/support/texlab/crates/syntax/src/latex/kind.rs b/support/texlab/crates/syntax/src/latex/kind.rs
index 3eadc90b48..39e2837932 100644
--- a/support/texlab/crates/syntax/src/latex/kind.rs
+++ b/support/texlab/crates/syntax/src/latex/kind.rs
@@ -73,7 +73,8 @@ pub enum SyntaxKind {
ACRONYM_DEFINITION,
ACRONYM_DECLARATION,
ACRONYM_REFERENCE,
- THEOREM_DEFINITION,
+ THEOREM_DEFINITION_AMSTHM,
+ THEOREM_DEFINITION_THMTOOLS,
COLOR_REFERENCE,
COLOR_DEFINITION,
COLOR_SET_DEFINITION,
diff --git a/support/texlab/crates/texlab/Cargo.toml b/support/texlab/crates/texlab/Cargo.toml
index 821ecb9813..1f9ca98abe 100644
--- a/support/texlab/crates/texlab/Cargo.toml
+++ b/support/texlab/crates/texlab/Cargo.toml
@@ -1,7 +1,7 @@
[package]
name = "texlab"
description = "LaTeX Language Server"
-version = "5.6.0"
+version = "5.7.0"
license.workspace = true
readme = "README.md"
authors.workspace = true
@@ -31,31 +31,31 @@ test = false
doctest = false
[dependencies]
-anyhow = "1.0.70"
+anyhow = "1.0.71"
base-db = { path = "../base-db" }
citeproc = { path = "../citeproc" }
-clap = { version = "4.2.2", features = ["derive"] }
+clap = { version = "4.3.0", features = ["derive"] }
commands = { path = "../commands" }
crossbeam-channel = "0.5.8"
-dirs = "5.0.0"
+dirs = "5.0.1"
distro = { path = "../distro" }
encoding_rs = "0.8.32"
encoding_rs_io = "0.1.7"
fern = "0.6.2"
-flate2 = "1.0.25"
+flate2 = "1.0.26"
fuzzy-matcher = { version = "0.3.7", features = ["compact"] }
itertools = "0.10.5"
log = "0.4.17"
lsp-server = "0.7.0"
lsp-types = "0.94.0"
-notify = "5.1.0"
+notify = "6.0.0"
once_cell = "1.17.1"
parking_lot = "0.12.1"
parser = { path = "../parser" }
-regex = "1.7.3"
+regex = "1.8.1"
rowan = "0.15.11"
rustc-hash = "1.1.0"
-serde = "1.0.160"
+serde = "1.0.163"
serde_json = "1.0.96"
serde_regex = "1.1.0"
serde_repr = "0.1.12"
@@ -68,8 +68,8 @@ symbols = { path = "../symbols" }
[dev-dependencies]
assert_unordered = "0.3.5"
-criterion = { version = "0.4.0" }
-insta = { version = "1.28.0", features = ["glob", "redactions", "json"] }
+criterion = { version = "0.5.1" }
+insta = { version = "1.29.0", features = ["glob", "redactions", "json"] }
[[bench]]
name = "bench_main"
diff --git a/support/texlab/crates/texlab/src/features/completion/builder.rs b/support/texlab/crates/texlab/src/features/completion/builder.rs
index b325cd183b..bae7ebbfb7 100644
--- a/support/texlab/crates/texlab/src/features/completion/builder.rs
+++ b/support/texlab/crates/texlab/src/features/completion/builder.rs
@@ -51,7 +51,7 @@ impl<'a> CompletionBuilder<'a> {
) -> Self {
let items = Vec::new();
let matcher: Box<dyn Matcher> = match context.workspace.config().completion.matcher {
- MatchingAlgo::Skim => Box::new(SkimMatcherV2::default()),
+ MatchingAlgo::Skim => Box::<SkimMatcherV2>::default(),
MatchingAlgo::SkimIgnoreCase => Box::new(SkimMatcherV2::default().ignore_case()),
MatchingAlgo::Prefix => Box::new(matcher::Prefix),
MatchingAlgo::PrefixIgnoreCase => Box::new(matcher::PrefixIgnoreCase),
@@ -290,7 +290,7 @@ impl<'a> CompletionBuilder<'a> {
) -> Option<()> {
let score = self
.matcher
- .score(&entry_type.name, &self.text_pattern[1..])?;
+ .score(entry_type.name, &self.text_pattern[1..])?;
self.items.push(Item {
range,
@@ -303,7 +303,7 @@ impl<'a> CompletionBuilder<'a> {
}
pub fn field(&mut self, range: TextRange, field: &'a BibtexFieldType<'a>) -> Option<()> {
- let score = self.matcher.score(&field.name, &self.text_pattern)?;
+ let score = self.matcher.score(field.name, &self.text_pattern)?;
self.items.push(Item {
range,
data: Data::Field { field },
@@ -750,8 +750,8 @@ enum Data<'a> {
impl<'db> Data<'db> {
pub fn label<'this: 'db>(&'this self) -> &'db str {
match self {
- Self::EntryType { entry_type } => &entry_type.name,
- Self::Field { field } => &field.name,
+ Self::EntryType { entry_type } => entry_type.name,
+ Self::Field { field } => field.name,
Self::Argument { name, .. } => name,
Self::BeginSnippet => "begin",
Self::Citation { key, .. } => key,
diff --git a/support/texlab/crates/texlab/src/features/completion/label.rs b/support/texlab/crates/texlab/src/features/completion/label.rs
index 800c7b7581..be6e1b9ab7 100644
--- a/support/texlab/crates/texlab/src/features/completion/label.rs
+++ b/support/texlab/crates/texlab/src/features/completion/label.rs
@@ -40,7 +40,7 @@ pub fn complete<'db>(
let header = rendered_label.detail();
let footer = match &rendered_label.object {
- RenderedObject::Float { caption, .. } => Some(caption.clone()),
+ RenderedObject::Float { caption, .. } => Some(*caption),
_ => None,
};
diff --git a/support/texlab/crates/texlab/src/features/completion/matcher.rs b/support/texlab/crates/texlab/src/features/completion/matcher.rs
index a2b1a45e6a..5d5c93b2b9 100644
--- a/support/texlab/crates/texlab/src/features/completion/matcher.rs
+++ b/support/texlab/crates/texlab/src/features/completion/matcher.rs
@@ -37,6 +37,6 @@ impl Matcher for PrefixIgnoreCase {
}
}
- return Some(-(choice.len() as i32));
+ Some(-(choice.len() as i32))
}
}
diff --git a/support/texlab/crates/texlab/src/features/formatting/latexindent.rs b/support/texlab/crates/texlab/src/features/formatting/latexindent.rs
index c269550b74..bf5385401b 100644
--- a/support/texlab/crates/texlab/src/features/formatting/latexindent.rs
+++ b/support/texlab/crates/texlab/src/features/formatting/latexindent.rs
@@ -5,8 +5,8 @@ use std::{
use base_db::{Document, LatexIndentConfig, Workspace};
use distro::Language;
-use lsp_types::TextEdit;
-use rowan::{TextLen, TextRange};
+use lsp_types::{Position, TextEdit};
+use rowan::TextLen;
use tempfile::tempdir;
use crate::util::line_index_ext::LineIndexExt;
@@ -51,8 +51,10 @@ pub fn format_with_latexindent(
None
} else {
let line_index = &document.line_index;
+ let start = Position::new(0, 0);
+ let end = line_index.line_col_lsp(old_text.text_len());
Some(vec![TextEdit {
- range: line_index.line_col_lsp_range(TextRange::new(0.into(), old_text.text_len())),
+ range: lsp_types::Range::new(start, end),
new_text,
}])
}
diff --git a/support/texlab/crates/texlab/src/features/inlay_hint.rs b/support/texlab/crates/texlab/src/features/inlay_hint.rs
index 40e2984ab8..14a53ae21d 100644
--- a/support/texlab/crates/texlab/src/features/inlay_hint.rs
+++ b/support/texlab/crates/texlab/src/features/inlay_hint.rs
@@ -36,7 +36,7 @@ impl<'db> InlayHintBuilder<'db> {
let position = self.document.line_index.line_col_lsp(offset);
self.hints.push(InlayHint {
position,
- label: InlayHintLabel::String(text),
+ label: InlayHintLabel::String(format!(" {text} ")),
kind: None,
text_edits: None,
tooltip: None,
diff --git a/support/texlab/crates/texlab/src/features/inlay_hint/label.rs b/support/texlab/crates/texlab/src/features/inlay_hint/label.rs
index dd33990f45..f73d3fd9ae 100644
--- a/support/texlab/crates/texlab/src/features/inlay_hint/label.rs
+++ b/support/texlab/crates/texlab/src/features/inlay_hint/label.rs
@@ -34,7 +34,7 @@ pub(super) fn find_hints(builder: &mut InlayHintBuilder) -> Option<()> {
RenderedObject::EnumItem => format!("Item {}", number),
};
- builder.push(label.name.range.end(), text);
+ builder.push(label.full_range.end(), text);
}
Some(())
diff --git a/support/texlab/crates/texlab/src/server.rs b/support/texlab/crates/texlab/src/server.rs
index 0370f00192..2a62abe96d 100644
--- a/support/texlab/crates/texlab/src/server.rs
+++ b/support/texlab/crates/texlab/src/server.rs
@@ -38,8 +38,8 @@ use crate::{
use self::{
extensions::{
- BuildParams, BuildRequest, BuildResult, BuildStatus, ForwardSearchRequest,
- ForwardSearchResult, ForwardSearchStatus,
+ BuildParams, BuildRequest, BuildResult, BuildStatus, EnvironmentLocation,
+ ForwardSearchRequest, ForwardSearchResult, ForwardSearchStatus, TextWithRange,
},
options::{Options, StartupOptions},
progress::ProgressReporter,
@@ -168,6 +168,9 @@ impl Server {
"texlab.cleanAuxiliary".into(),
"texlab.cleanArtifacts".into(),
"texlab.changeEnvironment".into(),
+ "texlab.findEnvironments".into(),
+ "texlab.showDependencyGraph".into(),
+ "texlab.cancelBuild".into(),
],
..Default::default()
}),
@@ -384,20 +387,18 @@ impl Server {
match change.range {
Some(range) => {
let range = document.line_index.offset_lsp_range(range);
- drop(document);
workspace.edit(&uri, range, &change.text);
}
None => {
let new_line = document.cursor.line.min(change.text.lines().count() as u32);
let language = document.language;
- drop(document);
workspace.open(
uri.clone(),
change.text,
language,
Owner::Client,
LineCol {
- line: new_line as u32,
+ line: new_line,
col: 0,
},
);
@@ -662,6 +663,10 @@ impl Server {
client.send_request::<ApplyWorkspaceEdit>(params?)
});
}
+ "texlab.findEnvironments" => {
+ let result = self.find_environments(params);
+ self.run_fallible(id, move || result);
+ }
"texlab.showDependencyGraph" => {
let workspace = self.workspace.read();
let dot = commands::show_dependency_graph(&workspace).unwrap();
@@ -867,7 +872,6 @@ impl Server {
if let Some(document) = workspace.lookup_path(&path) {
if document.owner == Owner::Server {
let uri = document.uri.clone();
- drop(document);
workspace.remove(&uri);
changed = true;
}
@@ -941,6 +945,32 @@ impl Server {
Ok(ApplyWorkspaceEditParams { label, edit })
}
+ fn find_environments(&self, params: ExecuteCommandParams) -> Result<Vec<EnvironmentLocation>> {
+ let workspace = self.workspace.read();
+ let params = self.parse_command_params::<TextDocumentPositionParams>(params.arguments)?;
+ let mut uri = params.text_document.uri;
+ normalize_uri(&mut uri);
+
+ let Some(document) = workspace.lookup(&uri) else {
+ anyhow::bail!("Document {} is not opened!", uri)
+ };
+
+ let line_index = &document.line_index;
+ let offset = line_index.offset_lsp(params.position);
+ let results = commands::find_environments(document, offset)
+ .into_iter()
+ .map(|result| EnvironmentLocation {
+ name: TextWithRange {
+ range: line_index.line_col_lsp_range(result.name.range),
+ text: result.name.text,
+ },
+ full_range: line_index.line_col_lsp_range(result.full_range),
+ })
+ .collect();
+
+ Ok(results)
+ }
+
fn parse_command_params<T: DeserializeOwned>(
&self,
params: Vec<serde_json::Value>,
diff --git a/support/texlab/crates/texlab/src/server/extensions.rs b/support/texlab/crates/texlab/src/server/extensions.rs
index e8a2050cff..2d9d17a5b3 100644
--- a/support/texlab/crates/texlab/src/server/extensions.rs
+++ b/support/texlab/crates/texlab/src/server/extensions.rs
@@ -1,5 +1,5 @@
use commands::ForwardSearchError;
-use lsp_types::{Position, TextDocumentIdentifier, TextDocumentPositionParams};
+use lsp_types::{Position, Range, TextDocumentIdentifier, TextDocumentPositionParams};
use serde::{Deserialize, Serialize};
use serde_repr::{Deserialize_repr, Serialize_repr};
@@ -70,6 +70,21 @@ impl From<ForwardSearchError> for ForwardSearchStatus {
}
#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)]
+#[serde(rename_all = "camelCase")]
pub struct ForwardSearchResult {
pub status: ForwardSearchStatus,
}
+
+#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)]
+#[serde(rename_all = "camelCase")]
+pub struct EnvironmentLocation {
+ pub name: TextWithRange,
+ pub full_range: Range,
+}
+
+#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)]
+#[serde(rename_all = "camelCase")]
+pub struct TextWithRange {
+ pub text: String,
+ pub range: Range,
+}
diff --git a/support/texlab/crates/texlab/src/util/cursor.rs b/support/texlab/crates/texlab/src/util/cursor.rs
index b03036386c..a39d0e7bf7 100644
--- a/support/texlab/crates/texlab/src/util/cursor.rs
+++ b/support/texlab/crates/texlab/src/util/cursor.rs
@@ -241,18 +241,13 @@ impl<'a, T> CursorContext<'a, T> {
pub fn find_environment(&self) -> Option<(latex::Key, latex::Key)> {
let token = self.cursor.as_tex()?;
-
- for env in token
+ let env = token
.parent_ancestors()
- .filter_map(latex::Environment::cast)
- {
- let beg = env.begin()?.name()?.key()?;
- let end = env.end()?.name()?.key()?;
-
- return Some((beg, end));
- }
+ .find_map(latex::Environment::cast)?;
- None
+ let beg = env.begin()?.name()?.key()?;
+ let end = env.end()?.name()?.key()?;
+ Some((beg, end))
}
pub fn find_curly_group_word(&self) -> Option<(String, TextRange, latex::CurlyGroupWord)> {
diff --git a/support/texlab/crates/texlab/tests/lsp/text_document/snapshots/lsp__text_document__inlay_hint__label_definition.snap b/support/texlab/crates/texlab/tests/lsp/text_document/snapshots/lsp__text_document__inlay_hint__label_definition.snap
index b8568fd2fd..050ae5afd3 100644
--- a/support/texlab/crates/texlab/tests/lsp/text_document/snapshots/lsp__text_document__inlay_hint__label_definition.snap
+++ b/support/texlab/crates/texlab/tests/lsp/text_document/snapshots/lsp__text_document__inlay_hint__label_definition.snap
@@ -1,38 +1,38 @@
---
-source: tests/lsp/text_document/inlay_hint.rs
+source: crates/texlab/tests/lsp/text_document/inlay_hint.rs
expression: "find_hints(r#\"\n%! main.tex\n\\documentclass{article}\n\\usepackage{caption}\n\\begin{document}\n\\section{Foo}\\label{sec:foo}\n\\section{Bar}\\label{sec:bar}\n\\subsection{Baz}\\label{sec:baz}\n\\begin{figure}\n Test\n \\label{fig:qux}\n \\caption{Qux}\n\\end{figure}\n\\end{document}\n |\n\n%! main.aux\n\\relax \n\\providecommand*\\caption@xref[2]{\\@setref\\relax\\@undefined{#1}}\n\\newlabel{fig:qux}{{\\caption@xref {fig:qux}{ on input line 15}}{1}}\n\\@writefile{lof}{\\contentsline {figure}{\\numberline {1}{\\ignorespaces Qux\\relax }}{1}{}\\protected@file@percent }\n\\@writefile{toc}{\\contentsline {section}{\\numberline {1}Foo}{1}{}\\protected@file@percent }\n\\newlabel{sec:foo}{{1}{1}}\n\\@writefile{toc}{\\contentsline {section}{\\numberline {2}Bar}{1}{}\\protected@file@percent }\n\\newlabel{sec:bar}{{2}{1}}\n\\@writefile{toc}{\\contentsline {subsection}{\\numberline {2.1}Baz}{1}{}\\protected@file@percent }\n\\newlabel{sec:baz}{{2.1}{1}}\n\\gdef \\@abspage@last{1}\"#)"
---
[
{
"position": {
"line": 3,
- "character": 27
+ "character": 28
},
- "label": "Section 1",
+ "label": " Section 1 ",
"paddingLeft": true
},
{
"position": {
"line": 4,
- "character": 27
+ "character": 28
},
- "label": "Section 2",
+ "label": " Section 2 ",
"paddingLeft": true
},
{
"position": {
"line": 5,
- "character": 30
+ "character": 31
},
- "label": "Subsection 2.1",
+ "label": " Subsection 2.1 ",
"paddingLeft": true
},
{
"position": {
"line": 8,
- "character": 18
+ "character": 19
},
- "label": "Figure fig:qux",
+ "label": " Figure fig:qux ",
"paddingLeft": true
}
]
diff --git a/support/texlab/texlab.1 b/support/texlab/texlab.1
index 8d0ecbeb45..4042ae0f1e 100644
--- a/support/texlab/texlab.1
+++ b/support/texlab/texlab.1
@@ -1,7 +1,7 @@
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.47.13.
-.TH TEXLAB "1" "May 2023" "texlab 5.6.0" "User Commands"
+.TH TEXLAB "1" "June 2023" "texlab 5.7.0" "User Commands"
.SH NAME
-texlab \- manual page for texlab 5.6.0
+texlab \- manual page for texlab 5.7.0
.SH SYNOPSIS
.B texlab
[\fI\,OPTIONS\/\fR]
diff --git a/support/texlab/texlab.pdf b/support/texlab/texlab.pdf
index a7ed8d359f..ed15c250f5 100644
--- a/support/texlab/texlab.pdf
+++ b/support/texlab/texlab.pdf
Binary files differ