From 59a6bf1b39c23af02a88422529a9b355ebcbf621 Mon Sep 17 00:00:00 2001 From: Mads Hougesen Date: Sat, 23 Mar 2024 15:14:54 +0100 Subject: [PATCH] feat(kotlin): add support for ktfmt Closes #106 --- README.md | 2 +- schemas/v0.0.2/mdsf.schema.json | 4 +-- src/formatters/ktfmt.rs | 45 +++++++++++++++++++++++++++++++++ src/formatters/mod.rs | 1 + src/languages/kotlin.rs | 34 +++++++++++++++++++++++-- 5 files changed, 81 insertions(+), 5 deletions(-) create mode 100644 src/formatters/ktfmt.rs diff --git a/README.md b/README.md index c76c2895..a0cdcf80 100644 --- a/README.md +++ b/README.md @@ -83,7 +83,7 @@ mdsf init | JavaScript | `biome`, `clang-format`, `deno_fmt`, `prettier` | | Json | `biome`, `clang-format`, `deno_fmt`, `prettier` | | Just | `just_fmt` | -| Kotlin | `ktlint` | +| Kotlin | `ktfmt`, `ktlint` | | Lua | `luaformatter`, `stylua` | | Markdown | `prettier` | | Nim | `nimpretty` | diff --git a/schemas/v0.0.2/mdsf.schema.json b/schemas/v0.0.2/mdsf.schema.json index e5122e26..fde06476 100644 --- a/schemas/v0.0.2/mdsf.schema.json +++ b/schemas/v0.0.2/mdsf.schema.json @@ -237,7 +237,7 @@ "kotlin": { "default": { "enabled": true, - "formatter": "ktlint" + "formatter": [["ktlint", "ktfmt"]] }, "allOf": [ { @@ -589,7 +589,7 @@ }, "Kotlin": { "type": "string", - "enum": ["ktlint"] + "enum": ["ktlint", "ktfmt"] }, "Lang_for_Blade": { "type": "object", diff --git a/src/formatters/ktfmt.rs b/src/formatters/ktfmt.rs new file mode 100644 index 00000000..f8a313c1 --- /dev/null +++ b/src/formatters/ktfmt.rs @@ -0,0 +1,45 @@ +use super::execute_command; + +#[inline] +pub fn format_using_ktfmt( + snippet_path: &std::path::Path, +) -> std::io::Result<(bool, Option)> { + let mut cmd = std::process::Command::new("ktfmt"); + + cmd.arg("--format") + .arg("--log-level=error") + .arg(snippet_path); + + execute_command(&mut cmd, snippet_path) +} + +#[cfg(test)] +mod test_ktfmt { + use crate::{formatters::setup_snippet, languages::Language}; + + use super::format_using_ktfmt; + + #[test_with::executable(ktfmt)] + #[test] + fn it_should_format_kotlin() { + let input = " fun add(a:Int ,b:Int ):Int { + return a + b + } + "; + + let expected_output = "fun add(a: Int, b: Int): Int { + return a + b +} +"; + + let snippet = setup_snippet(input, Language::Kotlin.to_file_ext()) + .expect("it to create a snippet file"); + + let output = format_using_ktfmt(snippet.path()) + .expect("it to be successful") + .1 + .expect("it to be some"); + + assert_eq!(output, expected_output); + } +} diff --git a/src/formatters/mod.rs b/src/formatters/mod.rs index d451a757..f78d7852 100644 --- a/src/formatters/mod.rs +++ b/src/formatters/mod.rs @@ -28,6 +28,7 @@ pub mod google_java_format; pub mod hindent; pub mod isort; pub mod just_fmt; +pub mod ktfmt; pub mod ktlint; pub mod luaformatter; pub mod mix_format; diff --git a/src/languages/kotlin.rs b/src/languages/kotlin.rs index 831fcb06..078bb7d9 100644 --- a/src/languages/kotlin.rs +++ b/src/languages/kotlin.rs @@ -1,6 +1,6 @@ use schemars::JsonSchema; -use crate::formatters::{ktlint::format_using_ktlint, MdsfFormatter}; +use crate::formatters::{ktfmt::format_using_ktfmt, ktlint::format_using_ktlint, MdsfFormatter}; use super::{Lang, LanguageFormatter}; @@ -10,6 +10,8 @@ pub enum Kotlin { #[default] #[serde(rename = "ktlint")] Ktlint, + #[serde(rename = "ktfmt")] + Ktfmt, } impl Default for Lang { @@ -25,7 +27,10 @@ impl Default for Lang { impl Default for MdsfFormatter { #[inline] fn default() -> Self { - Self::Single(Kotlin::Ktlint) + Self::Multiple(vec![Self::Multiple(vec![ + Self::Single(Kotlin::Ktlint), + Self::Single(Kotlin::Ktfmt), + ])]) } } @@ -37,6 +42,7 @@ impl LanguageFormatter for Kotlin { ) -> std::io::Result<(bool, Option)> { match self { Self::Ktlint => format_using_ktlint(snippet_path), + Self::Ktfmt => format_using_ktfmt(snippet_path), } } } @@ -100,6 +106,30 @@ fun add( ): Int { return a + b } +"; + + assert_eq!(output, expected_output); + } + + #[test_with::executable(ktfmt)] + #[test] + fn test_ktfmt() { + let l = Lang:: { + enabled: true, + formatter: MdsfFormatter::Single(Kotlin::Ktfmt), + }; + + let snippet = setup_snippet(INPUT, EXTENSION).expect("it to save the file"); + let snippet_path = snippet.path(); + + let output = l + .format(snippet_path) + .expect("it to not fail") + .expect("it to be a snippet"); + + let expected_output = "fun add(a: Int, b: Int): Int { + return a + b +} "; assert_eq!(output, expected_output);