summaryrefslogtreecommitdiff
path: root/support/texlab/crates/commands/src/fwd_search.rs
diff options
context:
space:
mode:
Diffstat (limited to 'support/texlab/crates/commands/src/fwd_search.rs')
-rw-r--r--support/texlab/crates/commands/src/fwd_search.rs102
1 files changed, 59 insertions, 43 deletions
diff --git a/support/texlab/crates/commands/src/fwd_search.rs b/support/texlab/crates/commands/src/fwd_search.rs
index 7e82f38487..4e3450681c 100644
--- a/support/texlab/crates/commands/src/fwd_search.rs
+++ b/support/texlab/crates/commands/src/fwd_search.rs
@@ -1,11 +1,7 @@
-use std::{
- ffi::OsStr,
- path::{Path, PathBuf},
- process::Stdio,
-};
+use std::{path::PathBuf, process::Stdio};
use anyhow::Result;
-use base_db::Workspace;
+use base_db::{Document, Workspace};
use thiserror::Error;
use url::Url;
@@ -44,62 +40,82 @@ impl ForwardSearch {
uri: &Url,
line: Option<u32>,
) -> Result<Self, ForwardSearchError> {
- let Some(config) = &workspace.config().synctex else {
- return Err(ForwardSearchError::Unconfigured);
- };
-
- let Some(child) = workspace.lookup(uri) else {
- return Err(ForwardSearchError::TexNotFound(uri.clone()));
- };
-
- let parents = workspace.parents(child);
- let parent = parents.into_iter().next().unwrap_or(child);
- if parent.uri.scheme() != "file" {
- return Err(ForwardSearchError::NotLocal(parent.uri.clone()));
- }
-
- let dir = workspace
- .pdf_dir(&workspace.current_dir(&parent.dir))
- .to_file_path()
- .unwrap();
+ log::debug!("[FwdSearch] Preparing forward search: document={uri}, line={line:#?}");
+ let synctex_config = workspace
+ .config()
+ .synctex
+ .as_ref()
+ .ok_or(ForwardSearchError::Unconfigured)?;
- let Some(tex_path) = &child.path else {
- return Err(ForwardSearchError::InvalidPath(child.uri.clone()));
- };
+ log::debug!("[FwdSearch] synctex_config={:?}", synctex_config);
- let override_path = workspace.config().build.output_filename.as_deref();
+ let child = workspace
+ .lookup(uri)
+ .ok_or_else(|| ForwardSearchError::TexNotFound(uri.clone()))?;
- let Some(pdf_path) = override_path
- .or(parent.path.as_deref())
- .and_then(Path::file_stem)
- .and_then(OsStr::to_str)
- .map(|stem| dir.join(format!("{stem}.pdf")))
- else {
- return Err(ForwardSearchError::InvalidPath(parent.uri.clone()));
- };
+ let parent = workspace.parents(child).into_iter().next().unwrap_or(child);
- if !pdf_path.exists() {
- return Err(ForwardSearchError::PdfNotFound(pdf_path));
- }
+ log::debug!("[FwdSearch] root_document={}", parent.uri,);
- let tex_path = tex_path.to_string_lossy().into_owned();
+ let pdf_path = Self::find_pdf(workspace, parent)?;
let pdf_path = pdf_path.to_string_lossy().into_owned();
+ let tex_path = child
+ .path
+ .as_deref()
+ .ok_or_else(|| ForwardSearchError::InvalidPath(child.uri.clone()))?;
+ let tex_path = tex_path.to_string_lossy().into_owned();
+
let line = line.unwrap_or(child.cursor.line);
let line = (line + 1).to_string();
- let program = config.program.clone();
+ let program = synctex_config.program.clone();
let args = replace_placeholders(
- &config.args,
+ &synctex_config.args,
&[('f', &tex_path), ('p', &pdf_path), ('l', &line)],
);
Ok(Self { program, args })
}
+
+ fn find_pdf(workspace: &Workspace, document: &Document) -> Result<PathBuf, ForwardSearchError> {
+ let base_dir = workspace.current_dir(&document.dir);
+ let pdf_dir = workspace.pdf_dir(&base_dir);
+
+ log::debug!("[FwdSearch] base_dir={base_dir}, pdf_dir={pdf_dir}");
+
+ let pdf_dir = pdf_dir
+ .to_file_path()
+ .map_err(|()| ForwardSearchError::InvalidPath(document.uri.clone()))?;
+
+ let pdf_name_override = workspace.config().build.output_filename.clone();
+ log::debug!("[FwdSearch] pdf_name_override={pdf_name_override:?}");
+
+ let pdf_name = pdf_name_override
+ .or_else(|| {
+ let stem = document.path.as_ref()?.file_stem()?;
+ Some(format!("{}.pdf", stem.to_string_lossy()))
+ })
+ .ok_or_else(|| ForwardSearchError::InvalidPath(document.uri.clone()))?;
+
+ let pdf_path = pdf_dir.join(&pdf_name);
+ let pdf_exists = pdf_path.exists();
+
+ log::debug!("[FwdSearch] pdf_path={pdf_path:?}, pdf_exists={pdf_exists}");
+ if !pdf_exists {
+ return Err(ForwardSearchError::PdfNotFound(pdf_path));
+ }
+
+ Ok(pdf_path)
+ }
}
impl ForwardSearch {
pub fn run(self) -> Result<(), ForwardSearchError> {
- log::debug!("Executing forward search: {} {:?}", self.program, self.args);
+ log::debug!(
+ "[FwdSearch] Executing command: {} {:?}",
+ self.program,
+ self.args
+ );
std::process::Command::new(self.program)
.args(self.args)