summaryrefslogtreecommitdiff
path: root/cli
diff options
context:
space:
mode:
authorSébastien d'Herbais de Thun <sebastien.d.herbais@gmail.com>2023-04-04 14:12:19 +0200
committerGitHub <noreply@github.com>2023-04-04 14:12:19 +0200
commit2d1598e51d10bfe4e331c1ad6ca7899c5cdbb468 (patch)
tree0764ab46b04859c7e1a337d400395eb82b02c7ea /cli
parent2c735294cd5e47f1f1eb6402a3b8c500dccd047b (diff)
CLI: open flag (#480)
Diffstat (limited to 'cli')
-rw-r--r--cli/Cargo.toml1
-rw-r--r--cli/src/main.rs64
2 files changed, 47 insertions, 18 deletions
diff --git a/cli/Cargo.toml b/cli/Cargo.toml
index f484bf32..8b0f3517 100644
--- a/cli/Cargo.toml
+++ b/cli/Cargo.toml
@@ -27,6 +27,7 @@ same-file = "1"
siphasher = "0.3"
walkdir = "2"
clap = { version = "4.2.1", features = ["derive"] }
+open = "4.0.1"
[features]
default = ["embed-fonts"]
diff --git a/cli/src/main.rs b/cli/src/main.rs
index 8726a301..98c7aa6a 100644
--- a/cli/src/main.rs
+++ b/cli/src/main.rs
@@ -57,7 +57,7 @@ enum Command {
/// Watches the input file and recompiles on changes
#[command(visible_alias = "w")]
- Watch(WatchCommand),
+ Watch(CompileCommand),
/// List all discovered fonts in system and custom font paths
Fonts(FontsCommand),
@@ -71,22 +71,16 @@ pub struct CompileCommand {
/// Path to output PDF file
output: Option<PathBuf>,
-}
-
-/// Watches the input file and recompiles on changes
-#[derive(Debug, Clone, Parser)]
-pub struct WatchCommand {
- /// Path to input Typst file
- input: PathBuf,
- /// Path to output PDF file
- output: Option<PathBuf>,
+ /// Opens the output file after compilation using the default PDF viewer
+ #[arg(long = "open")]
+ open: Option<Option<String>>,
}
/// List all discovered fonts in system and custom font paths
#[derive(Debug, Clone, Parser)]
pub struct FontsCommand {
- /// Add additional directories to search for fonts
+ /// Also list style variants of each font family
#[arg(long)]
variants: bool,
}
@@ -107,6 +101,9 @@ struct CompileSettings {
/// The paths to search for fonts.
font_paths: Vec<PathBuf>,
+
+ /// The open command to use.
+ open: Option<Option<String>>,
}
impl CompileSettings {
@@ -117,13 +114,13 @@ impl CompileSettings {
watch: bool,
root: Option<PathBuf>,
font_paths: Vec<PathBuf>,
+ open: Option<Option<String>>,
) -> Self {
let output = match output {
Some(path) => path,
None => input.with_extension("pdf"),
};
-
- Self { input, output, watch, root, font_paths }
+ Self { input, output, watch, root, font_paths, open }
}
/// Create a new compile settings from the CLI arguments and a compile command.
@@ -131,12 +128,13 @@ impl CompileSettings {
/// # Panics
/// Panics if the command is not a compile or watch command.
pub fn with_arguments(args: CliArguments) -> Self {
- let (input, output, watch) = match args.command {
- Command::Compile(command) => (command.input, command.output, false),
- Command::Watch(command) => (command.input, command.output, true),
+ let watch = matches!(args.command, Command::Watch(_));
+ let CompileCommand { input, output, open } = match args.command {
+ Command::Compile(command) => command,
+ Command::Watch(command) => command,
_ => unreachable!(),
};
- Self::new(input, output, watch, args.root, args.font_paths)
+ Self::new(input, output, watch, args.root, args.font_paths, open)
}
}
@@ -195,7 +193,7 @@ fn print_error(msg: &str) -> io::Result<()> {
}
/// Execute a compilation command.
-fn compile(command: CompileSettings) -> StrResult<()> {
+fn compile(mut command: CompileSettings) -> StrResult<()> {
let root = if let Some(root) = &command.root {
root.clone()
} else if let Some(dir) = command
@@ -215,6 +213,14 @@ fn compile(command: CompileSettings) -> StrResult<()> {
// Perform initial compilation.
let failed = compile_once(&mut world, &command)?;
+
+ // open the file if requested, this must be done on the first **successful** compilation
+ if !failed {
+ if let Some(open) = command.open.take() {
+ open_file(open.as_deref(), &command.output)?;
+ }
+ }
+
if !command.watch {
// Return with non-zero exit code in case of error.
if failed {
@@ -258,6 +264,11 @@ fn compile(command: CompileSettings) -> StrResult<()> {
if recompile {
compile_once(&mut world, &command)?;
comemo::evict(30);
+
+ // open the file if requested, this must be done on the first **successful** compilation
+ if let Some(open) = command.open.take() {
+ open_file(open.as_deref(), &command.output)?;
+ }
}
}
}
@@ -381,6 +392,23 @@ fn print_diagnostics(
Ok(())
}
+/// Opens the given file using:
+/// - The default file viewer if `open` is `None`.
+/// - The given viewer provided by `open` if it is `Some`.
+fn open_file(open: Option<&str>, path: &Path) -> StrResult<()> {
+ if let Some(app) = open {
+ open::with(path, app).map_err(|err| {
+ format!("failed to open `{}` with `{}`, reason: {}", path.display(), app, err)
+ })?;
+ } else {
+ open::that(path).map_err(|err| {
+ format!("failed to open `{}`, reason: {}", path.display(), err)
+ })?;
+ }
+
+ Ok(())
+}
+
/// Execute a font listing command.
fn fonts(command: FontsSettings) -> StrResult<()> {
let mut searcher = FontSearcher::new();