latexmk: respect the `-cd` option

#1 ยท open ยท 3 comments

View on GitHub โ†—

Thibaulltt

Currently, workspace detection seems to be borked because `texlab` does not respect the full path to the document it's compiling. Let's take the following folder structure: ``` papers/ (git root) |-- latexmkrc |-- resources/ |-- bibliography.bib |-- thesis |-- thesis.tex |-- chapters/ (and some other files under chapters/) ``` Here are the relevant contents of my latexmkrc: ```perl $pdf_mode = 4; $silent = 1; # Change into the file's directory before build: $do_cd = 1; $recorder = 1; # Add those options to all TeX engines: set_tex_cmds('-file-line-error -interaction=nonstopmode -synctex=1 %O %S'); # ...snip... # # All aux/bib/build files in build: $aux_dir = './build'; $out_dir = './build'; $bibtex_use = 1.5; # Change dir for bib[tex,er] and run them: $bibtex_fudge = 1; ``` I'm compiling the file `thesis.tex` using the following command line: `latexmk thesis/thesis.tex` from the `papers/` folder. The `thesis.tex` file includes the file `bibliography.bib` as `\usebibresource{../resources/bibliography.bib}`. This structure **works** using `latexmk`. If I open up a `neovim` instance from `project/thesis` using `nvim thesis.tex`, which will automatically set the project root to the path where my `latexmkrc` file resides (so, `project/`), then all bibliography links are unknown since `texlab` does not seem to recognize that my paths for inclusion are relative to the main file `thesis/thesis.tex`. It *seems* to only be because latexmk's folder inclusion mechanism is detected as follows: https://github.com/Thibaulltt/texlab/blob/d80c436aef6cbfea1866879d5c5e67b1cf727269/crates/parser/src/latexmkrc.rs#L86-L118 This means that the 'working directory' where texlab will search all its paths from is actually `project/`, and not `project/thesis` like it would when invoqued from the command-line. What follows is my work-in-progress to see what went wrong, and how to solve it ๐Ÿ‘‡

Comments

Thibaulltt

The function `parser::parse_latexmkrc()` (see main comment above) is used only once outside of its crate: in the `base_db` crate, for the `Document::parse()` function.

Thibaulltt

Since `parse` is such a widely-used name, here are all the files using the `base_db::Document` class: ``` commands/src/change_env.rs commands/src/clean.rs commands/src/find_envs.rs completion/src/providers/command.rs definition/src/command.rs definition/src/lib.rs diagnostics/src/build_log.rs diagnostics/src/grammar/bib.rs diagnostics/src/grammar/tex.rs folding/src/lib.rs hover/src/citation.rs links/src/lib.rs references/src/command.rs references/src/lib.rs references/src/string_def.rs rename/src/command.rs rename/src/lib.rs symbols/src/document.rs symbols/src/types.rs symbols/src/workspace/sort.rs test-utils/src/fixture.rs texlab/src/features/formatting/bibtex_internal.rs texlab/src/features/formatting/latexindent.rs ```

Thibaulltt

The basic gist of the fix would be this: get not only the root of the project, but the relative path from that root to the file currently being evaluated. If I open up `project/thesis/thesis.tex`, it should be `project/thesis` before setting it to `project/` when neovim sets the project root by looking for the `latexmkrc` file. Another way to do it would be to have a specific LSP command (`textDocument/setDocumentRoot`?) which allows to set the main file of a tex document to a given path, which will in turn update all latexmk (and bibtex, and include) paths relative to that file's location.