diff --git a/modules/plugins/formatter/conform-nvim/builders/builderTemplate.nix b/modules/plugins/formatter/conform-nvim/builders/builderTemplate.nix new file mode 100644 index 00000000..02d20412 --- /dev/null +++ b/modules/plugins/formatter/conform-nvim/builders/builderTemplate.nix @@ -0,0 +1,66 @@ +# 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 .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. + moduleInheritancePackage, + # + # 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 (moduleInheritancePackage) 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: + # "/bin/" + 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}; + }; + }; +} diff --git a/modules/plugins/formatter/conform-nvim/builders/default.nix b/modules/plugins/formatter/conform-nvim/builders/default.nix new file mode 100644 index 00000000..4586b768 --- /dev/null +++ b/modules/plugins/formatter/conform-nvim/builders/default.nix @@ -0,0 +1,70 @@ +{ + config, + pkgs, + lib, + ... +}: let + inherit (lib.options) mkOption; + inherit (lib.types) enum listOf package str; + inherit (lib.nvim.config) mkBool; + inherit (builtins) attrNames filter isAttrs hasAttr elemAt length; + + cfg = config.vim.languages.tex; +in { + imports = [ + ./latexmk.nix + ./tectonic.nix + ]; + + options.vim.languages.tex.build.builder = { + name = mkOption { + type = enum (attrNames cfg.build.builders); + 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. + Setting this parameter to the name of a declared builder will + not automatically enable that builder. + ''; + }; + args = mkOption { + type = listOf str; + 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 = 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 = "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. + ''; + }; + }; +} diff --git a/modules/plugins/formatter/conform-nvim/builders/latexmk.nix b/modules/plugins/formatter/conform-nvim/builders/latexmk.nix new file mode 100644 index 00000000..4d024eb3 --- /dev/null +++ b/modules/plugins/formatter/conform-nvim/builders/latexmk.nix @@ -0,0 +1,57 @@ +# TODO: I need testing. +{ + pkgs, + lib, + ... +} @ moduleInheritancePackage: let + # The name of the builder + name = "latexmk"; + + # The builder template + template = import ./builderTemplate.nix; + + inherit (lib.options) mkOption mkEnableOption; + inherit (lib.types) bool package str; +in ( + template { + inherit name moduleInheritancePackage; + + options = { + enable = mkEnableOption "Whether to enable Tex Compilation Via latexmk"; + + package = mkOption { + type = package; + default = pkgs.texlive.withPackages (ps: [ps.latexmk]); + description = "latexmk package"; + }; + + executable = mkOption { + type = str; + default = "latexmk"; + description = "The executable name from the build package that will be used to build/compile the tex."; + }; + + # Flag options + pdfOutput = mkOption { + type = bool; + default = true; + example = false; + description = "Insure the output file is a pdf."; + }; + }; + + args = builderCfg: ( + # Flags + ( + if builderCfg.pdfOutput + then ["-pdf"] + else [] + ) + # Base args + ++ [ + "-quiet" + "%f" + ] + ); + } +) diff --git a/modules/plugins/formatter/conform-nvim/builders/tectonic.nix b/modules/plugins/formatter/conform-nvim/builders/tectonic.nix new file mode 100644 index 00000000..1b131b33 --- /dev/null +++ b/modules/plugins/formatter/conform-nvim/builders/tectonic.nix @@ -0,0 +1,203 @@ +{ + config, + pkgs, + lib, + ... +} @ moduleInheritancePackage: let + # The name of the builder + name = "tectonic"; + + # The builder template + template = import ./builderTemplate.nix; + + inherit (lib.options) mkOption mkEnableOption; + inherit (lib.types) enum ints listOf package str; + inherit (lib.nvim.config) mkBool; + inherit (builtins) concatLists elem map toString; + + cfg = config.vim.languages.tex; +in ( + template { + inherit name moduleInheritancePackage; + + options = { + 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 = mkBool false '' + Keep the intermediate files generated during processing. + + If texlab is reporting build errors when there shouldn't be, disable this option. + ''; + keepLogs = mkBool true '' + Keep the log files generated during processing. + + Without the keepLogs flag, texlab won't be able to report compilation warnings. + ''; + onlyCached = mkBool false "Use only resource files cached locally"; + synctex = mkBool true "Generate SyncTeX data"; + untrustedInput = mkBool 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. + + Setting this value to 0 will disable setting this option. + ''; + }; + + 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 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 [] + ) + ); + } +)