diff --git a/crates/typst-cli/src/args.rs b/crates/typst-cli/src/args.rs index 9648d8efa..ef12c48ac 100644 --- a/crates/typst-cli/src/args.rs +++ b/crates/typst-cli/src/args.rs @@ -100,9 +100,11 @@ pub struct CompileCommand { #[arg(long = "format", short = 'f')] pub format: Option, - /// Opens the output file using the default viewer after compilation. - /// Ignored if output is stdout - #[arg(long = "open")] + /// Opens the output file with the default viewer or a specific program after + /// compilation + /// + /// Ignored if output is stdout. + #[arg(long = "open", value_name = "VIEWER")] pub open: Option>, /// The PPI (pixels per inch) to use for PNG export diff --git a/crates/typst-cli/src/compile.rs b/crates/typst-cli/src/compile.rs index ae712a85e..4b87c3bd3 100644 --- a/crates/typst-cli/src/compile.rs +++ b/crates/typst-cli/src/compile.rs @@ -472,14 +472,30 @@ fn write_make_deps(world: &mut SystemWorld, command: &CompileCommand) -> StrResu /// Opens the given file using: /// - The default file viewer if `open` is `None`. /// - The given viewer provided by `open` if it is `Some`. +/// +/// If the file could not be opened, an error is returned. fn open_file(open: Option<&str>, path: &Path) -> StrResult<()> { + // Some resource openers require the path to be canonicalized. + let path = path + .canonicalize() + .map_err(|err| eco_format!("failed to canonicalize path ({err})"))?; if let Some(app) = open { - open::with_in_background(path, app); + open::with_detached(&path, app) + .map_err(|err| eco_format!("failed to open file with {} ({})", app, err)) } else { - open::that_in_background(path); + open::that_detached(&path).map_err(|err| { + let openers = open::commands(path) + .iter() + .map(|command| command.get_program().to_string_lossy()) + .collect::>() + .join(", "); + eco_format!( + "failed to open file with any of these resource openers: {} ({})", + openers, + err, + ) + }) } - - Ok(()) } /// Adds useful hints when the main source file couldn't be read