summaryrefslogtreecommitdiff
path: root/support/texlab/crates/base-db
diff options
context:
space:
mode:
Diffstat (limited to 'support/texlab/crates/base-db')
-rw-r--r--support/texlab/crates/base-db/Cargo.toml6
-rw-r--r--support/texlab/crates/base-db/src/deps.rs2
-rw-r--r--support/texlab/crates/base-db/src/deps/discover.rs4
-rw-r--r--support/texlab/crates/base-db/src/deps/graph.rs8
-rw-r--r--support/texlab/crates/base-db/src/deps/root.rs40
-rw-r--r--support/texlab/crates/base-db/src/document.rs7
-rw-r--r--support/texlab/crates/base-db/src/semantics.rs9
-rw-r--r--support/texlab/crates/base-db/src/semantics/tex.rs29
-rw-r--r--support/texlab/crates/base-db/src/util.rs2
-rw-r--r--support/texlab/crates/base-db/src/util/expand.rs31
-rw-r--r--support/texlab/crates/base-db/src/workspace.rs20
11 files changed, 117 insertions, 41 deletions
diff --git a/support/texlab/crates/base-db/Cargo.toml b/support/texlab/crates/base-db/Cargo.toml
index 010c83d0e4..ca477c496c 100644
--- a/support/texlab/crates/base-db/Cargo.toml
+++ b/support/texlab/crates/base-db/Cargo.toml
@@ -10,17 +10,19 @@ rust-version.workspace = true
bibtex-utils = { path = "../bibtex-utils" }
dirs = "5.0.1"
distro = { path = "../distro" }
-itertools = "0.12.0"
+itertools = "0.12.1"
line-index = { path = "../line-index" }
log = "0.4.21"
notify = "6.0.1"
once_cell = "1.19.0"
parser = { path = "../parser" }
percent-encoding = "2.3.0"
-regex = "1.10.2"
+regex = "1.10.4"
rowan = "0.15.15"
rustc-hash = "1.1.0"
+shellexpand = "3.1.0"
syntax = { path = "../syntax" }
+titlecase = "3.0.0"
url = "2.5.0"
[lib]
diff --git a/support/texlab/crates/base-db/src/deps.rs b/support/texlab/crates/base-db/src/deps.rs
index 06689a0df2..f501d04935 100644
--- a/support/texlab/crates/base-db/src/deps.rs
+++ b/support/texlab/crates/base-db/src/deps.rs
@@ -5,7 +5,7 @@ mod root;
pub use self::{
discover::{discover, watch},
- graph::{DirectLinkData, Edge, EdgeData, Graph},
+ graph::{DirectLinkData, Edge, EdgeData, Graph, HOME_DIR},
project::{parents, Project},
root::ProjectRoot,
};
diff --git a/support/texlab/crates/base-db/src/deps/discover.rs b/support/texlab/crates/base-db/src/deps/discover.rs
index 06905905a5..cbcab4d8fb 100644
--- a/support/texlab/crates/base-db/src/deps/discover.rs
+++ b/support/texlab/crates/base-db/src/deps/discover.rs
@@ -84,7 +84,7 @@ fn discover_parents(workspace: &mut Workspace, checked_paths: &mut FxHashSet<Pat
continue;
}
- if workspace.lookup_path(&file).is_none() && file.exists() {
+ if workspace.lookup_file(&file).is_none() && file.exists() {
changed |= workspace.load(&file, lang).is_ok();
checked_paths.insert(file);
}
@@ -107,7 +107,7 @@ fn discover_children(workspace: &mut Workspace, checked_paths: &mut FxHashSet<Pa
for file in files {
let language = Language::from_path(&file).unwrap_or(Language::Tex);
- if workspace.lookup_path(&file).is_none() && file.exists() {
+ if workspace.lookup_file(&file).is_none() && file.exists() {
changed |= workspace.load(&file, language).is_ok();
checked_paths.insert(file);
}
diff --git a/support/texlab/crates/base-db/src/deps/graph.rs b/support/texlab/crates/base-db/src/deps/graph.rs
index a90d8fa204..e07368d078 100644
--- a/support/texlab/crates/base-db/src/deps/graph.rs
+++ b/support/texlab/crates/base-db/src/deps/graph.rs
@@ -7,11 +7,11 @@ use percent_encoding::percent_decode_str;
use rustc_hash::FxHashSet;
use url::Url;
-use crate::{semantics, Document, Workspace};
+use crate::{semantics, util, Document, Workspace};
use super::ProjectRoot;
-pub(crate) static HOME_DIR: Lazy<Option<PathBuf>> = Lazy::new(dirs::home_dir);
+pub static HOME_DIR: Lazy<Option<PathBuf>> = Lazy::new(dirs::home_dir);
#[derive(Debug, PartialEq, Eq, Clone, Hash)]
pub struct Edge {
@@ -158,7 +158,9 @@ impl Graph {
for target_uri in file_names
.iter()
- .flat_map(|file_name| start.root.src_dir.join(file_name))
+ .flat_map(|file_name| {
+ util::expand_relative_path(&file_name, &start.root.src_dir, workspace.folders())
+ })
.chain(distro_files)
{
match workspace.lookup(&target_uri) {
diff --git a/support/texlab/crates/base-db/src/deps/root.rs b/support/texlab/crates/base-db/src/deps/root.rs
index 442d6f9e35..a8cec6604a 100644
--- a/support/texlab/crates/base-db/src/deps/root.rs
+++ b/support/texlab/crates/base-db/src/deps/root.rs
@@ -1,6 +1,6 @@
use url::Url;
-use crate::{DocumentData, Workspace};
+use crate::{util, DocumentData, Workspace};
use super::graph::HOME_DIR;
@@ -74,6 +74,7 @@ impl ProjectRoot {
}
pub fn from_latexmkrc(workspace: &Workspace, dir: &Url) -> Option<Self> {
+ let config = workspace.config();
let rcfile = workspace
.iter()
.filter(|document| document.dir == *dir)
@@ -81,20 +82,30 @@ impl ProjectRoot {
let compile_dir = dir.clone();
let src_dir = dir.clone();
- let aux_dir = rcfile
+
+ let aux_dir_rc = rcfile
.aux_dir
.as_ref()
- .and_then(|path| append_dir(dir, path).ok())
- .unwrap_or_else(|| dir.clone());
+ .and_then(|path| append_dir(dir, path, workspace).ok());
- let out_dir = rcfile
+ let out_dir_rc = rcfile
.out_dir
.as_ref()
- .and_then(|path| append_dir(dir, path).ok())
+ .and_then(|path| append_dir(dir, path, workspace).ok());
+
+ let aux_dir = aux_dir_rc
+ .clone()
+ .or_else(|| append_dir(dir, &config.build.aux_dir, workspace).ok())
+ .unwrap_or_else(|| dir.clone());
+
+ let log_dir = aux_dir_rc
+ .or_else(|| append_dir(dir, &config.build.log_dir, workspace).ok())
+ .unwrap_or_else(|| dir.clone());
+
+ let pdf_dir = out_dir_rc
+ .or_else(|| append_dir(dir, &config.build.pdf_dir, workspace).ok())
.unwrap_or_else(|| dir.clone());
- let log_dir = out_dir.clone();
- let pdf_dir = out_dir;
let additional_files = vec![];
Some(Self {
@@ -124,9 +135,12 @@ impl ProjectRoot {
let compile_dir = dir.clone();
let src_dir = dir.clone();
let config = workspace.config();
- let aux_dir = append_dir(dir, &config.build.aux_dir).unwrap_or_else(|_| dir.clone());
- let log_dir = append_dir(dir, &config.build.log_dir).unwrap_or_else(|_| dir.clone());
- let pdf_dir = append_dir(dir, &config.build.pdf_dir).unwrap_or_else(|_| dir.clone());
+ let aux_dir =
+ append_dir(dir, &config.build.aux_dir, workspace).unwrap_or_else(|_| dir.clone());
+ let log_dir =
+ append_dir(dir, &config.build.log_dir, workspace).unwrap_or_else(|_| dir.clone());
+ let pdf_dir =
+ append_dir(dir, &config.build.pdf_dir, workspace).unwrap_or_else(|_| dir.clone());
let additional_files = vec![];
Self {
@@ -140,13 +154,13 @@ impl ProjectRoot {
}
}
-fn append_dir(dir: &Url, path: &str) -> Result<Url, url::ParseError> {
+fn append_dir(dir: &Url, path: &str, workspace: &Workspace) -> Result<Url, url::ParseError> {
let mut path = String::from(path);
if !path.ends_with('/') {
path.push('/');
}
- dir.join(&path)
+ util::expand_relative_path(&path, dir, workspace.folders())
}
impl std::fmt::Debug for ProjectRoot {
diff --git a/support/texlab/crates/base-db/src/document.rs b/support/texlab/crates/base-db/src/document.rs
index 25607a1bf5..7a388129fd 100644
--- a/support/texlab/crates/base-db/src/document.rs
+++ b/support/texlab/crates/base-db/src/document.rs
@@ -77,7 +77,12 @@ impl Document {
}
Language::Root => DocumentData::Root,
Language::Latexmkrc => {
- let data = parser::parse_latexmkrc(&text).unwrap_or_default();
+ let data = path
+ .as_deref()
+ .and_then(|path| path.parent())
+ .and_then(|dir| parser::parse_latexmkrc(&text, dir).ok())
+ .unwrap_or_default();
+
DocumentData::Latexmkrc(data)
}
Language::Tectonic => DocumentData::Tectonic,
diff --git a/support/texlab/crates/base-db/src/semantics.rs b/support/texlab/crates/base-db/src/semantics.rs
index f83d758cf7..a2f0de291f 100644
--- a/support/texlab/crates/base-db/src/semantics.rs
+++ b/support/texlab/crates/base-db/src/semantics.rs
@@ -1,3 +1,5 @@
+use rowan::{TextLen, TextRange};
+
pub mod auxiliary;
pub mod bib;
pub mod tex;
@@ -19,6 +21,13 @@ impl Span {
range: rowan::TextRange::empty(offset),
}
}
+
+ pub fn command<L: rowan::Language>(token: &rowan::SyntaxToken<L>) -> Self {
+ let range = token.text_range();
+ let range = TextRange::new(range.start() + "\\".text_len(), range.end());
+ let text = String::from(&token.text()[1..]);
+ Self::new(text, range)
+ }
}
impl std::fmt::Debug for Span {
diff --git a/support/texlab/crates/base-db/src/semantics/tex.rs b/support/texlab/crates/base-db/src/semantics/tex.rs
index 659ec8c166..1ad8969a80 100644
--- a/support/texlab/crates/base-db/src/semantics/tex.rs
+++ b/support/texlab/crates/base-db/src/semantics/tex.rs
@@ -1,6 +1,7 @@
-use rowan::{ast::AstNode, TextLen, TextRange};
+use rowan::{ast::AstNode, TextRange};
use rustc_hash::FxHashSet;
use syntax::latex::{self, HasBrack, HasCurly};
+use titlecase::titlecase;
use super::Span;
@@ -26,10 +27,7 @@ impl Semantics {
}
latex::SyntaxElement::Token(token) => {
if token.kind() == latex::COMMAND_NAME {
- let range = token.text_range();
- let range = TextRange::new(range.start() + "\\".text_len(), range.end());
- let text = String::from(&token.text()[1..]);
- self.commands.push(Span { range, text });
+ self.commands.push(Span::command(&token));
}
}
};
@@ -257,18 +255,15 @@ impl Semantics {
}
fn process_theorem_definition(&mut self, theorem_def: latex::TheoremDefinition) {
- let Some(name) = theorem_def.name().and_then(|name| name.key()) else {
- return;
- };
-
- let Some(heading) = theorem_def.heading() else {
- return;
- };
-
- self.theorem_definitions.push(TheoremDefinition {
- name: Span::from(&name),
- heading,
- });
+ for name in theorem_def.names() {
+ let name = Span::from(&name);
+ let heading = theorem_def
+ .heading()
+ .unwrap_or_else(|| titlecase(&name.text));
+
+ self.theorem_definitions
+ .push(TheoremDefinition { name, heading });
+ }
}
fn process_graphics_path(&mut self, graphics_path: latex::GraphicsPath) {
diff --git a/support/texlab/crates/base-db/src/util.rs b/support/texlab/crates/base-db/src/util.rs
index 068a0c9b2a..789eee9c85 100644
--- a/support/texlab/crates/base-db/src/util.rs
+++ b/support/texlab/crates/base-db/src/util.rs
@@ -1,8 +1,10 @@
+mod expand;
mod label;
pub mod queries;
mod regex_filter;
pub use self::{
+ expand::expand_relative_path,
label::{render_label, FloatKind, RenderedLabel, RenderedObject},
regex_filter::filter_regex_patterns,
};
diff --git a/support/texlab/crates/base-db/src/util/expand.rs b/support/texlab/crates/base-db/src/util/expand.rs
new file mode 100644
index 0000000000..a315737115
--- /dev/null
+++ b/support/texlab/crates/base-db/src/util/expand.rs
@@ -0,0 +1,31 @@
+use std::{borrow::Cow, path::PathBuf};
+
+use url::Url;
+
+use crate::deps::HOME_DIR;
+
+pub fn expand_relative_path(
+ path: &str,
+ current_dir: &Url,
+ workspace_folders: &[PathBuf],
+) -> Result<Url, url::ParseError> {
+ let home_dir = HOME_DIR.as_ref().and_then(|dir| dir.to_str());
+
+ let workspace_folder = workspace_folders.iter().find_map(|folder| {
+ let current_dir = current_dir.to_file_path().ok()?;
+ if current_dir.starts_with(folder) {
+ Some(folder.to_str()?)
+ } else {
+ None
+ }
+ });
+
+ let expand_var = |variable: &str| match variable {
+ "userHome" => home_dir.map(Cow::Borrowed),
+ "workspaceFolder" => Some(Cow::Borrowed(workspace_folder.unwrap_or("."))),
+ _ => std::env::var(variable).ok().map(Cow::Owned),
+ };
+
+ let path = shellexpand::full_with_context_no_errors(&path, || home_dir, expand_var);
+ current_dir.join(&path)
+}
diff --git a/support/texlab/crates/base-db/src/workspace.rs b/support/texlab/crates/base-db/src/workspace.rs
index 1afd4712e9..75674dcf8d 100644
--- a/support/texlab/crates/base-db/src/workspace.rs
+++ b/support/texlab/crates/base-db/src/workspace.rs
@@ -29,11 +29,22 @@ impl Workspace {
self.documents.get(key)
}
- pub fn lookup_path(&self, path: &Path) -> Option<&Document> {
+ pub fn lookup_file(&self, path: &Path) -> Option<&Document> {
self.iter()
.find(|document| document.path.as_deref() == Some(path))
}
+ pub fn lookup_file_or_dir<'a>(
+ &'a self,
+ file_or_dir: &'a Path,
+ ) -> impl Iterator<Item = &'a Document> + '_ {
+ self.iter().filter(move |doc| {
+ doc.path
+ .as_deref()
+ .map_or(false, |p| p.starts_with(file_or_dir))
+ })
+ }
+
pub fn iter(&self) -> impl Iterator<Item = &Document> + '_ {
self.documents.iter()
}
@@ -50,6 +61,10 @@ impl Workspace {
&self.graphs
}
+ pub fn folders(&self) -> &[PathBuf] {
+ &self.folders
+ }
+
pub fn open(
&mut self,
uri: Url,
@@ -90,7 +105,7 @@ impl Workspace {
Owner::Server
};
- if let Some(document) = self.lookup_path(path) {
+ if let Some(document) = self.lookup_file(path) {
if document.text == text {
return Ok(());
}
@@ -173,6 +188,7 @@ impl Workspace {
}
pub fn remove(&mut self, uri: &Url) {
+ log::info!("Removing moved or deleted document: {uri}");
self.documents.remove(uri);
}