Skip to content

Commit

Permalink
Use paths from latexmkrc if set
Browse files Browse the repository at this point in the history
  • Loading branch information
pfoerster committed Nov 26, 2023
1 parent ab18e66 commit a14efe0
Show file tree
Hide file tree
Showing 15 changed files with 149 additions and 81 deletions.
16 changes: 13 additions & 3 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

15 changes: 14 additions & 1 deletion crates/base-db/src/document.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use std::path::PathBuf;
use distro::Language;
use line_index::{LineCol, LineIndex};
use rowan::TextRange;
use syntax::{bibtex, latex, BuildError};
use syntax::{bibtex, latex, latexmkrc::LatexmkrcData, BuildError};
use url::Url;

use crate::{semantics, Config};
Expand Down Expand Up @@ -75,6 +75,10 @@ impl Document {
DocumentData::Log(LogDocumentData { errors })
}
Language::Root => DocumentData::Root,
Language::Latexmkrc => {
let data = parser::parse_latexmkrc(&text).unwrap_or_default();
DocumentData::Latexmkrc(data)
}
Language::Tectonic => DocumentData::Tectonic,
};

Expand Down Expand Up @@ -131,6 +135,7 @@ pub enum DocumentData {
Aux(AuxDocumentData),
Log(LogDocumentData),
Root,
Latexmkrc(LatexmkrcData),
Tectonic,
}

Expand Down Expand Up @@ -166,6 +171,14 @@ impl DocumentData {
None
}
}

pub fn as_latexmkrc(&self) -> Option<&LatexmkrcData> {
if let DocumentData::Latexmkrc(data) = self {
Some(data)
} else {
None
}
}
}

#[derive(Debug, Clone)]
Expand Down
5 changes: 2 additions & 3 deletions crates/base-db/src/graph.rs
Original file line number Diff line number Diff line change
Expand Up @@ -138,9 +138,8 @@ impl<'a> Graph<'a> {

fn add_implicit_edges(&mut self, source: &'a Document, base_dir: &Url) {
if source.language == Language::Tex {
let config = &self.workspace.config().build;
let aux_dir = self.workspace.output_dir(base_dir, config.aux_dir.clone());
let log_dir = self.workspace.output_dir(base_dir, config.log_dir.clone());
let aux_dir = self.workspace.aux_dir(base_dir);
let log_dir = self.workspace.log_dir(base_dir);

let relative_path = base_dir.make_relative(&source.uri).unwrap();

Expand Down
69 changes: 47 additions & 22 deletions crates/base-db/src/workspace.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use itertools::Itertools;
use line_index::LineCol;
use rowan::{TextLen, TextRange};
use rustc_hash::FxHashSet;
use syntax::latexmkrc::LatexmkrcData;
use url::Url;

use crate::{graph, Config, Document, DocumentData, DocumentParams, Owner};
Expand Down Expand Up @@ -115,22 +116,11 @@ impl Workspace {
self.iter()
.filter(|document| document.uri.scheme() == "file")
.flat_map(|document| {
let dir1 = self.output_dir(
&self.current_dir(&document.dir),
self.config.build.aux_dir.clone(),
);

let dir2 = self.output_dir(
&self.current_dir(&document.dir),
self.config.build.log_dir.clone(),
);

let dir3 = &document.dir;
[
dir1.to_file_path(),
dir2.to_file_path(),
dir3.to_file_path(),
]
let current_dir = &self.current_dir(&document.dir);
let doc_dir = document.dir.to_file_path();
let aux_dir = self.aux_dir(current_dir).to_file_path();
let log_dir = self.log_dir(current_dir).to_file_path();
[aux_dir, log_dir, doc_dir]
})
.flatten()
.for_each(|path| {
Expand All @@ -154,13 +144,45 @@ impl Workspace {
.unwrap_or_else(|| base_dir.clone())
}

pub fn output_dir(&self, base_dir: &Url, relative_path: String) -> Url {
let mut path = relative_path;
if !path.ends_with('/') {
path.push('/');
pub fn aux_dir(&self, base_dir: &Url) -> Url {
self.output_dir(base_dir, &self.config.build.aux_dir, |data| {
data.aux_dir.as_deref()
})
}

pub fn log_dir(&self, base_dir: &Url) -> Url {
self.output_dir(base_dir, &self.config.build.log_dir, |_| None)
}

pub fn pdf_dir(&self, base_dir: &Url) -> Url {
self.output_dir(base_dir, &self.config.build.pdf_dir, |_| None)
}

fn current_latexmkrc(&self, base_dir: &Url) -> Option<&LatexmkrcData> {
self.documents
.iter()
.filter(|document| document.language == Language::Latexmkrc)
.find(|document| document.uri.join(".").as_ref() == Ok(base_dir))
.and_then(|document| document.data.as_latexmkrc())
}

fn output_dir(
&self,
base_dir: &Url,
config: &str,
extract_latexmkrc: impl FnOnce(&LatexmkrcData) -> Option<&str>,
) -> Url {
let mut dir: String = self
.current_latexmkrc(base_dir)
.and_then(|data| extract_latexmkrc(data).or_else(|| data.out_dir.as_deref()))
.unwrap_or(config)
.into();

if !dir.ends_with('/') {
dir.push('/');
}

base_dir.join(&path).unwrap_or_else(|_| base_dir.clone())
base_dir.join(&dir).unwrap_or_else(|_| base_dir.clone())
}

pub fn contains(&self, path: &Path) -> bool {
Expand Down Expand Up @@ -299,7 +321,10 @@ impl Workspace {
continue;
};

if !matches!(lang, Language::Tex | Language::Root | Language::Tectonic) {
if !matches!(
lang,
Language::Tex | Language::Root | Language::Tectonic | Language::Latexmkrc
) {
continue;
}

Expand Down
11 changes: 4 additions & 7 deletions crates/commands/src/clean.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,18 +29,15 @@ impl CleanCommand {
};

let out_dir = match target {
CleanTarget::Auxiliary => &workspace.config().build.aux_dir,
CleanTarget::Artifacts => &workspace.config().build.pdf_dir,
CleanTarget::Auxiliary => workspace.aux_dir(&base_dir),
CleanTarget::Artifacts => workspace.pdf_dir(&base_dir),
};

let out_dir = workspace
.output_dir(&base_dir, out_dir.clone())
.to_file_path()
.unwrap();
let out_dir_path = out_dir.to_file_path().unwrap();

let executable = String::from("latexmk");
let args = vec![
format!("-outdir={}", out_dir.display()),
format!("-outdir={}", out_dir_path.display()),
String::from(flag),
path.display().to_string(),
];
Expand Down
3 changes: 1 addition & 2 deletions crates/commands/src/fwd_search.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,8 @@ impl ForwardSearch {
return Err(ForwardSearchError::NotLocal(parent.uri.clone()));
}

let dir = workspace.current_dir(&parent.dir);
let dir = workspace
.output_dir(&dir, workspace.config().build.pdf_dir.clone())
.pdf_dir(&workspace.current_dir(&parent.dir))
.to_file_path()
.unwrap();

Expand Down
5 changes: 5 additions & 0 deletions crates/distro/src/language.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ pub enum Language {
Aux,
Log,
Root,
Latexmkrc,
Tectonic,
}

Expand All @@ -21,6 +22,10 @@ impl Language {
return Some(Self::Tectonic);
}

if name.eq_ignore_ascii_case(".latexmkrc") || name.eq_ignore_ascii_case("latexmkrc") {
return Some(Self::Latexmkrc);
}

let extname = path.extension()?.to_str()?;
match extname.to_lowercase().as_str() {
"tex" | "sty" | "cls" | "def" | "lco" | "rnw" => Some(Self::Tex),
Expand Down
1 change: 1 addition & 0 deletions crates/parser/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ regex = "1.9.1"
rowan = "0.15.13"
rustc-hash = "1.1.0"
syntax = { path = "../syntax" }
tempfile = "3.8.1"

[dev-dependencies]
expect-test = "1.4.1"
Expand Down
45 changes: 45 additions & 0 deletions crates/parser/src/latexmkrc.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
use std::io::Write;

use syntax::latexmkrc::LatexmkrcData;
use tempfile::tempdir;

/// Extra section at the bottom of the latexmkrc file to print the values of $aux_dir and $log_dir.
const EXTRA: &str = r#"
print "texlab:aux_dir=" . $aux_dir . "\n";
print "texlab:out_dir=" . $out_dir . "\n";
exit 0; # Don't build the document"#;

pub fn parse_latexmkrc(input: &str) -> std::io::Result<LatexmkrcData> {
let temp_dir = tempdir()?;
let rc_path = temp_dir.path().join("latexmkrc");
let mut rc_file = std::fs::File::create(&rc_path)?;
rc_file.write_all(input.as_bytes())?;
rc_file.write_all(EXTRA.as_bytes())?;
drop(rc_file);

let output = std::process::Command::new("latexmk")
.arg("-r")
.arg(rc_path)
.output()?;

let mut result = LatexmkrcData::default();
let stdout = String::from_utf8_lossy(&output.stdout);

for line in stdout.lines() {
result.aux_dir = result
.aux_dir
.or_else(|| extract_dir(line, "texlab:aux_dir="));

result.out_dir = result
.out_dir
.or_else(|| extract_dir(line, "texlab:out_dir="));
}

Ok(result)
}

fn extract_dir(line: &str, key: &str) -> Option<String> {
line.strip_prefix(key)
.filter(|path| !path.is_empty())
.map(String::from)
}
6 changes: 5 additions & 1 deletion crates/parser/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,9 @@ mod bibtex;
mod build_log;
mod config;
mod latex;
mod latexmkrc;

pub use self::{bibtex::parse_bibtex, build_log::parse_build_log, config::*, latex::parse_latex};
pub use self::{
bibtex::parse_bibtex, build_log::parse_build_log, config::*, latex::parse_latex,
latexmkrc::parse_latexmkrc,
};
1 change: 1 addition & 0 deletions crates/symbols/src/document.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ pub fn document_symbols(workspace: &Workspace, document: &Document) -> Vec<Symbo
DocumentData::Aux(_)
| DocumentData::Log(_)
| DocumentData::Root
| DocumentData::Latexmkrc(_)
| DocumentData::Tectonic => Vec::new(),
};

Expand Down
5 changes: 5 additions & 0 deletions crates/syntax/src/latexmkrc.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#[derive(Debug, Clone, Default)]
pub struct LatexmkrcData {
pub aux_dir: Option<String>,
pub out_dir: Option<String>,
}
1 change: 1 addition & 0 deletions crates/syntax/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
pub mod bibtex;
pub mod latex;
pub mod latexmkrc;

#[derive(Debug, PartialEq, Eq, Clone, Copy, PartialOrd, Ord, Hash)]
pub enum BuildErrorLevel {
Expand Down
6 changes: 5 additions & 1 deletion crates/texlab/src/features/formatting.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@ pub fn format_source_code(
Formatter::Server => format_bibtex_internal(workspace, document, options),
Formatter::LatexIndent => format_with_latexindent(workspace, document),
},
Language::Aux | Language::Log | Language::Root | Language::Tectonic => None,
Language::Aux
| Language::Log
| Language::Root
| Language::Latexmkrc
| Language::Tectonic => None,
}
}
41 changes: 0 additions & 41 deletions crates/texlab/src/features/inlay_hint/label.rs

This file was deleted.

0 comments on commit a14efe0

Please sign in to comment.