From c71f520588b55a0b7fbd1585960dc9290aea9ecc Mon Sep 17 00:00:00 2001 From: Mads Hougesen Date: Thu, 21 Mar 2024 02:14:45 +0100 Subject: [PATCH] feat(haskell): add support for ormolu --- src/formatters/mod.rs | 1 + src/formatters/ormolu.rs | 44 ++++++++++++++++++++++++++++++++++++++++ src/languages/haskell.rs | 33 ++++++++++++++++++++++++++++-- 3 files changed, 76 insertions(+), 2 deletions(-) create mode 100644 src/formatters/ormolu.rs diff --git a/src/formatters/mod.rs b/src/formatters/mod.rs index 94fd55c4..0e517fcf 100644 --- a/src/formatters/mod.rs +++ b/src/formatters/mod.rs @@ -31,6 +31,7 @@ pub mod mix_format; pub mod nimpretty; pub mod npm_groovy_lint; pub mod ocamlformat; +pub mod ormolu; pub mod perltidy; pub mod prettier; pub mod purs_tidy; diff --git a/src/formatters/ormolu.rs b/src/formatters/ormolu.rs new file mode 100644 index 00000000..089b5338 --- /dev/null +++ b/src/formatters/ormolu.rs @@ -0,0 +1,44 @@ +use super::execute_command; + +#[inline] +pub fn format_using_ormolu( + snippet_path: &std::path::Path, +) -> std::io::Result<(bool, Option)> { + let mut cmd = std::process::Command::new("ormolu"); + + cmd.arg("--mode").arg("inplace").arg(snippet_path); + + execute_command(&mut cmd, snippet_path) +} + +#[cfg(test)] +mod test_ormolu { + use crate::{formatters::setup_snippet, languages::Language}; + + use super::format_using_ormolu; + + #[test_with::executable(ormolu)] + #[test] + fn it_should_format_haskell() { + let input = " +addNumbers::Int->Int->Int +addNumbers a b = do + a + b + "; + + let expected_output = "addNumbers :: Int -> Int -> Int +addNumbers a b = do + a + b +"; + + let snippet = setup_snippet(input, Language::Haskell.to_file_ext()) + .expect("it to create a snippet file"); + + let output = format_using_ormolu(snippet.path()) + .expect("it to be successful") + .1 + .expect("it to be some"); + + assert_eq!(output, expected_output); + } +} diff --git a/src/languages/haskell.rs b/src/languages/haskell.rs index 9adbacbf..98a13d5d 100644 --- a/src/languages/haskell.rs +++ b/src/languages/haskell.rs @@ -1,7 +1,8 @@ use schemars::JsonSchema; use crate::formatters::{ - fourmolu::format_using_fourmolu, hindent::format_using_hindent, MdsfFormatter, + fourmolu::format_using_fourmolu, hindent::format_using_hindent, ormolu::format_using_ormolu, + MdsfFormatter, }; use super::{Lang, LanguageFormatter}; @@ -9,9 +10,11 @@ use super::{Lang, LanguageFormatter}; #[derive(Debug, Default, serde::Serialize, serde::Deserialize, JsonSchema)] #[cfg_attr(test, derive(PartialEq, Eq))] pub enum Haskell { - #[default] #[serde(rename = "fourmolu")] Fourmolu, + #[default] + #[serde(rename = "ormolu")] + Ormolu, #[serde(rename = "hindent")] HIndent, } @@ -31,6 +34,7 @@ impl Default for MdsfFormatter { fn default() -> Self { Self::Multiple(vec![Self::Multiple(vec![ Self::Single(Haskell::Fourmolu), + Self::Single(Haskell::Ormolu), Self::Single(Haskell::HIndent), ])]) } @@ -44,6 +48,7 @@ impl LanguageFormatter for Haskell { ) -> std::io::Result<(bool, Option)> { match self { Self::Fourmolu => format_using_fourmolu(snippet_path), + Self::Ormolu => format_using_ormolu(snippet_path), Self::HIndent => format_using_hindent(snippet_path), } } @@ -109,6 +114,30 @@ addNumbers a b = do assert_eq!(output, expected_output); } + #[test_with::executable(ormolu)] + #[test] + fn test_ormolu() { + let l = Lang:: { + enabled: true, + formatter: MdsfFormatter::Single(Haskell::Ormolu), + }; + + 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 = "addNumbers :: Int -> Int -> Int +addNumbers a b = do + a + b +"; + + assert_eq!(output, expected_output); + } + #[test_with::executable(hindent)] #[test] fn test_hindent() {