Skip to content

Commit

Permalink
Merge pull request #839 from latex-lsp/simplify-project-resolution
Browse files Browse the repository at this point in the history
Simplify project resolution algorithm
  • Loading branch information
pfoerster authored Jan 21, 2023
2 parents 1a47c8c + 75e41b3 commit 9cbc238
Show file tree
Hide file tree
Showing 17 changed files with 178 additions and 70 deletions.
15 changes: 15 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,21 @@ 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).

## [Unreleased]

### Added

- Allow manually overriding the root directory using a `texlabroot`/`.texlabroot` marker file ([#826](https://github.com/latex-lsp/texlab/issues/826), [#838](https://github.com/latex-lsp/texlab/pull/838))

### Deprecated

- Deprecate `texlab.rootDirectory` setting in favor of `.texlabroot` files

### Fixed

- Do not use `.git`, `.chktexrc`, `.latexmkrc` files/directories to determine the root directory
- Fix building documents without an explicit root directory ([#837](https://github.com/latex-lsp/texlab/issues/837))

## [5.0.0] - 2022-12-29

### Changed
Expand Down
1 change: 1 addition & 0 deletions src/db/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ pub fn collect(db: &dyn Db, workspace: Workspace) -> FxHashMap<Document, Vec<Dia
.extend(diagnostics.clone());
});
}
Language::TexlabRoot | Language::Tectonic => {}
}
}

Expand Down
14 changes: 9 additions & 5 deletions src/db/discovery.rs
Original file line number Diff line number Diff line change
Expand Up @@ -226,12 +226,16 @@ fn discover_parents(db: &mut dyn Db, workspace: Workspace) -> bool {
.flatten()
.filter(|entry| entry.file_type().map_or(false, |ty| ty.is_file()))
.map(|entry| entry.path())
.filter(|path| Language::from_path(&path) == Some(Language::Tex))
{
if workspace.lookup_path(db, &path).is_none() {
changed |= workspace
.load(db, &path, Language::Tex, Owner::Server)
.is_some();
if let Some(language) = Language::from_path(&path) {
let can_be_parent = matches!(
language,
Language::Tex | Language::TexlabRoot | Language::Tectonic
);

if can_be_parent && workspace.lookup_path(db, &path).is_none() {
changed |= workspace.load(db, &path, language, Owner::Server).is_some();
}
}
}

Expand Down
44 changes: 24 additions & 20 deletions src/db/document.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,12 @@
use std::{
ffi::OsStr,
path::{Path, PathBuf},
};
use std::path::{Path, PathBuf};

use lsp_types::Url;
use rowan::{TextRange, TextSize};

use crate::{
db::{
diagnostics::Diagnostic,
parse::{BibDocumentData, LogDocumentData, TexDocumentData},
parse::{BibDocumentData, LogDocumentData, TectonicData, TexDocumentData, TexlabRootData},
},
parser::{parse_bibtex, parse_build_log, parse_latex},
util::line_index::LineIndex,
Expand Down Expand Up @@ -49,14 +46,6 @@ impl Location {
let uri = self.uri(db).join(path).ok()?;
Some(Location::new(db, uri))
}

pub fn into_dir(self, db: &dyn Db) -> Location {
if self.uri(db).path().ends_with("/") {
self.join(db, ".").unwrap()
} else {
self
}
}
}

#[salsa::input]
Expand Down Expand Up @@ -84,17 +73,23 @@ pub enum Language {
Tex,
Bib,
Log,
TexlabRoot,
Tectonic,
}

impl Language {
pub fn from_path(path: &Path) -> Option<Self> {
path.extension()
.and_then(OsStr::to_str)
.and_then(Self::from_extension)
}
let name = path.file_name()?;
if name.eq_ignore_ascii_case(".texlabroot") || name.eq_ignore_ascii_case("texlabroot") {
return Some(Self::TexlabRoot);
}

if name.eq_ignore_ascii_case("Tectonic.toml") {
return Some(Self::Tectonic);
}

pub fn from_extension(extension: &str) -> Option<Self> {
match extension.to_lowercase().as_str() {
let extname = path.extension()?.to_str()?;
match extname.to_lowercase().as_str() {
"tex" | "sty" | "cls" | "def" | "lco" | "aux" | "rnw" => Some(Self::Tex),
"bib" | "bibtex" => Some(Self::Bib),
"log" => Some(Self::Log),
Expand All @@ -106,6 +101,7 @@ impl Language {
match id {
"tex" | "latex" => Some(Self::Tex),
"bib" | "bibtex" => Some(Self::Bib),
"texlabroot" => Some(Self::TexlabRoot),
_ => None,
}
}
Expand Down Expand Up @@ -136,7 +132,7 @@ impl Document {
}

pub fn directory(self, db: &dyn Db) -> Location {
self.location(db).into_dir(db)
self.location(db).join(db, ".").unwrap()
}

pub fn ancestor_dirs<'db>(self, db: &'db dyn Db) -> impl Iterator<Item = &'db Path> + 'db {
Expand Down Expand Up @@ -167,6 +163,14 @@ impl Document {
let data = LogDocumentData::new(db, parse_build_log(text));
DocumentData::Log(data)
}
Language::TexlabRoot => {
let data = TexlabRootData;
DocumentData::TexlabRoot(data)
}
Language::Tectonic => {
let data = TectonicData;
DocumentData::Tectonic(data)
}
}
}

Expand Down
8 changes: 8 additions & 0 deletions src/db/parse.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,19 @@ pub struct LogDocumentData {
pub log: BuildLog,
}

#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Copy, Hash)]
pub struct TexlabRootData;

#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Copy, Hash)]
pub struct TectonicData;

#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Copy, Hash)]
pub enum DocumentData {
Tex(TexDocumentData),
Bib(BibDocumentData),
Log(LogDocumentData),
TexlabRoot(TexlabRootData),
Tectonic(TectonicData),
}

impl DocumentData {
Expand Down
49 changes: 15 additions & 34 deletions src/db/workspace.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ use rustc_hash::FxHashSet;
use crate::{
db::document::{Document, Location},
distro::FileNameDB,
util::HOME_DIR,
Db, Options,
};

Expand Down Expand Up @@ -154,49 +153,31 @@ impl Workspace {
}
}

const SPECIAL_ENTRIES: &[&str] = &[
".git",
"Tectonic.toml",
".latexmkrc",
"latexmkrc",
".chktexrc",
"chktexrc",
];

#[salsa::tracked]
impl Workspace {
#[salsa::tracked]
pub fn working_dir(self, db: &dyn Db, base_dir: Location) -> Location {
let mut path = self
if let Some(dir) = self
.options(db)
.root_directory
.as_deref()
.and_then(|path| path.to_str())
.or_else(|| {
for dir in base_dir
.path(db)
.as_deref()?
.ancestors()
.skip(1)
.filter(|path| Some(*path) != HOME_DIR.as_deref())
{
for name in SPECIAL_ENTRIES {
if dir.join(name).exists() {
return Some(dir.to_str()?);
}
}
}

None
})
.unwrap_or(".")
.to_string();

if !path.ends_with(".") {
path.push('/');
.and_then(|path| base_dir.join(db, path))
{
return dir;
}

base_dir.join(db, &path).unwrap_or(base_dir)
self.documents(db)
.iter()
.filter(|doc| matches!(doc.language(db), Language::TexlabRoot | Language::Tectonic))
.filter_map(|doc| doc.location(db).join(db, "."))
.find(|root_dir| {
base_dir
.uri(db)
.as_str()
.starts_with(root_dir.uri(db).as_str())
})
.unwrap_or(base_dir)
}

#[salsa::tracked]
Expand Down
11 changes: 8 additions & 3 deletions src/features/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,12 +104,17 @@ impl Command {
.stdin(Stdio::null())
.stdout(Stdio::piped())
.stderr(Stdio::piped())
.current_dir(self.working_dir)
.current_dir(&self.working_dir)
.spawn()
{
Ok(process) => process,
Err(_) => {
log::error!("Failed to spawn process: {:?}", self.executable);
Err(why) => {
log::error!(
"Failed to spawn process {:?} in directory {}: {}",
self.executable,
self.working_dir.display(),
why
);
return BuildStatus::FAILURE;
}
};
Expand Down
4 changes: 3 additions & 1 deletion src/features/folding.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,9 @@ pub fn find_all(db: &dyn Db, uri: &Url) -> Option<Vec<FoldingRange>> {
.map(|node| create_range(line_index.line_col_lsp_range(node.text_range())))
.collect()
}
DocumentData::Log(_) => return None,
DocumentData::Log(_) | DocumentData::TexlabRoot(_) | DocumentData::Tectonic(_) => {
return None;
}
};

Some(foldings)
Expand Down
2 changes: 1 addition & 1 deletion src/features/formatting.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,6 @@ pub fn format_source_code(
BibtexFormatter::Texlab => format_bibtex_internal(db, document, options),
BibtexFormatter::Latexindent => format_with_latexindent(db, document),
},
Language::Log => None,
Language::Log | Language::TexlabRoot | Language::Tectonic => None,
}
}
5 changes: 4 additions & 1 deletion src/features/reference/entry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,10 @@ pub(super) fn find_all_references(
results.push(ReferenceResult { document, range });
});
}
DocumentData::Bib(_) | DocumentData::Log(_) => {}
DocumentData::Bib(_)
| DocumentData::Log(_)
| DocumentData::TexlabRoot(_)
| DocumentData::Tectonic(_) => {}
};
}

Expand Down
2 changes: 1 addition & 1 deletion src/features/rename/entry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ pub(super) fn rename(context: &CursorContext<Params>) -> Option<RenameResult> {
.collect();
changes.insert(document, edits);
}
DocumentData::Log(_) => {}
DocumentData::Log(_) | DocumentData::TexlabRoot(_) | DocumentData::Tectonic(_) => {}
}
}

Expand Down
4 changes: 3 additions & 1 deletion src/tests/fixture.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@ enum Line<'a> {
}

fn parse_line(line: &str) -> Line {
if let Some(name) = line.strip_prefix("%TEX ") {
if let Some(name) = line.strip_prefix("%ROOT ") {
Line::File(name, "texlabroot")
} else if let Some(name) = line.strip_prefix("%TEX ") {
Line::File(name, "latex")
} else if let Some(name) = line.strip_prefix("%BIB ") {
Line::File(name, "bibtex")
Expand Down
2 changes: 1 addition & 1 deletion src/tests/snapshots/texlab__tests__issues__issue_707.snap
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
source: src/tests/issues.rs
expression: "serde_json::from_value::<Option<Options>>(serde_json::json!({}))?.unwrap_or_default()"
expression: "serde_json::from_value::<Option<Options>>(serde_json::json!({})).unwrap().unwrap_or_default()"
---
Options {
root_directory: None,
Expand Down
24 changes: 23 additions & 1 deletion src/tests/text_document/completion.rs
Original file line number Diff line number Diff line change
Expand Up @@ -791,7 +791,7 @@ fn test_user_environment() {
}

#[test]
fn test_project_resolution() {
fn test_project_resolution_import() {
assert_items!(complete(
r#"
%TEX main.tex
Expand All @@ -810,3 +810,25 @@ fn test_project_resolution() {
"#
));
}

#[test]
fn test_project_resolution_texlabroot() {
assert_items!(complete(
r#"
%TEX src/main.tex
%SRC \documentclass{article}
%SRC \include{src/foo}
%SRC \lipsu
%CUR ^
%1.1 ^^^^^
%TEX src/foo.tex
%SRC \include{src/bar}
%TEX src/bar.tex
%SRC \usepackage{lipsum}
%ROOT .texlabroot
"#
));
}
Loading

0 comments on commit 9cbc238

Please sign in to comment.