summaryrefslogtreecommitdiff
path: root/support/texlab
diff options
context:
space:
mode:
Diffstat (limited to 'support/texlab')
-rw-r--r--support/texlab/CHANGELOG.md59
-rw-r--r--support/texlab/Cargo.lock338
-rw-r--r--support/texlab/Cargo.toml22
-rw-r--r--support/texlab/crates/base-db/Cargo.toml18
-rw-r--r--support/texlab/crates/base-db/src/config.rs3
-rw-r--r--support/texlab/crates/base-db/src/deps/discover.rs2
-rw-r--r--support/texlab/crates/base-db/src/deps/graph.rs87
-rw-r--r--support/texlab/crates/base-db/src/deps/root.rs6
-rw-r--r--support/texlab/crates/base-db/src/document.rs21
-rw-r--r--support/texlab/crates/base-db/src/semantics/auxiliary.rs36
-rw-r--r--support/texlab/crates/base-db/src/semantics/tex.rs94
-rw-r--r--support/texlab/crates/bibfmt/Cargo.toml4
-rw-r--r--support/texlab/crates/bibtex-utils/Cargo.toml12
-rw-r--r--support/texlab/crates/citeproc/Cargo.toml14
-rw-r--r--support/texlab/crates/commands/Cargo.toml22
-rw-r--r--support/texlab/crates/commands/src/build.rs6
-rw-r--r--support/texlab/crates/commands/src/clean.rs6
-rw-r--r--support/texlab/crates/commands/src/dep_graph.rs1
-rw-r--r--support/texlab/crates/commands/src/fwd_search.rs6
-rw-r--r--support/texlab/crates/completion-data/Cargo.toml12
-rw-r--r--support/texlab/crates/completion/Cargo.toml11
-rw-r--r--support/texlab/crates/completion/src/lib.rs2
-rw-r--r--support/texlab/crates/completion/src/providers/include.rs2
-rw-r--r--support/texlab/crates/completion/src/providers/label_ref.rs46
-rw-r--r--support/texlab/crates/completion/src/tests.rs213
-rw-r--r--support/texlab/crates/definition/Cargo.toml6
-rw-r--r--support/texlab/crates/definition/src/command.rs2
-rw-r--r--support/texlab/crates/diagnostics/Cargo.toml16
-rw-r--r--support/texlab/crates/diagnostics/src/chktex.rs2
-rw-r--r--support/texlab/crates/diagnostics/src/citations.rs46
-rw-r--r--support/texlab/crates/diagnostics/src/manager.rs83
-rw-r--r--support/texlab/crates/diagnostics/src/tests.rs70
-rw-r--r--support/texlab/crates/diagnostics/src/types.rs86
-rw-r--r--support/texlab/crates/distro/Cargo.toml4
-rw-r--r--support/texlab/crates/distro/src/language.rs2
-rw-r--r--support/texlab/crates/distro/src/lib.rs17
-rw-r--r--support/texlab/crates/folding/Cargo.toml4
-rw-r--r--support/texlab/crates/highlights/Cargo.toml4
-rw-r--r--support/texlab/crates/hover/Cargo.toml4
-rw-r--r--support/texlab/crates/inlay-hints/Cargo.toml6
-rw-r--r--support/texlab/crates/ipc/Cargo.toml10
-rw-r--r--support/texlab/crates/line-index/Cargo.toml2
-rw-r--r--support/texlab/crates/links/Cargo.toml2
-rw-r--r--support/texlab/crates/parser/Cargo.toml20
-rw-r--r--support/texlab/crates/parser/src/bibtex.rs54
-rw-r--r--support/texlab/crates/parser/src/bibtex/tests.rs277
-rw-r--r--support/texlab/crates/parser/src/config.rs26
-rw-r--r--support/texlab/crates/parser/src/file_list.rs44
-rw-r--r--support/texlab/crates/parser/src/latex.rs62
-rw-r--r--support/texlab/crates/parser/src/latex/lexer.rs2
-rw-r--r--support/texlab/crates/parser/src/latex/lexer/commands.rs3
-rw-r--r--support/texlab/crates/parser/src/latex/lexer/types.rs52
-rw-r--r--support/texlab/crates/parser/src/latex/tests.rs110
-rw-r--r--support/texlab/crates/parser/src/lib.rs6
-rw-r--r--support/texlab/crates/parser/src/util.rs52
-rw-r--r--support/texlab/crates/references/Cargo.toml4
-rw-r--r--support/texlab/crates/references/src/command.rs4
-rw-r--r--support/texlab/crates/references/src/tests.rs40
-rw-r--r--support/texlab/crates/rename/Cargo.toml5
-rw-r--r--support/texlab/crates/rename/src/command.rs5
-rw-r--r--support/texlab/crates/rename/src/entry.rs2
-rw-r--r--support/texlab/crates/rename/src/label.rs47
-rw-r--r--support/texlab/crates/rename/src/lib.rs22
-rw-r--r--support/texlab/crates/rename/src/tests.rs111
-rw-r--r--support/texlab/crates/symbols/Cargo.toml12
-rw-r--r--support/texlab/crates/symbols/src/document.rs1
-rw-r--r--support/texlab/crates/symbols/src/document/tests.rs72
-rw-r--r--support/texlab/crates/symbols/src/document/tex.rs25
-rw-r--r--support/texlab/crates/syntax/Cargo.toml5
-rw-r--r--support/texlab/crates/syntax/src/file_list.rs10
-rw-r--r--support/texlab/crates/syntax/src/latex/cst.rs46
-rw-r--r--support/texlab/crates/syntax/src/latex/kind.rs4
-rw-r--r--support/texlab/crates/syntax/src/lib.rs1
-rw-r--r--support/texlab/crates/test-utils/Cargo.toml4
-rw-r--r--support/texlab/crates/texlab/Cargo.toml34
-rw-r--r--support/texlab/crates/texlab/src/features/formatting.rs3
-rw-r--r--support/texlab/crates/texlab/src/features/formatting/latexindent.rs11
-rw-r--r--support/texlab/crates/texlab/src/features/inlay_hint.rs7
-rw-r--r--support/texlab/crates/texlab/src/server/options.rs8
-rw-r--r--support/texlab/crates/texlab/src/util.rs59
-rw-r--r--support/texlab/crates/texlab/src/util/client_flags.rs6
-rw-r--r--support/texlab/crates/texlab/src/util/from_proto.rs32
-rw-r--r--support/texlab/crates/texlab/src/util/to_proto.rs34
-rw-r--r--support/texlab/texlab.14
-rw-r--r--support/texlab/texlab.pdfbin26420 -> 26339 bytes
85 files changed, 2136 insertions, 599 deletions
diff --git a/support/texlab/CHANGELOG.md b/support/texlab/CHANGELOG.md
index 8008720d9b..526ec6889c 100644
--- a/support/texlab/CHANGELOG.md
+++ b/support/texlab/CHANGELOG.md
@@ -5,6 +5,65 @@ 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.21.0] - 2024-10-26
+
+### Added
+
+- Support starred variants in "Go to References" ([#1234](https://github.com/latex-lsp/texlab/issues/1234))
+- Add `texlab.latexindent.replacement` setting to allow passing a replacement flag to `latexindent` ([#1222](https://github.com/latex-lsp/texlab/issues/1222))
+- Don't require a label to show section numbers for document symbols ([#910](https://github.com/latex-lsp/texlab/issues/910))
+- Support navigating to files that are part of the `TEXINPUTS` similar to `BIBINPUTS` ([#1228](https://github.com/latex-lsp/texlab/discussions/1228))
+
+### Fixed
+
+- Fix opening `untitled` documents ([#1242](https://github.com/latex-lsp/texlab/issues/1242))
+- Handle `\bibitem` when checking for undefined references ([#1171](https://github.com/latex-lsp/texlab/issues/1171))
+- Fix false-positive syntax error when using a command inside a `\label` ([#879](https://github.com/latex-lsp/texlab/issues/879))
+
+## [5.20.0] - 2024-10-08
+
+### Added
+
+- Add `texlab.inlayHints.maxLength` setting to allow limiting inlay hint text length ([#1212](https://github.com/latex-lsp/texlab/issues/1212))
+- Allow suppressing diagnostics using `% texlab: ignore` magic comments ([#1211](https://github.com/latex-lsp/texlab/pull/1211))
+
+### Fixed
+
+- Fix enabling `texlab.build.useFileList` setting
+- Make "Goto Definition" work correctly with starred commands ([#1197](https://github.com/latex-lsp/texlab/issues/1197))
+
+## [5.19.0] - 2024-07-08
+
+### Added
+
+- Add `texlab.build.useFileList` setting to allow controlling whether to use the `.fls` files
+
+### Changed
+
+- Disable using `.fls` files for project detection by default
+
+## [5.18.0] - 2024-07-06
+
+### Added
+
+- Parse `.fls` files to make the project detection more reliable ([#1145](https://github.com/latex-lsp/texlab/issues/1145))
+
+### Fixed
+
+- Fix parsing commands with unicode characters inside BibTeX entries
+ ([#1147](https://github.com/latex-lsp/texlab/issues/1147))
+- Improve detection of included files when non-ASCII characters are used ([#923](https://github.com/latex-lsp/texlab/issues/923))
+- Fix resolving includes starting from files included using `\subimport` ([#1145](https://github.com/latex-lsp/texlab/issues/1145))
+
+## [5.17.0] - 2024-06-23
+
+### Added
+
+- Add label commands from `zref` and `zref-clever` to the list of default label commands
+ ([#1140](https://github.com/latex-lsp/texlab/pull/1140))
+- Add `texlab.experimental.labelDefinitionPrefixes` and
+ `texlab.experimental.labelReferencePrefixes` options ([#1139](https://github.com/latex-lsp/texlab/pull/1139))
+
## [5.16.1] - 2024-05-25
### Fixed
diff --git a/support/texlab/Cargo.lock b/support/texlab/Cargo.lock
index 9d651234e1..aca7dcd943 100644
--- a/support/texlab/Cargo.lock
+++ b/support/texlab/Cargo.lock
@@ -3,10 +3,10 @@
version = 3
[[package]]
-name = "adler"
-version = "1.0.2"
+name = "adler2"
+version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
+checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627"
[[package]]
name = "aho-corasick"
@@ -39,9 +39,9 @@ dependencies = [
[[package]]
name = "anstyle"
-version = "1.0.3"
+version = "1.0.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b84bf0a05bbb2a83e5eb6fa36bb6e87baa08193c35ff52bbf6b38d8af2890e46"
+checksum = "1bec1de6f59aedf83baf9ff929c98f2ad654b97c9510f4e70cf6f661d49fd5b1"
[[package]]
name = "anstyle-parse"
@@ -73,9 +73,9 @@ dependencies = [
[[package]]
name = "anyhow"
-version = "1.0.86"
+version = "1.0.90"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da"
+checksum = "37bf3594c4c988a53154954629820791dde498571819ae4ca50ca811e060cc95"
[[package]]
name = "autocfg"
@@ -90,7 +90,7 @@ dependencies = [
"bibtex-utils",
"dirs",
"distro",
- "itertools 0.12.1",
+ "itertools 0.13.0",
"line-index",
"log",
"notify",
@@ -99,7 +99,7 @@ dependencies = [
"percent-encoding",
"regex",
"rowan",
- "rustc-hash",
+ "rustc-hash 2.0.0",
"shellexpand",
"syntax",
"titlecase",
@@ -130,10 +130,10 @@ dependencies = [
"chrono",
"expect-test",
"human_name",
- "itertools 0.12.1",
+ "itertools 0.13.0",
"parser",
"rowan",
- "rustc-hash",
+ "rustc-hash 2.0.0",
"syntax",
"unicode-normalization",
]
@@ -152,9 +152,9 @@ checksum = "b4682ae6287fcf752ecaabbfcc7b6f9b72aa33933dc23a554d853aea8eea8635"
[[package]]
name = "bstr"
-version = "1.9.1"
+version = "1.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "05efc5cfd9110c8416e471df0e96702d58690178e206e61b7173706673c93706"
+checksum = "40723b8fb387abc38f4f4a37c09073622e41dd12327033091ef8950659e6dc0c"
dependencies = [
"memchr",
"regex-automata",
@@ -232,10 +232,10 @@ dependencies = [
"bibtex-utils",
"expect-test",
"isocountry",
- "itertools 0.12.1",
+ "itertools 0.13.0",
"parser",
"rowan",
- "rustc-hash",
+ "rustc-hash 2.0.0",
"syntax",
"titlecase",
"unicode-normalization",
@@ -244,9 +244,9 @@ dependencies = [
[[package]]
name = "clap"
-version = "4.5.4"
+version = "4.5.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "90bc066a67923782aa8515dbaea16946c5bcc5addbd668bb80af688e53e548a0"
+checksum = "b97f376d85a664d5837dbae44bf546e6477a679ff6610010f17276f686d867e8"
dependencies = [
"clap_builder",
"clap_derive",
@@ -254,9 +254,9 @@ dependencies = [
[[package]]
name = "clap_builder"
-version = "4.5.2"
+version = "4.5.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ae129e2e766ae0ec03484e609954119f123cc1fe650337e155d03b022f24f7b4"
+checksum = "19bc80abd44e4bed93ca373a0704ccbd1b710dc5749406201bb018272808dc54"
dependencies = [
"anstream",
"anstyle",
@@ -266,9 +266,9 @@ dependencies = [
[[package]]
name = "clap_derive"
-version = "4.5.4"
+version = "4.5.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "528131438037fd55894f62d6e9f068b8f45ac57ffa77517819645d10aed04f64"
+checksum = "4ac6a0c7b1a9e9a5186361f67dfa1b88213572f427fb9ab038efb2bd8c582dab"
dependencies = [
"heck",
"proc-macro2",
@@ -298,11 +298,11 @@ dependencies = [
"crossbeam-channel",
"distro",
"expect-test",
- "itertools 0.12.1",
+ "itertools 0.13.0",
"libc",
"log",
"rowan",
- "rustc-hash",
+ "rustc-hash 2.0.0",
"syntax",
"test-utils",
"thiserror",
@@ -334,9 +334,10 @@ dependencies = [
"expect-test",
"fuzzy-matcher",
"line-index",
+ "parser",
"rayon",
"rowan",
- "rustc-hash",
+ "rustc-hash 2.0.0",
"syntax",
"test-utils",
"url",
@@ -347,9 +348,9 @@ name = "completion-data"
version = "0.0.0"
dependencies = [
"flate2",
- "itertools 0.12.1",
+ "itertools 0.13.0",
"once_cell",
- "rustc-hash",
+ "rustc-hash 2.0.0",
"serde",
"serde_json",
]
@@ -407,9 +408,9 @@ dependencies = [
[[package]]
name = "crossbeam-channel"
-version = "0.5.12"
+version = "0.5.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ab3db02a9c5b5121e1e42fbdb1aeb65f5e02624cc58c43f2884c6ccac0b82f95"
+checksum = "33480d6946193aa8033910124896ca395333cae7e2d1113d1fef6c3272217df2"
dependencies = [
"crossbeam-utils",
]
@@ -449,9 +450,9 @@ name = "definition"
version = "0.0.0"
dependencies = [
"base-db",
- "itertools 0.12.1",
+ "itertools 0.13.0",
"rowan",
- "rustc-hash",
+ "rustc-hash 2.0.0",
"syntax",
"test-utils",
]
@@ -464,14 +465,14 @@ dependencies = [
"encoding_rs",
"encoding_rs_io",
"expect-test",
- "itertools 0.12.1",
+ "itertools 0.13.0",
"line-index",
"log",
"multimap",
"once_cell",
"regex",
"rowan",
- "rustc-hash",
+ "rustc-hash 2.0.0",
"syntax",
"test-utils",
"url",
@@ -509,7 +510,7 @@ name = "distro"
version = "0.0.0"
dependencies = [
"anyhow",
- "rustc-hash",
+ "rustc-hash 2.0.0",
]
[[package]]
@@ -558,15 +559,15 @@ dependencies = [
[[package]]
name = "fastrand"
-version = "2.0.1"
+version = "2.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5"
+checksum = "e8c02a5121d4ea3eb16a80748c74f5549a5665e4c21333c6098f283870fbdea6"
[[package]]
name = "fern"
-version = "0.6.2"
+version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d9f0c14694cbd524c8720dd69b0e3179344f04ebb5f90f2e4a440c6ea3b2f1ee"
+checksum = "69ff9c9d5fb3e6da8ac2f77ab76fe7e8087d512ce095200f8f29ac5b656cf6dc"
dependencies = [
"log",
]
@@ -594,9 +595,9 @@ dependencies = [
[[package]]
name = "flate2"
-version = "1.0.30"
+version = "1.0.34"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5f54427cfd1c7829e2a139fcefea601bf088ebca651d2bf53ebc600eac295dae"
+checksum = "a1b589b4dc103969ad3cf85c950899926ec64300a1a46d76c03a6072957036f0"
dependencies = [
"crc32fast",
"miniz_oxide",
@@ -648,9 +649,9 @@ dependencies = [
[[package]]
name = "getrandom"
-version = "0.2.10"
+version = "0.2.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427"
+checksum = "c85e1d9ab2eadba7e5040d4e09cbd6d072b76a557ad64e797c2cb9d4da21d7e4"
dependencies = [
"cfg-if",
"libc",
@@ -682,6 +683,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d77f7ec81a6d05a3abb01ab6eb7590f6083d08449fe5a1c8b1e620283546ccb7"
[[package]]
+name = "hermit-abi"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fbf6a919d6cf397374f7dfeeea91d974c7c0a7221d0d0f4f20d859d329e53fcc"
+
+[[package]]
name = "highlights"
version = "0.0.0"
dependencies = [
@@ -707,9 +714,9 @@ dependencies = [
[[package]]
name = "human_name"
-version = "2.0.3"
+version = "2.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7d40d3a11bc31949eb1d5070deb0cbb481bbd17d9423ecd3afdb3db5d81499b9"
+checksum = "fbd70ad9620f3a33a270cedfa47114c9566660c28ff8d0b3772b5c8dc1dac085"
dependencies = [
"compact_str",
"crossbeam-utils",
@@ -741,7 +748,7 @@ dependencies = [
"base-db",
"expect-test",
"rowan",
- "rustc-hash",
+ "rustc-hash 2.0.0",
"test-utils",
]
@@ -780,13 +787,13 @@ dependencies = [
[[package]]
name = "is-terminal"
-version = "0.4.9"
+version = "0.4.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cb0889898416213fab133e1d33a0e5858a48177452750691bde3666d0fdbaf8b"
+checksum = "261f68e344040fbd0edea105bef17c66edf46f984ddb1115b775ce31be948f4b"
dependencies = [
- "hermit-abi",
- "rustix",
- "windows-sys 0.48.0",
+ "hermit-abi 0.4.0",
+ "libc",
+ "windows-sys 0.52.0",
]
[[package]]
@@ -810,9 +817,9 @@ dependencies = [
[[package]]
name = "itertools"
-version = "0.12.1"
+version = "0.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569"
+checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186"
dependencies = [
"either",
]
@@ -860,15 +867,15 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
[[package]]
name = "libc"
-version = "0.2.154"
+version = "0.2.161"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ae743338b92ff9146ce83992f766a31066a91a8c84a45e0e9f21e7cf6de6d346"
+checksum = "8e9489c2807c139ffd9c1794f4af0ebe86a828db53ecdc7fea2111d0fed085d1"
[[package]]
name = "line-index"
version = "0.0.0"
dependencies = [
- "rustc-hash",
+ "rustc-hash 2.0.0",
"text-size",
]
@@ -883,9 +890,9 @@ dependencies = [
[[package]]
name = "linux-raw-sys"
-version = "0.4.13"
+version = "0.4.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c"
+checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89"
[[package]]
name = "lock_api"
@@ -899,24 +906,24 @@ dependencies = [
[[package]]
name = "log"
-version = "0.4.21"
+version = "0.4.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c"
+checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24"
[[package]]
name = "logos"
-version = "0.14.0"
+version = "0.14.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "161971eb88a0da7ae0c333e1063467c5b5727e7fb6b710b8db4814eade3a42e8"
+checksum = "1c6b6e02facda28ca5fb8dbe4b152496ba3b1bd5a4b40bb2b1b2d8ad74e0f39b"
dependencies = [
"logos-derive",
]
[[package]]
name = "logos-codegen"
-version = "0.14.0"
+version = "0.14.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8e31badd9de5131fdf4921f6473d457e3dd85b11b7f091ceb50e4df7c3eeb12a"
+checksum = "b32eb6b5f26efacd015b000bfc562186472cd9b34bdba3f6b264e2a052676d10"
dependencies = [
"beef",
"fnv",
@@ -929,18 +936,18 @@ dependencies = [
[[package]]
name = "logos-derive"
-version = "0.14.0"
+version = "0.14.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1c2a69b3eb68d5bd595107c9ee58d7e07fe2bb5e360cc85b0f084dedac80de0a"
+checksum = "3e5d0c5463c911ef55624739fc353238b4e310f0144be1f875dc42fec6bfd5ec"
dependencies = [
"logos-codegen",
]
[[package]]
name = "lsp-server"
-version = "0.7.6"
+version = "0.7.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "248f65b78f6db5d8e1b1604b4098a28b43d21a8eb1deeca22b1c421b276c7095"
+checksum = "550446e84739dcaf6d48a4a093973850669e13e8a34d8f8d64851041be267cd9"
dependencies = [
"crossbeam-channel",
"log",
@@ -984,11 +991,11 @@ checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
[[package]]
name = "miniz_oxide"
-version = "0.7.1"
+version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7"
+checksum = "e2d80299ef12ff69b16a84bb182e3b9df68b5a91574d3d4fa6e41b65deec4df1"
dependencies = [
- "adler",
+ "adler2",
]
[[package]]
@@ -1043,9 +1050,9 @@ dependencies = [
[[package]]
name = "notify-debouncer-full"
-version = "0.3.1"
+version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "49f5dab59c348b9b50cf7f261960a20e389feb2713636399cd9082cd4b536154"
+checksum = "fb7fd166739789c9ff169e654dc1501373db9d80a4c3f972817c8a4d7cf8f34e"
dependencies = [
"crossbeam-channel",
"file-id",
@@ -1070,15 +1077,15 @@ version = "1.16.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43"
dependencies = [
- "hermit-abi",
+ "hermit-abi 0.3.3",
"libc",
]
[[package]]
name = "once_cell"
-version = "1.19.0"
+version = "1.20.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92"
+checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775"
[[package]]
name = "oorandom"
@@ -1094,9 +1101,9 @@ checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d"
[[package]]
name = "parking_lot"
-version = "0.12.2"
+version = "0.12.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7e4af0ca4f6caed20e900d564c242b8e5d4903fdacf31d3daf527b66fe6f42fb"
+checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27"
dependencies = [
"lock_api",
"parking_lot_core",
@@ -1126,7 +1133,7 @@ dependencies = [
"pathdiff",
"regex",
"rowan",
- "rustc-hash",
+ "rustc-hash 2.0.0",
"syntax",
"tempfile",
"versions",
@@ -1134,9 +1141,9 @@ dependencies = [
[[package]]
name = "pathdiff"
-version = "0.2.1"
+version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8835116a5c179084a830efb3adc117ab007512b535bc1a21c991d3b32a6b44dd"
+checksum = "d61c5ce1153ab5b689d0c074c4e7fc613e942dfb7dd9eea5ab202d2ad91fe361"
[[package]]
name = "percent-encoding"
@@ -1298,16 +1305,16 @@ version = "0.0.0"
dependencies = [
"base-db",
"rowan",
- "rustc-hash",
+ "rustc-hash 2.0.0",
"syntax",
"test-utils",
]
[[package]]
name = "regex"
-version = "1.10.4"
+version = "1.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c117dbdfde9c8308975b6a18d71f3f385c89461f7b3fb054288ecf2a2058ba4c"
+checksum = "38200e5ee88914975b69f657f0801b6f6dccafd44fd9326302a4aaeecfacb1d8"
dependencies = [
"aho-corasick",
"memchr",
@@ -1317,9 +1324,9 @@ dependencies = [
[[package]]
name = "regex-automata"
-version = "0.4.6"
+version = "0.4.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "86b83b8b9847f9bf95ef68afb0b8e6cdb80f498442f5179a29fad448fcc1eaea"
+checksum = "368758f23274712b504848e9d5a6f010445cc8b87a7cdb4d7cbee666c1288da3"
dependencies = [
"aho-corasick",
"memchr",
@@ -1328,31 +1335,31 @@ dependencies = [
[[package]]
name = "regex-syntax"
-version = "0.8.2"
+version = "0.8.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f"
+checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c"
[[package]]
name = "rename"
version = "0.0.0"
dependencies = [
"base-db",
+ "parser",
"rowan",
- "rustc-hash",
+ "rustc-hash 2.0.0",
"syntax",
"test-utils",
]
[[package]]
name = "rowan"
-version = "0.15.15"
+version = "0.15.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "32a58fa8a7ccff2aec4f39cc45bf5f985cec7125ab271cf681c279fd00192b49"
+checksum = "0a542b0253fa46e632d27a1dc5cf7b930de4df8659dc6e720b647fc72147ae3d"
dependencies = [
"countme",
"hashbrown",
- "memoffset",
- "rustc-hash",
+ "rustc-hash 1.1.0",
"text-size",
]
@@ -1363,10 +1370,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
[[package]]
+name = "rustc-hash"
+version = "2.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "583034fd73374156e66797ed8e5b0d5690409c9226b22d87cb7f19821c05d152"
+
+[[package]]
name = "rustix"
-version = "0.38.31"
+version = "0.38.37"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6ea3e1a662af26cd7a3ba09c0297a31af215563ecf42817c98df621387f4e949"
+checksum = "8acb788b847c24f28525660c4d7758620a7210875711f79e7f663cc152726811"
dependencies = [
"bitflags 2.4.0",
"errno",
@@ -1404,18 +1417,18 @@ checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
[[package]]
name = "serde"
-version = "1.0.202"
+version = "1.0.210"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "226b61a0d411b2ba5ff6d7f73a476ac4f8bb900373459cd00fab8512828ba395"
+checksum = "c8e3592472072e6e22e0a54d5904d9febf8508f65fb8552499a1abc7d1078c3a"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
-version = "1.0.202"
+version = "1.0.210"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6048858004bcff69094cd972ed40a32500f153bd3be9f716b2eed2e8217c4838"
+checksum = "243902eda00fad750862fc144cea25caca5e20d615af0a81bee94ca738f1df1f"
dependencies = [
"proc-macro2",
"quote",
@@ -1424,11 +1437,12 @@ dependencies = [
[[package]]
name = "serde_json"
-version = "1.0.117"
+version = "1.0.132"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "455182ea6142b14f93f4bc5320a2b31c1f266b66a4a5c858b013302a5d8cbfc3"
+checksum = "d726bfaff4b320266d395898905d0eba0345aae23b54aee3a737e260fd46db03"
dependencies = [
"itoa",
+ "memchr",
"ryu",
"serde",
]
@@ -1494,7 +1508,7 @@ dependencies = [
"base-db",
"distro",
"expect-test",
- "itertools 0.12.1",
+ "itertools 0.13.0",
"line-index",
"regex",
"rowan",
@@ -1519,20 +1533,22 @@ dependencies = [
name = "syntax"
version = "0.0.0"
dependencies = [
- "itertools 0.12.1",
+ "itertools 0.13.0",
"rowan",
+ "rustc-hash 2.0.0",
]
[[package]]
name = "tempfile"
-version = "3.10.1"
+version = "3.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1"
+checksum = "f0f2c9fc62d0beef6951ccffd757e241266a2c833136efbe35af6cd2567dca5b"
dependencies = [
"cfg-if",
"fastrand",
+ "once_cell",
"rustix",
- "windows-sys 0.52.0",
+ "windows-sys 0.59.0",
]
[[package]]
@@ -1548,7 +1564,7 @@ dependencies = [
[[package]]
name = "texlab"
-version = "5.16.1"
+version = "5.21.0"
dependencies = [
"anyhow",
"base-db",
@@ -1582,7 +1598,7 @@ dependencies = [
"regex",
"rename",
"rowan",
- "rustc-hash",
+ "rustc-hash 2.0.0",
"serde",
"serde_json",
"serde_regex",
@@ -1601,18 +1617,18 @@ checksum = "f18aa187839b2bdb1ad2fa35ead8c4c2976b64e4363c386d45ac0f7ee85c9233"
[[package]]
name = "thiserror"
-version = "1.0.59"
+version = "1.0.64"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f0126ad08bff79f29fc3ae6a55cc72352056dfff61e3ff8bb7129476d44b23aa"
+checksum = "d50af8abc119fb8bb6dbabcfa89656f46f84aa0ac7688088608076ad2b459a84"
dependencies = [
"thiserror-impl",
]
[[package]]
name = "thiserror-impl"
-version = "1.0.59"
+version = "1.0.64"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d1cd413b5d558b4c5bf3680e324a6fa5014e7b7c067a51e69dbdf47eb7148b66"
+checksum = "08904e7672f5eb876eaaf87e0ce17857500934f4981c4a0ab2b4aa98baac7fc3"
dependencies = [
"proc-macro2",
"quote",
@@ -1665,9 +1681,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
[[package]]
name = "titlecase"
-version = "3.0.0"
+version = "3.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bb3223c7b6ee54ec8521af7b060ad616cb90a66d0b94d05af340de30cf02c514"
+checksum = "e0e20e744fbec1913fa168f3ffbef64324bbcb152c6cda8394baa79fa5ec9142"
dependencies = [
"regex",
]
@@ -1703,9 +1719,9 @@ checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
[[package]]
name = "unicode-normalization"
-version = "0.1.23"
+version = "0.1.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a56d1686db2308d901306f92a263857ef59ea39678a5458e7cb17f01415101f5"
+checksum = "5033c97c4262335cded6d6fc3e5c18ab755e1a3dc96376350f3d8e9f009ad956"
dependencies = [
"tinyvec",
]
@@ -1724,9 +1740,9 @@ checksum = "402bb19d8e03f1d1a7450e2bd613980869438e0666331be3e073089124aa1adc"
[[package]]
name = "url"
-version = "2.5.0"
+version = "2.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "31e6302e3bb753d46e83516cae55ae196fc0c309407cf11ab35cc51a4c2a4633"
+checksum = "22784dbdf76fdde8af1aeda5622b546b422b6fc585325248a2bf9f5e41e94d6c"
dependencies = [
"form_urlencoded",
"idna",
@@ -1742,11 +1758,11 @@ checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a"
[[package]]
name = "versions"
-version = "6.2.0"
+version = "6.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "38a8931f8d167b6448076020e70b9de46dcf5ea1731212481a092d0071c4ac5b"
+checksum = "f25d498b63d1fdb376b4250f39ab3a5ee8d103957346abacd911e2d8b612c139"
dependencies = [
- "itertools 0.12.1",
+ "itertools 0.13.0",
"nom",
]
@@ -1768,9 +1784,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
[[package]]
name = "wasm-bindgen"
-version = "0.2.87"
+version = "0.2.92"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7706a72ab36d8cb1f80ffbf0e071533974a60d0a308d01a5d0375bf60499a342"
+checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8"
dependencies = [
"cfg-if",
"wasm-bindgen-macro",
@@ -1778,9 +1794,9 @@ dependencies = [
[[package]]
name = "wasm-bindgen-backend"
-version = "0.2.87"
+version = "0.2.92"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5ef2b6d3c510e9625e5fe6f509ab07d66a760f0885d858736483c32ed7809abd"
+checksum = "614d787b966d3989fa7bb98a654e369c762374fd3213d212cfc0251257e747da"
dependencies = [
"bumpalo",
"log",
@@ -1793,9 +1809,9 @@ dependencies = [
[[package]]
name = "wasm-bindgen-macro"
-version = "0.2.87"
+version = "0.2.92"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dee495e55982a3bd48105a7b947fd2a9b4a8ae3010041b9e0faab3f9cd028f1d"
+checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726"
dependencies = [
"quote",
"wasm-bindgen-macro-support",
@@ -1803,9 +1819,9 @@ dependencies = [
[[package]]
name = "wasm-bindgen-macro-support"
-version = "0.2.87"
+version = "0.2.92"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b"
+checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7"
dependencies = [
"proc-macro2",
"quote",
@@ -1816,9 +1832,9 @@ dependencies = [
[[package]]
name = "wasm-bindgen-shared"
-version = "0.2.87"
+version = "0.2.92"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ca6ad05a4870b2bf5fe995117d3728437bd27d7cd5f06f13c17443ef369775a1"
+checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96"
[[package]]
name = "web-sys"
@@ -1876,7 +1892,16 @@ version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
dependencies = [
- "windows-targets 0.52.4",
+ "windows-targets 0.52.6",
+]
+
+[[package]]
+name = "windows-sys"
+version = "0.59.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b"
+dependencies = [
+ "windows-targets 0.52.6",
]
[[package]]
@@ -1896,17 +1921,18 @@ dependencies = [
[[package]]
name = "windows-targets"
-version = "0.52.4"
+version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7dd37b7e5ab9018759f893a1952c9420d060016fc19a472b4bb20d1bdd694d1b"
+checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
dependencies = [
- "windows_aarch64_gnullvm 0.52.4",
- "windows_aarch64_msvc 0.52.4",
- "windows_i686_gnu 0.52.4",
- "windows_i686_msvc 0.52.4",
- "windows_x86_64_gnu 0.52.4",
- "windows_x86_64_gnullvm 0.52.4",
- "windows_x86_64_msvc 0.52.4",
+ "windows_aarch64_gnullvm 0.52.6",
+ "windows_aarch64_msvc 0.52.6",
+ "windows_i686_gnu 0.52.6",
+ "windows_i686_gnullvm",
+ "windows_i686_msvc 0.52.6",
+ "windows_x86_64_gnu 0.52.6",
+ "windows_x86_64_gnullvm 0.52.6",
+ "windows_x86_64_msvc 0.52.6",
]
[[package]]
@@ -1917,9 +1943,9 @@ checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8"
[[package]]
name = "windows_aarch64_gnullvm"
-version = "0.52.4"
+version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bcf46cf4c365c6f2d1cc93ce535f2c8b244591df96ceee75d8e83deb70a9cac9"
+checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
[[package]]
name = "windows_aarch64_msvc"
@@ -1929,9 +1955,9 @@ checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc"
[[package]]
name = "windows_aarch64_msvc"
-version = "0.52.4"
+version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "da9f259dd3bcf6990b55bffd094c4f7235817ba4ceebde8e6d11cd0c5633b675"
+checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
[[package]]
name = "windows_i686_gnu"
@@ -1941,9 +1967,15 @@ checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e"
[[package]]
name = "windows_i686_gnu"
-version = "0.52.4"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"
+
+[[package]]
+name = "windows_i686_gnullvm"
+version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b474d8268f99e0995f25b9f095bc7434632601028cf86590aea5c8a5cb7801d3"
+checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
[[package]]
name = "windows_i686_msvc"
@@ -1953,9 +1985,9 @@ checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406"
[[package]]
name = "windows_i686_msvc"
-version = "0.52.4"
+version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1515e9a29e5bed743cb4415a9ecf5dfca648ce85ee42e15873c3cd8610ff8e02"
+checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
[[package]]
name = "windows_x86_64_gnu"
@@ -1965,9 +1997,9 @@ checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e"
[[package]]
name = "windows_x86_64_gnu"
-version = "0.52.4"
+version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5eee091590e89cc02ad514ffe3ead9eb6b660aedca2183455434b93546371a03"
+checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
[[package]]
name = "windows_x86_64_gnullvm"
@@ -1977,9 +2009,9 @@ checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc"
[[package]]
name = "windows_x86_64_gnullvm"
-version = "0.52.4"
+version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "77ca79f2451b49fa9e2af39f0747fe999fcda4f5e241b2898624dca97a1f2177"
+checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
[[package]]
name = "windows_x86_64_msvc"
@@ -1989,6 +2021,6 @@ checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538"
[[package]]
name = "windows_x86_64_msvc"
-version = "0.52.4"
+version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "32b752e52a2da0ddfbdbcc6fceadfeede4c939ed16d13e648833a61dfb611ed8"
+checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
diff --git a/support/texlab/Cargo.toml b/support/texlab/Cargo.toml
index 3894cb649f..c898466e4e 100644
--- a/support/texlab/Cargo.toml
+++ b/support/texlab/Cargo.toml
@@ -3,13 +3,33 @@ members = ["crates/*"]
resolver = "2"
[workspace.package]
+version = "5.21.0"
license = "GPL-3.0"
authors = [
"Eric Förster <eric.foerster@outlook.com>",
"Patrick Förster <patrick.foerster@outlook.de>",
]
edition = "2021"
-rust-version = "1.75"
+rust-version = "1.80"
+
+[workspace.dependencies]
+anyhow = "1.0.90"
+criterion = "0.5.1"
+crossbeam-channel = "0.5.13"
+expect-test = "1.5.0"
+itertools = "0.13.0"
+log = "0.4.22"
+notify = "6.1.1"
+once_cell = "1.20.2"
+regex = "1.11.0"
+rowan = "0.15.16"
+rustc-hash = "2.0.0"
+serde = { version = "1.0.210", features = ["derive"] }
+serde_json = "1.0.132"
+tempfile = "3.13.0"
+titlecase = "3.3.0"
+unicode-normalization = "0.1.24"
+url = "2.5.2"
[profile.release]
lto = "thin"
diff --git a/support/texlab/crates/base-db/Cargo.toml b/support/texlab/crates/base-db/Cargo.toml
index ca477c496c..04fde63b56 100644
--- a/support/texlab/crates/base-db/Cargo.toml
+++ b/support/texlab/crates/base-db/Cargo.toml
@@ -10,20 +10,20 @@ rust-version.workspace = true
bibtex-utils = { path = "../bibtex-utils" }
dirs = "5.0.1"
distro = { path = "../distro" }
-itertools = "0.12.1"
+itertools.workspace = true
line-index = { path = "../line-index" }
-log = "0.4.21"
-notify = "6.0.1"
-once_cell = "1.19.0"
+log.workspace = true
+notify.workspace = true
+once_cell.workspace = true
parser = { path = "../parser" }
percent-encoding = "2.3.0"
-regex = "1.10.4"
-rowan = "0.15.15"
-rustc-hash = "1.1.0"
+regex.workspace = true
+rowan.workspace = true
+rustc-hash.workspace = true
shellexpand = "3.1.0"
syntax = { path = "../syntax" }
-titlecase = "3.0.0"
-url = "2.5.0"
+titlecase.workspace = true
+url.workspace = true
[lib]
doctest = false
diff --git a/support/texlab/crates/base-db/src/config.rs b/support/texlab/crates/base-db/src/config.rs
index e4c827e61c..5774f2a0ec 100644
--- a/support/texlab/crates/base-db/src/config.rs
+++ b/support/texlab/crates/base-db/src/config.rs
@@ -68,6 +68,7 @@ pub enum Formatter {
pub struct LatexIndentConfig {
pub local: Option<String>,
pub modify_line_breaks: bool,
+ pub replacement: Option<String>,
}
#[derive(Debug, Default)]
@@ -80,6 +81,7 @@ pub struct SymbolConfig {
pub struct InlayHintConfig {
pub label_definitions: bool,
pub label_references: bool,
+ pub max_length: Option<usize>,
}
#[derive(Debug)]
@@ -140,6 +142,7 @@ impl Default for InlayHintConfig {
Self {
label_definitions: true,
label_references: true,
+ max_length: None,
}
}
}
diff --git a/support/texlab/crates/base-db/src/deps/discover.rs b/support/texlab/crates/base-db/src/deps/discover.rs
index cbcab4d8fb..3039d7b0f4 100644
--- a/support/texlab/crates/base-db/src/deps/discover.rs
+++ b/support/texlab/crates/base-db/src/deps/discover.rs
@@ -15,7 +15,7 @@ pub fn watch(
) {
let roots = workspace
.iter()
- .map(|document| &document.dir)
+ .filter_map(|document| document.dir.as_ref())
.filter(|dir| dir.scheme() == "file")
.unique()
.map(|dir| ProjectRoot::walk_and_find(workspace, dir));
diff --git a/support/texlab/crates/base-db/src/deps/graph.rs b/support/texlab/crates/base-db/src/deps/graph.rs
index 4b2399b7f8..aec5cea92b 100644
--- a/support/texlab/crates/base-db/src/deps/graph.rs
+++ b/support/texlab/crates/base-db/src/deps/graph.rs
@@ -1,4 +1,4 @@
-use std::{ffi::OsStr, path::PathBuf, rc::Rc};
+use std::{ffi::OsStr, path::PathBuf, rc::Rc, sync::Arc};
use distro::Language;
use itertools::Itertools;
@@ -23,6 +23,7 @@ pub struct Edge {
#[derive(Debug, PartialEq, Eq, Clone, Hash)]
pub enum EdgeData {
DirectLink(Box<DirectLinkData>),
+ FileList(Arc<ProjectRoot>),
AdditionalFiles,
Artifact,
}
@@ -54,7 +55,11 @@ impl Graph {
start: start.uri.clone(),
};
- let root = ProjectRoot::walk_and_find(workspace, &start.dir);
+ let Some(start_dir) = &start.dir else {
+ return graph;
+ };
+
+ let root = ProjectRoot::walk_and_find(workspace, start_dir);
let mut stack = vec![(start, Rc::new(root))];
let mut visited = FxHashSet::default();
@@ -74,6 +79,7 @@ impl Graph {
if visited.insert(edge.target.clone()) {
let new_root = match &edge.data {
EdgeData::DirectLink(data) => data.new_root.clone(),
+ EdgeData::FileList(root) => Some(root.as_ref().clone()),
_ => None,
};
@@ -101,6 +107,10 @@ impl Graph {
self.add_direct_links(workspace, start);
self.add_artifacts(workspace, start);
self.add_additional_files(workspace, start);
+
+ if workspace.config().syntax.use_file_list {
+ self.add_file_list_links(workspace, start);
+ }
}
fn add_additional_files(&mut self, workspace: &Workspace, start: Start) {
@@ -120,6 +130,43 @@ impl Graph {
}
}
+ fn add_file_list_links(&mut self, workspace: &Workspace, start: Start) -> Option<()> {
+ let file_list = start.source.data.as_file_list()?;
+ let home_dir = HOME_DIR.as_deref();
+
+ let working_dir = file_list
+ .working_dir
+ .as_deref()
+ .and_then(|dir| Url::from_directory_path(dir).ok());
+
+ let working_dir = working_dir.as_ref().or(start.source.dir.as_ref())?;
+ let new_root = Arc::new(ProjectRoot::from_config(workspace, working_dir));
+
+ for target_uri in file_list
+ .inputs
+ .iter()
+ .chain(file_list.outputs.iter())
+ .filter(|path| {
+ path.is_relative()
+ || Language::from_path(&path) == Some(Language::Bib)
+ || home_dir.map_or(false, |home_dir| path.starts_with(home_dir))
+ })
+ .filter_map(|path| working_dir.join(path.to_str()?).ok())
+ {
+ if workspace.lookup(&target_uri).is_some() {
+ self.edges.push(Edge {
+ source: start.source.uri.clone(),
+ target: target_uri,
+ data: EdgeData::FileList(Arc::clone(&new_root)),
+ });
+ } else {
+ self.missing.push(target_uri);
+ }
+ }
+
+ Some(())
+ }
+
fn add_direct_links(&mut self, workspace: &Workspace, start: Start) -> Option<()> {
let data = start.source.data.as_tex()?;
@@ -169,7 +216,7 @@ impl Graph {
.base_dir
.as_deref()
.and_then(|path| start.root.src_dir.join(path).ok())
- .map(|dir| ProjectRoot::walk_and_find(workspace, &dir));
+ .map(|dir| ProjectRoot::from_config(workspace, &dir));
let link_data = DirectLinkData {
link: link.clone(),
@@ -197,27 +244,33 @@ impl Graph {
}
let root = start.root;
- let relative_path = root.compile_dir.make_relative(&start.source.uri).unwrap();
-
- self.add_artifact(
- workspace,
- start.source,
- &root.aux_dir.join(&relative_path).unwrap(),
- "aux",
- );
+ self.add_artifact_group(workspace, start, &root.aux_dir, "aux");
+ self.add_artifact_group(workspace, start, &root.log_dir, "log");
+ self.add_artifact_group(workspace, start, &root.aux_dir, "fls");
+ }
- self.add_artifact(workspace, start.source, &root.aux_dir, "aux");
- self.add_artifact(workspace, start.source, &root.compile_dir, "aux");
+ fn add_artifact_group(
+ &mut self,
+ workspace: &Workspace,
+ start: Start,
+ dir: &Url,
+ extension: &str,
+ ) {
+ let relative_path = start
+ .root
+ .compile_dir
+ .make_relative(&start.source.uri)
+ .unwrap();
self.add_artifact(
workspace,
start.source,
- &root.log_dir.join(&relative_path).unwrap(),
- "log",
+ &dir.join(&relative_path).unwrap(),
+ extension,
);
- self.add_artifact(workspace, start.source, &root.log_dir, "log");
- self.add_artifact(workspace, start.source, &root.compile_dir, "log");
+ self.add_artifact(workspace, start.source, &dir, extension);
+ self.add_artifact(workspace, start.source, &start.root.compile_dir, extension);
}
fn add_artifact(
diff --git a/support/texlab/crates/base-db/src/deps/root.rs b/support/texlab/crates/base-db/src/deps/root.rs
index 03fd41a9a0..aa3969353d 100644
--- a/support/texlab/crates/base-db/src/deps/root.rs
+++ b/support/texlab/crates/base-db/src/deps/root.rs
@@ -45,7 +45,7 @@ impl ProjectRoot {
pub fn from_tectonic(workspace: &Workspace, dir: &Url) -> Option<Self> {
let exists = workspace
.iter()
- .filter(|document| document.dir == *dir)
+ .filter(|document| document.dir.as_ref() == Some(dir))
.any(|document| matches!(document.data, DocumentData::Tectonic));
if !exists {
@@ -77,7 +77,7 @@ impl ProjectRoot {
let config = workspace.config();
let rcfile = workspace
.iter()
- .filter(|document| document.dir == *dir)
+ .filter(|document| document.dir.as_ref() == Some(dir))
.find_map(|document| document.data.as_latexmkrc())?;
let compile_dir = dir.clone();
@@ -121,7 +121,7 @@ impl ProjectRoot {
pub fn from_rootfile(workspace: &Workspace, dir: &Url) -> Option<Self> {
let exists = workspace
.iter()
- .filter(|document| document.dir == *dir)
+ .filter(|document| document.dir.as_ref() == Some(dir))
.any(|document| matches!(document.data, DocumentData::Root));
if !exists {
diff --git a/support/texlab/crates/base-db/src/document.rs b/support/texlab/crates/base-db/src/document.rs
index 7a388129fd..0b81fa2871 100644
--- a/support/texlab/crates/base-db/src/document.rs
+++ b/support/texlab/crates/base-db/src/document.rs
@@ -3,7 +3,7 @@ use std::path::PathBuf;
use distro::Language;
use line_index::{LineCol, LineIndex};
use rowan::TextRange;
-use syntax::{bibtex, latex, latexmkrc::LatexmkrcData, BuildError};
+use syntax::{bibtex, file_list::FileList, latex, latexmkrc::LatexmkrcData, BuildError};
use url::Url;
use crate::{semantics, Config};
@@ -28,7 +28,7 @@ pub struct DocumentParams<'a> {
#[derive(Clone)]
pub struct Document {
pub uri: Url,
- pub dir: Url,
+ pub dir: Option<Url>,
pub path: Option<PathBuf>,
pub text: String,
pub line_index: LineIndex,
@@ -42,7 +42,7 @@ impl Document {
pub fn parse(params: DocumentParams) -> Self {
let DocumentParams { uri, text, .. } = params;
- let dir = uri.join(".").unwrap();
+ let dir = uri.join(".").ok();
let path = if uri.scheme() == "file" {
uri.to_file_path().ok()
@@ -56,7 +56,10 @@ impl Document {
Language::Tex => {
let green = parser::parse_latex(&text, &params.config.syntax);
let mut semantics = semantics::tex::Semantics::default();
- semantics.process_root(&latex::SyntaxNode::new_root(green.clone()));
+ semantics.process_root(
+ &params.config.syntax,
+ &latex::SyntaxNode::new_root(green.clone()),
+ );
DocumentData::Tex(TexDocumentData { green, semantics })
}
Language::Bib => {
@@ -86,6 +89,7 @@ impl Document {
DocumentData::Latexmkrc(data)
}
Language::Tectonic => DocumentData::Tectonic,
+ Language::FileList => DocumentData::FileList(parser::parse_file_list(&text)),
};
Self {
@@ -143,6 +147,7 @@ pub enum DocumentData {
Root,
Latexmkrc(LatexmkrcData),
Tectonic,
+ FileList(FileList),
}
impl DocumentData {
@@ -185,6 +190,14 @@ impl DocumentData {
None
}
}
+
+ pub fn as_file_list(&self) -> Option<&FileList> {
+ if let DocumentData::FileList(data) = self {
+ Some(data)
+ } else {
+ None
+ }
+ }
}
#[derive(Debug, Clone)]
diff --git a/support/texlab/crates/base-db/src/semantics/auxiliary.rs b/support/texlab/crates/base-db/src/semantics/auxiliary.rs
index 8c9fe012e6..bb9a2c065c 100644
--- a/support/texlab/crates/base-db/src/semantics/auxiliary.rs
+++ b/support/texlab/crates/base-db/src/semantics/auxiliary.rs
@@ -5,6 +5,7 @@ use syntax::latex::{self, HasCurly};
#[derive(Debug, Clone, Default)]
pub struct Semantics {
pub label_numbers: FxHashMap<String, String>,
+ pub section_numbers: FxHashMap<String, String>,
}
impl Semantics {
@@ -18,6 +19,9 @@ impl Semantics {
if let Some(label_number) = latex::LabelNumber::cast(node.clone()) {
self.process_label_number(&label_number);
}
+ if let Some(toc_line) = latex::TocContentsLine::cast(node.clone()) {
+ self.process_toc_line(&toc_line);
+ }
}
fn process_label_number(&mut self, label_number: &latex::LabelNumber) -> Option<()> {
@@ -40,4 +44,36 @@ impl Semantics {
self.label_numbers.insert(name, text);
Some(())
}
+
+ fn process_toc_line(&mut self, toc_line: &latex::TocContentsLine) -> Option<()> {
+ let unit = toc_line.unit().and_then(|u| u.content_text())?.to_string();
+
+ if [
+ "part",
+ "chapter",
+ "section",
+ "subsection",
+ "subsubsection",
+ "paragraph",
+ "subparagraph",
+ ]
+ .contains(&unit.as_str())
+ {
+ let line = toc_line.line()?;
+ let name = line.syntax().children().find_map(|child| {
+ latex::Text::cast(child.clone())?;
+ Some(child)
+ })?;
+ let name = name.to_string();
+
+ let num_line = line
+ .syntax()
+ .children()
+ .find_map(|child| latex::TocNumberLine::cast(child.clone()))?;
+ let number = num_line.number()?;
+ let number = number.content_text()?.replace(['{', '}'], "");
+ self.section_numbers.insert(name, number);
+ }
+ Some(())
+ }
}
diff --git a/support/texlab/crates/base-db/src/semantics/tex.rs b/support/texlab/crates/base-db/src/semantics/tex.rs
index 7e4c926f5d..7d150fc4b3 100644
--- a/support/texlab/crates/base-db/src/semantics/tex.rs
+++ b/support/texlab/crates/base-db/src/semantics/tex.rs
@@ -3,7 +3,28 @@ use rustc_hash::FxHashSet;
use syntax::latex::{self, HasBrack, HasCurly};
use titlecase::titlecase;
+use parser::SyntaxConfig;
+
use super::Span;
+use crate::semantics::tex::latex::SyntaxToken;
+
+fn maybe_prepend_prefix(
+ map: &Vec<(String, String)>,
+ command: &Option<SyntaxToken>,
+ name: &Span,
+) -> Span {
+ match command {
+ Some(x) => Span::new(
+ map.iter()
+ .find_map(|(k, v)| if k == &x.text()[1..] { Some(v) } else { None })
+ .unwrap_or(&String::new())
+ .to_owned()
+ + &name.text,
+ name.range,
+ ),
+ None => name.clone(),
+ }
+}
#[derive(Debug, Clone, Default)]
pub struct Semantics {
@@ -16,20 +37,26 @@ pub struct Semantics {
pub graphics_paths: FxHashSet<String>,
pub can_be_root: bool,
pub can_be_compiled: bool,
+ pub diagnostic_suppressions: Vec<TextRange>,
+ pub bibitems: FxHashSet<Span>,
}
impl Semantics {
- pub fn process_root(&mut self, root: &latex::SyntaxNode) {
+ pub fn process_root(&mut self, conf: &SyntaxConfig, root: &latex::SyntaxNode) {
for node in root.descendants_with_tokens() {
match node {
latex::SyntaxElement::Node(node) => {
- self.process_node(&node);
+ self.process_node(conf, &node);
}
- latex::SyntaxElement::Token(token) => {
- if token.kind() == latex::COMMAND_NAME {
- self.commands.push(Span::command(&token));
+ latex::SyntaxElement::Token(token) => match token.kind() {
+ latex::COMMAND_NAME => {
+ self.commands.push(Span::command(&token));
}
- }
+ latex::COMMENT if token.text().contains("texlab: ignore") => {
+ self.diagnostic_suppressions.push(token.text_range());
+ }
+ _ => {}
+ },
};
}
@@ -40,17 +67,17 @@ impl Semantics {
.any(|link| link.kind == LinkKind::Cls && link.path.text == "subfiles");
}
- fn process_node(&mut self, node: &latex::SyntaxNode) {
+ fn process_node(&mut self, conf: &SyntaxConfig, node: &latex::SyntaxNode) {
if let Some(include) = latex::Include::cast(node.clone()) {
self.process_include(include);
} else if let Some(import) = latex::Import::cast(node.clone()) {
self.process_import(import);
} else if let Some(label) = latex::LabelDefinition::cast(node.clone()) {
- self.process_label_definition(label);
+ self.process_label_definition(conf, label);
} else if let Some(label) = latex::LabelReference::cast(node.clone()) {
- self.process_label_reference(label);
+ self.process_label_reference(conf, label);
} else if let Some(label) = latex::LabelReferenceRange::cast(node.clone()) {
- self.process_label_reference_range(label);
+ self.process_label_reference_range(conf, label);
} else if let Some(citation) = latex::Citation::cast(node.clone()) {
self.process_citation(citation);
} else if let Some(environment) = latex::Environment::cast(node.clone()) {
@@ -59,6 +86,8 @@ impl Semantics {
self.process_theorem_definition(theorem_def);
} else if let Some(graphics_path) = latex::GraphicsPath::cast(node.clone()) {
self.process_graphics_path(graphics_path);
+ } else if let Some(bibitem) = latex::BibItem::cast(node.clone()) {
+ self.process_bibitem(bibitem);
}
}
@@ -111,7 +140,7 @@ impl Semantics {
});
}
- fn process_label_definition(&mut self, label: latex::LabelDefinition) {
+ fn process_label_definition(&mut self, conf: &SyntaxConfig, label: latex::LabelDefinition) {
let Some(name) = label.name().and_then(|group| group.key()) else {
return;
};
@@ -190,13 +219,14 @@ impl Semantics {
self.labels.push(Label {
kind: LabelKind::Definition,
- name,
+ cmd: label.command().map(|x| x.text()[1..].to_string()),
+ name: maybe_prepend_prefix(&conf.label_definition_prefixes, &label.command(), &name),
targets: objects,
full_range,
});
}
- fn process_label_reference(&mut self, label: latex::LabelReference) {
+ fn process_label_reference(&mut self, conf: &SyntaxConfig, label: latex::LabelReference) {
let Some(name_list) = label.name_list() else {
return;
};
@@ -207,7 +237,12 @@ impl Semantics {
if !name.text.contains('#') {
self.labels.push(Label {
kind: LabelKind::Reference,
- name,
+ cmd: label.command().map(|x| x.text()[1..].to_string()),
+ name: maybe_prepend_prefix(
+ &conf.label_reference_prefixes,
+ &label.command(),
+ &name,
+ ),
targets: Vec::new(),
full_range,
});
@@ -215,14 +250,23 @@ impl Semantics {
}
}
- fn process_label_reference_range(&mut self, label: latex::LabelReferenceRange) {
+ fn process_label_reference_range(
+ &mut self,
+ conf: &SyntaxConfig,
+ label: latex::LabelReferenceRange,
+ ) {
let full_range = latex::small_range(&label);
if let Some(from) = label.from().and_then(|group| group.key()) {
let name = Span::from(&from);
if !name.text.contains('#') {
self.labels.push(Label {
kind: LabelKind::ReferenceRange,
- name,
+ cmd: label.command().map(|x| x.text()[1..].to_string()),
+ name: maybe_prepend_prefix(
+ &conf.label_reference_prefixes,
+ &label.command(),
+ &name,
+ ),
targets: Vec::new(),
full_range,
});
@@ -234,7 +278,12 @@ impl Semantics {
if !name.text.contains('#') {
self.labels.push(Label {
kind: LabelKind::ReferenceRange,
- name,
+ cmd: label.command().map(|x| x.text()[1..].to_string()),
+ name: maybe_prepend_prefix(
+ &conf.label_reference_prefixes,
+ &label.command(),
+ &name,
+ ),
targets: Vec::new(),
full_range,
});
@@ -288,6 +337,16 @@ impl Semantics {
self.graphics_paths.insert(path.to_string());
}
}
+
+ fn process_bibitem(&mut self, bibitem: latex::BibItem) {
+ if let Some(name) = bibitem.name() {
+ if let Some(key) = name.key() {
+ self.bibitems.insert(
+ Span::from(&key)
+ );
+ }
+ }
+ }
}
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Copy, Hash)]
@@ -336,6 +395,7 @@ pub enum LabelKind {
#[derive(Debug, Clone)]
pub struct Label {
pub kind: LabelKind,
+ pub cmd: Option<String>,
pub name: Span,
pub targets: Vec<LabelTarget>,
pub full_range: TextRange,
diff --git a/support/texlab/crates/bibfmt/Cargo.toml b/support/texlab/crates/bibfmt/Cargo.toml
index a712908d7d..c4931f87bb 100644
--- a/support/texlab/crates/bibfmt/Cargo.toml
+++ b/support/texlab/crates/bibfmt/Cargo.toml
@@ -7,7 +7,7 @@ edition.workspace = true
rust-version.workspace = true
[dependencies]
-rowan = "0.15.15"
+rowan.workspace = true
syntax = { path = "../syntax" }
line-index = { path = "../line-index" }
@@ -15,5 +15,5 @@ line-index = { path = "../line-index" }
doctest = false
[dev-dependencies]
-expect-test = "1.5.0"
+expect-test.workspace = true
parser = { path = "../parser" }
diff --git a/support/texlab/crates/bibtex-utils/Cargo.toml b/support/texlab/crates/bibtex-utils/Cargo.toml
index c20508107c..1271823eac 100644
--- a/support/texlab/crates/bibtex-utils/Cargo.toml
+++ b/support/texlab/crates/bibtex-utils/Cargo.toml
@@ -8,16 +8,16 @@ rust-version.workspace = true
[dependencies]
chrono = { version = "0.4.38", default-features = false, features = ["std"] }
-human_name = "2.0.3"
-itertools = "0.12.1"
-rowan = "0.15.15"
-rustc-hash = "1.1.0"
+human_name = "2.0.4"
+itertools.workspace = true
+rowan.workspace = true
+rustc-hash.workspace = true
syntax = { path = "../syntax" }
-unicode-normalization = "0.1.23"
+unicode-normalization.workspace = true
[lib]
doctest = false
[dev-dependencies]
-expect-test = "1.5.0"
+expect-test.workspace = true
parser = { path = "../parser" }
diff --git a/support/texlab/crates/citeproc/Cargo.toml b/support/texlab/crates/citeproc/Cargo.toml
index 9e187f88e6..9ad0c82e56 100644
--- a/support/texlab/crates/citeproc/Cargo.toml
+++ b/support/texlab/crates/citeproc/Cargo.toml
@@ -10,17 +10,17 @@ rust-version.workspace = true
bibtex-utils = { path = "../bibtex-utils" }
base-db = { path = "../base-db" }
isocountry = "0.3.2"
-itertools = "0.12.1"
-rowan = "0.15.15"
-rustc-hash = "1.1.0"
+itertools.workspace = true
+rowan.workspace = true
+rustc-hash.workspace = true
syntax = { path = "../syntax" }
-titlecase = "3.0.0"
-unicode-normalization = "0.1.23"
-url = "2.5.0"
+titlecase.workspace = true
+unicode-normalization.workspace = true
+url.workspace = true
[lib]
doctest = false
[dev-dependencies]
-expect-test = "1.5.0"
+expect-test.workspace = true
parser = { path = "../parser" }
diff --git a/support/texlab/crates/commands/Cargo.toml b/support/texlab/crates/commands/Cargo.toml
index 095828fbc5..b348ad2b87 100644
--- a/support/texlab/crates/commands/Cargo.toml
+++ b/support/texlab/crates/commands/Cargo.toml
@@ -7,22 +7,22 @@ edition.workspace = true
rust-version.workspace = true
[dependencies]
-anyhow = "1.0.86"
+anyhow.workspace = true
base-db = { path = "../base-db" }
-bstr = "1.9.1"
-crossbeam-channel = "0.5.12"
-itertools = "0.12.1"
-libc = "0.2.154"
-log = "0.4.21"
-rowan = "0.15.15"
-rustc-hash = "1.1.0"
+bstr = "1.10.0"
+crossbeam-channel.workspace = true
+itertools.workspace = true
+libc = "0.2.161"
+log.workspace = true
+rowan.workspace = true
+rustc-hash.workspace = true
syntax = { path = "../syntax" }
-thiserror = "1.0.59"
-url = "2.5.0"
+thiserror = "1.0.64"
+url.workspace = true
[dev-dependencies]
distro = { path = "../distro" }
-expect-test = "1.5.0"
+expect-test.workspace = true
test-utils = { path = "../test-utils" }
[lib]
diff --git a/support/texlab/crates/commands/src/build.rs b/support/texlab/crates/commands/src/build.rs
index 34d39f26e4..23a6e16b7b 100644
--- a/support/texlab/crates/commands/src/build.rs
+++ b/support/texlab/crates/commands/src/build.rs
@@ -47,6 +47,10 @@ impl BuildCommand {
.next()
.unwrap_or(document);
+ let Some(document_dir) = &document.dir else {
+ return Err(BuildError::NotLocal(document.uri.clone()));
+ };
+
let Some(path) = document.path.as_deref().and_then(Path::to_str) else {
return Err(BuildError::NotLocal(document.uri.clone()));
};
@@ -55,7 +59,7 @@ impl BuildCommand {
let program = config.program.clone();
let args = replace_placeholders(&config.args, &[('f', path)]);
- let root = ProjectRoot::walk_and_find(workspace, &document.dir);
+ let root = ProjectRoot::walk_and_find(workspace, document_dir);
let Ok(working_dir) = root.compile_dir.to_file_path() else {
return Err(BuildError::NotLocal(document.uri.clone()));
diff --git a/support/texlab/crates/commands/src/clean.rs b/support/texlab/crates/commands/src/clean.rs
index d4ec6b24f4..e429d1afa2 100644
--- a/support/texlab/crates/commands/src/clean.rs
+++ b/support/texlab/crates/commands/src/clean.rs
@@ -21,7 +21,11 @@ impl CleanCommand {
anyhow::bail!("document '{}' is not a local file", document.uri)
};
- let root = ProjectRoot::walk_and_find(workspace, &document.dir);
+ let Some(document_dir) = &document.dir else {
+ anyhow::bail!("document '{}' is not a local file", document.uri)
+ };
+
+ let root = ProjectRoot::walk_and_find(workspace, document_dir);
let flag = match target {
CleanTarget::Auxiliary => "-c",
diff --git a/support/texlab/crates/commands/src/dep_graph.rs b/support/texlab/crates/commands/src/dep_graph.rs
index fe9ff3829c..86b49da0ac 100644
--- a/support/texlab/crates/commands/src/dep_graph.rs
+++ b/support/texlab/crates/commands/src/dep_graph.rs
@@ -48,6 +48,7 @@ pub fn show_dependency_graph(workspace: &Workspace) -> Result<String> {
base_db::deps::EdgeData::DirectLink(data) => &data.link.path.text,
base_db::deps::EdgeData::AdditionalFiles => "<project>",
base_db::deps::EdgeData::Artifact => "<artifact>",
+ base_db::deps::EdgeData::FileList(_) => "<fls>",
};
writeln!(&mut writer, "\t{source} -> {target} [label=\"{label}\"];")?;
diff --git a/support/texlab/crates/commands/src/fwd_search.rs b/support/texlab/crates/commands/src/fwd_search.rs
index f3480ef3e2..8b6227d8c2 100644
--- a/support/texlab/crates/commands/src/fwd_search.rs
+++ b/support/texlab/crates/commands/src/fwd_search.rs
@@ -84,7 +84,11 @@ impl ForwardSearch {
}
fn find_pdf(workspace: &Workspace, document: &Document) -> Result<PathBuf, ForwardSearchError> {
- let root = ProjectRoot::walk_and_find(workspace, &document.dir);
+ let Some(document_dir) = &document.dir else {
+ return Err(ForwardSearchError::NotLocal(document.uri.clone()));
+ };
+
+ let root = ProjectRoot::walk_and_find(workspace, document_dir);
log::debug!("[FwdSearch] root={root:#?}");
diff --git a/support/texlab/crates/completion-data/Cargo.toml b/support/texlab/crates/completion-data/Cargo.toml
index 970cd6a578..c06a4994c8 100644
--- a/support/texlab/crates/completion-data/Cargo.toml
+++ b/support/texlab/crates/completion-data/Cargo.toml
@@ -7,12 +7,12 @@ edition.workspace = true
rust-version.workspace = true
[dependencies]
-flate2 = "1.0.30"
-itertools = "0.12.1"
-once_cell = "1.19.0"
-rustc-hash = "1.1.0"
-serde = { version = "1.0.202", features = ["derive"] }
-serde_json = "1.0.117"
+flate2 = "1.0.34"
+itertools.workspace = true
+once_cell.workspace = true
+rustc-hash.workspace = true
+serde.workspace = true
+serde_json.workspace = true
[lib]
doctest = false
diff --git a/support/texlab/crates/completion/Cargo.toml b/support/texlab/crates/completion/Cargo.toml
index e28e04dfc7..e31f254e1c 100644
--- a/support/texlab/crates/completion/Cargo.toml
+++ b/support/texlab/crates/completion/Cargo.toml
@@ -12,16 +12,17 @@ completion-data = { path = "../completion-data" }
fuzzy-matcher = { version = "0.3.7", features = ["compact"] }
line-index = { path = "../line-index" }
rayon = "1.10.0"
-rowan = "0.15.15"
-rustc-hash = "1.1.0"
+rowan.workspace = true
+rustc-hash.workspace = true
syntax = { path = "../syntax" }
-url = "2.5.0"
+url.workspace = true
[dev-dependencies]
-criterion = "0.5.1"
+criterion.workspace = true
distro = { path = "../distro" }
-expect-test = "1.5.0"
+expect-test.workspace = true
test-utils = { path = "../test-utils" }
+parser = { path = "../parser" }
[lib]
doctest = false
diff --git a/support/texlab/crates/completion/src/lib.rs b/support/texlab/crates/completion/src/lib.rs
index b1050052f0..5bfd94d944 100644
--- a/support/texlab/crates/completion/src/lib.rs
+++ b/support/texlab/crates/completion/src/lib.rs
@@ -72,7 +72,7 @@ impl<'a> CompletionItemData<'a> {
Self::Citation(data) => &data.entry.name.text,
Self::Environment(data) => data.name,
Self::GlossaryEntry(data) => &data.name,
- Self::Label(data) => data.name,
+ Self::Label(data) => &data.name,
Self::Color(name) => name,
Self::ColorModel(name) => name,
Self::File(name) => name,
diff --git a/support/texlab/crates/completion/src/providers/include.rs b/support/texlab/crates/completion/src/providers/include.rs
index d0a042252f..f3deb3a108 100644
--- a/support/texlab/crates/completion/src/providers/include.rs
+++ b/support/texlab/crates/completion/src/providers/include.rs
@@ -118,7 +118,7 @@ fn current_dir(
.next()
.map_or(params.document, Clone::clone);
- let root = ProjectRoot::walk_and_find(workspace, &parent.dir);
+ let root = ProjectRoot::walk_and_find(workspace, parent.dir.as_ref()?);
let mut path = PathBuf::new();
if let Some(graphics_path) = graphics_path {
diff --git a/support/texlab/crates/completion/src/providers/label_ref.rs b/support/texlab/crates/completion/src/providers/label_ref.rs
index 6f71ae3241..8b262f13ca 100644
--- a/support/texlab/crates/completion/src/providers/label_ref.rs
+++ b/support/texlab/crates/completion/src/providers/label_ref.rs
@@ -11,12 +11,30 @@ use crate::{
CompletionItem, CompletionItemData, CompletionParams,
};
+fn trim_prefix<'a>(prefix: Option<&'a str>, text: &'a str) -> &'a str {
+ prefix
+ .and_then(|pref| text.strip_prefix(pref))
+ .unwrap_or(text)
+}
+
pub fn complete_label_references<'a>(
params: &'a CompletionParams<'a>,
builder: &mut CompletionBuilder<'a>,
) -> Option<()> {
- let FindResult { cursor, is_math } =
- find_reference(params).or_else(|| find_reference_range(params))?;
+ let FindResult {
+ cursor,
+ is_math,
+ command,
+ } = find_reference(params).or_else(|| find_reference_range(params))?;
+ let ref_pref = params
+ .feature
+ .workspace
+ .config()
+ .syntax
+ .label_reference_prefixes
+ .iter()
+ .find_map(|(k, v)| if *k == command { Some(v) } else { None })
+ .map(|x| x.as_str());
for document in &params.feature.project.documents {
let DocumentData::Tex(data) = &document.data else {
@@ -29,6 +47,10 @@ pub fn complete_label_references<'a>(
.iter()
.filter(|label| label.kind == LabelKind::Definition)
{
+ if ref_pref.map_or(false, |pref| !label.name.text.starts_with(pref)) {
+ continue;
+ }
+ let labeltext = trim_prefix(ref_pref, &label.name.text);
match render_label(params.feature.workspace, &params.feature.project, label) {
Some(rendered_label) => {
if is_math && !matches!(rendered_label.object, RenderedObject::Equation) {
@@ -41,11 +63,12 @@ pub fn complete_label_references<'a>(
_ => None,
};
- let keywords = format!("{} {}", label.name.text, rendered_label.reference());
+ let keywords = format!("{} {}", labeltext, rendered_label.reference());
if let Some(score) = builder.matcher.score(&keywords, &cursor.text) {
+ let name = trim_prefix(ref_pref, &label.name.text);
let data = CompletionItemData::Label(crate::LabelData {
- name: &label.name.text,
+ name,
header,
footer,
object: Some(rendered_label.object),
@@ -59,12 +82,13 @@ pub fn complete_label_references<'a>(
}
None => {
if let Some(score) = builder.matcher.score(&label.name.text, &cursor.text) {
+ let name = trim_prefix(ref_pref, &label.name.text);
let data = CompletionItemData::Label(crate::LabelData {
- name: &label.name.text,
+ name,
header: None,
footer: None,
object: None,
- keywords: label.name.text.clone(),
+ keywords: labeltext.to_string(),
});
builder
@@ -82,20 +106,26 @@ pub fn complete_label_references<'a>(
struct FindResult {
cursor: Span,
is_math: bool,
+ command: String,
}
fn find_reference(params: &CompletionParams) -> Option<FindResult> {
let (cursor, group) = find_curly_group_word_list(params)?;
let reference = latex::LabelReference::cast(group.syntax().parent()?)?;
let is_math = reference.command()?.text() == "\\eqref";
- Some(FindResult { cursor, is_math })
+ Some(FindResult {
+ cursor,
+ is_math,
+ command: reference.command()?.text()[1..].to_string(),
+ })
}
fn find_reference_range(params: &CompletionParams) -> Option<FindResult> {
let (cursor, group) = find_curly_group_word(params)?;
- latex::LabelReferenceRange::cast(group.syntax().parent()?)?;
+ let refrange = latex::LabelReferenceRange::cast(group.syntax().parent()?)?;
Some(FindResult {
cursor,
is_math: false,
+ command: refrange.command()?.text()[1..].to_string(),
})
}
diff --git a/support/texlab/crates/completion/src/tests.rs b/support/texlab/crates/completion/src/tests.rs
index c6bed6e08e..8c68b71dd9 100644
--- a/support/texlab/crates/completion/src/tests.rs
+++ b/support/texlab/crates/completion/src/tests.rs
@@ -1,11 +1,17 @@
-use base_db::FeatureParams;
+use base_db::{Config, FeatureParams};
use expect_test::{expect, Expect};
+use parser::SyntaxConfig;
use rowan::TextRange;
use crate::CompletionParams;
-fn check(input: &str, expect: Expect) {
- let fixture = test_utils::fixture::Fixture::parse(input);
+fn check_with_syntax_config(config: SyntaxConfig, input: &str, expect: Expect) {
+ let mut fixture = test_utils::fixture::Fixture::parse(input);
+ fixture.workspace.set_config(Config {
+ syntax: config,
+ ..Config::default()
+ });
+ let fixture = fixture;
let (offset, spec) = fixture
.documents
@@ -37,6 +43,10 @@ fn check(input: &str, expect: Expect) {
expect.assert_debug_eq(&items);
}
+fn check(input: &str, expect: Expect) {
+ check_with_syntax_config(SyntaxConfig::default(), input, expect)
+}
+
#[test]
fn acronym_ref_simple() {
check(
@@ -2134,3 +2144,200 @@ fn issue_885() {
"#]],
);
}
+
+#[test]
+fn test_custom_label_prefix_ref() {
+ let mut config = SyntaxConfig::default();
+ config.label_definition_commands.insert("asm".to_string());
+ config
+ .label_definition_prefixes
+ .push(("asm".to_string(), "asm:".to_string()));
+
+ check_with_syntax_config(
+ config,
+ r#"
+%! main.tex
+ \begin{enumerate}\label{baz}
+ \asm{foo}{what}
+ \end{enumerate}
+
+ \ref{}
+ |
+% Comment"#,
+ expect![[r#"
+ [
+ Label(
+ LabelData {
+ name: "asm:foo",
+ header: None,
+ footer: None,
+ object: None,
+ keywords: "asm:foo",
+ },
+ ),
+ Label(
+ LabelData {
+ name: "baz",
+ header: None,
+ footer: None,
+ object: None,
+ keywords: "baz",
+ },
+ ),
+ ]
+ "#]],
+ );
+}
+
+#[test]
+fn test_custom_label_prefix_custom_ref() {
+ let mut config = SyntaxConfig::default();
+ config.label_definition_commands.insert("asm".to_string());
+ config
+ .label_definition_prefixes
+ .push(("asm".to_string(), "asm:".to_string()));
+ config.label_reference_commands.insert("asmref".to_string());
+ config
+ .label_reference_prefixes
+ .push(("asmref".to_string(), "asm:".to_string()));
+
+ check_with_syntax_config(
+ config,
+ r#"
+%! main.tex
+ \begin{enumerate}\label{baz}
+ \asm{foo}{what}
+ \end{enumerate}
+
+ \asmref{}
+ |
+% Comment"#,
+ expect![[r#"
+ [
+ Label(
+ LabelData {
+ name: "foo",
+ header: None,
+ footer: None,
+ object: None,
+ keywords: "foo",
+ },
+ ),
+ ]
+ "#]],
+ );
+}
+
+#[test]
+fn test_custom_label_multiple_prefix_custom_ref() {
+ let mut config = SyntaxConfig::default();
+ config
+ .label_definition_commands
+ .extend(vec!["asm", "goal"].into_iter().map(String::from));
+ config.label_definition_prefixes.extend(
+ vec![("asm", "asm:"), ("goal", "goal:")]
+ .into_iter()
+ .map(|(x, y)| (String::from(x), String::from(y))),
+ );
+ config
+ .label_reference_commands
+ .extend(vec!["asmref", "goalref"].into_iter().map(String::from));
+ config.label_reference_prefixes.extend(
+ vec![("asmref", "asm:"), ("goalref", "goal:")]
+ .into_iter()
+ .map(|(x, y)| (String::from(x), String::from(y))),
+ );
+
+ check_with_syntax_config(
+ config,
+ r#"
+%! main.tex
+ \begin{enumerate}\label{baz}
+ \asm{foo}{what}
+ \goal{foo}{what}
+ \end{enumerate}
+
+ \goalref{}
+ |
+% Comment"#,
+ expect![[r#"
+ [
+ Label(
+ LabelData {
+ name: "foo",
+ header: None,
+ footer: None,
+ object: None,
+ keywords: "foo",
+ },
+ ),
+ ]
+ "#]],
+ );
+}
+
+#[test]
+fn test_custom_label_multiple_prefix_ref() {
+ let mut config = SyntaxConfig::default();
+ config
+ .label_definition_commands
+ .extend(vec!["asm", "goal"].into_iter().map(String::from));
+ config.label_definition_prefixes.extend(
+ vec![("asm", "asm:"), ("goal", "goal:")]
+ .into_iter()
+ .map(|(x, y)| (String::from(x), String::from(y))),
+ );
+ config
+ .label_reference_commands
+ .extend(vec!["asmref", "goalref"].into_iter().map(String::from));
+ config.label_reference_prefixes.extend(
+ vec![("asmref", "asm:"), ("goalref", "goal:")]
+ .into_iter()
+ .map(|(x, y)| (String::from(x), String::from(y))),
+ );
+
+ check_with_syntax_config(
+ config,
+ r#"
+%! main.tex
+ \begin{enumerate}\label{baz}
+ \asm{foo}{what}
+ \goal{foo}{what}
+ \end{enumerate}
+
+ \ref{}
+ |
+% Comment"#,
+ expect![[r#"
+ [
+ Label(
+ LabelData {
+ name: "asm:foo",
+ header: None,
+ footer: None,
+ object: None,
+ keywords: "asm:foo",
+ },
+ ),
+ Label(
+ LabelData {
+ name: "baz",
+ header: None,
+ footer: None,
+ object: None,
+ keywords: "baz",
+ },
+ ),
+ Label(
+ LabelData {
+ name: "goal:foo",
+ header: None,
+ footer: None,
+ object: None,
+ keywords: "goal:foo",
+ },
+ ),
+ ]
+ "#]],
+ );
+}
diff --git a/support/texlab/crates/definition/Cargo.toml b/support/texlab/crates/definition/Cargo.toml
index 63ba15c308..20bf3ed5fc 100644
--- a/support/texlab/crates/definition/Cargo.toml
+++ b/support/texlab/crates/definition/Cargo.toml
@@ -8,12 +8,12 @@ rust-version.workspace = true
[dependencies]
base-db = { path = "../base-db" }
-rowan = "0.15.15"
-rustc-hash = "1.1.0"
+rowan.workspace = true
+rustc-hash.workspace = true
syntax = { path = "../syntax" }
[dev-dependencies]
-itertools = "0.12.1"
+itertools.workspace = true
test-utils = { path = "../test-utils" }
[lib]
diff --git a/support/texlab/crates/definition/src/command.rs b/support/texlab/crates/definition/src/command.rs
index ea7ef8c2c2..4892dad257 100644
--- a/support/texlab/crates/definition/src/command.rs
+++ b/support/texlab/crates/definition/src/command.rs
@@ -27,7 +27,7 @@ pub(super) fn goto_definition(context: &mut DefinitionContext) -> Option<()> {
.filter_map(|node| {
process_old_definition(node.clone()).or_else(|| process_new_definition(node))
})
- .filter(|(_, command)| command.text() == name.text())
+ .filter(|(_, command)| command.text() == name.text().trim_end_matches("*"))
.map(|(target_range, command)| DefinitionResult {
origin_selection_range,
target: document,
diff --git a/support/texlab/crates/diagnostics/Cargo.toml b/support/texlab/crates/diagnostics/Cargo.toml
index 1cb09fdec9..51bf19c0a3 100644
--- a/support/texlab/crates/diagnostics/Cargo.toml
+++ b/support/texlab/crates/diagnostics/Cargo.toml
@@ -10,19 +10,19 @@ rust-version.workspace = true
base-db = { path = "../base-db" }
encoding_rs = "0.8.34"
encoding_rs_io = "0.1.7"
-itertools = "0.12.1"
+itertools.workspace = true
line-index = { path = "../line-index" }
-log = "0.4.21"
+log.workspace = true
multimap = "0.10.0"
-once_cell = "1.19.0"
-regex = "1.10.4"
-rowan = "0.15.15"
-rustc-hash = "1.1.0"
+once_cell.workspace = true
+regex.workspace = true
+rowan.workspace = true
+rustc-hash.workspace = true
syntax = { path = "../syntax" }
-url = "2.5.0"
+url.workspace = true
[dev-dependencies]
-expect-test = "1.5.0"
+expect-test.workspace = true
test-utils = { path = "../test-utils" }
[lib]
diff --git a/support/texlab/crates/diagnostics/src/chktex.rs b/support/texlab/crates/diagnostics/src/chktex.rs
index a3f539440d..b7cd80d67b 100644
--- a/support/texlab/crates/diagnostics/src/chktex.rs
+++ b/support/texlab/crates/diagnostics/src/chktex.rs
@@ -36,7 +36,7 @@ impl Command {
return None;
}
- let root = ProjectRoot::walk_and_find(workspace, &parent.dir);
+ let root = ProjectRoot::walk_and_find(workspace, parent.dir.as_ref()?);
let working_dir = root.src_dir.to_file_path().ok()?;
log::debug!("Calling ChkTeX from directory: {}", working_dir.display());
diff --git a/support/texlab/crates/diagnostics/src/citations.rs b/support/texlab/crates/diagnostics/src/citations.rs
index 43d5f495d2..2678d7e456 100644
--- a/support/texlab/crates/diagnostics/src/citations.rs
+++ b/support/texlab/crates/diagnostics/src/citations.rs
@@ -18,13 +18,17 @@ pub fn detect_undefined_citations<'a>(
) -> Option<()> {
let data = document.data.as_tex()?;
+ let bibitems: FxHashSet<&str> = data.semantics.bibitems.iter()
+ .map(|bib| bib.text.as_str())
+ .collect();
+
let entries: FxHashSet<&str> = Entry::find_all(project)
.map(|(_, entry)| entry.name_text())
.collect();
for citation in &data.semantics.citations {
let name = citation.name_text();
- if name != "*" && !entries.contains(name) {
+ if name != "*" && !entries.contains(name) && !bibitems.contains(name) {
let diagnostic = Diagnostic::Tex(citation.name.range, TexError::UndefinedCitation);
results
.entry(document.uri.clone())
@@ -41,24 +45,38 @@ pub fn detect_unused_entries<'a>(
document: &'a Document,
results: &mut FxHashMap<Url, Vec<Diagnostic>>,
) -> Option<()> {
- let data = document.data.as_bib()?;
-
- // If this is a huge bibliography, then don't bother checking for unused entries.
- if data.semantics.entries.len() > MAX_UNUSED_ENTRIES {
- return None;
- }
let citations: FxHashSet<&str> = Citation::find_all(project)
.map(|(_, citation)| citation.name_text())
.collect();
- for entry in &data.semantics.entries {
- if !citations.contains(entry.name.text.as_str()) {
- let diagnostic = Diagnostic::Bib(entry.name.range, BibError::UnusedEntry);
- results
- .entry(document.uri.clone())
- .or_default()
- .push(diagnostic);
+ if let Some(data) = document.data.as_bib()
+ {
+ // If this is a huge bibliography, then don't bother checking for unused entries.
+ if data.semantics.entries.len() > MAX_UNUSED_ENTRIES {
+ return None;
+ }
+
+ for entry in &data.semantics.entries {
+ if !citations.contains(entry.name.text.as_str()) {
+ let diagnostic = Diagnostic::Bib(entry.name.range, BibError::UnusedEntry);
+ results
+ .entry(document.uri.clone())
+ .or_default()
+ .push(diagnostic);
+ }
+ }
+ };
+
+ if let Some(tex_data) = document.data.as_tex(){
+ for bibitem in &tex_data.semantics.bibitems {
+ if !citations.contains(bibitem.text.as_str()) {
+ let diagnostic = Diagnostic::Bib(bibitem.range, BibError::UnusedEntry);
+ results
+ .entry(document.uri.clone())
+ .or_default()
+ .push(diagnostic);
+ }
}
}
diff --git a/support/texlab/crates/diagnostics/src/manager.rs b/support/texlab/crates/diagnostics/src/manager.rs
index 500dc99c13..2829286a17 100644
--- a/support/texlab/crates/diagnostics/src/manager.rs
+++ b/support/texlab/crates/diagnostics/src/manager.rs
@@ -1,5 +1,8 @@
-use base_db::{deps::Project, util::filter_regex_patterns, Document, Owner, Workspace};
+use base_db::{
+ deps::Project, util::filter_regex_patterns, Document, DocumentData, Owner, Workspace,
+};
use multimap::MultiMap;
+use rowan::TextRange;
use rustc_hash::{FxHashMap, FxHashSet};
use url::Url;
@@ -16,7 +19,7 @@ pub struct Manager {
impl Manager {
/// Updates the syntax-based diagnostics for the given document.
pub fn update_syntax(&mut self, workspace: &Workspace, document: &Document) {
- if !Self::is_relevant(document) {
+ if !Self::is_relevant_document(document) {
return;
}
@@ -76,7 +79,7 @@ impl Manager {
for document in workspace
.iter()
- .filter(|document| Self::is_relevant(document))
+ .filter(|document| Self::is_relevant_document(document))
{
let project = Project::from_child(workspace, document);
super::citations::detect_undefined_citations(&project, document, &mut results);
@@ -87,28 +90,78 @@ impl Manager {
super::labels::detect_duplicate_labels(workspace, &mut results);
super::labels::detect_undefined_and_unused_labels(workspace, &mut results);
- let config = &workspace.config().diagnostics;
-
- results.retain(|uri, _| workspace.lookup(uri).map_or(false, Self::is_relevant));
+ results.retain(|uri, _| {
+ workspace
+ .lookup(uri)
+ .map_or(false, Self::is_relevant_document)
+ });
- for diagnostics in results.values_mut() {
- diagnostics.retain(|diagnostic| {
- filter_regex_patterns(
- diagnostic.message(),
- &config.allowed_patterns,
- &config.ignored_patterns,
- )
- });
+ for (uri, diagnostics) in results.iter_mut() {
+ diagnostics
+ .retain_mut(|diagnostic| Self::filter_diagnostic(workspace, uri, diagnostic));
}
results
}
- fn is_relevant(document: &Document) -> bool {
+ fn is_relevant_document(document: &Document) -> bool {
match document.owner {
Owner::Client => true,
Owner::Server => true,
Owner::Distro => false,
}
}
+
+ fn filter_diagnostic(workspace: &Workspace, uri: &Url, diagnostic: &mut Diagnostic) -> bool {
+ let config = &workspace.config().diagnostics;
+
+ if !filter_regex_patterns(
+ diagnostic.message(),
+ &config.allowed_patterns,
+ &config.ignored_patterns,
+ ) {
+ return false;
+ }
+
+ let Some(document) = workspace.lookup(uri) else {
+ return false;
+ };
+
+ let Some(primary_range) = diagnostic.range(&document.line_index) else {
+ return false;
+ };
+
+ if Self::is_ignored(workspace, &document.uri, &primary_range) {
+ return false;
+ }
+
+ let Some(additional_locations) = diagnostic.additional_locations_mut() else {
+ return true;
+ };
+
+ additional_locations.retain(|(uri, range)| !Self::is_ignored(workspace, uri, range));
+ if additional_locations.is_empty() {
+ return false;
+ }
+
+ true
+ }
+
+ fn is_ignored(workspace: &Workspace, uri: &Url, diag_range: &TextRange) -> bool {
+ let Some(document) = workspace.lookup(uri) else {
+ return false;
+ };
+
+ let DocumentData::Tex(data) = &document.data else {
+ return false;
+ };
+
+ let diag_line_col = document.line_index.line_col(diag_range.start());
+
+ data.semantics
+ .diagnostic_suppressions
+ .iter()
+ .map(|r| document.line_index.line_col(r.start()))
+ .any(|r| r.line == diag_line_col.line || r.line + 1 == diag_line_col.line)
+ }
}
diff --git a/support/texlab/crates/diagnostics/src/tests.rs b/support/texlab/crates/diagnostics/src/tests.rs
index 05ad67fc8b..ff5f53ec3e 100644
--- a/support/texlab/crates/diagnostics/src/tests.rs
+++ b/support/texlab/crates/diagnostics/src/tests.rs
@@ -284,6 +284,33 @@ fn test_citation_undefined() {
}
#[test]
+fn test_citation_undefined_ignore() {
+ check(
+ r#"
+%! main.tex
+% texlab: ignore
+\cite{foo}
+"#,
+ expect![[r#"
+ []
+ "#]],
+ )
+}
+
+#[test]
+fn test_citation_undefined_ignore_single_line() {
+ check(
+ r#"
+%! main.tex
+\cite{foo} % texlab: ignore
+"#,
+ expect![[r#"
+ []
+ "#]],
+ )
+}
+
+#[test]
fn test_citation_unused() {
check(
r#"
@@ -306,3 +333,46 @@ fn test_citation_unused() {
"#]],
)
}
+
+#[test]
+fn test_label_duplicate() {
+ check(
+ r#"
+%! main.tex
+\label{foo}
+ ^^^
+\label{foo}
+ ^^^
+\label{foo} % texlab: ignore
+
+\ref{foo}
+"#,
+ expect![[r#"
+ [
+ (
+ "file:///texlab/main.tex",
+ [
+ Tex(
+ 7..10,
+ DuplicateLabel(
+ (
+ "file:///texlab/main.tex",
+ 19..22,
+ ),
+ ),
+ ),
+ Tex(
+ 19..22,
+ DuplicateLabel(
+ (
+ "file:///texlab/main.tex",
+ 7..10,
+ ),
+ ),
+ ),
+ ],
+ ),
+ ]
+ "#]],
+ )
+}
diff --git a/support/texlab/crates/diagnostics/src/types.rs b/support/texlab/crates/diagnostics/src/types.rs
index 9cbbf8936f..9cc195863b 100644
--- a/support/texlab/crates/diagnostics/src/types.rs
+++ b/support/texlab/crates/diagnostics/src/types.rs
@@ -1,9 +1,9 @@
-use line_index::LineCol;
+use line_index::{LineCol, LineIndex};
use rowan::TextRange;
use syntax::BuildError;
use url::Url;
-#[derive(Debug, PartialEq, Eq, Clone)]
+#[derive(PartialEq, Eq, Clone)]
pub enum TexError {
UnexpectedRCurly,
ExpectingRCurly,
@@ -14,7 +14,28 @@ pub enum TexError {
DuplicateLabel(Vec<(Url, TextRange)>),
}
-#[derive(Debug, PartialEq, Eq, Clone)]
+impl std::fmt::Debug for TexError {
+ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+ match self {
+ Self::UnexpectedRCurly => write!(f, "UnexpectedRCurly"),
+ Self::ExpectingRCurly => write!(f, "ExpectingRCurly"),
+ Self::MismatchedEnvironment => write!(f, "MismatchedEnvironment"),
+ Self::UnusedLabel => write!(f, "UnusedLabel"),
+ Self::UndefinedLabel => write!(f, "UndefinedLabel"),
+ Self::UndefinedCitation => write!(f, "UndefinedCitation"),
+ Self::DuplicateLabel(locations) => {
+ let mut t = f.debug_tuple("DuplicateLabel");
+ for (uri, range) in locations {
+ t.field(&(uri.as_str(), range));
+ }
+
+ t.finish()
+ }
+ }
+ }
+}
+
+#[derive(PartialEq, Eq, Clone)]
pub enum BibError {
ExpectingLCurly,
ExpectingKey,
@@ -25,6 +46,27 @@ pub enum BibError {
DuplicateEntry(Vec<(Url, TextRange)>),
}
+impl std::fmt::Debug for BibError {
+ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+ match self {
+ Self::ExpectingLCurly => write!(f, "ExpectingLCurly"),
+ Self::ExpectingKey => write!(f, "ExpectingKey"),
+ Self::ExpectingRCurly => write!(f, "ExpectingRCurly"),
+ Self::ExpectingEq => write!(f, "ExpectingEq"),
+ Self::ExpectingFieldValue => write!(f, "ExpectingFieldValue"),
+ Self::UnusedEntry => write!(f, "UnusedEntry"),
+ Self::DuplicateEntry(locations) => {
+ let mut t = f.debug_tuple("DuplicateEntry");
+ for (uri, range) in locations {
+ t.field(&(uri.as_str(), range));
+ }
+
+ t.finish()
+ }
+ }
+ }
+}
+
#[derive(Debug, PartialEq, Eq, Clone)]
pub struct ChktexError {
pub start: LineCol,
@@ -74,4 +116,42 @@ impl Diagnostic {
Diagnostic::Chktex(error) => &error.message,
}
}
+
+ pub fn range(&self, line_index: &LineIndex) -> Option<TextRange> {
+ Some(match self {
+ Diagnostic::Tex(range, _) => *range,
+ Diagnostic::Bib(range, _) => *range,
+ Diagnostic::Build(range, _) => *range,
+ Diagnostic::Chktex(error) => {
+ let start = line_index.offset(error.start)?;
+ let end = line_index.offset(error.end)?;
+ TextRange::new(start, end)
+ }
+ })
+ }
+
+ pub fn additional_locations_mut(&mut self) -> Option<&mut Vec<(Url, TextRange)>> {
+ match self {
+ Diagnostic::Tex(_, err) => match err {
+ TexError::UnexpectedRCurly
+ | TexError::ExpectingRCurly
+ | TexError::MismatchedEnvironment
+ | TexError::UnusedLabel
+ | TexError::UndefinedLabel
+ | TexError::UndefinedCitation => None,
+ TexError::DuplicateLabel(locations) => Some(locations),
+ },
+ Diagnostic::Bib(_, err) => match err {
+ BibError::ExpectingLCurly
+ | BibError::ExpectingKey
+ | BibError::ExpectingRCurly
+ | BibError::ExpectingEq
+ | BibError::ExpectingFieldValue
+ | BibError::UnusedEntry => None,
+ BibError::DuplicateEntry(locations) => Some(locations),
+ },
+ Diagnostic::Chktex(_) => None,
+ Diagnostic::Build(_, _) => None,
+ }
+ }
}
diff --git a/support/texlab/crates/distro/Cargo.toml b/support/texlab/crates/distro/Cargo.toml
index dea6a56979..de89de935f 100644
--- a/support/texlab/crates/distro/Cargo.toml
+++ b/support/texlab/crates/distro/Cargo.toml
@@ -7,8 +7,8 @@ edition.workspace = true
rust-version.workspace = true
[dependencies]
-anyhow = "1.0.86"
-rustc-hash = "1.1.0"
+anyhow.workspace = true
+rustc-hash.workspace = true
[lib]
doctest = false
diff --git a/support/texlab/crates/distro/src/language.rs b/support/texlab/crates/distro/src/language.rs
index 201ed0702b..0a94a93604 100644
--- a/support/texlab/crates/distro/src/language.rs
+++ b/support/texlab/crates/distro/src/language.rs
@@ -9,6 +9,7 @@ pub enum Language {
Root,
Latexmkrc,
Tectonic,
+ FileList,
}
impl Language {
@@ -32,6 +33,7 @@ impl Language {
"bib" | "bibtex" => Some(Self::Bib),
"aux" => Some(Self::Aux),
"log" => Some(Self::Log),
+ "fls" => Some(Self::FileList),
_ => None,
}
}
diff --git a/support/texlab/crates/distro/src/lib.rs b/support/texlab/crates/distro/src/lib.rs
index 5c0dbe51fb..cf1420baa9 100644
--- a/support/texlab/crates/distro/src/lib.rs
+++ b/support/texlab/crates/distro/src/lib.rs
@@ -4,7 +4,10 @@ mod language;
mod miktex;
mod texlive;
-use std::process::{Command, Stdio};
+use std::{
+ env,
+ process::{Command, Stdio},
+};
use anyhow::Result;
@@ -70,8 +73,14 @@ impl Distro {
DistroKind::Tectonic | DistroKind::Unknown => FileNameDB::default(),
};
- if let Some(bibinputs) = std::env::var_os("BIBINPUTS") {
- for dir in std::env::split_paths(&bibinputs) {
+ Self::read_env_dir(&mut file_name_db, "TEXINPUTS");
+ Self::read_env_dir(&mut file_name_db, "BIBINPUTS");
+ Ok(Self { kind, file_name_db })
+ }
+
+ fn read_env_dir(file_name_db: &mut FileNameDB, env_var: &str) {
+ if let Some(paths) = env::var_os(env_var) {
+ for dir in env::split_paths(&paths) {
if let Ok(entries) = std::fs::read_dir(dir) {
for file in entries
.flatten()
@@ -83,7 +92,5 @@ impl Distro {
}
}
}
-
- Ok(Self { kind, file_name_db })
}
}
diff --git a/support/texlab/crates/folding/Cargo.toml b/support/texlab/crates/folding/Cargo.toml
index 684ddeb1b9..862f2301d1 100644
--- a/support/texlab/crates/folding/Cargo.toml
+++ b/support/texlab/crates/folding/Cargo.toml
@@ -8,11 +8,11 @@ rust-version.workspace = true
[dependencies]
base-db = { path = "../base-db" }
-rowan = "0.15.15"
+rowan.workspace = true
syntax = { path = "../syntax" }
[dev-dependencies]
-expect-test = "1.5.0"
+expect-test.workspace = true
test-utils = { path = "../test-utils" }
[lib]
diff --git a/support/texlab/crates/highlights/Cargo.toml b/support/texlab/crates/highlights/Cargo.toml
index 785c282e3a..d509c7f89f 100644
--- a/support/texlab/crates/highlights/Cargo.toml
+++ b/support/texlab/crates/highlights/Cargo.toml
@@ -8,10 +8,10 @@ rust-version.workspace = true
[dependencies]
base-db = { path = "../base-db" }
-rowan = "0.15.15"
+rowan.workspace = true
[dev-dependencies]
-expect-test = "1.5.0"
+expect-test.workspace = true
test-utils = { path = "../test-utils" }
[lib]
diff --git a/support/texlab/crates/hover/Cargo.toml b/support/texlab/crates/hover/Cargo.toml
index 946ed734fe..683da15e43 100644
--- a/support/texlab/crates/hover/Cargo.toml
+++ b/support/texlab/crates/hover/Cargo.toml
@@ -11,11 +11,11 @@ base-db = { path = "../base-db" }
bibtex-utils = { path = "../bibtex-utils" }
citeproc = { path = "../citeproc" }
completion-data = { path = "../completion-data" }
-rowan = "0.15.15"
+rowan.workspace = true
syntax = { path = "../syntax" }
[dev-dependencies]
-expect-test = "1.5.0"
+expect-test.workspace = true
test-utils = { path = "../test-utils" }
[lib]
diff --git a/support/texlab/crates/inlay-hints/Cargo.toml b/support/texlab/crates/inlay-hints/Cargo.toml
index ede4ca6188..07e0172de2 100644
--- a/support/texlab/crates/inlay-hints/Cargo.toml
+++ b/support/texlab/crates/inlay-hints/Cargo.toml
@@ -8,12 +8,12 @@ rust-version.workspace = true
[dependencies]
base-db = { path = "../base-db" }
-rowan = "0.15.15"
-rustc-hash = "1.1.0"
+rowan.workspace = true
+rustc-hash.workspace = true
[dev-dependencies]
test-utils = { path = "../test-utils" }
-expect-test = "1.5.0"
+expect-test.workspace = true
[lib]
doctest = false
diff --git a/support/texlab/crates/ipc/Cargo.toml b/support/texlab/crates/ipc/Cargo.toml
index 1e1ff7a822..c00b98ff12 100644
--- a/support/texlab/crates/ipc/Cargo.toml
+++ b/support/texlab/crates/ipc/Cargo.toml
@@ -7,15 +7,15 @@ edition.workspace = true
rust-version.workspace = true
[dependencies]
-crossbeam-channel = "0.5.12"
-serde = "1.0.202"
-serde_json = "1.0.117"
-log = "0.4.21"
+crossbeam-channel.workspace = true
+serde.workspace = true
+serde_json.workspace = true
+log.workspace = true
uds_windows = "1.1.0"
[lib]
doctest = false
[dev-dependencies]
-expect-test = "1.5.0"
+expect-test.workspace = true
parser = { path = "../parser" }
diff --git a/support/texlab/crates/line-index/Cargo.toml b/support/texlab/crates/line-index/Cargo.toml
index 73d2766d60..3b385ca2bf 100644
--- a/support/texlab/crates/line-index/Cargo.toml
+++ b/support/texlab/crates/line-index/Cargo.toml
@@ -7,7 +7,7 @@ edition.workspace = true
rust-version.workspace = true
[dependencies]
-rustc-hash = "1.1.0"
+rustc-hash.workspace = true
text-size = "1.1.1"
[lib]
diff --git a/support/texlab/crates/links/Cargo.toml b/support/texlab/crates/links/Cargo.toml
index 74378483a9..f36edf1e20 100644
--- a/support/texlab/crates/links/Cargo.toml
+++ b/support/texlab/crates/links/Cargo.toml
@@ -11,7 +11,7 @@ base-db = { path = "../base-db" }
[dev-dependencies]
test-utils = { path = "../test-utils" }
-expect-test = "1.5.0"
+expect-test.workspace = true
[lib]
doctest = false
diff --git a/support/texlab/crates/parser/Cargo.toml b/support/texlab/crates/parser/Cargo.toml
index 39fa34ef63..e1edb782c5 100644
--- a/support/texlab/crates/parser/Cargo.toml
+++ b/support/texlab/crates/parser/Cargo.toml
@@ -7,19 +7,19 @@ edition.workspace = true
rust-version.workspace = true
[dependencies]
-log = "0.4.21"
-logos = "0.14.0"
-once_cell = "1.19.0"
-pathdiff = "0.2.1"
-regex = "1.10.4"
-rowan = "0.15.15"
-rustc-hash = "1.1.0"
+log.workspace = true
+logos = "0.14.2"
+once_cell.workspace = true
+pathdiff = "0.2.2"
+regex.workspace = true
+rowan.workspace = true
+rustc-hash.workspace = true
syntax = { path = "../syntax" }
-tempfile = "3.10.1"
-versions = "6.2.0"
+tempfile.workspace = true
+versions = "6.3.2"
[dev-dependencies]
-expect-test = "1.5.0"
+expect-test.workspace = true
[lib]
doctest = false
diff --git a/support/texlab/crates/parser/src/bibtex.rs b/support/texlab/crates/parser/src/bibtex.rs
index e2cde27dec..4d1e561dbe 100644
--- a/support/texlab/crates/parser/src/bibtex.rs
+++ b/support/texlab/crates/parser/src/bibtex.rs
@@ -2,6 +2,8 @@ use logos::Logos;
use rowan::{GreenNode, GreenNodeBuilder};
use syntax::bibtex::SyntaxKind::{self, *};
+use crate::util::lex_command_name;
+
pub fn parse_bibtex(input: &str) -> GreenNode {
let mut ptr = TokenPtr {
builder: GreenNodeBuilder::new(),
@@ -135,8 +137,8 @@ fn curly_group(mut ptr: TokenPtr<ContentToken>) -> TokenPtr<ContentToken> {
| ContentToken::Quote
| ContentToken::Word => ptr.bump(),
ContentToken::LCurly => ptr = curly_group(ptr),
- ContentToken::AccentName => ptr = accent(ptr),
- ContentToken::CommandName => ptr = command(ptr),
+ ContentToken::CommandName(CommandName::Accent) => ptr = accent(ptr),
+ ContentToken::CommandName(CommandName::Generic) => ptr = command(ptr),
};
}
@@ -160,8 +162,8 @@ fn quote_group(mut ptr: TokenPtr<ContentToken>) -> TokenPtr<ContentToken> {
| ContentToken::Integer
| ContentToken::Word => ptr.bump(),
ContentToken::LCurly => ptr = curly_group(ptr),
- ContentToken::AccentName => ptr = accent(ptr),
- ContentToken::CommandName => ptr = command(ptr),
+ ContentToken::CommandName(CommandName::Accent) => ptr = accent(ptr),
+ ContentToken::CommandName(CommandName::Generic) => ptr = command(ptr),
};
}
@@ -181,7 +183,7 @@ fn accent(mut ptr: TokenPtr<ContentToken>) -> TokenPtr<ContentToken> {
ptr.expect(ContentToken::Whitespace);
}
- if ptr.at(ContentToken::Word) || ptr.at(ContentToken::CommandName) {
+ if ptr.at(ContentToken::Word) || ptr.at(ContentToken::CommandName(CommandName::Generic)) {
ptr.bump();
}
@@ -355,31 +357,29 @@ enum ContentToken {
#[token(r#"~"#)]
Nbsp,
- #[token(r#"\`"#)]
- #[token(r#"\'"#)]
- #[token(r#"\^"#)]
- #[token(r#"\""#)]
- #[token(r#"\H"#)]
- #[token(r#"\~"#)]
- #[token(r#"\c"#)]
- #[token(r#"\k"#)]
- #[token(r#"\="#)]
- #[token(r#"\b"#)]
- #[token(r#"\."#)]
- #[token(r#"\d"#)]
- #[token(r#"\r"#)]
- #[token(r#"\u"#)]
- #[token(r#"\v"#)]
- #[token(r#"\t"#)]
- AccentName,
-
- #[regex(r"\\([^\r\n]|[@a-zA-Z:_]+\*?)?")]
- CommandName,
+ #[regex(r"\\", |lexer| { CommandName::from(lex_command_name(lexer)) })]
+ CommandName(CommandName),
#[regex(r#"[^\s"\{\}\\~,]+"#)]
Word,
}
+#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Copy, Hash)]
+enum CommandName {
+ Generic,
+ Accent,
+}
+
+impl From<&str> for CommandName {
+ fn from(value: &str) -> Self {
+ match value {
+ "`" | "'" | "^" | "\"" | "H" | "~" | "c" | "k" | "=" | "b" | "." | "d" | "r" | "u"
+ | "v" | "t" => CommandName::Accent,
+ _ => CommandName::Generic,
+ }
+ }
+}
+
impl From<RootToken> for SyntaxKind {
fn from(token: RootToken) -> Self {
match token {
@@ -428,8 +428,8 @@ impl From<ContentToken> for SyntaxKind {
ContentToken::Quote => QUOTE,
ContentToken::Integer => INTEGER,
ContentToken::Nbsp => NBSP,
- ContentToken::AccentName => ACCENT_NAME,
- ContentToken::CommandName => COMMAND_NAME,
+ ContentToken::CommandName(CommandName::Accent) => ACCENT_NAME,
+ ContentToken::CommandName(CommandName::Generic) => COMMAND_NAME,
ContentToken::Word => WORD,
}
}
diff --git a/support/texlab/crates/parser/src/bibtex/tests.rs b/support/texlab/crates/parser/src/bibtex/tests.rs
index e2bb1314d8..f0872b4ca6 100644
--- a/support/texlab/crates/parser/src/bibtex/tests.rs
+++ b/support/texlab/crates/parser/src/bibtex/tests.rs
@@ -3992,3 +3992,280 @@ fn test_rivest_1978() {
"#]],
);
}
+
+#[test]
+fn test_cuesta_2002() {
+ check(
+ r#"@INPROCEEDINGS{Cuesta02,
+ author = {Cuesta, Carlos E. and de la Fuente, Pablo and Barrio-Sol\órzano, Manuel and Beato, Encarnaci\ón},
+ title = {{Coordination in a Reflective Architecture Description Language}},
+ booktitle = {{Proceedings of the 5th International Conference on Coordination Models and Languages (COORDINATION'02)}},
+ year = 2002,
+ editor = {Arbab, Fahrad and Talcott, Carolyn},
+ pages = {141--148},
+ address = {York, United Kingdom},
+ organization = {},
+ publisher = {Springer},
+ volume = {},
+ number = {},
+ series = {Lecture Notes in Computer Science 2315},
+ month = apr,
+ note = {}
+}"#,
+ expect![[r#"
+ ROOT@0..617
+ ENTRY@0..617
+ TYPE@0..14 "@INPROCEEDINGS"
+ L_DELIM@14..15 "{"
+ NAME@15..23 "Cuesta02"
+ COMMA@23..24 ","
+ WHITESPACE@24..27 "\n "
+ FIELD@27..136
+ NAME@27..33 "author"
+ WHITESPACE@33..34 " "
+ EQ@34..35 "="
+ WHITESPACE@35..36 " "
+ CURLY_GROUP@36..135
+ L_CURLY@36..37 "{"
+ WORD@37..43 "Cuesta"
+ COMMA@43..44 ","
+ WHITESPACE@44..45 " "
+ WORD@45..51 "Carlos"
+ WHITESPACE@51..52 " "
+ WORD@52..54 "E."
+ WHITESPACE@54..55 " "
+ WORD@55..58 "and"
+ WHITESPACE@58..59 " "
+ WORD@59..61 "de"
+ WHITESPACE@61..62 " "
+ WORD@62..64 "la"
+ WHITESPACE@64..65 " "
+ WORD@65..71 "Fuente"
+ COMMA@71..72 ","
+ WHITESPACE@72..73 " "
+ WORD@73..78 "Pablo"
+ WHITESPACE@78..79 " "
+ WORD@79..82 "and"
+ WHITESPACE@82..83 " "
+ WORD@83..93 "Barrio-Sol"
+ COMMAND@93..101
+ COMMAND_NAME@93..101 "\\órzano"
+ COMMA@101..102 ","
+ WHITESPACE@102..103 " "
+ WORD@103..109 "Manuel"
+ WHITESPACE@109..110 " "
+ WORD@110..113 "and"
+ WHITESPACE@113..114 " "
+ WORD@114..119 "Beato"
+ COMMA@119..120 ","
+ WHITESPACE@120..121 " "
+ WORD@121..130 "Encarnaci"
+ COMMAND@130..134
+ COMMAND_NAME@130..134 "\\ón"
+ R_CURLY@134..135 "}"
+ COMMA@135..136 ","
+ WHITESPACE@136..139 "\n "
+ FIELD@139..214
+ NAME@139..144 "title"
+ WHITESPACE@144..145 " "
+ EQ@145..146 "="
+ WHITESPACE@146..147 " "
+ CURLY_GROUP@147..213
+ L_CURLY@147..148 "{"
+ CURLY_GROUP@148..212
+ L_CURLY@148..149 "{"
+ WORD@149..161 "Coordination"
+ WHITESPACE@161..162 " "
+ WORD@162..164 "in"
+ WHITESPACE@164..165 " "
+ WORD@165..166 "a"
+ WHITESPACE@166..167 " "
+ WORD@167..177 "Reflective"
+ WHITESPACE@177..178 " "
+ WORD@178..190 "Architecture"
+ WHITESPACE@190..191 " "
+ WORD@191..202 "Description"
+ WHITESPACE@202..203 " "
+ WORD@203..211 "Language"
+ R_CURLY@211..212 "}"
+ R_CURLY@212..213 "}"
+ COMMA@213..214 ","
+ WHITESPACE@214..217 "\n "
+ FIELD@217..336
+ NAME@217..226 "booktitle"
+ WHITESPACE@226..227 " "
+ EQ@227..228 "="
+ WHITESPACE@228..229 " "
+ CURLY_GROUP@229..335
+ L_CURLY@229..230 "{"
+ CURLY_GROUP@230..334
+ L_CURLY@230..231 "{"
+ WORD@231..242 "Proceedings"
+ WHITESPACE@242..243 " "
+ WORD@243..245 "of"
+ WHITESPACE@245..246 " "
+ WORD@246..249 "the"
+ WHITESPACE@249..250 " "
+ WORD@250..253 "5th"
+ WHITESPACE@253..254 " "
+ WORD@254..267 "International"
+ WHITESPACE@267..268 " "
+ WORD@268..278 "Conference"
+ WHITESPACE@278..279 " "
+ WORD@279..281 "on"
+ WHITESPACE@281..282 " "
+ WORD@282..294 "Coordination"
+ WHITESPACE@294..295 " "
+ WORD@295..301 "Models"
+ WHITESPACE@301..302 " "
+ WORD@302..305 "and"
+ WHITESPACE@305..306 " "
+ WORD@306..315 "Languages"
+ WHITESPACE@315..316 " "
+ WORD@316..333 "(COORDINATION'02)"
+ R_CURLY@333..334 "}"
+ R_CURLY@334..335 "}"
+ COMMA@335..336 ","
+ WHITESPACE@336..339 "\n "
+ FIELD@339..351
+ NAME@339..343 "year"
+ WHITESPACE@343..344 " "
+ EQ@344..345 "="
+ WHITESPACE@345..346 " "
+ LITERAL@346..350
+ INTEGER@346..350 "2002"
+ COMMA@350..351 ","
+ WHITESPACE@351..354 "\n "
+ FIELD@354..400
+ NAME@354..360 "editor"
+ WHITESPACE@360..361 " "
+ EQ@361..362 "="
+ WHITESPACE@362..363 " "
+ CURLY_GROUP@363..399
+ L_CURLY@363..364 "{"
+ WORD@364..369 "Arbab"
+ COMMA@369..370 ","
+ WHITESPACE@370..371 " "
+ WORD@371..377 "Fahrad"
+ WHITESPACE@377..378 " "
+ WORD@378..381 "and"
+ WHITESPACE@381..382 " "
+ WORD@382..389 "Talcott"
+ COMMA@389..390 ","
+ WHITESPACE@390..391 " "
+ WORD@391..398 "Carolyn"
+ R_CURLY@398..399 "}"
+ COMMA@399..400 ","
+ WHITESPACE@400..403 "\n "
+ FIELD@403..422
+ NAME@403..408 "pages"
+ WHITESPACE@408..409 " "
+ EQ@409..410 "="
+ WHITESPACE@410..411 " "
+ CURLY_GROUP@411..421
+ L_CURLY@411..412 "{"
+ WORD@412..420 "141--148"
+ R_CURLY@420..421 "}"
+ COMMA@421..422 ","
+ WHITESPACE@422..425 "\n "
+ FIELD@425..458
+ NAME@425..432 "address"
+ WHITESPACE@432..433 " "
+ EQ@433..434 "="
+ WHITESPACE@434..435 " "
+ CURLY_GROUP@435..457
+ L_CURLY@435..436 "{"
+ WORD@436..440 "York"
+ COMMA@440..441 ","
+ WHITESPACE@441..442 " "
+ WORD@442..448 "United"
+ WHITESPACE@448..449 " "
+ WORD@449..456 "Kingdom"
+ R_CURLY@456..457 "}"
+ COMMA@457..458 ","
+ WHITESPACE@458..461 "\n "
+ FIELD@461..479
+ NAME@461..473 "organization"
+ WHITESPACE@473..474 " "
+ EQ@474..475 "="
+ WHITESPACE@475..476 " "
+ CURLY_GROUP@476..478
+ L_CURLY@476..477 "{"
+ R_CURLY@477..478 "}"
+ COMMA@478..479 ","
+ WHITESPACE@479..482 "\n "
+ FIELD@482..505
+ NAME@482..491 "publisher"
+ WHITESPACE@491..492 " "
+ EQ@492..493 "="
+ WHITESPACE@493..494 " "
+ CURLY_GROUP@494..504
+ L_CURLY@494..495 "{"
+ WORD@495..503 "Springer"
+ R_CURLY@503..504 "}"
+ COMMA@504..505 ","
+ WHITESPACE@505..508 "\n "
+ FIELD@508..520
+ NAME@508..514 "volume"
+ WHITESPACE@514..515 " "
+ EQ@515..516 "="
+ WHITESPACE@516..517 " "
+ CURLY_GROUP@517..519
+ L_CURLY@517..518 "{"
+ R_CURLY@518..519 "}"
+ COMMA@519..520 ","
+ WHITESPACE@520..523 "\n "
+ FIELD@523..535
+ NAME@523..529 "number"
+ WHITESPACE@529..530 " "
+ EQ@530..531 "="
+ WHITESPACE@531..532 " "
+ CURLY_GROUP@532..534
+ L_CURLY@532..533 "{"
+ R_CURLY@533..534 "}"
+ COMMA@534..535 ","
+ WHITESPACE@535..538 "\n "
+ FIELD@538..588
+ NAME@538..544 "series"
+ WHITESPACE@544..545 " "
+ EQ@545..546 "="
+ WHITESPACE@546..547 " "
+ CURLY_GROUP@547..587
+ L_CURLY@547..548 "{"
+ WORD@548..555 "Lecture"
+ WHITESPACE@555..556 " "
+ WORD@556..561 "Notes"
+ WHITESPACE@561..562 " "
+ WORD@562..564 "in"
+ WHITESPACE@564..565 " "
+ WORD@565..573 "Computer"
+ WHITESPACE@573..574 " "
+ WORD@574..581 "Science"
+ WHITESPACE@581..582 " "
+ INTEGER@582..586 "2315"
+ R_CURLY@586..587 "}"
+ COMMA@587..588 ","
+ WHITESPACE@588..591 "\n "
+ FIELD@591..603
+ NAME@591..596 "month"
+ WHITESPACE@596..597 " "
+ EQ@597..598 "="
+ WHITESPACE@598..599 " "
+ LITERAL@599..602
+ NAME@599..602 "apr"
+ COMMA@602..603 ","
+ WHITESPACE@603..606 "\n "
+ FIELD@606..616
+ NAME@606..610 "note"
+ WHITESPACE@610..611 " "
+ EQ@611..612 "="
+ WHITESPACE@612..613 " "
+ CURLY_GROUP@613..615
+ L_CURLY@613..614 "{"
+ R_CURLY@614..615 "}"
+ WHITESPACE@615..616 "\n"
+ R_DELIM@616..617 "}"
+
+ "#]],
+ )
+}
diff --git a/support/texlab/crates/parser/src/config.rs b/support/texlab/crates/parser/src/config.rs
index f81083f132..2c5380448f 100644
--- a/support/texlab/crates/parser/src/config.rs
+++ b/support/texlab/crates/parser/src/config.rs
@@ -3,12 +3,15 @@ use rustc_hash::FxHashSet;
#[derive(Debug)]
pub struct SyntaxConfig {
pub follow_package_links: bool,
+ pub use_file_list: bool,
pub math_environments: FxHashSet<String>,
pub enum_environments: FxHashSet<String>,
pub verbatim_environments: FxHashSet<String>,
pub citation_commands: FxHashSet<String>,
pub label_definition_commands: FxHashSet<String>,
+ pub label_definition_prefixes: Vec<(String, String)>,
pub label_reference_commands: FxHashSet<String>,
+ pub label_reference_prefixes: Vec<(String, String)>,
}
impl Default for SyntaxConfig {
@@ -38,19 +41,32 @@ impl Default for SyntaxConfig {
.map(ToString::to_string)
.collect();
+ let label_definition_prefixes = DEFAULT_LABEL_DEFINITION_PREFIXES
+ .iter()
+ .map(|(x, y)| (ToString::to_string(x), ToString::to_string(y)))
+ .collect();
+
let label_reference_commands = DEFAULT_LABEL_REFERENCE_COMMANDS
.iter()
.map(ToString::to_string)
.collect();
+ let label_reference_prefixes = DEFAULT_LABEL_REFERENCE_PREFIXES
+ .iter()
+ .map(|(x, y)| (ToString::to_string(x), ToString::to_string(y)))
+ .collect();
+
Self {
follow_package_links: false,
+ use_file_list: false,
math_environments,
enum_environments,
verbatim_environments,
citation_commands,
label_definition_commands,
+ label_definition_prefixes,
label_reference_commands,
+ label_reference_prefixes,
}
}
}
@@ -170,7 +186,9 @@ static DEFAULT_CITATION_COMMANDS: &[&str] = &[
"citeA*",
];
-static DEFAULT_LABEL_DEFINITION_COMMANDS: &[&str] = &["label"];
+static DEFAULT_LABEL_DEFINITION_COMMANDS: &[&str] = &["label", "zlabel"];
+
+static DEFAULT_LABEL_DEFINITION_PREFIXES: &[(&str, &str)] = &[];
static DEFAULT_LABEL_REFERENCE_COMMANDS: &[&str] = &[
"ref",
@@ -182,6 +200,10 @@ static DEFAULT_LABEL_REFERENCE_COMMANDS: &[&str] = &[
"cref*",
"Cref",
"Cref*",
+ "zcref",
+ "zcref*",
+ "zcpageref",
+ "zcpageref*",
"namecref",
"nameCref",
"lcnamecref",
@@ -192,3 +214,5 @@ static DEFAULT_LABEL_REFERENCE_COMMANDS: &[&str] = &[
"labelcpageref",
"eqref",
];
+
+static DEFAULT_LABEL_REFERENCE_PREFIXES: &[(&str, &str)] = &[];
diff --git a/support/texlab/crates/parser/src/file_list.rs b/support/texlab/crates/parser/src/file_list.rs
new file mode 100644
index 0000000000..c892ebfeef
--- /dev/null
+++ b/support/texlab/crates/parser/src/file_list.rs
@@ -0,0 +1,44 @@
+use syntax::file_list::FileList;
+
+pub fn parse_file_list(input: &str) -> FileList {
+ let mut file_list = FileList::default();
+ for line in input.lines() {
+ if let Some(working_dir) = line.strip_prefix("PWD ") {
+ file_list.working_dir = Some(working_dir.into());
+ } else if let Some(input) = line.strip_prefix("INPUT ") {
+ file_list.inputs.insert(input.into());
+ } else if let Some(output) = line.strip_prefix("OUTPUT ") {
+ file_list.outputs.insert(output.into());
+ }
+ }
+
+ file_list
+}
+
+#[cfg(test)]
+mod tests {
+ use rustc_hash::FxHashSet;
+
+ use super::*;
+
+ #[test]
+ fn test_parse_file_list() {
+ let input = r#"
+PWD /home/user
+INPUT file1.tex
+INPUT file1.tex
+OUTPUT file2.pdf"#;
+
+ let expected_file_list = FileList {
+ working_dir: Some("/home/user".into()),
+ inputs: FxHashSet::from_iter(["file1.tex".into()]),
+ outputs: FxHashSet::from_iter(["file2.pdf".into()]),
+ };
+ let actual_file_list = parse_file_list(input);
+ assert_eq!(actual_file_list, expected_file_list);
+
+ assert_eq!(actual_file_list.working_dir, Some("/home/user".into()));
+ assert_eq!(actual_file_list.inputs.len(), 1);
+ assert_eq!(actual_file_list.outputs.len(), 1);
+ }
+}
diff --git a/support/texlab/crates/parser/src/latex.rs b/support/texlab/crates/parser/src/latex.rs
index 669ba82f99..8379d9c5ca 100644
--- a/support/texlab/crates/parser/src/latex.rs
+++ b/support/texlab/crates/parser/src/latex.rs
@@ -158,6 +158,9 @@ impl<'a> Parser<'a> {
CommandName::EndBlockComment => self.generic_command(),
CommandName::VerbatimBlock => self.verbatim_block(),
CommandName::GraphicsPath => self.graphics_path(),
+ CommandName::BibItem => self.bibitem(),
+ CommandName::TocContentsLine => self.toc_contents_line(),
+ CommandName::TocNumberLine => self.toc_number_line(),
},
}
}
@@ -862,7 +865,20 @@ impl<'a> Parser<'a> {
}
if self.lexer.peek() == Some(Token::LCurly) {
- self.curly_group_word();
+ self.builder.start_node(CURLY_GROUP_WORD.into());
+ self.eat();
+ self.trivia();
+
+ if self.peek() == Some(Token::Word) || self.peek() == Some(Token::Pipe) {
+ self.key();
+ }
+
+ if let Some(Token::CommandName(_)) = self.peek() {
+ self.content(ParserContext::default());
+ }
+
+ self.expect(Token::RCurly);
+ self.builder.finish_node();
}
self.builder.finish_node();
@@ -1235,6 +1251,50 @@ impl<'a> Parser<'a> {
}
}
}
+
+ fn bibitem(&mut self) {
+ self.builder.start_node(BIBITEM.into());
+ self.eat();
+ self.trivia();
+
+ if self.lexer.peek() == Some(Token::LCurly) {
+ self.curly_group_word();
+ }
+
+ self.builder.finish_node();
+ }
+
+ fn toc_contents_line(&mut self) {
+ self.builder.start_node(TOC_CONTENTS_LINE.into());
+ self.eat();
+ self.trivia();
+
+ if self.lexer.peek() == Some(Token::LCurly) {
+ self.curly_group();
+ }
+
+ if self.lexer.peek() == Some(Token::LCurly) {
+ self.curly_group();
+ }
+
+ if self.lexer.peek() == Some(Token::LCurly) {
+ self.curly_group();
+ }
+
+ self.builder.finish_node();
+ }
+
+ fn toc_number_line(&mut self) {
+ self.builder.start_node(TOC_NUMBER_LINE.into());
+ self.eat();
+ self.trivia();
+
+ if self.lexer.peek() == Some(Token::LCurly) {
+ self.curly_group();
+ }
+
+ self.builder.finish_node();
+ }
}
pub fn parse_latex(text: &str, config: &SyntaxConfig) -> GreenNode {
diff --git a/support/texlab/crates/parser/src/latex/lexer.rs b/support/texlab/crates/parser/src/latex/lexer.rs
index 47a6c43b06..19d5ddade5 100644
--- a/support/texlab/crates/parser/src/latex/lexer.rs
+++ b/support/texlab/crates/parser/src/latex/lexer.rs
@@ -27,7 +27,7 @@ impl<'a> Lexer<'a> {
pub fn eat(&mut self) -> Option<(SyntaxKind, &'a str)> {
let (kind, text) = self.tokens.pop()?;
let kind = match kind {
- Token::LineBreak => SyntaxKind::LINE_BREAK,
+ Token::LineBreak => SyntaxKind::WHITESPACE,
Token::Whitespace => SyntaxKind::WHITESPACE,
Token::LineComment => SyntaxKind::COMMENT,
Token::LCurly => SyntaxKind::L_CURLY,
diff --git a/support/texlab/crates/parser/src/latex/lexer/commands.rs b/support/texlab/crates/parser/src/latex/lexer/commands.rs
index 4d1a7ca320..3f8b6e36ed 100644
--- a/support/texlab/crates/parser/src/latex/lexer/commands.rs
+++ b/support/texlab/crates/parser/src/latex/lexer/commands.rs
@@ -96,6 +96,9 @@ pub fn classify(name: &str, config: &SyntaxConfig) -> CommandName {
"iffalse" => CommandName::BeginBlockComment,
"fi" => CommandName::EndBlockComment,
"verb" => CommandName::VerbatimBlock,
+ "bibitem" => CommandName::BibItem,
+ "contentsline" => CommandName::TocContentsLine,
+ "numberline" => CommandName::TocNumberLine,
_ if config.citation_commands.contains(name) => CommandName::Citation,
_ if config.label_definition_commands.contains(name) => CommandName::LabelDefinition,
diff --git a/support/texlab/crates/parser/src/latex/lexer/types.rs b/support/texlab/crates/parser/src/latex/lexer/types.rs
index 896ce01c05..796378f671 100644
--- a/support/texlab/crates/parser/src/latex/lexer/types.rs
+++ b/support/texlab/crates/parser/src/latex/lexer/types.rs
@@ -1,5 +1,7 @@
use logos::Logos;
+use crate::util::lex_command_name;
+
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Copy, Hash, Logos)]
pub enum Token {
#[regex(r"[\r\n]+", priority = 2)]
@@ -44,55 +46,10 @@ pub enum Token {
#[regex(r"\$\$?")]
Dollar,
- #[regex(r"\\", lex_command_name)]
+ #[regex(r"\\", |lexer| { lex_command_name(lexer); CommandName::Generic } )]
CommandName(CommandName),
}
-fn lex_command_name(lexer: &mut logos::Lexer<Token>) -> CommandName {
- let input = &lexer.source()[lexer.span().end..];
-
- let mut chars = input.chars().peekable();
- let Some(c) = chars.next() else {
- return CommandName::Generic;
- };
-
- if c.is_whitespace() {
- return CommandName::Generic;
- }
-
- lexer.bump(c.len_utf8());
- if !c.is_alphanumeric() && c != '@' {
- return CommandName::Generic;
- }
-
- while let Some(c) = chars.next() {
- match c {
- '*' => {
- lexer.bump(c.len_utf8());
- break;
- }
- c if c.is_alphanumeric() => {
- lexer.bump(c.len_utf8());
- }
- '_' => {
- if !matches!(chars.peek(), Some(c) if c.is_alphanumeric()) {
- break;
- }
-
- lexer.bump(c.len_utf8());
- }
- '@' | ':' => {
- lexer.bump(c.len_utf8());
- }
- _ => {
- break;
- }
- }
- }
-
- CommandName::Generic
-}
-
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Copy, Hash)]
pub enum CommandName {
Generic,
@@ -138,6 +95,9 @@ pub enum CommandName {
BeginBlockComment,
EndBlockComment,
VerbatimBlock,
+ BibItem,
+ TocContentsLine,
+ TocNumberLine,
}
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Copy, Hash)]
diff --git a/support/texlab/crates/parser/src/latex/tests.rs b/support/texlab/crates/parser/src/latex/tests.rs
index 2c9dc9335f..623c9329fb 100644
--- a/support/texlab/crates/parser/src/latex/tests.rs
+++ b/support/texlab/crates/parser/src/latex/tests.rs
@@ -24,24 +24,24 @@ Baz"#,
PREAMBLE@0..48
TEXT@0..4
WORD@0..3 "Foo"
- LINE_BREAK@3..4 "\n"
+ WHITESPACE@3..4 "\n"
BLOCK_COMMENT@4..22
COMMAND_NAME@4..12 "\\iffalse"
- LINE_BREAK@12..13 "\n"
+ WHITESPACE@12..13 "\n"
WORD@13..18 "Test1"
- LINE_BREAK@18..19 "\n"
+ WHITESPACE@18..19 "\n"
COMMAND_NAME@19..22 "\\fi"
- LINE_BREAK@22..23 "\n"
+ WHITESPACE@22..23 "\n"
TEXT@23..27
WORD@23..26 "Bar"
- LINE_BREAK@26..27 "\n"
+ WHITESPACE@26..27 "\n"
BLOCK_COMMENT@27..44
COMMAND_NAME@27..35 "\\iffalse"
- LINE_BREAK@35..36 "\n"
+ WHITESPACE@35..36 "\n"
COMMAND_NAME@36..40 "\\fii"
- LINE_BREAK@40..41 "\n"
+ WHITESPACE@40..41 "\n"
COMMAND_NAME@41..44 "\\fi"
- LINE_BREAK@44..45 "\n"
+ WHITESPACE@44..45 "\n"
TEXT@45..48
WORD@45..48 "Baz"
@@ -776,7 +776,7 @@ fn test_environment_asymptote() {
KEY@7..10
WORD@7..10 "asy"
R_CURLY@10..11 "}"
- LINE_BREAK@11..12 "\n"
+ WHITESPACE@11..12 "\n"
WHITESPACE@12..16 " "
TEXT@16..22
WORD@16..22 "printf"
@@ -793,7 +793,7 @@ fn test_environment_asymptote() {
R_PAREN@38..39 ")"
TEXT@39..41
WORD@39..40 ";"
- LINE_BREAK@40..41 "\n"
+ WHITESPACE@40..41 "\n"
END@41..50
COMMAND_NAME@41..45 "\\end"
CURLY_GROUP_WORD@45..50
@@ -1289,7 +1289,7 @@ fn test_acronym_package() {
WHITESPACE@26..27 " "
WORD@27..33 "Second"
R_CURLY@33..34 "}"
- LINE_BREAK@34..35 "\n"
+ WHITESPACE@34..35 "\n"
"#]],
);
@@ -2384,7 +2384,7 @@ fn test_issue_568() {
WHITESPACE@15..16 " "
WORD@16..34 "scripts/test.ipynb"
R_CURLY@34..35 "}"
- LINE_BREAK@35..36 "\n"
+ WHITESPACE@35..36 "\n"
LABEL_DEFINITION@36..51
COMMAND_NAME@36..42 "\\label"
CURLY_GROUP_WORD@42..51
@@ -2433,7 +2433,7 @@ fn test_issue_745() {
KEY@15..22
WORD@15..22 "article"
R_CURLY@22..23 "}"
- LINE_BREAK@23..24 "\n"
+ WHITESPACE@23..24 "\n"
PACKAGE_INCLUDE@24..50
COMMAND_NAME@24..35 "\\usepackage"
CURLY_GROUP_WORD_LIST@35..50
@@ -2442,10 +2442,10 @@ fn test_issue_745() {
WORD@36..46 "tabularray"
R_CURLY@46..47 "}"
WHITESPACE@47..48 " "
- LINE_BREAK@48..50 "\n\n"
+ WHITESPACE@48..50 "\n\n"
GENERIC_COMMAND@50..64
COMMAND_NAME@50..63 "\\ExplSyntaxOn"
- LINE_BREAK@63..64 "\n"
+ WHITESPACE@63..64 "\n"
ENVIRONMENT_DEFINITION@64..200
COMMAND_NAME@64..87 "\\NewDocumentEnvironment"
CURLY_GROUP_WORD@87..96
@@ -2463,19 +2463,19 @@ fn test_issue_745() {
TEXT@100..101
WORD@100..101 "m"
R_CURLY@101..102 "}"
- LINE_BREAK@102..103 "\n"
+ WHITESPACE@102..103 "\n"
WHITESPACE@103..107 " "
CURLY_GROUP@107..200
L_CURLY@107..108 "{"
- LINE_BREAK@108..109 "\n"
+ WHITESPACE@108..109 "\n"
WHITESPACE@109..113 " "
GENERIC_COMMAND@113..194
COMMAND_NAME@113..119 "\\use:x"
- LINE_BREAK@119..120 "\n"
+ WHITESPACE@119..120 "\n"
WHITESPACE@120..124 " "
CURLY_GROUP@124..194
L_CURLY@124..125 "{"
- LINE_BREAK@125..126 "\n"
+ WHITESPACE@125..126 "\n"
WHITESPACE@126..130 " "
GENERIC_COMMAND@130..141
COMMAND_NAME@130..140 "\\exp_not:N"
@@ -2488,7 +2488,7 @@ fn test_issue_745() {
KEY@148..152
WORD@148..152 "tblr"
R_CURLY@152..153 "}"
- LINE_BREAK@153..154 "\n"
+ WHITESPACE@153..154 "\n"
WHITESPACE@154..158 " "
BRACK_GROUP@158..179
L_BRACK@158..159 "["
@@ -2500,24 +2500,24 @@ fn test_issue_745() {
WORD@170..172 "#1"
R_CURLY@172..173 "}"
R_BRACK@173..174 "]"
- LINE_BREAK@174..175 "\n"
+ WHITESPACE@174..175 "\n"
WHITESPACE@175..179 " "
CURLY_GROUP@179..188
L_CURLY@179..180 "{"
TEXT@180..182
WORD@180..182 "#2"
R_CURLY@182..183 "}"
- LINE_BREAK@183..184 "\n"
+ WHITESPACE@183..184 "\n"
WHITESPACE@184..188 " "
R_CURLY@188..189 "}"
- LINE_BREAK@189..190 "\n"
+ WHITESPACE@189..190 "\n"
WHITESPACE@190..194 " "
R_CURLY@194..195 "}"
- LINE_BREAK@195..196 "\n"
+ WHITESPACE@195..196 "\n"
WHITESPACE@196..200 " "
CURLY_GROUP@200..223
L_CURLY@200..201 "{"
- LINE_BREAK@201..202 "\n"
+ WHITESPACE@201..202 "\n"
WHITESPACE@202..206 " "
GENERIC_COMMAND@206..221
COMMAND_NAME@206..210 "\\end"
@@ -2526,13 +2526,13 @@ fn test_issue_745() {
TEXT@211..215
WORD@211..215 "tblr"
R_CURLY@215..216 "}"
- LINE_BREAK@216..217 "\n"
+ WHITESPACE@216..217 "\n"
WHITESPACE@217..221 " "
R_CURLY@221..222 "}"
- LINE_BREAK@222..223 "\n"
+ WHITESPACE@222..223 "\n"
GENERIC_COMMAND@223..239
COMMAND_NAME@223..237 "\\ExplSyntaxOff"
- LINE_BREAK@237..239 "\n\n"
+ WHITESPACE@237..239 "\n\n"
ENVIRONMENT@239..271
BEGIN@239..257
COMMAND_NAME@239..245 "\\begin"
@@ -2541,7 +2541,7 @@ fn test_issue_745() {
KEY@246..254
WORD@246..254 "document"
R_CURLY@254..255 "}"
- LINE_BREAK@255..257 "\n\n"
+ WHITESPACE@255..257 "\n\n"
END@257..271
COMMAND_NAME@257..261 "\\end"
CURLY_GROUP_WORD@261..271
@@ -2620,7 +2620,7 @@ This is an asdf undefined command
KEY@15..22
WORD@15..22 "minimal"
R_CURLY@22..23 "}"
- LINE_BREAK@23..24 "\n"
+ WHITESPACE@23..24 "\n"
ENVIRONMENT@24..135
BEGIN@24..41
COMMAND_NAME@24..30 "\\begin"
@@ -2629,7 +2629,7 @@ This is an asdf undefined command
KEY@31..39
WORD@31..39 "document"
R_CURLY@39..40 "}"
- LINE_BREAK@40..41 "\n"
+ WHITESPACE@40..41 "\n"
TEXT@41..75
WORD@41..45 "This"
WHITESPACE@45..46 " "
@@ -2642,24 +2642,24 @@ This is an asdf undefined command
WORD@57..66 "undefined"
WHITESPACE@66..67 " "
WORD@67..74 "command"
- LINE_BREAK@74..75 "\n"
+ WHITESPACE@74..75 "\n"
BLOCK_COMMENT@75..120
COMMAND_NAME@75..83 "\\iffalse"
- LINE_BREAK@83..84 "\n"
+ WHITESPACE@83..84 "\n"
WHITESPACE@84..86 " "
BLOCK_COMMENT@86..97
COMMAND_NAME@86..94 "\\iffalse"
COMMAND_NAME@94..97 "\\fi"
- LINE_BREAK@97..98 "\n"
+ WHITESPACE@97..98 "\n"
WHITESPACE@98..100 " "
COMMAND_NAME@100..104 "\\end"
L_CURLY@104..105 "{"
WORD@105..114 "enumerate"
R_CURLY@114..115 "}"
WHITESPACE@115..116 " "
- LINE_BREAK@116..117 "\n"
+ WHITESPACE@116..117 "\n"
COMMAND_NAME@117..120 "\\fi"
- LINE_BREAK@120..121 "\n"
+ WHITESPACE@120..121 "\n"
END@121..135
COMMAND_NAME@121..125 "\\end"
CURLY_GROUP_WORD@125..135
@@ -2688,7 +2688,7 @@ fn test_issue_857() {
CURLY_GROUP@14..17
L_CURLY@14..15 "{"
R_CURLY@15..16 "}"
- LINE_BREAK@16..17 "\n"
+ WHITESPACE@16..17 "\n"
NEW_COMMAND_DEFINITION@17..38
COMMAND_NAME@17..28 "\\newcommand"
CURLY_GROUP_COMMAND@28..35
@@ -2698,7 +2698,7 @@ fn test_issue_857() {
CURLY_GROUP@35..38
L_CURLY@35..36 "{"
R_CURLY@36..37 "}"
- LINE_BREAK@37..38 "\n"
+ WHITESPACE@37..38 "\n"
NEW_COMMAND_DEFINITION@38..49
COMMAND_NAME@38..49 "\\newcommand"
GENERIC_COMMAND@49..55
@@ -2768,31 +2768,31 @@ fn test_issue_919() {
KEY@15..22
WORD@15..22 "article"
R_CURLY@22..23 "}"
- LINE_BREAK@23..25 "\n\n"
+ WHITESPACE@23..25 "\n\n"
PACKAGE_INCLUDE@25..173
COMMAND_NAME@25..36 "\\usepackage"
CURLY_GROUP_WORD_LIST@36..173
L_CURLY@36..37 "{"
- LINE_BREAK@37..38 "\n"
+ WHITESPACE@37..38 "\n"
WHITESPACE@38..42 " "
KEY@42..48
WORD@42..48 "lipsum"
COMMA@48..49 ","
WHITESPACE@49..50 " "
COMMENT@50..70 "% provides blindtext"
- LINE_BREAK@70..71 "\n"
+ WHITESPACE@70..71 "\n"
WHITESPACE@71..75 " "
KEY@75..83
WORD@75..83 "booktabs"
COMMA@83..84 ","
WHITESPACE@84..85 " "
COMMENT@85..110 "% better rules for ta ..."
- LINE_BREAK@110..111 "\n"
+ WHITESPACE@110..111 "\n"
WHITESPACE@111..115 " "
COMMENT@115..169 "%xcolor % easily defi ..."
- LINE_BREAK@169..170 "\n"
+ WHITESPACE@169..170 "\n"
R_CURLY@170..171 "}"
- LINE_BREAK@171..173 "\n\n"
+ WHITESPACE@171..173 "\n\n"
ENVIRONMENT@173..217
BEGIN@173..194
COMMAND_NAME@173..179 "\\begin"
@@ -2801,11 +2801,11 @@ fn test_issue_919() {
KEY@180..188
WORD@180..188 "document"
R_CURLY@188..189 "}"
- LINE_BREAK@189..190 "\n"
+ WHITESPACE@189..190 "\n"
WHITESPACE@190..194 " "
GENERIC_COMMAND@194..202
COMMAND_NAME@194..201 "\\lipsum"
- LINE_BREAK@201..202 "\n"
+ WHITESPACE@201..202 "\n"
END@202..217
COMMAND_NAME@202..206 "\\end"
CURLY_GROUP_WORD@206..217
@@ -2813,7 +2813,7 @@ fn test_issue_919() {
KEY@207..215
WORD@207..215 "document"
R_CURLY@215..216 "}"
- LINE_BREAK@216..217 "\n"
+ WHITESPACE@216..217 "\n"
"#]],
);
@@ -2853,7 +2853,7 @@ world}"#,
L_CURLY@6..7 "{"
KEY@7..13
WORD@7..12 "hello"
- LINE_BREAK@12..13 "\n"
+ WHITESPACE@12..13 "\n"
TEXT@13..18
WORD@13..18 "world"
ERROR@18..19
@@ -3150,12 +3150,12 @@ Section 2"#,
WHITESPACE@16..17 " "
WORD@17..18 "1"
R_CURLY@18..19 "}"
- LINE_BREAK@19..20 "\n"
+ WHITESPACE@19..20 "\n"
TEXT@20..31
WORD@20..27 "Section"
WHITESPACE@27..28 " "
WORD@28..29 "1"
- LINE_BREAK@29..31 "\n\n"
+ WHITESPACE@29..31 "\n\n"
PARAGRAPH@31..68
COMMAND_NAME@31..41 "\\paragraph"
CURLY_GROUP@41..55
@@ -3165,12 +3165,12 @@ Section 2"#,
WHITESPACE@51..52 " "
WORD@52..53 "1"
R_CURLY@53..54 "}"
- LINE_BREAK@54..55 "\n"
+ WHITESPACE@54..55 "\n"
TEXT@55..68
WORD@55..64 "Paragraph"
WHITESPACE@64..65 " "
WORD@65..66 "1"
- LINE_BREAK@66..68 "\n\n"
+ WHITESPACE@66..68 "\n\n"
PARAGRAPH@68..105
COMMAND_NAME@68..78 "\\paragraph"
CURLY_GROUP@78..92
@@ -3180,12 +3180,12 @@ Section 2"#,
WHITESPACE@88..89 " "
WORD@89..90 "2"
R_CURLY@90..91 "}"
- LINE_BREAK@91..92 "\n"
+ WHITESPACE@91..92 "\n"
TEXT@92..105
WORD@92..101 "Paragraph"
WHITESPACE@101..102 " "
WORD@102..103 "2"
- LINE_BREAK@103..105 "\n\n"
+ WHITESPACE@103..105 "\n\n"
SECTION@105..134
COMMAND_NAME@105..113 "\\section"
CURLY_GROUP@113..125
@@ -3195,7 +3195,7 @@ Section 2"#,
WHITESPACE@121..122 " "
WORD@122..123 "2"
R_CURLY@123..124 "}"
- LINE_BREAK@124..125 "\n"
+ WHITESPACE@124..125 "\n"
TEXT@125..134
WORD@125..132 "Section"
WHITESPACE@132..133 " "
diff --git a/support/texlab/crates/parser/src/lib.rs b/support/texlab/crates/parser/src/lib.rs
index 2a4190b7e2..b3952d6ea5 100644
--- a/support/texlab/crates/parser/src/lib.rs
+++ b/support/texlab/crates/parser/src/lib.rs
@@ -1,10 +1,12 @@
mod bibtex;
mod build_log;
mod config;
+mod file_list;
mod latex;
mod latexmkrc;
+pub(crate) mod util;
pub use self::{
- bibtex::parse_bibtex, build_log::parse_build_log, config::*, latex::parse_latex,
- latexmkrc::parse_latexmkrc,
+ bibtex::parse_bibtex, build_log::parse_build_log, config::*, file_list::parse_file_list,
+ latex::parse_latex, latexmkrc::parse_latexmkrc,
};
diff --git a/support/texlab/crates/parser/src/util.rs b/support/texlab/crates/parser/src/util.rs
new file mode 100644
index 0000000000..cb147c493b
--- /dev/null
+++ b/support/texlab/crates/parser/src/util.rs
@@ -0,0 +1,52 @@
+use std::ops::{Index, Range};
+
+use logos::{Logos, Source};
+
+pub fn lex_command_name<'a, T>(lexer: &mut logos::Lexer<'a, T>) -> &'a str
+where
+ T: Logos<'a>,
+ T::Source: Index<Range<usize>, Output = str>,
+{
+ let start = lexer.span().end;
+ let input = &lexer.source()[start..lexer.source().len()];
+
+ let mut chars = input.chars().peekable();
+ let Some(c) = chars.next() else {
+ return "";
+ };
+
+ if c.is_whitespace() {
+ return "";
+ }
+
+ lexer.bump(c.len_utf8());
+
+ if c.is_alphanumeric() || c == '@' {
+ while let Some(c) = chars.next() {
+ match c {
+ '*' => {
+ lexer.bump(c.len_utf8());
+ break;
+ }
+ c if c.is_alphanumeric() => {
+ lexer.bump(c.len_utf8());
+ }
+ '_' => {
+ if !matches!(chars.peek(), Some(c) if c.is_alphanumeric()) {
+ break;
+ }
+
+ lexer.bump(c.len_utf8());
+ }
+ '@' | ':' => {
+ lexer.bump(c.len_utf8());
+ }
+ _ => {
+ break;
+ }
+ }
+ }
+ }
+
+ &lexer.source()[start..lexer.span().end]
+}
diff --git a/support/texlab/crates/references/Cargo.toml b/support/texlab/crates/references/Cargo.toml
index e78e84ea4c..3b3abf0ecc 100644
--- a/support/texlab/crates/references/Cargo.toml
+++ b/support/texlab/crates/references/Cargo.toml
@@ -8,8 +8,8 @@ rust-version.workspace = true
[dependencies]
base-db = { path = "../base-db" }
-rowan = "0.15.15"
-rustc-hash = "1.1.0"
+rowan.workspace = true
+rustc-hash.workspace = true
syntax = { path = "../syntax" }
[dev-dependencies]
diff --git a/support/texlab/crates/references/src/command.rs b/support/texlab/crates/references/src/command.rs
index f4504641f2..cf5849a136 100644
--- a/support/texlab/crates/references/src/command.rs
+++ b/support/texlab/crates/references/src/command.rs
@@ -32,7 +32,9 @@ pub(super) fn find_all(context: &mut ReferenceContext) -> Option<()> {
.collect();
for command in &data.semantics.commands {
- if command.text == token.text()[1..] {
+ let command_text = command.text.trim_end_matches('*');
+ let token_text = token.text()[1..].trim_end_matches('*');
+ if command_text == token_text {
let kind = if defs.contains(command) {
ReferenceKind::Definition
} else {
diff --git a/support/texlab/crates/references/src/tests.rs b/support/texlab/crates/references/src/tests.rs
index 845282afb0..7131480699 100644
--- a/support/texlab/crates/references/src/tests.rs
+++ b/support/texlab/crates/references/src/tests.rs
@@ -260,3 +260,43 @@ fn test_new_command_definition_include_decl() {
true,
);
}
+
+#[test]
+fn test_new_command_definition_starred() {
+ check(
+ r#"
+%! main.tex
+\foo
+ ^^^
+\foo*
+ |
+ ^^^^
+
+\NewDocumentCommand{\foo}{s m}{%
+ \IfBooleanTF{#1}{\textbf{#2}}{#2}%
+}
+"#,
+ false,
+ );
+}
+
+#[test]
+fn test_new_command_definition_starred_include_decl() {
+ check(
+ r#"
+%! main.tex
+\foo
+ ^^^
+\foo*
+ |
+ ^^^^
+
+\NewDocumentCommand{\foo}{s m}{%
+ ^^^
+ \IfBooleanTF{#1}{\textbf{#2}}{#2}%
+}
+
+"#,
+ true,
+ );
+}
diff --git a/support/texlab/crates/rename/Cargo.toml b/support/texlab/crates/rename/Cargo.toml
index 1b2b91ee2a..bbc3487ccf 100644
--- a/support/texlab/crates/rename/Cargo.toml
+++ b/support/texlab/crates/rename/Cargo.toml
@@ -8,12 +8,13 @@ rust-version.workspace = true
[dependencies]
base-db = { path = "../base-db" }
-rowan = "0.15.15"
-rustc-hash = "1.1.0"
+rowan.workspace = true
+rustc-hash.workspace = true
syntax = { path = "../syntax" }
[dev-dependencies]
test-utils = { path = "../test-utils" }
+parser = { path = "../parser" }
[lib]
doctest = false
diff --git a/support/texlab/crates/rename/src/command.rs b/support/texlab/crates/rename/src/command.rs
index 7b17d4271c..037e09e4ca 100644
--- a/support/texlab/crates/rename/src/command.rs
+++ b/support/texlab/crates/rename/src/command.rs
@@ -35,7 +35,10 @@ pub(super) fn rename(builder: &mut RenameBuilder) -> Option<()> {
}
}
- builder.result.changes.insert(*document, edits);
+ builder
+ .result
+ .changes
+ .insert(*document, edits.iter().map(|&x| x.into()).collect());
}
Some(())
diff --git a/support/texlab/crates/rename/src/entry.rs b/support/texlab/crates/rename/src/entry.rs
index 5bed4ae613..d35d9e9e84 100644
--- a/support/texlab/crates/rename/src/entry.rs
+++ b/support/texlab/crates/rename/src/entry.rs
@@ -42,7 +42,7 @@ pub(super) fn rename(builder: &mut RenameBuilder) -> Option<()> {
for (document, range) in citations.chain(entries) {
let entry = builder.result.changes.entry(document);
- entry.or_default().push(range);
+ entry.or_default().push(range.into());
}
Some(())
diff --git a/support/texlab/crates/rename/src/label.rs b/support/texlab/crates/rename/src/label.rs
index b21e1b795e..1d82f5e2b4 100644
--- a/support/texlab/crates/rename/src/label.rs
+++ b/support/texlab/crates/rename/src/label.rs
@@ -3,22 +3,65 @@ use base_db::{
util::queries::{self, Object},
};
-use crate::{RenameBuilder, RenameParams};
+use crate::{RenameBuilder, RenameInformation, RenameParams};
+
+struct PrefixInformation<'a> {
+ def_prefixes: &'a Vec<(String, String)>,
+ ref_prefixes: &'a Vec<(String, String)>,
+}
+
+fn label_has_prefix(pref_info: &PrefixInformation, label: &tex::Label) -> Option<String> {
+ match label.kind {
+ tex::LabelKind::Definition => pref_info.def_prefixes.iter(),
+ _ => pref_info.ref_prefixes.iter(),
+ }
+ .find_map(|(k, v)| {
+ if k == &label.cmd.clone().unwrap_or(String::new()) {
+ Some(v)
+ } else {
+ None
+ }
+ })
+ .cloned()
+}
+
+fn find_prefix_in_any(
+ builder: &mut RenameBuilder,
+ pref_info: &PrefixInformation,
+ name: &str,
+) -> Option<String> {
+ let project = &builder.params.feature.project;
+ queries::objects_with_name::<tex::Label>(project, name)
+ .find_map(|(_, label)| label_has_prefix(&pref_info, label))
+}
pub(super) fn prepare_rename(params: &RenameParams) -> Option<Span> {
let data = params.feature.document.data.as_tex()?;
let labels = &data.semantics.labels;
let label = queries::object_at_cursor(labels, params.offset, queries::SearchMode::Name)?;
+
Some(Span::new(label.object.name.text.clone(), label.range))
}
pub(super) fn rename(builder: &mut RenameBuilder) -> Option<()> {
let name = prepare_rename(&builder.params)?;
+ let syn = &builder.params.feature.workspace.config().syntax;
+ let pref_info = PrefixInformation {
+ def_prefixes: &syn.label_definition_prefixes,
+ ref_prefixes: &syn.label_reference_prefixes,
+ };
+ let prefix = find_prefix_in_any(builder, &pref_info, &name.text);
+
let project = &builder.params.feature.project;
for (document, label) in queries::objects_with_name::<tex::Label>(project, &name.text) {
+ let prefix = label_has_prefix(&pref_info, label).map_or(prefix.clone(), |_| None);
+
let entry = builder.result.changes.entry(document);
- entry.or_default().push(label.name_range());
+ entry.or_default().push(RenameInformation {
+ range: label.name_range(),
+ prefix: prefix.clone(),
+ });
}
Some(())
diff --git a/support/texlab/crates/rename/src/lib.rs b/support/texlab/crates/rename/src/lib.rs
index bf9023ddef..e6c05ad268 100644
--- a/support/texlab/crates/rename/src/lib.rs
+++ b/support/texlab/crates/rename/src/lib.rs
@@ -13,8 +13,14 @@ pub struct RenameParams<'a> {
}
#[derive(Debug, Default)]
+pub struct RenameInformation {
+ pub range: TextRange,
+ pub prefix: Option<String>,
+}
+
+#[derive(Debug, Default)]
pub struct RenameResult<'a> {
- pub changes: FxHashMap<&'a Document, Vec<TextRange>>,
+ pub changes: FxHashMap<&'a Document, Vec<RenameInformation>>,
}
struct RenameBuilder<'a> {
@@ -22,6 +28,20 @@ struct RenameBuilder<'a> {
result: RenameResult<'a>,
}
+impl From<TextRange> for RenameInformation {
+ fn from(range: TextRange) -> Self {
+ RenameInformation {
+ range,
+ prefix: None,
+ }
+ }
+}
+impl PartialEq for RenameInformation {
+ fn eq(&self, other: &Self) -> bool {
+ self.range == other.range
+ }
+}
+
pub fn prepare_rename(params: &RenameParams) -> Option<TextRange> {
command::prepare_rename(params)
.or_else(|| entry::prepare_rename(params))
diff --git a/support/texlab/crates/rename/src/tests.rs b/support/texlab/crates/rename/src/tests.rs
index 0f4263033e..4da866fb08 100644
--- a/support/texlab/crates/rename/src/tests.rs
+++ b/support/texlab/crates/rename/src/tests.rs
@@ -1,23 +1,37 @@
use rustc_hash::FxHashMap;
-use crate::RenameParams;
+use base_db::Config;
+use parser::SyntaxConfig;
-fn check(input: &str) {
- let fixture = test_utils::fixture::Fixture::parse(input);
+use crate::{RenameInformation, RenameParams};
+
+fn check_with_syntax_config(config: SyntaxConfig, input: &str) {
+ let mut fixture = test_utils::fixture::Fixture::parse(input);
+ fixture.workspace.set_config(Config {
+ syntax: config,
+ ..Config::default()
+ });
+ let fixture = fixture;
- let mut expected = FxHashMap::default();
+ let mut expected: FxHashMap<_, Vec<RenameInformation>> = FxHashMap::default();
for spec in &fixture.documents {
if !spec.ranges.is_empty() {
let document = fixture.workspace.lookup(&spec.uri).unwrap();
- expected.insert(document, spec.ranges.clone());
+ expected.insert(
+ document,
+ spec.ranges.iter().map(|r| r.clone().into()).collect(),
+ );
}
}
-
let (feature, offset) = fixture.make_params().unwrap();
let actual = crate::rename(RenameParams { feature, offset });
assert_eq!(actual.changes, expected);
}
+fn check(input: &str) {
+ check_with_syntax_config(SyntaxConfig::default(), input)
+}
+
#[test]
fn test_command() {
check(
@@ -78,12 +92,97 @@ fn test_label() {
|
^^^
+%! baz.tex
+\ref{foo}
+
%! bar.tex
\ref{foo}
^^^
+"#,
+ )
+}
+
+#[test]
+fn test_custom_label_ref() {
+ let mut config = SyntaxConfig::default();
+ config
+ .label_definition_commands
+ .extend(vec!["asm", "goal"].into_iter().map(String::from));
+ config.label_definition_prefixes.extend(
+ vec![("asm", "asm:"), ("goal", "goal:")]
+ .into_iter()
+ .map(|(x, y)| (String::from(x), String::from(y))),
+ );
+ config
+ .label_reference_commands
+ .extend(vec!["asmref", "goalref"].into_iter().map(String::from));
+ config.label_reference_prefixes.extend(
+ vec![("asmref", "asm:"), ("goalref", "goal:")]
+ .into_iter()
+ .map(|(x, y)| (String::from(x), String::from(y))),
+ );
+ check_with_syntax_config(
+ config,
+ r#"
+%! foo.tex
+\goal{foo}
+
+\asm{foo}\include{bar}\include{baz}
+ |
+ ^^^
+
+%! bar.tex
+\asmref{foo}
+ ^^^
+
+%! baz.tex
+\ref{foo}
+
+\ref{asm:foo}
+ ^^^^^^^
+
+"#,
+ )
+}
+
+#[test]
+fn test_custom_label_def() {
+ let mut config = SyntaxConfig::default();
+ config
+ .label_definition_commands
+ .extend(vec!["asm", "goal"].into_iter().map(String::from));
+ config.label_definition_prefixes.extend(
+ vec![("asm", "asm:"), ("goal", "goal:")]
+ .into_iter()
+ .map(|(x, y)| (String::from(x), String::from(y))),
+ );
+ config
+ .label_reference_commands
+ .extend(vec!["asmref", "goalref"].into_iter().map(String::from));
+ config.label_reference_prefixes.extend(
+ vec![("asmref", "asm:"), ("goalref", "goal:")]
+ .into_iter()
+ .map(|(x, y)| (String::from(x), String::from(y))),
+ );
+ check_with_syntax_config(
+ config,
+ r#"
+%! foo.tex
+\goal{foo}
+
+\label{asm:foo}\include{bar}\include{baz}
+ |
+ ^^^^^^^
+
+%! bar.tex
+\asmref{foo}
+ ^^^
%! baz.tex
\ref{foo}
+
+\ref{asm:foo}
+ ^^^^^^^
"#,
)
}
diff --git a/support/texlab/crates/symbols/Cargo.toml b/support/texlab/crates/symbols/Cargo.toml
index 65db0fc0bd..3ebc88fa50 100644
--- a/support/texlab/crates/symbols/Cargo.toml
+++ b/support/texlab/crates/symbols/Cargo.toml
@@ -12,14 +12,14 @@ doctest = false
[dependencies]
base-db = { path = "../base-db" }
distro = { path = "../distro" }
-itertools = "0.12.1"
+itertools.workspace = true
line-index = { path = "../line-index" }
-rowan = "0.15.15"
+rowan.workspace = true
syntax = { path = "../syntax" }
-titlecase = "3.0.0"
-url = "2.5.0"
+titlecase.workspace = true
+url.workspace = true
[dev-dependencies]
-regex = "1.10.4"
+regex.workspace = true
test-utils = { path = "../test-utils" }
-expect-test = "1.5.0"
+expect-test.workspace = true
diff --git a/support/texlab/crates/symbols/src/document.rs b/support/texlab/crates/symbols/src/document.rs
index 791f119919..611a7e0370 100644
--- a/support/texlab/crates/symbols/src/document.rs
+++ b/support/texlab/crates/symbols/src/document.rs
@@ -23,6 +23,7 @@ pub fn document_symbols(workspace: &Workspace, document: &Document) -> Vec<Symbo
| DocumentData::Log(_)
| DocumentData::Root
| DocumentData::Latexmkrc(_)
+ | DocumentData::FileList(_)
| DocumentData::Tectonic => Vec::new(),
};
diff --git a/support/texlab/crates/symbols/src/document/tests.rs b/support/texlab/crates/symbols/src/document/tests.rs
index 25450a6cc5..cf599529fb 100644
--- a/support/texlab/crates/symbols/src/document/tests.rs
+++ b/support/texlab/crates/symbols/src/document/tests.rs
@@ -281,44 +281,44 @@ fn test_section() {
check(
&fixture,
expect![[r#"
- [
- Symbol {
- name: "Foo",
- kind: Section,
- label: None,
- full_range: 43..56,
- selection_range: 43..56,
- children: [],
- },
- Symbol {
- name: "2 Bar",
- kind: Section,
- label: Some(
- Span(
- "sec:bar",
- 71..86,
+ [
+ Symbol {
+ name: "1 Foo",
+ kind: Section,
+ label: None,
+ full_range: 43..56,
+ selection_range: 43..56,
+ children: [],
+ },
+ Symbol {
+ name: "2 Bar",
+ kind: Section,
+ label: Some(
+ Span(
+ "sec:bar",
+ 71..86,
+ ),
),
- ),
- full_range: 58..119,
- selection_range: 71..86,
- children: [
- Symbol {
- name: "Baz",
- kind: Section,
- label: Some(
- Span(
- "sec:baz",
- 104..119,
+ full_range: 58..119,
+ selection_range: 71..86,
+ children: [
+ Symbol {
+ name: "Baz",
+ kind: Section,
+ label: Some(
+ Span(
+ "sec:baz",
+ 104..119,
+ ),
),
- ),
- full_range: 88..119,
- selection_range: 104..119,
- children: [],
- },
- ],
- },
- ]
- "#]],
+ full_range: 88..119,
+ selection_range: 104..119,
+ children: [],
+ },
+ ],
+ },
+ ]
+ "#]],
);
}
diff --git a/support/texlab/crates/symbols/src/document/tex.rs b/support/texlab/crates/symbols/src/document/tex.rs
index e0df9c85c1..734335ef0e 100644
--- a/support/texlab/crates/symbols/src/document/tex.rs
+++ b/support/texlab/crates/symbols/src/document/tex.rs
@@ -67,16 +67,14 @@ impl<'a> SymbolBuilder<'a> {
let group_text = group.content_text()?;
let kind = SymbolKind::Section;
- let symbol = match self.find_label(section.syntax()) {
- Some(label) => {
- let name = match self.find_label_number(&label.text) {
- Some(number) => format!("{number} {group_text}"),
- None => group_text,
- };
+ let name = match self.find_section_number(&group_text) {
+ Some(number) => format!("{number} {group_text}"),
+ None => group_text,
+ };
- Symbol::new_label(name, kind, range, label)
- }
- None => Symbol::new_simple(group_text, kind, range, range),
+ let symbol = match self.find_label(section.syntax()) {
+ Some(label) => Symbol::new_label(name, kind, range, label),
+ None => Symbol::new_simple(name, kind, range, range)
};
Some(symbol)
@@ -247,6 +245,15 @@ impl<'a> SymbolBuilder<'a> {
Some(Span { text, range })
}
+ fn find_section_number(&self, name: &str) -> Option<&str> {
+ self.project
+ .documents
+ .iter()
+ .filter_map(|document| document.data.as_aux())
+ .find_map(|data| data.semantics.section_numbers.get(name))
+ .map(String::as_str)
+ }
+
fn find_label_number(&self, name: &str) -> Option<&str> {
self.project
.documents
diff --git a/support/texlab/crates/syntax/Cargo.toml b/support/texlab/crates/syntax/Cargo.toml
index a2d3d866b6..5ae82f8bc5 100644
--- a/support/texlab/crates/syntax/Cargo.toml
+++ b/support/texlab/crates/syntax/Cargo.toml
@@ -7,8 +7,9 @@ edition.workspace = true
rust-version.workspace = true
[dependencies]
-itertools = "0.12.1"
-rowan = "0.15.15"
+itertools.workspace = true
+rowan.workspace = true
+rustc-hash.workspace = true
[lib]
doctest = false
diff --git a/support/texlab/crates/syntax/src/file_list.rs b/support/texlab/crates/syntax/src/file_list.rs
new file mode 100644
index 0000000000..cd32e787da
--- /dev/null
+++ b/support/texlab/crates/syntax/src/file_list.rs
@@ -0,0 +1,10 @@
+use std::path::PathBuf;
+
+use rustc_hash::FxHashSet;
+
+#[derive(Debug, PartialEq, Eq, Clone, Default)]
+pub struct FileList {
+ pub working_dir: Option<PathBuf>,
+ pub inputs: FxHashSet<PathBuf>,
+ pub outputs: FxHashSet<PathBuf>,
+}
diff --git a/support/texlab/crates/syntax/src/latex/cst.rs b/support/texlab/crates/syntax/src/latex/cst.rs
index f16d703162..580ef6af12 100644
--- a/support/texlab/crates/syntax/src/latex/cst.rs
+++ b/support/texlab/crates/syntax/src/latex/cst.rs
@@ -12,7 +12,7 @@ pub fn small_range(node: &dyn AstNode<Language = LatexLanguage>) -> TextRange {
let start = full_range.start();
let mut token = node.syntax().last_token();
while let Some(current) = token {
- if !matches!(current.kind(), LINE_BREAK | WHITESPACE | COMMENT) {
+ if !matches!(current.kind(), WHITESPACE | COMMENT) {
return TextRange::new(start, current.text_range().end());
}
token = current.prev_token();
@@ -233,7 +233,7 @@ impl Key {
self.syntax()
.children_with_tokens()
.filter_map(|node| node.into_token())
- .filter(|node| !matches!(node.kind(), WHITESPACE | LINE_BREAK | COMMENT))
+ .filter(|node| !matches!(node.kind(), WHITESPACE | COMMENT))
}
}
@@ -258,7 +258,7 @@ impl ToString for Key {
.children_with_tokens()
.filter_map(|node| node.into_token())
{
- if matches!(token.kind(), WHITESPACE | LINE_BREAK | COMMENT) {
+ if matches!(token.kind(), WHITESPACE | COMMENT) {
buf.push(' ');
} else {
buf.push_str(token.text());
@@ -750,3 +750,43 @@ impl GraphicsPath {
self.syntax().descendants().filter_map(CurlyGroupWord::cast)
}
}
+
+cst_node!(BibItem, BIBITEM);
+
+impl BibItem {
+ pub fn command(&self) -> Option<SyntaxToken> {
+ self.syntax().first_token()
+ }
+
+ pub fn name(&self) -> Option<CurlyGroupWord> {
+ self.syntax().children().find_map(CurlyGroupWord::cast)
+ }
+}
+
+cst_node!(TocContentsLine, TOC_CONTENTS_LINE);
+
+impl TocContentsLine {
+ pub fn command(&self) -> Option<SyntaxToken> {
+ self.syntax().first_token()
+ }
+
+ pub fn unit(&self) -> Option<CurlyGroup> {
+ self.syntax().children().find_map(CurlyGroup::cast)
+ }
+
+ pub fn line(&self) -> Option<CurlyGroup> {
+ self.syntax().children().filter_map(CurlyGroup::cast).nth(1)
+ }
+}
+
+cst_node!(TocNumberLine, TOC_NUMBER_LINE);
+
+impl TocNumberLine {
+ pub fn command(&self) -> Option<SyntaxToken> {
+ self.syntax().first_token()
+ }
+
+ pub fn number(&self) -> Option<CurlyGroup> {
+ self.syntax().children().find_map(CurlyGroup::cast)
+ }
+}
diff --git a/support/texlab/crates/syntax/src/latex/kind.rs b/support/texlab/crates/syntax/src/latex/kind.rs
index 8b649b1f31..f67201e003 100644
--- a/support/texlab/crates/syntax/src/latex/kind.rs
+++ b/support/texlab/crates/syntax/src/latex/kind.rs
@@ -4,7 +4,6 @@
pub enum SyntaxKind {
ERROR = 0,
- LINE_BREAK,
WHITESPACE,
COMMENT,
VERBATIM,
@@ -83,6 +82,9 @@ pub enum SyntaxKind {
ENVIRONMENT_DEFINITION,
GRAPHICS_PATH,
BLOCK_COMMENT,
+ BIBITEM,
+ TOC_CONTENTS_LINE,
+ TOC_NUMBER_LINE,
ROOT,
}
diff --git a/support/texlab/crates/syntax/src/lib.rs b/support/texlab/crates/syntax/src/lib.rs
index 35f1bb8c52..d3e2098757 100644
--- a/support/texlab/crates/syntax/src/lib.rs
+++ b/support/texlab/crates/syntax/src/lib.rs
@@ -1,4 +1,5 @@
pub mod bibtex;
+pub mod file_list;
pub mod latex;
pub mod latexmkrc;
diff --git a/support/texlab/crates/test-utils/Cargo.toml b/support/texlab/crates/test-utils/Cargo.toml
index b08d9cc09f..581be2e6a2 100644
--- a/support/texlab/crates/test-utils/Cargo.toml
+++ b/support/texlab/crates/test-utils/Cargo.toml
@@ -10,8 +10,8 @@ rust-version.workspace = true
base-db = { path = "../base-db" }
distro = { path = "../distro" }
line-index = { path = "../line-index" }
-rowan = "0.15.15"
-url = "2.5.0"
+rowan.workspace = true
+url.workspace = true
[lib]
doctest = false
diff --git a/support/texlab/crates/texlab/Cargo.toml b/support/texlab/crates/texlab/Cargo.toml
index a2fb78e11f..5f73cbf024 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.16.1"
+version.workspace = true
license.workspace = true
readme = "README.md"
authors.workspace = true
@@ -22,19 +22,19 @@ test = false
doctest = false
[dependencies]
-anyhow = "1.0.86"
+anyhow.workspace = true
base-db = { path = "../base-db" }
bibfmt = { path = "../bibfmt" }
citeproc = { path = "../citeproc" }
-clap = { version = "4.5.4", features = ["derive"] }
+clap = { version = "4.5.20", features = ["derive"] }
commands = { path = "../commands" }
completion = { path = "../completion" }
completion-data = { path = "../completion-data" }
-crossbeam-channel = "0.5.12"
+crossbeam-channel.workspace = true
definition = { path = "../definition" }
diagnostics = { path = "../diagnostics" }
distro = { path = "../distro" }
-fern = "0.6.2"
+fern = "0.7.0"
folding = { path = "../folding" }
highlights = { path = "../highlights" }
hover = { path = "../hover" }
@@ -42,29 +42,29 @@ inlay-hints = { path = "../inlay-hints" }
ipc = { path = "../ipc" }
line-index = { path = "../line-index" }
links = { path = "../links" }
-log = "0.4.21"
-lsp-server = "0.7.6"
+log.workspace = true
+lsp-server = "0.7.7"
lsp-types = "0.95.1"
-notify = "6.1.1"
-notify-debouncer-full = "0.3.1"
-parking_lot = "0.12.2"
+notify.workspace = true
+notify-debouncer-full = "0.3.2"
+parking_lot = "0.12.3"
parser = { path = "../parser" }
references = { path = "../references" }
-regex = "1.10.4"
+regex.workspace = true
rename = { path = "../rename" }
-rowan = "0.15.15"
-rustc-hash = "1.1.0"
-serde = "1.0.202"
-serde_json = "1.0.117"
+rowan.workspace = true
+rustc-hash.workspace = true
+serde.workspace = true
+serde_json.workspace = true
serde_regex = "1.1.0"
serde_repr = "0.1.19"
symbols = { path = "../symbols" }
syntax = { path = "../syntax" }
-tempfile = "3.10.1"
+tempfile.workspace = true
threadpool = "1.8.1"
[dev-dependencies]
-criterion = { version = "0.5.1" }
+criterion.workspace = true
[[bench]]
name = "bench_main"
diff --git a/support/texlab/crates/texlab/src/features/formatting.rs b/support/texlab/crates/texlab/src/features/formatting.rs
index 3fcd66e39b..9d152f6e8b 100644
--- a/support/texlab/crates/texlab/src/features/formatting.rs
+++ b/support/texlab/crates/texlab/src/features/formatting.rs
@@ -27,6 +27,7 @@ pub fn format_source_code(
| Language::Log
| Language::Root
| Language::Latexmkrc
- | Language::Tectonic => None,
+ | Language::Tectonic
+ | Language::FileList => None,
}
}
diff --git a/support/texlab/crates/texlab/src/features/formatting/latexindent.rs b/support/texlab/crates/texlab/src/features/formatting/latexindent.rs
index d3fffc2050..b956378ed5 100644
--- a/support/texlab/crates/texlab/src/features/formatting/latexindent.rs
+++ b/support/texlab/crates/texlab/src/features/formatting/latexindent.rs
@@ -16,7 +16,7 @@ pub fn format_with_latexindent(
) -> Option<Vec<lsp_types::TextEdit>> {
let config = workspace.config();
let target_dir = tempdir().ok()?;
- let root = ProjectRoot::walk_and_find(workspace, &document.dir);
+ let root = ProjectRoot::walk_and_find(workspace, document.dir.as_ref()?);
let source_dir = root.src_dir.to_file_path().ok()?;
let target_file = target_dir
@@ -72,6 +72,15 @@ fn build_arguments(config: &LatexIndentConfig, target_file: &Path) -> Vec<String
args.push("--modifylinebreaks".to_string());
}
+ match &config.replacement {
+ Some(replacement_flag) => {
+ if ["-r", "-rv", "-rr"].contains(& replacement_flag.as_str()) {
+ args.push(replacement_flag.clone());
+ }
+ },
+ None => {}
+ }
+
args.push(target_file.display().to_string());
args
}
diff --git a/support/texlab/crates/texlab/src/features/inlay_hint.rs b/support/texlab/crates/texlab/src/features/inlay_hint.rs
index ddd8ff26d8..0689f07af0 100644
--- a/support/texlab/crates/texlab/src/features/inlay_hint.rs
+++ b/support/texlab/crates/texlab/src/features/inlay_hint.rs
@@ -7,10 +7,11 @@ pub fn find_all(
params: lsp_types::InlayHintParams,
) -> Option<Vec<lsp_types::InlayHint>> {
let params = from_proto::inlay_hint_params(workspace, params)?;
+ let line_index = &params.feature.document.line_index;
+ let max_length = workspace.config().inlay_hints.max_length;
let hints = inlay_hints::find_all(&params)?
.into_iter()
- .filter_map(|hint| to_proto::inlay_hint(hint, &params.feature.document.line_index))
- .collect();
+ .filter_map(|hint| to_proto::inlay_hint(hint, line_index, max_length));
- Some(hints)
+ Some(hints.collect())
}
diff --git a/support/texlab/crates/texlab/src/server/options.rs b/support/texlab/crates/texlab/src/server/options.rs
index 3f50faefd7..fcb8e1ec60 100644
--- a/support/texlab/crates/texlab/src/server/options.rs
+++ b/support/texlab/crates/texlab/src/server/options.rs
@@ -1,6 +1,7 @@
-use regex::Regex;
use serde::{Deserialize, Serialize};
+use regex::Regex;
+
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
#[serde(default)]
@@ -55,6 +56,7 @@ impl Default for LatexFormatter {
pub struct LatexindentOptions {
pub local: Option<String>,
pub modify_line_breaks: bool,
+ pub replacement: Option<String>,
}
#[derive(Debug, PartialEq, Eq, Clone, Default, Serialize, Deserialize)]
@@ -69,6 +71,7 @@ pub struct BuildOptions {
pub log_directory: Option<String>,
pub pdf_directory: Option<String>,
pub filename: Option<String>,
+ pub use_file_list: bool,
}
#[derive(Debug, PartialEq, Eq, Clone, Default, Serialize, Deserialize)]
@@ -102,6 +105,7 @@ pub struct DiagnosticsOptions {
pub struct InlayHintOptions {
pub label_definitions: Option<bool>,
pub label_references: Option<bool>,
+ pub max_length: Option<usize>,
}
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
@@ -125,7 +129,9 @@ pub struct ExperimentalOptions {
pub verbatim_environments: Vec<String>,
pub citation_commands: Vec<String>,
pub label_definition_commands: Vec<String>,
+ pub label_definition_prefixes: Vec<(String, String)>,
pub label_reference_commands: Vec<String>,
+ pub label_reference_prefixes: Vec<(String, String)>,
}
#[derive(Debug, PartialEq, Eq, Clone, Default, Serialize, Deserialize)]
diff --git a/support/texlab/crates/texlab/src/util.rs b/support/texlab/crates/texlab/src/util.rs
index c301dc7722..87e41a78ae 100644
--- a/support/texlab/crates/texlab/src/util.rs
+++ b/support/texlab/crates/texlab/src/util.rs
@@ -18,9 +18,28 @@ pub fn normalize_uri(uri: &mut lsp_types::Url) {
}
}
+ uri.set_path(&normalize_percent_encoding(uri.path()));
uri.set_fragment(None);
}
+fn normalize_percent_encoding(input: &str) -> String {
+ let mut output = String::new();
+ let mut i = 0;
+ for c in input.chars() {
+ if c == '%' && i == 0 {
+ output.push(c);
+ i = 2;
+ } else if i > 0 {
+ output.push(c.to_ascii_uppercase());
+ i -= 1;
+ } else {
+ output.push(c);
+ }
+ }
+
+ output
+}
+
fn fix_drive_letter(text: &str) -> Option<String> {
if !text.is_ascii() || text.is_empty() {
return None;
@@ -59,4 +78,44 @@ mod tests {
normalize_uri(&mut uri);
assert_eq!(uri.as_str(), "foo:///bar/baz.txt");
}
+
+ #[test]
+ #[cfg(unix)]
+ fn test_lowercase_percent_encoding_unix() {
+ let mut uri1 = Url::parse("file:///foo/%c3%a4.tex").unwrap();
+ let uri2 = Url::from_file_path("/foo/ä.tex").unwrap();
+
+ normalize_uri(&mut uri1);
+ assert_eq!(uri1, uri2);
+ }
+
+ #[test]
+ #[cfg(unix)]
+ fn test_uppercase_percent_encoding_unix() {
+ let mut uri1 = Url::parse("file:///foo/%C3%A4.tex").unwrap();
+ let uri2 = Url::from_file_path("/foo/ä.tex").unwrap();
+
+ normalize_uri(&mut uri1);
+ assert_eq!(uri1, uri2);
+ }
+
+ #[test]
+ #[cfg(windows)]
+ fn test_lowercase_percent_encoding_windows() {
+ let mut uri1 = Url::parse("file:///c%3a/foo/%c3%a4.tex").unwrap();
+ let uri2 = Url::from_file_path("C:/foo/ä.tex").unwrap();
+
+ normalize_uri(&mut uri1);
+ assert_eq!(uri1, uri2);
+ }
+
+ #[test]
+ #[cfg(windows)]
+ fn test_uppercase_percent_encoding_windows() {
+ let mut uri1 = Url::parse("file:///c%3A/foo/%C3%A4.tex").unwrap();
+ let uri2 = Url::from_file_path("C:/foo/ä.tex").unwrap();
+
+ normalize_uri(&mut uri1);
+ assert_eq!(uri1, uri2);
+ }
}
diff --git a/support/texlab/crates/texlab/src/util/client_flags.rs b/support/texlab/crates/texlab/src/util/client_flags.rs
index 842dbb1eae..2829041832 100644
--- a/support/texlab/crates/texlab/src/util/client_flags.rs
+++ b/support/texlab/crates/texlab/src/util/client_flags.rs
@@ -20,18 +20,12 @@ pub struct ClientFlags {
/// If not set, then fuzzy citation completion will not work.
pub completion_always_incomplete: bool,
- /// If `true`, the server can include markdown in hover responses.
- pub hover_markdown: bool,
-
/// If `true`, the server can pull the configuration from the client.
pub configuration_pull: bool,
/// If `true`, the client notifies the server when the configuration changes.
pub configuration_push: bool,
- /// If `true`, the client can return `LocationLink` instead of `Location`.
- pub definition_link: bool,
-
/// If `true`, the server can return custom kinds like `section`.
pub folding_custom_kinds: bool,
diff --git a/support/texlab/crates/texlab/src/util/from_proto.rs b/support/texlab/crates/texlab/src/util/from_proto.rs
index 789edbf9c3..928b3d6d61 100644
--- a/support/texlab/crates/texlab/src/util/from_proto.rs
+++ b/support/texlab/crates/texlab/src/util/from_proto.rs
@@ -56,15 +56,6 @@ pub fn client_flags(
let completion_always_incomplete = info.map_or(false, |info| info.name == "Visual Studio Code");
- let hover_markdown = capabilities
- .text_document
- .as_ref()
- .and_then(|cap| cap.hover.as_ref())
- .and_then(|cap| cap.content_format.as_ref())
- .map_or(false, |formats| {
- formats.contains(&lsp_types::MarkupKind::Markdown)
- });
-
let configuration_pull = capabilities
.workspace
.as_ref()
@@ -78,13 +69,6 @@ pub fn client_flags(
.and_then(|cap| cap.dynamic_registration)
.unwrap_or(false);
- let definition_link = capabilities
- .text_document
- .as_ref()
- .and_then(|cap| cap.definition)
- .and_then(|cap| cap.link_support)
- .unwrap_or(false);
-
let folding_custom_kinds = capabilities
.text_document
.as_ref()
@@ -111,10 +95,8 @@ pub fn client_flags(
completion_snippets,
completion_kinds,
completion_always_incomplete,
- hover_markdown,
configuration_pull,
configuration_push,
- definition_link,
folding_custom_kinds,
progress,
show_document,
@@ -300,6 +282,7 @@ pub fn config(value: Options) -> Config {
config.formatting.latex_indent.local = value.latexindent.local;
config.formatting.latex_indent.modify_line_breaks = value.latexindent.modify_line_breaks;
+ config.formatting.latex_indent.replacement = value.latexindent.replacement;
config.synctex = value
.forward_search
@@ -323,6 +306,7 @@ pub fn config(value: Options) -> Config {
config.inlay_hints.label_definitions = value.inlay_hints.label_definitions.unwrap_or(true);
config.inlay_hints.label_references = value.inlay_hints.label_references.unwrap_or(true);
+ config.inlay_hints.max_length = value.inlay_hints.max_length;
config.completion.matcher = match value.completion.matcher {
CompletionMatcher::Fuzzy => base_db::MatchingAlgo::Skim,
@@ -331,6 +315,8 @@ pub fn config(value: Options) -> Config {
CompletionMatcher::PrefixIgnoreCase => base_db::MatchingAlgo::PrefixIgnoreCase,
};
+ config.syntax.use_file_list = value.build.use_file_list;
+
config
.syntax
.math_environments
@@ -358,8 +344,18 @@ pub fn config(value: Options) -> Config {
config
.syntax
+ .label_definition_prefixes
+ .extend(value.experimental.label_definition_prefixes);
+
+ config
+ .syntax
.label_reference_commands
.extend(value.experimental.label_reference_commands);
config
+ .syntax
+ .label_reference_prefixes
+ .extend(value.experimental.label_reference_prefixes);
+
+ config
}
diff --git a/support/texlab/crates/texlab/src/util/to_proto.rs b/support/texlab/crates/texlab/src/util/to_proto.rs
index f5cf2edf8b..82d0132434 100644
--- a/support/texlab/crates/texlab/src/util/to_proto.rs
+++ b/support/texlab/crates/texlab/src/util/to_proto.rs
@@ -191,13 +191,25 @@ pub fn diagnostic(
})
}
-pub fn inlay_hint(hint: InlayHint, line_index: &LineIndex) -> Option<lsp_types::InlayHint> {
+pub fn inlay_hint(
+ hint: InlayHint,
+ line_index: &LineIndex,
+ max_length: Option<usize>,
+) -> Option<lsp_types::InlayHint> {
let position = line_index.line_col_lsp(hint.offset)?;
+ let trim_text = |text: &mut String| match max_length {
+ Some(max_length) if text.len() > max_length => {
+ text.truncate(max_length);
+ text.push('…');
+ }
+ _ => {}
+ };
+
Some(match hint.data {
InlayHintData::LabelDefinition(label) => {
let number = label.number?;
- let text = match &label.object {
+ let mut text = match &label.object {
RenderedObject::Section { prefix, .. } => {
format!("{} {}", prefix, number)
}
@@ -211,9 +223,11 @@ pub fn inlay_hint(hint: InlayHint, line_index: &LineIndex) -> Option<lsp_types::
RenderedObject::EnumItem => format!("Item {}", number),
};
+ trim_text(&mut text);
+
lsp_types::InlayHint {
position,
- label: lsp_types::InlayHintLabel::String(format!(" {text} ")),
+ label: lsp_types::InlayHintLabel::String(format!(" {text} ",)),
kind: None,
text_edits: None,
tooltip: None,
@@ -223,7 +237,8 @@ pub fn inlay_hint(hint: InlayHint, line_index: &LineIndex) -> Option<lsp_types::
}
}
InlayHintData::LabelReference(label) => {
- let text = label.reference();
+ let mut text = label.reference();
+ trim_text(&mut text);
lsp_types::InlayHint {
position,
@@ -396,8 +411,15 @@ pub fn workspace_edit(result: RenameResult, new_name: &str) -> lsp_types::Worksp
let mut edits = Vec::new();
ranges
.into_iter()
- .filter_map(|range| document.line_index.line_col_lsp_range(range))
- .for_each(|range| edits.push(lsp_types::TextEdit::new(range, new_name.into())));
+ .filter_map(|info| {
+ document.line_index.line_col_lsp_range(info.range).map(|i| {
+ (
+ i,
+ info.prefix.map_or(new_name.into(), |p| p + new_name.into()),
+ )
+ })
+ })
+ .for_each(|(range, new_name)| edits.push(lsp_types::TextEdit::new(range, new_name)));
changes.insert(document.uri.clone(), edits);
}
diff --git a/support/texlab/texlab.1 b/support/texlab/texlab.1
index 69f16a0bf9..27fabe2066 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.49.1.
-.TH TEXLAB "1" "May 2024" "texlab 5.16.1" "User Commands"
+.TH TEXLAB "1" "October 2024" "texlab 5.21.0" "User Commands"
.SH NAME
-texlab \- manual page for texlab 5.16.1
+texlab \- manual page for texlab 5.21.0
.SH SYNOPSIS
.B texlab
[\fI\,OPTIONS\/\fR] [\fI\,COMMAND\/\fR]
diff --git a/support/texlab/texlab.pdf b/support/texlab/texlab.pdf
index 8731c5ef78..152ab2bac4 100644
--- a/support/texlab/texlab.pdf
+++ b/support/texlab/texlab.pdf
Binary files differ