diff --git a/doc/manual/generate-manpage.nix b/doc/manual/generate-manpage.nix index 5c6a2a48a..4abf7c302 100644 --- a/doc/manual/generate-manpage.nix +++ b/doc/manual/generate-manpage.nix @@ -1,26 +1,134 @@ +with builtins; + let - inherit (builtins) - attrNames - attrValues - fromJSON - listToAttrs - mapAttrs - concatStringsSep - concatMap - length - lessThan - replaceStrings - sort - ; - inherit (import ./utils.nix) - concatStrings - optionalString - filterAttrs - trim - squash - unique - showSettings - ; + splitLines = s: filter (x: !isList x) (split "\n" s); + + concatStrings = concatStringsSep ""; + + replaceStringsRec = + from: to: string: + # recursively replace occurrences of `from` with `to` within `string` + # example: + # replaceStringRec "--" "-" "hello-----world" + # => "hello-world" + let + replaced = replaceStrings [ from ] [ to ] string; + in + if replaced == string then string else replaceStringsRec from to replaced; + + squash = replaceStringsRec "\n\n\n" "\n\n"; + + trim = + string: + # trim trailing spaces and squash non-leading spaces + let + trimLine = + line: + let + # separate leading spaces from the rest + parts = split "(^ *)" line; + spaces = head (elemAt parts 1); + rest = elemAt parts 2; + # drop trailing spaces + body = head (split " *$" rest); + in + spaces + replaceStringsRec " " " " body; + in + concatStringsSep "\n" (map trimLine (splitLines string)); + + # FIXME: O(n^2) + unique = foldl' (acc: e: if elem e acc then acc else acc ++ [ e ]) [ ]; + + nameValuePair = name: value: { inherit name value; }; + + filterAttrs = + pred: set: + listToAttrs ( + concatMap ( + name: + let + v = set.${name}; + in + if pred name v then [ (nameValuePair name v) ] else [ ] + ) (attrNames set) + ); + + optionalString = cond: string: if cond then string else ""; + + showSetting = + { inlineHTML }: + name: + { + description, + documentDefault, + defaultValue, + aliases, + value, + experimentalFeature, + }: + let + result = squash '' + - ${ + if inlineHTML then ''[`${name}`](#conf-${name})'' else ''`${name}`'' + } + + ${indent " " body} + ''; + + experimentalFeatureNote = optionalString (experimentalFeature != null) '' + > **Warning** + > This setting is part of an + > [experimental feature](@docroot@/contributing/experimental-features.md). + + To change this setting, you need to make sure the corresponding experimental feature, + [`${experimentalFeature}`](@docroot@/contributing/experimental-features.md#xp-feature-${experimentalFeature}), + is enabled. + For example, include the following in [`nix.conf`](#): + + ``` + extra-experimental-features = ${experimentalFeature} + ${name} = ... + ``` + ''; + + # separate body to cleanly handle indentation + body = '' + ${description} + + ${experimentalFeatureNote} + + **Default:** ${showDefault documentDefault defaultValue} + + ${showAliases aliases} + ''; + + showDefault = + documentDefault: defaultValue: + if documentDefault then + # a StringMap value type is specified as a string, but + # this shows the value type. The empty stringmap is `null` in + # JSON, but that converts to `{ }` here. + if defaultValue == "" || defaultValue == [ ] || isAttrs defaultValue then + "*empty*" + else if isBool defaultValue then + if defaultValue then "`true`" else "`false`" + else + "`${toString defaultValue}`" + else + "*machine-specific*"; + + showAliases = + aliases: + optionalString (aliases != [ ]) + "**Deprecated alias:** ${(concatStringsSep ", " (map (s: "`${s}`") aliases))}"; + in + result; + + indent = + prefix: s: concatStringsSep "\n" (map (x: if x == "" then x else "${prefix}${x}") (splitLines s)); + + showSettings = + args: settingsInfo: concatStrings (attrValues (mapAttrs (showSetting args) settingsInfo)); in inlineHTML: commandDump: diff --git a/doc/manual/utils.nix b/doc/manual/utils.nix deleted file mode 100644 index 17e6378eb..000000000 --- a/doc/manual/utils.nix +++ /dev/null @@ -1,139 +0,0 @@ -with builtins; - -rec { - splitLines = s: filter (x: !isList x) (split "\n" s); - - concatStrings = concatStringsSep ""; - - attrsToList = - a: - map (name: { - inherit name; - value = a.${name}; - }) (builtins.attrNames a); - - replaceStringsRec = - from: to: string: - # recursively replace occurrences of `from` with `to` within `string` - # example: - # replaceStringRec "--" "-" "hello-----world" - # => "hello-world" - let - replaced = replaceStrings [ from ] [ to ] string; - in - if replaced == string then string else replaceStringsRec from to replaced; - - squash = replaceStringsRec "\n\n\n" "\n\n"; - - trim = - string: - # trim trailing spaces and squash non-leading spaces - let - trimLine = - line: - let - # separate leading spaces from the rest - parts = split "(^ *)" line; - spaces = head (elemAt parts 1); - rest = elemAt parts 2; - # drop trailing spaces - body = head (split " *$" rest); - in - spaces + replaceStringsRec " " " " body; - in - concatStringsSep "\n" (map trimLine (splitLines string)); - - # FIXME: O(n^2) - unique = foldl' (acc: e: if elem e acc then acc else acc ++ [ e ]) [ ]; - - nameValuePair = name: value: { inherit name value; }; - - filterAttrs = - pred: set: - listToAttrs ( - concatMap ( - name: - let - v = set.${name}; - in - if pred name v then [ (nameValuePair name v) ] else [ ] - ) (attrNames set) - ); - - optionalString = cond: string: if cond then string else ""; - - showSetting = - { inlineHTML }: - name: - { - description, - documentDefault, - defaultValue, - aliases, - value, - experimentalFeature, - }: - let - result = squash '' - - ${ - if inlineHTML then ''[`${name}`](#conf-${name})'' else ''`${name}`'' - } - - ${indent " " body} - ''; - - experimentalFeatureNote = optionalString (experimentalFeature != null) '' - > **Warning** - > This setting is part of an - > [experimental feature](@docroot@/contributing/experimental-features.md). - - To change this setting, you need to make sure the corresponding experimental feature, - [`${experimentalFeature}`](@docroot@/contributing/experimental-features.md#xp-feature-${experimentalFeature}), - is enabled. - For example, include the following in [`nix.conf`](#): - - ``` - extra-experimental-features = ${experimentalFeature} - ${name} = ... - ``` - ''; - - # separate body to cleanly handle indentation - body = '' - ${description} - - ${experimentalFeatureNote} - - **Default:** ${showDefault documentDefault defaultValue} - - ${showAliases aliases} - ''; - - showDefault = - documentDefault: defaultValue: - if documentDefault then - # a StringMap value type is specified as a string, but - # this shows the value type. The empty stringmap is `null` in - # JSON, but that converts to `{ }` here. - if defaultValue == "" || defaultValue == [ ] || isAttrs defaultValue then - "*empty*" - else if isBool defaultValue then - if defaultValue then "`true`" else "`false`" - else - "`${toString defaultValue}`" - else - "*machine-specific*"; - - showAliases = - aliases: - optionalString (aliases != [ ]) - "**Deprecated alias:** ${(concatStringsSep ", " (map (s: "`${s}`") aliases))}"; - in - result; - - indent = - prefix: s: concatStringsSep "\n" (map (x: if x == "" then x else "${prefix}${x}") (splitLines s)); - - showSettings = - args: settingsInfo: concatStrings (attrValues (mapAttrs (showSetting args) settingsInfo)); -} diff --git a/lix/nix/main.cc b/lix/nix/main.cc index 6047a8e17..b94e8151c 100644 --- a/lix/nix/main.cc +++ b/lix/nix/main.cc @@ -261,14 +261,6 @@ static void showHelp(std::vector subcommand, NixArgs & toplevel) #include "generate-manpage.nix.gen.hh" , CanonPath::root), *vGenerateManpage); - auto vUtils = state.mem.allocValue(); - state.cacheFile( - CanonPath("/utils.nix"), CanonPath("/utils.nix"), - &state.parseExprFromString( - #include "utils.nix.gen.hh" - , CanonPath::root), - *vUtils); - auto vDump = state.mem.allocValue(); vDump->mkString(toplevel.dumpCli()); diff --git a/lix/nix/meson.build b/lix/nix/meson.build index 37d411cac..3172b2d4c 100644 --- a/lix/nix/meson.build +++ b/lix/nix/meson.build @@ -1,6 +1,5 @@ nix_generated_headers = [ gen_header.process(meson.project_source_root() / 'doc/manual/generate-manpage.nix'), - gen_header.process(meson.project_source_root() / 'doc/manual/utils.nix'), gen_header.process('get-env.sh'), ]