diff options
Diffstat (limited to 'support')
39 files changed, 698 insertions, 192 deletions
diff --git a/support/TeX4ht/source/ChangeLog b/support/TeX4ht/source/ChangeLog index f98f416574..6bf8ba7fce 100644 --- a/support/TeX4ht/source/ChangeLog +++ b/support/TeX4ht/source/ChangeLog @@ -1,3 +1,9 @@ +2024-07-06 Michal Hoftich <michal.h21@gmail.com> + + * tex4ht-html4.tex (html4.4ht): added itemize+ option. It will keep + original characters for itemize bullets. + https://tex.stackexchange.com/a/722062/2891 + 2024-07-03 Michal Hoftich <michal.h21@gmail.com> * tex4ht-4ht.tex (fontawesome5.4ht): use icon name as the alt text. diff --git a/support/TeX4ht/source/tex4ht-html4.tex b/support/TeX4ht/source/tex4ht-html4.tex index eb45f6f2ac..13bf280c88 100644 --- a/support/TeX4ht/source/tex4ht-html4.tex +++ b/support/TeX4ht/source/tex4ht-html4.tex @@ -1,4 +1,4 @@ -% $Id: tex4ht-html4.tex 1533 2024-06-21 13:38:57Z michal_h21 $ +% $Id: tex4ht-html4.tex 1537 2024-07-06 19:48:42Z michal_h21 $ % Compile 4 times: latex tex4ht-html4 % Copy html4.4ht into the work directory before all but the last compilation. % @@ -2950,6 +2950,22 @@ such a case, we don't have proper nestings of environments. \EndP\HCode{</li></ul>}\ShowPar} {\end:itm \global\def\end:itm{\EndP\Tg</li>}\DeleteMark} {\HCode{<li class="\getClass{li}itemize">}\afterGetClass{li}|<list par|>} + +\:CheckOption{itemize+}\if:Option +\ConfigureList{itemize}% + {\EndP\HCode{<ul \a:LRdir + class="\getClass{itemize}itemize\expandafter\the + \csname @itemdepth\endcsname">}% + \afterGetClass{itemize}% + |<save end:itm|>\global\let\end:itm=\empty} + {|<recall end:itm|>\ifvmode \IgnorePar\fi + \EndP\HCode{</li></ul>}\ShowPar} + {\end:itm \global\def\end:itm{\EndP\Tg</li>}\HCode{<li class="\getClass{li}itemize"><span class="itemizeHead" aria-hidden="true">}\afterGetClass{li}} + {\HCode{</span>}|<list par|>} +\Css{.itemizeHead{float: left; margin-left: -1em; width: 1em;}} +\Css{li.itemize{list-style: none;}} +\fi + \NewConfigure{itemizeClass}{2} \Configure{itemizeClass}{}{} \NewConfigure{liClass}{2} diff --git a/support/texlab/CHANGELOG.md b/support/texlab/CHANGELOG.md index 007f344876..8765fc1a30 100644 --- a/support/texlab/CHANGELOG.md +++ b/support/texlab/CHANGELOG.md @@ -5,6 +5,19 @@ 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.18.0] + +### 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 diff --git a/support/texlab/Cargo.lock b/support/texlab/Cargo.lock index 09847a2a79..4102d1f40a 100644 --- a/support/texlab/Cargo.lock +++ b/support/texlab/Cargo.lock @@ -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", ] @@ -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.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90bc066a67923782aa8515dbaea16946c5bcc5addbd668bb80af688e53e548a0" +checksum = "84b3edb18336f4df585bc9aa31dd99c036dfa5dc5e9a2939a722a188f3a8970d" dependencies = [ "clap_builder", "clap_derive", @@ -254,9 +254,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.2" +version = "4.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae129e2e766ae0ec03484e609954119f123cc1fe650337e155d03b022f24f7b4" +checksum = "c1c09dd5ada6c6c78075d6fd0da3f90d8080651e2d6cc8eb2f1aaa4034ced708" dependencies = [ "anstream", "anstyle", @@ -266,9 +266,9 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.5.4" +version = "4.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "528131438037fd55894f62d6e9f068b8f45ac57ffa77517819645d10aed04f64" +checksum = "2bac35c6dafb060fd4d275d9a4ffae97917c13a6327903a8be2153cd964f7085" 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", @@ -337,7 +337,7 @@ dependencies = [ "parser", "rayon", "rowan", - "rustc-hash", + "rustc-hash 2.0.0", "syntax", "test-utils", "url", @@ -348,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", ] @@ -408,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", ] @@ -450,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", ] @@ -465,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", @@ -510,7 +510,7 @@ name = "distro" version = "0.0.0" dependencies = [ "anyhow", - "rustc-hash", + "rustc-hash 2.0.0", ] [[package]] @@ -742,7 +742,7 @@ dependencies = [ "base-db", "expect-test", "rowan", - "rustc-hash", + "rustc-hash 2.0.0", "test-utils", ] @@ -811,9 +811,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", ] @@ -869,7 +869,7 @@ checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" name = "line-index" version = "0.0.0" dependencies = [ - "rustc-hash", + "rustc-hash 2.0.0", "text-size", ] @@ -900,9 +900,9 @@ 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" @@ -1127,7 +1127,7 @@ dependencies = [ "pathdiff", "regex", "rowan", - "rustc-hash", + "rustc-hash 2.0.0", "syntax", "tempfile", "versions", @@ -1299,16 +1299,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.10.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c117dbdfde9c8308975b6a18d71f3f385c89461f7b3fb054288ecf2a2058ba4c" +checksum = "b91213439dad192326a0d7c6ee3955910425f441d7038e0d6933b0aec5c4517f" dependencies = [ "aho-corasick", "memchr", @@ -1340,7 +1340,7 @@ dependencies = [ "base-db", "parser", "rowan", - "rustc-hash", + "rustc-hash 2.0.0", "syntax", "test-utils", ] @@ -1354,7 +1354,7 @@ dependencies = [ "countme", "hashbrown", "memoffset", - "rustc-hash", + "rustc-hash 1.1.0", "text-size", ] @@ -1365,6 +1365,12 @@ 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" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1406,18 +1412,18 @@ checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] name = "serde" -version = "1.0.202" +version = "1.0.203" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "226b61a0d411b2ba5ff6d7f73a476ac4f8bb900373459cd00fab8512828ba395" +checksum = "7253ab4de971e72fb7be983802300c30b5a7f0c2e56fab8abfc6a214307c0094" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.202" +version = "1.0.203" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6048858004bcff69094cd972ed40a32500f153bd3be9f716b2eed2e8217c4838" +checksum = "500cbc0ebeb6f46627f50f3f5811ccf6bf00643be300b4c3eabc0ef55dc5b5ba" dependencies = [ "proc-macro2", "quote", @@ -1426,9 +1432,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.117" +version = "1.0.119" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "455182ea6142b14f93f4bc5320a2b31c1f266b66a4a5c858b013302a5d8cbfc3" +checksum = "e8eddb61f0697cc3989c5d64b452f5488e2b8a60fd7d5076a3045076ffef8cb0" dependencies = [ "itoa", "ryu", @@ -1496,7 +1502,7 @@ dependencies = [ "base-db", "distro", "expect-test", - "itertools 0.12.1", + "itertools 0.13.0", "line-index", "regex", "rowan", @@ -1521,8 +1527,9 @@ dependencies = [ name = "syntax" version = "0.0.0" dependencies = [ - "itertools 0.12.1", + "itertools 0.13.0", "rowan", + "rustc-hash 2.0.0", ] [[package]] @@ -1550,7 +1557,7 @@ dependencies = [ [[package]] name = "texlab" -version = "5.17.0" +version = "5.18.0" dependencies = [ "anyhow", "base-db", @@ -1584,7 +1591,7 @@ dependencies = [ "regex", "rename", "rowan", - "rustc-hash", + "rustc-hash 2.0.0", "serde", "serde_json", "serde_regex", @@ -1744,11 +1751,11 @@ checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" [[package]] name = "versions" -version = "6.2.0" +version = "6.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38a8931f8d167b6448076020e70b9de46dcf5ea1731212481a092d0071c4ac5b" +checksum = "5fc28d1172a20e32754969ea1a873c2c6e68e36c449c6056aa3e2ee5fe69a794" dependencies = [ - "itertools 0.12.1", + "itertools 0.13.0", "nom", ] diff --git a/support/texlab/crates/base-db/Cargo.toml b/support/texlab/crates/base-db/Cargo.toml index ca477c496c..547ba2ad77 100644 --- a/support/texlab/crates/base-db/Cargo.toml +++ b/support/texlab/crates/base-db/Cargo.toml @@ -10,16 +10,16 @@ rust-version.workspace = true bibtex-utils = { path = "../bibtex-utils" } dirs = "5.0.1" distro = { path = "../distro" } -itertools = "0.12.1" +itertools = "0.13.0" line-index = { path = "../line-index" } -log = "0.4.21" +log = "0.4.22" notify = "6.0.1" once_cell = "1.19.0" parser = { path = "../parser" } percent-encoding = "2.3.0" -regex = "1.10.4" +regex = "1.10.5" rowan = "0.15.15" -rustc-hash = "1.1.0" +rustc-hash = "2.0.0" shellexpand = "3.1.0" syntax = { path = "../syntax" } titlecase = "3.0.0" diff --git a/support/texlab/crates/base-db/src/deps/graph.rs b/support/texlab/crates/base-db/src/deps/graph.rs index 4b2399b7f8..580e2865d6 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, } @@ -74,6 +75,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 +103,7 @@ impl Graph { self.add_direct_links(workspace, start); self.add_artifacts(workspace, start); self.add_additional_files(workspace, start); + self.add_file_list_links(workspace, start); } fn add_additional_files(&mut self, workspace: &Workspace, start: Start) { @@ -120,6 +123,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().unwrap_or(&start.source.dir); + 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 +209,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 +237,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/document.rs b/support/texlab/crates/base-db/src/document.rs index afb5869d69..6fdcf30c16 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}; @@ -89,6 +89,7 @@ impl Document { DocumentData::Latexmkrc(data) } Language::Tectonic => DocumentData::Tectonic, + Language::FileList => DocumentData::FileList(parser::parse_file_list(&text)), }; Self { @@ -146,6 +147,7 @@ pub enum DocumentData { Root, Latexmkrc(LatexmkrcData), Tectonic, + FileList(FileList), } impl DocumentData { @@ -188,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/bibtex-utils/Cargo.toml b/support/texlab/crates/bibtex-utils/Cargo.toml index c20508107c..88ba2d3a37 100644 --- a/support/texlab/crates/bibtex-utils/Cargo.toml +++ b/support/texlab/crates/bibtex-utils/Cargo.toml @@ -9,9 +9,9 @@ rust-version.workspace = true [dependencies] chrono = { version = "0.4.38", default-features = false, features = ["std"] } human_name = "2.0.3" -itertools = "0.12.1" +itertools = "0.13.0" rowan = "0.15.15" -rustc-hash = "1.1.0" +rustc-hash = "2.0.0" syntax = { path = "../syntax" } unicode-normalization = "0.1.23" diff --git a/support/texlab/crates/citeproc/Cargo.toml b/support/texlab/crates/citeproc/Cargo.toml index 9e187f88e6..c87ab14b0e 100644 --- a/support/texlab/crates/citeproc/Cargo.toml +++ b/support/texlab/crates/citeproc/Cargo.toml @@ -10,9 +10,9 @@ rust-version.workspace = true bibtex-utils = { path = "../bibtex-utils" } base-db = { path = "../base-db" } isocountry = "0.3.2" -itertools = "0.12.1" +itertools = "0.13.0" rowan = "0.15.15" -rustc-hash = "1.1.0" +rustc-hash = "2.0.0" syntax = { path = "../syntax" } titlecase = "3.0.0" unicode-normalization = "0.1.23" diff --git a/support/texlab/crates/commands/Cargo.toml b/support/texlab/crates/commands/Cargo.toml index 6e415f20d6..6507efb3b8 100644 --- a/support/texlab/crates/commands/Cargo.toml +++ b/support/texlab/crates/commands/Cargo.toml @@ -10,12 +10,12 @@ rust-version.workspace = true anyhow = "1.0.86" base-db = { path = "../base-db" } bstr = "1.9.1" -crossbeam-channel = "0.5.12" -itertools = "0.12.1" +crossbeam-channel = "0.5.13" +itertools = "0.13.0" libc = "0.2.155" -log = "0.4.21" +log = "0.4.22" rowan = "0.15.15" -rustc-hash = "1.1.0" +rustc-hash = "2.0.0" syntax = { path = "../syntax" } thiserror = "1.0.61" url = "2.5.0" 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/completion-data/Cargo.toml b/support/texlab/crates/completion-data/Cargo.toml index 970cd6a578..6dbb7d4086 100644 --- a/support/texlab/crates/completion-data/Cargo.toml +++ b/support/texlab/crates/completion-data/Cargo.toml @@ -8,11 +8,11 @@ rust-version.workspace = true [dependencies] flate2 = "1.0.30" -itertools = "0.12.1" +itertools = "0.13.0" once_cell = "1.19.0" -rustc-hash = "1.1.0" -serde = { version = "1.0.202", features = ["derive"] } -serde_json = "1.0.117" +rustc-hash = "2.0.0" +serde = { version = "1.0.203", features = ["derive"] } +serde_json = "1.0.119" [lib] doctest = false diff --git a/support/texlab/crates/completion/Cargo.toml b/support/texlab/crates/completion/Cargo.toml index 6469b5f004..f98f12260b 100644 --- a/support/texlab/crates/completion/Cargo.toml +++ b/support/texlab/crates/completion/Cargo.toml @@ -13,7 +13,7 @@ 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" +rustc-hash = "2.0.0" syntax = { path = "../syntax" } url = "2.5.0" diff --git a/support/texlab/crates/definition/Cargo.toml b/support/texlab/crates/definition/Cargo.toml index 63ba15c308..254bea0314 100644 --- a/support/texlab/crates/definition/Cargo.toml +++ b/support/texlab/crates/definition/Cargo.toml @@ -9,11 +9,11 @@ rust-version.workspace = true [dependencies] base-db = { path = "../base-db" } rowan = "0.15.15" -rustc-hash = "1.1.0" +rustc-hash = "2.0.0" syntax = { path = "../syntax" } [dev-dependencies] -itertools = "0.12.1" +itertools = "0.13.0" test-utils = { path = "../test-utils" } [lib] diff --git a/support/texlab/crates/diagnostics/Cargo.toml b/support/texlab/crates/diagnostics/Cargo.toml index 1cb09fdec9..37e39280ad 100644 --- a/support/texlab/crates/diagnostics/Cargo.toml +++ b/support/texlab/crates/diagnostics/Cargo.toml @@ -10,14 +10,14 @@ 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 = "0.13.0" line-index = { path = "../line-index" } -log = "0.4.21" +log = "0.4.22" multimap = "0.10.0" once_cell = "1.19.0" -regex = "1.10.4" +regex = "1.10.5" rowan = "0.15.15" -rustc-hash = "1.1.0" +rustc-hash = "2.0.0" syntax = { path = "../syntax" } url = "2.5.0" diff --git a/support/texlab/crates/distro/Cargo.toml b/support/texlab/crates/distro/Cargo.toml index dea6a56979..c81288e86e 100644 --- a/support/texlab/crates/distro/Cargo.toml +++ b/support/texlab/crates/distro/Cargo.toml @@ -8,7 +8,7 @@ rust-version.workspace = true [dependencies] anyhow = "1.0.86" -rustc-hash = "1.1.0" +rustc-hash = "2.0.0" [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/inlay-hints/Cargo.toml b/support/texlab/crates/inlay-hints/Cargo.toml index ede4ca6188..94651ef4c7 100644 --- a/support/texlab/crates/inlay-hints/Cargo.toml +++ b/support/texlab/crates/inlay-hints/Cargo.toml @@ -9,7 +9,7 @@ rust-version.workspace = true [dependencies] base-db = { path = "../base-db" } rowan = "0.15.15" -rustc-hash = "1.1.0" +rustc-hash = "2.0.0" [dev-dependencies] test-utils = { path = "../test-utils" } diff --git a/support/texlab/crates/ipc/Cargo.toml b/support/texlab/crates/ipc/Cargo.toml index 1e1ff7a822..92afbba876 100644 --- a/support/texlab/crates/ipc/Cargo.toml +++ b/support/texlab/crates/ipc/Cargo.toml @@ -7,10 +7,10 @@ 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 = "0.5.13" +serde = "1.0.203" +serde_json = "1.0.119" +log = "0.4.22" uds_windows = "1.1.0" [lib] diff --git a/support/texlab/crates/line-index/Cargo.toml b/support/texlab/crates/line-index/Cargo.toml index 73d2766d60..58e2fa9e16 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 = "2.0.0" text-size = "1.1.1" [lib] diff --git a/support/texlab/crates/parser/Cargo.toml b/support/texlab/crates/parser/Cargo.toml index 39fa34ef63..2faadcb262 100644 --- a/support/texlab/crates/parser/Cargo.toml +++ b/support/texlab/crates/parser/Cargo.toml @@ -7,16 +7,16 @@ edition.workspace = true rust-version.workspace = true [dependencies] -log = "0.4.21" +log = "0.4.22" logos = "0.14.0" once_cell = "1.19.0" pathdiff = "0.2.1" -regex = "1.10.4" +regex = "1.10.5" rowan = "0.15.15" -rustc-hash = "1.1.0" +rustc-hash = "2.0.0" syntax = { path = "../syntax" } tempfile = "3.10.1" -versions = "6.2.0" +versions = "6.3.0" [dev-dependencies] expect-test = "1.5.0" 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/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/lexer/types.rs b/support/texlab/crates/parser/src/latex/lexer/types.rs index 896ce01c05..85e542792b 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, 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..8d4e3a6936 100644 --- a/support/texlab/crates/references/Cargo.toml +++ b/support/texlab/crates/references/Cargo.toml @@ -9,7 +9,7 @@ rust-version.workspace = true [dependencies] base-db = { path = "../base-db" } rowan = "0.15.15" -rustc-hash = "1.1.0" +rustc-hash = "2.0.0" syntax = { path = "../syntax" } [dev-dependencies] diff --git a/support/texlab/crates/rename/Cargo.toml b/support/texlab/crates/rename/Cargo.toml index dc7558515a..592bafb474 100644 --- a/support/texlab/crates/rename/Cargo.toml +++ b/support/texlab/crates/rename/Cargo.toml @@ -9,7 +9,7 @@ rust-version.workspace = true [dependencies] base-db = { path = "../base-db" } rowan = "0.15.15" -rustc-hash = "1.1.0" +rustc-hash = "2.0.0" syntax = { path = "../syntax" } [dev-dependencies] diff --git a/support/texlab/crates/symbols/Cargo.toml b/support/texlab/crates/symbols/Cargo.toml index 65db0fc0bd..c44f120153 100644 --- a/support/texlab/crates/symbols/Cargo.toml +++ b/support/texlab/crates/symbols/Cargo.toml @@ -12,7 +12,7 @@ doctest = false [dependencies] base-db = { path = "../base-db" } distro = { path = "../distro" } -itertools = "0.12.1" +itertools = "0.13.0" line-index = { path = "../line-index" } rowan = "0.15.15" syntax = { path = "../syntax" } @@ -20,6 +20,6 @@ titlecase = "3.0.0" url = "2.5.0" [dev-dependencies] -regex = "1.10.4" +regex = "1.10.5" test-utils = { path = "../test-utils" } expect-test = "1.5.0" 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/syntax/Cargo.toml b/support/texlab/crates/syntax/Cargo.toml index a2d3d866b6..14dfffe380 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" +itertools = "0.13.0" rowan = "0.15.15" +rustc-hash = "2.0.0" [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/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/texlab/Cargo.toml b/support/texlab/crates/texlab/Cargo.toml index fa419413f5..c6fca1bfda 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.17.0" +version = "5.18.0" license.workspace = true readme = "README.md" authors.workspace = true @@ -26,11 +26,11 @@ anyhow = "1.0.86" base-db = { path = "../base-db" } bibfmt = { path = "../bibfmt" } citeproc = { path = "../citeproc" } -clap = { version = "4.5.4", features = ["derive"] } +clap = { version = "4.5.8", features = ["derive"] } commands = { path = "../commands" } completion = { path = "../completion" } completion-data = { path = "../completion-data" } -crossbeam-channel = "0.5.12" +crossbeam-channel = "0.5.13" definition = { path = "../definition" } diagnostics = { path = "../diagnostics" } distro = { path = "../distro" } @@ -42,7 +42,7 @@ inlay-hints = { path = "../inlay-hints" } ipc = { path = "../ipc" } line-index = { path = "../line-index" } links = { path = "../links" } -log = "0.4.21" +log = "0.4.22" lsp-server = "0.7.6" lsp-types = "0.95.1" notify = "6.1.1" @@ -50,12 +50,12 @@ notify-debouncer-full = "0.3.1" parking_lot = "0.12.3" parser = { path = "../parser" } references = { path = "../references" } -regex = "1.10.4" +regex = "1.10.5" rename = { path = "../rename" } rowan = "0.15.15" -rustc-hash = "1.1.0" -serde = "1.0.202" -serde_json = "1.0.117" +rustc-hash = "2.0.0" +serde = "1.0.203" +serde_json = "1.0.119" serde_regex = "1.1.0" serde_repr = "0.1.19" symbols = { path = "../symbols" } 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/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/texlab.1 b/support/texlab/texlab.1 index d829a081f9..c5f5920c6b 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" "June 2024" "texlab 5.17.0" "User Commands" +.TH TEXLAB "1" "July 2024" "texlab 5.18.0" "User Commands" .SH NAME -texlab \- manual page for texlab 5.17.0 +texlab \- manual page for texlab 5.18.0 .SH SYNOPSIS .B texlab [\fI\,OPTIONS\/\fR] [\fI\,COMMAND\/\fR] diff --git a/support/texlab/texlab.pdf b/support/texlab/texlab.pdf Binary files differindex 828032ce0c..7c0c4b7388 100644 --- a/support/texlab/texlab.pdf +++ b/support/texlab/texlab.pdf |