summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorCharlotte Thomas <contact@nwa2coco.fr>2023-10-26 15:31:16 +0200
committerDavid Knaack <davidkna@users.noreply.github.com>2023-11-12 19:02:31 +0100
commit7b217056bdb8dcb5b328b51fa3b68fe837f9fb3c (patch)
tree6cf9bcad5d73f1a0706740b459115a1b5890b501 /src
parentb5f9457b28db92406c03576663a6181a7081fd0f (diff)
feat: add typst module
Co-authored-by: David Knaack <davidkna@users.noreply.github.com>
Diffstat (limited to 'src')
-rw-r--r--src/configs/mod.rs3
-rw-r--r--src/configs/starship_root.rs1
-rw-r--r--src/configs/typst.rs34
-rw-r--r--src/module.rs1
-rw-r--r--src/modules/mod.rs3
-rw-r--r--src/modules/typst.rs98
-rw-r--r--src/utils.rs5
7 files changed, 145 insertions, 0 deletions
diff --git a/src/configs/mod.rs b/src/configs/mod.rs
index aeb8193fd..883055b81 100644
--- a/src/configs/mod.rs
+++ b/src/configs/mod.rs
@@ -84,6 +84,7 @@ pub mod sudo;
pub mod swift;
pub mod terraform;
pub mod time;
+pub mod typst;
pub mod username;
pub mod v;
pub mod vagrant;
@@ -269,6 +270,8 @@ pub struct FullConfig<'a> {
#[serde(borrow)]
time: time::TimeConfig<'a>,
#[serde(borrow)]
+ typst: typst::TypstConfig<'a>,
+ #[serde(borrow)]
username: username::UsernameConfig<'a>,
#[serde(borrow)]
vagrant: vagrant::VagrantConfig<'a>,
diff --git a/src/configs/starship_root.rs b/src/configs/starship_root.rs
index 6308d6d99..c93c1543f 100644
--- a/src/configs/starship_root.rs
+++ b/src/configs/starship_root.rs
@@ -91,6 +91,7 @@ pub const PROMPT_ORDER: &[&str] = &[
"solidity",
"swift",
"terraform",
+ "typst",
"vlang",
"vagrant",
"zig",
diff --git a/src/configs/typst.rs b/src/configs/typst.rs
new file mode 100644
index 000000000..28f4fc62b
--- /dev/null
+++ b/src/configs/typst.rs
@@ -0,0 +1,34 @@
+use serde::{Deserialize, Serialize};
+
+#[derive(Clone, Deserialize, Serialize)]
+#[cfg_attr(
+ feature = "config-schema",
+ derive(schemars::JsonSchema),
+ schemars(deny_unknown_fields)
+)]
+#[serde(default)]
+pub struct TypstConfig<'a> {
+ pub format: &'a str,
+ pub version_format: &'a str,
+ pub symbol: &'a str,
+ pub style: &'a str,
+ pub disabled: bool,
+ pub detect_extensions: Vec<&'a str>,
+ pub detect_files: Vec<&'a str>,
+ pub detect_folders: Vec<&'a str>,
+}
+
+impl<'a> Default for TypstConfig<'a> {
+ fn default() -> Self {
+ TypstConfig {
+ format: "via [$symbol($version )]($style)",
+ version_format: "v${raw}",
+ symbol: "t ",
+ style: "bold #0093A7",
+ disabled: false,
+ detect_extensions: vec!["typ"],
+ detect_files: vec!["template.typ"],
+ detect_folders: vec![],
+ }
+ }
+}
diff --git a/src/module.rs b/src/module.rs
index 26d46c976..33f8287b7 100644
--- a/src/module.rs
+++ b/src/module.rs
@@ -90,6 +90,7 @@ pub const ALL_MODULES: &[&str] = &[
"swift",
"terraform",
"time",
+ "typst",
"username",
"vagrant",
"vcsh",
diff --git a/src/modules/mod.rs b/src/modules/mod.rs
index fe4f42305..cc1eec4e4 100644
--- a/src/modules/mod.rs
+++ b/src/modules/mod.rs
@@ -89,6 +89,7 @@ mod zig;
#[cfg(feature = "battery")]
mod battery;
+mod typst;
#[cfg(feature = "battery")]
pub use self::battery::{BatteryInfoProvider, BatteryInfoProviderImpl};
@@ -185,6 +186,7 @@ pub fn handle<'a>(module: &str, context: &'a Context) -> Option<Module<'a>> {
"sudo" => sudo::module(context),
"terraform" => terraform::module(context),
"time" => time::module(context),
+ "typst" => typst::module(context),
"crystal" => crystal::module(context),
"username" => username::module(context),
"vlang" => vlang::module(context),
@@ -303,6 +305,7 @@ pub fn description(module: &str) -> &'static str {
"swift" => "The currently installed version of Swift",
"terraform" => "The currently selected terraform workspace and version",
"time" => "The current local time",
+ "typst" => "The current installed version of typst",
"username" => "The active user's username",
"vagrant" => "The currently installed version of Vagrant",
"vcsh" => "The currently active VCSH repository",
diff --git a/src/modules/typst.rs b/src/modules/typst.rs
new file mode 100644
index 000000000..a1c0ba4a0
--- /dev/null
+++ b/src/modules/typst.rs
@@ -0,0 +1,98 @@
+use super::{Context, Module, ModuleConfig};
+
+use crate::configs::typst::TypstConfig;
+use crate::formatter::{StringFormatter, VersionFormatter};
+
+/// Creates a module with the current Typst version
+pub fn module<'a>(context: &'a Context) -> Option<Module<'a>> {
+ let mut module = context.new_module("typst");
+ let config = TypstConfig::try_load(module.config);
+
+ let is_typst_project = context
+ .try_begin_scan()?
+ .set_files(&config.detect_files)
+ .set_extensions(&config.detect_extensions)
+ .set_folders(&config.detect_folders)
+ .is_match();
+
+ if !is_typst_project {
+ return None;
+ }
+
+ let parsed = StringFormatter::new(config.format).and_then(|formatter| {
+ formatter
+ .map_meta(|var, _| match var {
+ "symbol" => Some(config.symbol),
+ _ => None,
+ })
+ .map_style(|variable| match variable {
+ "style" => Some(Ok(config.style)),
+ _ => None,
+ })
+ .map(|variable| match variable {
+ "version" => {
+ let version = get_typst_config(context)?;
+ VersionFormatter::format_module_version(
+ module.get_name(),
+ &version,
+ config.version_format,
+ )
+ .map(Ok)
+ }
+ _ => None,
+ })
+ .parse(None, Some(context))
+ });
+
+ module.set_segments(match parsed {
+ Ok(segments) => segments,
+ Err(error) => {
+ log::warn!("Error in module `typst`:\n{}", error);
+ return None;
+ }
+ });
+
+ Some(module)
+}
+
+fn get_typst_config(context: &Context) -> Option<String> {
+ context
+ .exec_cmd("typst", &["--version"])?
+ .stdout
+ .trim()
+ .strip_prefix("typst ")
+ .and_then(|version| version.split_whitespace().next().map(ToOwned::to_owned))
+}
+
+#[cfg(test)]
+mod tests {
+ use crate::test::ModuleRenderer;
+ use nu_ansi_term::Color;
+ use std::fs::File;
+ use std::io;
+ #[test]
+ fn read_typst_not_present() -> io::Result<()> {
+ let dir = tempfile::tempdir()?;
+
+ let actual = ModuleRenderer::new("typst").path(dir.path()).collect();
+
+ let expected = None;
+ assert_eq!(expected, actual);
+ dir.close()
+ }
+
+ #[test]
+ fn read_typst_present() -> io::Result<()> {
+ let dir = tempfile::tempdir()?;
+
+ File::create(dir.path().join("test.typ"))?.sync_all()?;
+
+ let actual = ModuleRenderer::new("typst").path(dir.path()).collect();
+ let expected = Some(format!(
+ "via {}",
+ Color::Rgb(0, 147, 167).bold().paint("t v0.10 ")
+ ));
+ assert_eq!(expected, actual);
+ dir.close()
+ }
+}
diff --git a/src/utils.rs b/src/utils.rs
index d4d68a812..0459f5f76 100644
--- a/src/utils.rs
+++ b/src/utils.rs
@@ -341,6 +341,11 @@ WebAssembly: unavailable
stdout: String::from("default\n"),
stderr: String::default(),
}),
+ "typst --version" => Some(CommandOutput {
+ stdout: String::from("typst 0.10 (360cc9b9)"),
+ stderr: String::default(),
+ }),
+
"esy ocaml -vnum" => Some(CommandOutput {
stdout: String::from("4.08.1\n"),
stderr: String::default(),