From 2cb43216d3c2cbc6f40e0d6646abb9f31a1c40f7 Mon Sep 17 00:00:00 2001 From: "quentin@aristote.fr" Date: Sat, 26 Aug 2023 23:28:27 +0200 Subject: devenv: add more modules --- modules/devenv/default.nix | 2 +- modules/devenv/dotfiles.nix | 56 +++++++++++++ modules/devenv/integrations/default.nix | 3 + modules/devenv/integrations/emacs.nix | 53 +++++++++++++ modules/devenv/integrations/gitignore.nix | 25 ++++++ modules/devenv/languages/default.nix | 2 +- modules/devenv/languages/latex.nix | 127 ++++++++++++++++++++++++++++++ 7 files changed, 266 insertions(+), 2 deletions(-) create mode 100644 modules/devenv/dotfiles.nix create mode 100644 modules/devenv/integrations/default.nix create mode 100644 modules/devenv/integrations/emacs.nix create mode 100644 modules/devenv/integrations/gitignore.nix create mode 100644 modules/devenv/languages/latex.nix diff --git a/modules/devenv/default.nix b/modules/devenv/default.nix index 273b94f..8aedcf6 100644 --- a/modules/devenv/default.nix +++ b/modules/devenv/default.nix @@ -1,3 +1,3 @@ { - imports = [ ./languages ]; + imports = [./dotfiles.nix ./integrations ./languages]; } diff --git a/modules/devenv/dotfiles.nix b/modules/devenv/dotfiles.nix new file mode 100644 index 0000000..8b8d95b --- /dev/null +++ b/modules/devenv/dotfiles.nix @@ -0,0 +1,56 @@ +{ + config, + lib, + ... +}: let + cfg = config.dotfiles; + dotfilesToIgnore = lib.attrNames (lib.filterAttrs (_: {gitignore, ...}: gitignore) cfg); +in { + options.dotfiles = lib.mkOption { + type = with lib.types; + # this cannot be a lazyAttrsOf, see https://nixos.org/manual/nixos/unstable/#sec-option-types-composed + attrsOf (submodule { + options = { + gitignore = + lib.mkEnableOption "" + // { + default = true; + description = "Whether git should ignore this dotfile, typically if it is generated to contain absolute paths."; + }; + text = lib.mkOption { + type = lib.types.lines; + default = ""; + description = "The content of the dotfile."; + }; + }; + }); + }; + + config.enterShell = + lib.mkIf (cfg != {}) + ('' + echo Installing dotfiles... + '' + + lib.concatStringsSep "\n" (lib.mapAttrsToList ( + name: { + text, + gitignore, + }: + # this has to be done here to avoid infinite recursion + let + content = + text + + lib.optionalString (name == ".gitignore") '' + # dotfiles + ${lib.concatStringsSep "\n" dotfilesToIgnore} + ''; + in '' + ${ + if gitignore + then "ln -s" + else "cp" + } "${builtins.toFile name content}" "${name}" + '' + ) + cfg)); +} diff --git a/modules/devenv/integrations/default.nix b/modules/devenv/integrations/default.nix new file mode 100644 index 0000000..7fa74bd --- /dev/null +++ b/modules/devenv/integrations/default.nix @@ -0,0 +1,3 @@ +{ + imports = [./emacs.nix ./gitignore.nix]; +} diff --git a/modules/devenv/integrations/emacs.nix b/modules/devenv/integrations/emacs.nix new file mode 100644 index 0000000..b7f1e42 --- /dev/null +++ b/modules/devenv/integrations/emacs.nix @@ -0,0 +1,53 @@ +{ + config, + lib, + ... +}: let + cfg = config.emacs; + attrs2alist = value: + if lib.isAttrs value + then "(${lib.concatStringsSep "\n" (lib.mapAttrsToList (name: value: "(${name} . ${attrs2alist value})") value)})" + else + ( + if lib.isList value + then "(${lib.concatStringsSep " " value})" + else + ( + if lib.isBool value + then + ( + if value + then "t" + else "nil" + ) + else builtins.toString value + ) + ); +in { + options.emacs = { + enable = lib.mkEnableOption "emacs integration"; + dirLocals = lib.mkOption { + type = with lib.types; attrsOf (attrsOf str); + default = {}; + example = + # the first example from https://www.gnu.org/software/emacs/manual/html_node/emacs/Directory-Variables.html + { + nil = { + indent-tabs-mode = true; + fill-column = 80; + mode = "auto-fill"; + }; + c-mode = { + c-file-style = ''"BSD"''; + subdirs = "nil"; + }; + "\"src/imported\"".nil.change-log-default-name = ''"ChangeLog.local"''; + }; + }; + }; + + config.dotfiles.".dir-locals.el" = lib.mkIf (cfg.dirLocals != {}) { + gitignore = lib.mkDefault true; + text = attrs2alist cfg.dirLocals; + }; +} diff --git a/modules/devenv/integrations/gitignore.nix b/modules/devenv/integrations/gitignore.nix new file mode 100644 index 0000000..ed0e61a --- /dev/null +++ b/modules/devenv/integrations/gitignore.nix @@ -0,0 +1,25 @@ +{ + config, + lib, + ... +}: let + cfg = config.gitignore; +in { + options.gitignore = { + extra = lib.mkOption { + type = lib.types.lines; + default = ""; + example = '' + *.my-file-extension + ''; + }; + }; + + config.dotfiles.gitignore = lib.mkIf (cfg.extra != "") { + gitignore = lib.mkDefault false; + text = '' + ## Miscellaneous + ${cfg.extra}; + ''; + }; +} diff --git a/modules/devenv/languages/default.nix b/modules/devenv/languages/default.nix index 2f4fc86..a97402c 100644 --- a/modules/devenv/languages/default.nix +++ b/modules/devenv/languages/default.nix @@ -1,3 +1,3 @@ { - imports = [ ./nix.nix ]; + imports = [./latex.nix ./nix.nix]; } diff --git a/modules/devenv/languages/latex.nix b/modules/devenv/languages/latex.nix new file mode 100644 index 0000000..eece173 --- /dev/null +++ b/modules/devenv/languages/latex.nix @@ -0,0 +1,127 @@ +{ + config, + lib, + pkgs, + devenv, + ... +}: let + cfg = config.languages.texlive; + pdfModes = { + "pdflatex" = "1"; + "ps2pdf" = "2"; + "dvi2pdf" = "3"; + "lulatex" = "4"; + "xelatex" = "5"; + }; + dviModes = { + "latex" = "1"; + "lualatex" = "2"; + }; + latexmkrc = with latexmkrc; let + pdfMode = with output.pdf; + if enable + then pdfModes."${mode}" + else "0"; + dviMode = with output.dvi; + if enable + then dviModes."${mode}" + else "0"; + psMode = + if output.ps.enable + then "1" + else "0"; + in '' + set_tex_cmds('${extraFlags}'); + $pdf_mode=${pdfMode} + $dvi_mode=${dviMode} + $ps_mode=${psMode} + + ${extraConfig} + ''; + packages = cfg.packages cfg.base; + packagesRequireShellEscape = packages ? minted; + texlive = cfg.base.combine packages; +in { + disabledModules = ["${devenv}/src/modules/languages/texlive.nix"]; + + options.languages.texlive = { + enable = lib.mkEnableOption "TeX Live"; + base = lib.mkPackageOption pkgs "TeX Live" { + default = ["texlive"]; + }; + packages = lib.mkOption { + type = with lib.types; + functionTo (attrsOf (submodule { + pkgs = lib.mkOption { + type = listOf package; + }; + })); + default = tl: {inherit (tl) scheme-medium;}; + description = "Packages available to TeX Live."; + }; + + latexmk = { + enable = lib.mkEnableOption "latexmk"; + shellEscape.enable = lib.mkEnableOption "shell escaping"; + extraFlags = lib.mkOption { + type = with lib.types; listOf str; + default = []; + example = ["--interaction=nonstopmode"]; + }; + output = let + mkOutputOptions = formats: + lib.mapAttrs (format: extra: + lib.recursiveUpdate { + enable = lib.mkEnableOption "${format} output"; + } + extra) + formats; + in + mkOutputOptions { + pdf = { + enable.default = true; + mode = lib.mkOption { + type = lib.types.enum (lib.attrNames pdfModes); + default = "lualatex"; + description = "How to generate the pdf file."; + }; + }; + dvi = { + mode = lib.mkOption { + type = lib.types.enum (lib.attrNames dviModes); + default = "latex"; + description = "How to generate the dvi file."; + }; + }; + ps = {}; + }; + extraConfig = lib.mkOption { + type = lib.types.lines; + default = ""; + description = "Extra configuration to put inside the RC file."; + }; + }; + }; + + config = lib.mkMerge [ + { + languages.texlive = { + latexmk = { + shellEscape.enable = lib.mkIf (lib.mkDefault packagesRequireShellEscape true); + extraFlags = lib.optional cfg.latexmkrc.shellEscape.enable "-shell-escape"; + }; + packages = tl: lib.optionalAttrs cfg.latexmk.enable {inherit (tl) latexmk;}; + }; + packages = lib.optional cfg.enable texlive; + } + (lib.mkIf cfg.latexmk.enable { + scripts.latexmk.exec = '' + ${texlive}/bin/latexmk -r ${devenv.root}/.latexmkrc + ''; + dotfiles.".latexmkrc" = { + gitignore = lib.mkDefault false; + text = latexmkrc; + }; + }) + ]; +} -- cgit v1.2.3