Created builder template for making new builders that will work with existing code

This commit is contained in:
isaacST08 2025-01-24 10:28:17 -07:00
commit 387eb9ba27
5 changed files with 508 additions and 206 deletions

View file

@ -0,0 +1,67 @@
# This function acts as a template for creating new builders.
# It enforces providing all the parameters required for creating
# a new builder for it to be able to work in the existing code.
# The first layer requirements are as follows:
{
# This is the name of the builder, it will only be used internally and
# should match the <name>.nix file that the builder is implemented in.
name,
# Module attribute set. This is the attribute set that the module that is
# defining a builder is passed as its input.
moduleInheritencePackage,
# These are the standard options for the builder just like creating any
# other module. Some options are required and are described below but
# it will also accept any other options that are provided to it.
options,
# These are the command line arguments that will accompany the executable
# when the build command is called.
# This is a function that will take in the cfg of its own builder.
# i.e. will be called as "args cfg.build.builders.${name}"
args,
...
}: let
# Inherit the necessary variables available to any module.
inherit (moduleInheritencePackage) lib config;
# Inherit other useful functions.
inherit (lib.modules) mkIf;
# Set the cfg variable
cfg = config.vim.languages.tex;
in {
# These are the options for the builder. It will accept any options
# provided to it but some options are mandatory:
options.vim.languages.tex.build.builders.${name} = ({
# The enable option. This one is self explanatory.
enable,
# This is the package option for the builder.
package,
# This is the executable that will be used to call the builder.
# It, along with package will result in:
# "<package_path>/bin/<executable>"
executable,
# Any other options provided are accepted.
...
} @ opts:
opts)
options;
# Check that the language and this builder have been enabled
# before making any config.
config = mkIf (cfg.enable && cfg.build.builders.${name}.enable) {
vim.languages.tex.build.builder = {
inherit name;
package = cfg.build.builders.${name}.package;
executable = cfg.build.builders.${name}.executable;
args = args cfg.build.builders.${name};
};
};
}

View file

@ -6,7 +6,8 @@
}: let
inherit (lib.options) mkOption;
inherit (lib.modules) mkIf;
inherit (lib.types) bool listOf package str ;
inherit (lib.types) bool listOf package str;
inherit (lib) mkDefault;
cfg = config.vim.languages.tex;
@ -56,10 +57,10 @@ in {
config = mkIf (cfg.enable && cfg.build.builders.custom.enable) {
vim.languages.tex.build.builder = {
name = "custom";
args = collateArgs cfg.build;
package = cfg.build.builders.custom.package;
executable = cfg.build.builders.custom.executable;
name = mkDefault "custom";
args = mkDefault (collateArgs cfg.build);
package = mkDefault (cfg.build.builders.custom.package);
executable = mkDefault (cfg.build.builders.custom.executable);
};
};
}

View file

@ -1,5 +1,6 @@
{
config,
pkgs,
lib,
...
}:
@ -12,30 +13,57 @@ let
in
{
imports = [
./custom.nix
# ./custom.nix
./tectonic.nix
];
options.vim.languages.tex.build.builder = {
name = mkOption {
type = enum (attrNames cfg.build.builders);
default = "tectonic";
description = "The tex builder to use";
default = "latexmk";
description = ''
The tex builder to use.
This is just the default custom option. By setting any of the
builders to true, this will be overwritten by that builder's
parameters.
'';
};
args = mkOption {
type = listOf str;
default = [];
description = "The list of args to pass to the builder";
default = [
"-pdf"
"%f"
];
description = ''
The list of args to pass to the builder.
This is just the default custom option. By setting any of the
builders to true, this will be overwritten by that builder's
parameters.
'';
};
package = mkOption {
type = package;
default = cfg.build.builders.tectonic.package;
description = "The tex builder package to use";
default = (pkgs.texlive.withPackages (ps: [ ps.latexmk ]));
description = ''
The tex builder package to use.
This is just the default custom option. By setting any of the
builders to true, this will be overwritten by that builder's
parameters.
'';
};
executable = mkOption {
type = str;
default = cfg.build.builders.tectonic.executable;
description = "The tex builder executable to use";
default = "latexmk";
description = ''
The tex builder executable to use.
This is just the default custom option. By setting any of the
builders to true, this will be overwritten by that builder's
parameters.
'';
};
};
}

View file

@ -3,18 +3,15 @@
pkgs,
lib,
...
}: let
} @ moduleInheritencePackage: let
# The name of the builder
name = "tectonic";
# The builder template
template = import ./builderTemplate.nix;
inherit (lib.options) mkOption mkEnableOption;
inherit (lib.modules) mkIf;
inherit
(lib.types)
bool
enum
ints
listOf
package
str
;
inherit (lib.types) bool enum ints listOf package str;
inherit (builtins) concatLists elem map toString;
cfg = config.vim.languages.tex;
@ -26,192 +23,184 @@
example = !default;
description = description;
});
in (
template {
inherit name moduleInheritencePackage;
# --- Arg Collation Functions --
collateArgs = buildConfig: let
selfConfig = buildConfig.builders.tectonic;
in (
# Base args
[
"-X"
"compile"
"%f"
]
# Flags
++ (
if selfConfig.keepIntermediates
then ["--keep-intermediates"]
else []
)
++ (
if selfConfig.keepLogs
then ["--keep-logs"]
else []
)
++ (
if selfConfig.onlyCached
then ["--only-cached"]
else []
)
++ (
if selfConfig.synctex
then ["--synctex"]
else []
)
++ (
if selfConfig.untrustedInput
then ["--untrusted"]
else []
)
# Options
++ (
if selfConfig.reruns > 0
then ["--reruns" "${toString selfConfig.reruns}"]
else []
)
++ (
if selfConfig.bundle != ""
then ["--bundle" "${toString selfConfig.bundle}"]
else []
)
++ (
if selfConfig.webBundle != ""
then ["--web-bundle" "${toString selfConfig.webBundle}"]
else []
)
++ (
if selfConfig.outfmt != ""
then ["--outfmt" "${toString selfConfig.outfmt}"]
else []
)
++ (concatLists (map (x: ["--hide" x]) selfConfig.hidePaths))
++ (
if selfConfig.format != ""
then ["--format" "${toString selfConfig.format}"]
else []
)
++ (
if selfConfig.color != ""
then ["--color" "${toString selfConfig.color}"]
else []
)
# Still options but these are not defined by builder specific options but
# instead synchronize options between the global build options and builder
# specific options
++ (
if !(elem buildConfig.pdfDirectory ["." ""])
then ["--outdir" "${buildConfig.pdfDirectory}"]
else []
)
);
in {
options.vim.languages.tex.build.builders.tectonic = {
enable = mkEnableOption "Whether to enable Tex Compilation Via Tectonic";
options = {
enable = mkEnableOption "Whether to enable Tex Compilation Via Tectonic";
package = mkOption {
type = package;
default = pkgs.tectonic;
description = "tectonic package";
};
package = mkOption {
type = package;
default = pkgs.tectonic;
description = "tectonic package";
};
executable = mkOption {
type = str;
default = "tectonic";
description = "The executable name from the build package that will be used to build/compile the tex.";
};
executable = mkOption {
type = str;
default = "tectonic";
description = "The executable name from the build package that will be used to build/compile the tex.";
};
# -- Flags --
keepIntermediates = mkEnableDefaultOption false ''
Keep the intermediate files generated during processing.
# -- Flags --
keepIntermediates = mkEnableDefaultOption false ''
Keep the intermediate files generated during processing.
If texlab is reporting build errors when there shouldn't be, disable this option.
'';
keepLogs = mkEnableDefaultOption true ''
Keep the log files generated during processing.
Without the keepLogs flag, texlab won't be able to report compilation warnings.
'';
onlyCached = mkEnableDefaultOption false "Use only resource files cached locally";
synctex = mkEnableDefaultOption true "Generate SyncTeX data";
untrustedInput = mkEnableDefaultOption false "Input is untrusted -- disable all known-insecure features";
# -- Options --
reruns = mkOption {
type = ints.unsigned;
default = 0;
example = 2;
description = "Rerun the TeX engine exactly this many times after the first";
};
bundle = mkOption {
type = str;
default = "";
description = "Use this directory or Zip-format bundle file to find resource files instead of the default";
};
webBundle = mkOption {
type = str;
default = "";
description = "Use this URL to find resource files instead of the default";
};
outfmt = mkOption {
type = enum [
"pdf"
"html"
"xdv"
"aux"
"fmt"
""
];
default = "";
description = "The kind of output to generate";
};
hidePaths = mkOption {
type = listOf str;
default = [];
example = [
"./secrets.tex"
"./passwords.tex"
];
description = "Tell the engine that no file at <hide_path> exists, if it tries to read it.";
};
format = mkOption {
type = str;
default = "";
description = "The name of the \"format\" file used to initialize the TeX engine";
};
color = mkOption {
type = enum [
"always"
"auto"
"never"
""
];
default = "";
example = "always";
description = "Enable/disable colorful log output";
};
extraOptions = {
type = listOf str;
default = [];
description = ''
Add extra command line options to include in the tectonic build command.
Extra options added here will not overwrite the options set in as nvf options.
If texlab is reporting build errors when there shouldn't be, disable this option.
'';
};
};
keepLogs = mkEnableDefaultOption true ''
Keep the log files generated during processing.
config = mkIf (cfg.enable && cfg.build.builders.tectonic.enable) {
vim.languages.tex.build.builder = {
name = "tectonic";
args = collateArgs cfg.build;
package = cfg.build.builders.tectonic.package;
executable = cfg.build.builders.tectonic.executable;
Without the keepLogs flag, texlab won't be able to report compilation warnings.
'';
onlyCached = mkEnableDefaultOption false "Use only resource files cached locally";
synctex = mkEnableDefaultOption true "Generate SyncTeX data";
untrustedInput = mkEnableDefaultOption false "Input is untrusted -- disable all known-insecure features";
# -- Options --
reruns = mkOption {
type = ints.unsigned;
default = 0;
example = 2;
description = "Rerun the TeX engine exactly this many times after the first";
};
bundle = mkOption {
type = str;
default = "";
description = "Use this directory or Zip-format bundle file to find resource files instead of the default";
};
webBundle = mkOption {
type = str;
default = "";
description = "Use this URL to find resource files instead of the default";
};
outfmt = mkOption {
type = enum [
"pdf"
"html"
"xdv"
"aux"
"fmt"
""
];
default = "";
description = "The kind of output to generate";
};
hidePaths = mkOption {
type = listOf str;
default = [];
example = [
"./secrets.tex"
"./passwords.tex"
];
description = "Tell the engine that no file at <hide_path> exists, if it tries to read it.";
};
format = mkOption {
type = str;
default = "";
description = "The name of the \"format\" file used to initialize the TeX engine";
};
color = mkOption {
type = enum [
"always"
"auto"
"never"
""
];
default = "";
example = "always";
description = "Enable/disable colorful log output";
};
extraOptions = {
type = listOf str;
default = [];
description = ''
Add extra command line options to include in the tectonic build command.
Extra options added here will not overwrite the options set in as nvf options.
'';
};
};
};
}
args = builderCfg: (
# Base args
[
"-X"
"compile"
"%f"
]
# Flags
++ (
if builderCfg.keepIntermediates
then ["--keep-intermediates"]
else []
)
++ (
if builderCfg.keepLogs
then ["--keep-logs"]
else []
)
++ (
if builderCfg.onlyCached
then ["--only-cached"]
else []
)
++ (
if builderCfg.synctex
then ["--synctex"]
else []
)
++ (
if builderCfg.untrustedInput
then ["--untrusted"]
else []
)
# Options
++ (
if builderCfg.reruns > 0
then ["--reruns" "${toString builderCfg.reruns}"]
else []
)
++ (
if builderCfg.bundle != ""
then ["--bundle" "${toString builderCfg.bundle}"]
else []
)
++ (
if builderCfg.webBundle != ""
then ["--web-bundle" "${toString builderCfg.webBundle}"]
else []
)
++ (
if builderCfg.outfmt != ""
then ["--outfmt" "${toString builderCfg.outfmt}"]
else []
)
++ (concatLists (map (x: ["--hide" x]) builderCfg.hidePaths))
++ (
if builderCfg.format != ""
then ["--format" "${toString builderCfg.format}"]
else []
)
++ (
if builderCfg.color != ""
then ["--color" "${toString builderCfg.color}"]
else []
)
# Still options but these are not defined by builder specific options but
# instead synchronize options between the global build options and builder
# specific options
++ (
if !(elem cfg.build.pdfDirectory ["." ""])
then ["--outdir" "${cfg.build.pdfDirectory}"]
else []
)
);
}
)

View file

@ -0,0 +1,217 @@
{
config,
pkgs,
lib,
...
}: let
inherit (lib.options) mkOption mkEnableOption;
inherit (lib.modules) mkIf;
inherit
(lib.types)
bool
enum
ints
listOf
package
str
;
inherit (builtins) concatLists elem map toString;
cfg = config.vim.languages.tex;
# --- Enable Options ---
mkEnableDefaultOption = default: description: (mkOption {
type = bool;
default = default;
example = !default;
description = description;
});
# --- Arg Collation Functions --
collateArgs = buildConfig: let
selfConfig = buildConfig.builders.tectonic;
in (
# Base args
[
"-X"
"compile"
"%f"
]
# Flags
++ (
if selfConfig.keepIntermediates
then ["--keep-intermediates"]
else []
)
++ (
if selfConfig.keepLogs
then ["--keep-logs"]
else []
)
++ (
if selfConfig.onlyCached
then ["--only-cached"]
else []
)
++ (
if selfConfig.synctex
then ["--synctex"]
else []
)
++ (
if selfConfig.untrustedInput
then ["--untrusted"]
else []
)
# Options
++ (
if selfConfig.reruns > 0
then ["--reruns" "${toString selfConfig.reruns}"]
else []
)
++ (
if selfConfig.bundle != ""
then ["--bundle" "${toString selfConfig.bundle}"]
else []
)
++ (
if selfConfig.webBundle != ""
then ["--web-bundle" "${toString selfConfig.webBundle}"]
else []
)
++ (
if selfConfig.outfmt != ""
then ["--outfmt" "${toString selfConfig.outfmt}"]
else []
)
++ (concatLists (map (x: ["--hide" x]) selfConfig.hidePaths))
++ (
if selfConfig.format != ""
then ["--format" "${toString selfConfig.format}"]
else []
)
++ (
if selfConfig.color != ""
then ["--color" "${toString selfConfig.color}"]
else []
)
# Still options but these are not defined by builder specific options but
# instead synchronize options between the global build options and builder
# specific options
++ (
if !(elem buildConfig.pdfDirectory ["." ""])
then ["--outdir" "${buildConfig.pdfDirectory}"]
else []
)
);
in {
options.vim.languages.tex.build.builders.tectonic = {
enable = mkEnableOption "Whether to enable Tex Compilation Via Tectonic";
package = mkOption {
type = package;
default = pkgs.tectonic;
description = "tectonic package";
};
executable = mkOption {
type = str;
default = "tectonic";
description = "The executable name from the build package that will be used to build/compile the tex.";
};
# -- Flags --
keepIntermediates = mkEnableDefaultOption false ''
Keep the intermediate files generated during processing.
If texlab is reporting build errors when there shouldn't be, disable this option.
'';
keepLogs = mkEnableDefaultOption true ''
Keep the log files generated during processing.
Without the keepLogs flag, texlab won't be able to report compilation warnings.
'';
onlyCached = mkEnableDefaultOption false "Use only resource files cached locally";
synctex = mkEnableDefaultOption true "Generate SyncTeX data";
untrustedInput = mkEnableDefaultOption false "Input is untrusted -- disable all known-insecure features";
# -- Options --
reruns = mkOption {
type = ints.unsigned;
default = 0;
example = 2;
description = "Rerun the TeX engine exactly this many times after the first";
};
bundle = mkOption {
type = str;
default = "";
description = "Use this directory or Zip-format bundle file to find resource files instead of the default";
};
webBundle = mkOption {
type = str;
default = "";
description = "Use this URL to find resource files instead of the default";
};
outfmt = mkOption {
type = enum [
"pdf"
"html"
"xdv"
"aux"
"fmt"
""
];
default = "";
description = "The kind of output to generate";
};
hidePaths = mkOption {
type = listOf str;
default = [];
example = [
"./secrets.tex"
"./passwords.tex"
];
description = "Tell the engine that no file at <hide_path> exists, if it tries to read it.";
};
format = mkOption {
type = str;
default = "";
description = "The name of the \"format\" file used to initialize the TeX engine";
};
color = mkOption {
type = enum [
"always"
"auto"
"never"
""
];
default = "";
example = "always";
description = "Enable/disable colorful log output";
};
extraOptions = {
type = listOf str;
default = [];
description = ''
Add extra command line options to include in the tectonic build command.
Extra options added here will not overwrite the options set in as nvf options.
'';
};
};
config = mkIf (cfg.enable && cfg.build.builders.tectonic.enable) {
vim.languages.tex.build.builder = {
name = "tectonic";
args = collateArgs cfg.build;
package = cfg.build.builders.tectonic.package;
executable = cfg.build.builders.tectonic.executable;
};
};
}