diff --git a/README.md b/README.md index f9764c6..964775d 100644 --- a/README.md +++ b/README.md @@ -221,7 +221,7 @@ functions. -`treefmt-nix` currently supports 94 formatters: +`treefmt-nix` currently supports 95 formatters: * [actionlint](programs/actionlint.nix) * [alejandra](programs/alejandra.nix) @@ -253,6 +253,7 @@ functions. * [fourmolu](programs/fourmolu.nix) * [fprettify](programs/fprettify.nix) * [gdformat](programs/gdformat.nix) +* [genemichaels](programs/genemichaels.nix) * [gleam](programs/gleam.nix) * [gofmt](programs/gofmt.nix) * [gofumpt](programs/gofumpt.nix) diff --git a/checks/default.nix b/checks/default.nix index 3ffc293..ae99f8c 100644 --- a/checks/default.nix +++ b/checks/default.nix @@ -41,7 +41,7 @@ let (name: value: '' { echo "# Example generated by ../examples.sh" - sed -n '/^$/q;p' ${value} | sed 's|\(command = "\).*/\([^"]\+"\)|\1\2|' + sed -n '/^$/q;p' ${value} | sed 's|\(command = "\).*/\([^"]\+"\)|\1\2|' | sed 's|/nix/store/.*-||' } > "$out/${name}.toml" '') ( diff --git a/examples/formatter-genemichaels.toml b/examples/formatter-genemichaels.toml new file mode 100644 index 0000000..f2d800d --- /dev/null +++ b/examples/formatter-genemichaels.toml @@ -0,0 +1,6 @@ +# Example generated by ../examples.sh +[formatter.genemichaels] +command = "genemichaels" +excludes = [] +includes = ["*.rs"] +options = ["--config", "genemichaels.json"] diff --git a/programs/genemichaels.nix b/programs/genemichaels.nix new file mode 100644 index 0000000..8daba65 --- /dev/null +++ b/programs/genemichaels.nix @@ -0,0 +1,166 @@ +{ + lib, + pkgs, + config, + ... +}: +let + cfg = config.programs.genemichaels; + configFormat = pkgs.formats.json { }; + + inherit (lib) + types + ; + + inherit (lib.lists) + optionals + ; + + inherit (lib.modules) + mkIf + ; + + inherit (lib.options) + mkEnableOption + mkOption + mkPackageOption + ; +in +{ + meta.maintainers = [ "djacu" ]; + + options.programs.genemichaels = { + enable = mkEnableOption "genemichaels"; + package = mkPackageOption pkgs "genemichaels" { }; + + # Configuration scheme for genemichaels, which we generate .genemichaels.json with. + # Definition taken from https://github.com/andrewbaxter/genemichaels/blob/genemichaels-v0.5.7/readme.md#configuration + settings = { + max_width = mkOption { + description = '' + Ideal maximum line width. If there's an unbreakable element the line + won't be split. + ''; + type = types.ints.positive; + example = 80; + default = 120; + }; + root_splits = mkOption { + description = '' + When breaking a child element, also break all parent elements. + ''; + type = types.bool; + example = true; + default = false; + }; + split_brace_threshold = mkOption { + description = '' + Break a `()` or `{}` if it has greater than this number of children. + Set to `null` to disable breaking due to high child counts. + ''; + type = types.nullOr types.ints.positive; + example = null; + default = 1; + }; + split_attributes = mkOption { + description = '' + Break a `#[]` on a separate line before the element it's associated + with. + ''; + type = types.bool; + example = false; + default = true; + }; + split_where = mkOption { + description = '' + Put the `where` clause on a new line. + ''; + type = types.bool; + example = false; + default = true; + }; + comment_width = mkOption { + description = '' + Maximum relative line length for comments (past the comment + indentation level). Can be `null` to disable relative wrapping. If + disabled, still wraps at `max_width`. + ''; + type = types.nullOr types.ints.positive; + example = null; + default = 80; + }; + comment_errors_fatal = mkOption { + description = '' + If reformatting comments results in an error, abort formatting the + document. + ''; + type = types.bool; + example = true; + default = false; + }; + keep_max_blank_lines = mkOption { + description = '' + Genemichaels will replace line breaks with it's own deterministic + line breaks. You can use this to keep extra line breaks (1 will keep + up to 1 extra line break) during comment extraction. This is unused + during formatting. + ''; + type = types.ints.unsigned; + example = 1; + default = 0; + }; + }; + + settingsFile = mkOption { + description = "The configuration file used by `genemichaels`."; + type = types.path; + example = ./.genemichaels.json; + default = configFormat.generate ".genemichaels.json" cfg.settings; + }; + + threadCount = mkOption { + description = '' + How many threads to use for formatting multiple files. Set to `null` to + default to the number of cores on the system. + ''; + type = types.nullOr types.ints.unsigned; + example = 1; + default = null; + }; + + includes = mkOption { + description = '' + Path / file patterns to include for genemichaels. + ''; + type = types.listOf types.str; + default = [ + "*.rs" + ]; + }; + + excludes = mkOption { + description = '' + Path / file patterns to exclude for genemichaels. + ''; + type = types.listOf types.str; + default = [ ]; + }; + }; + + config = mkIf cfg.enable { + settings.formatter.genemichaels = { + command = "${cfg.package}/bin/genemichaels"; + options = + (optionals (cfg.threadCount != null) [ + "--thread-count" + (toString cfg.threadCount) + ]) + ++ [ + "--config" + (toString cfg.settingsFile) + ]; + includes = cfg.includes; + excludes = cfg.excludes; + }; + }; +}