From e500c2bde06c17acfe9ef55980bf265c3cef5487 Mon Sep 17 00:00:00 2001 From: Daniel Baker Date: Mon, 9 Dec 2024 20:20:43 -0800 Subject: [PATCH] genemichaels: init Adds a module to use the genemichaels formatter for Rust files that is compatible with version 0.5.7. --- examples/formatter-genemichaels.toml | 6 + programs/genemichaels.nix | 165 +++++++++++++++++++++++++++ 2 files changed, 171 insertions(+) create mode 100644 examples/formatter-genemichaels.toml create mode 100644 programs/genemichaels.nix diff --git a/examples/formatter-genemichaels.toml b/examples/formatter-genemichaels.toml new file mode 100644 index 0000000..3049d83 --- /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", "/nix/store/vx37ijcbwxg86nws25wrhaz96mrs4ady-genemichaels.json"] diff --git a/programs/genemichaels.nix b/programs/genemichaels.nix new file mode 100644 index 0000000..85db2ea --- /dev/null +++ b/programs/genemichaels.nix @@ -0,0 +1,165 @@ +{ 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; + }; + }; +}