From 9357bde934d07236237df850aeebd58f7a54ce79 Mon Sep 17 00:00:00 2001 From: isaacST08 Date: Thu, 23 Jan 2025 15:37:45 -0700 Subject: [PATCH 1/6] Added texlab tectonic options --- modules/plugins/languages/tex.nix | 346 ++++++++++++++++++++++++++---- 1 file changed, 303 insertions(+), 43 deletions(-) diff --git a/modules/plugins/languages/tex.nix b/modules/plugins/languages/tex.nix index 6fb6e845..e39a4be3 100644 --- a/modules/plugins/languages/tex.nix +++ b/modules/plugins/languages/tex.nix @@ -22,7 +22,11 @@ inherit (lib.types) bool + either + enum + ints listOf + oneOf package str ; @@ -30,14 +34,113 @@ inherit (builtins) any + attrNames attrValues + concatLists concatStringsSep + elem + elemAt + filter + hasAttr + isAttrs length map + throw toString ; cfg = config.vim.languages.tex; + + # --- Enable Options --- + mkEnableDefaultOption = default: description: (mkOption { + type = bool; + default = default; + example = !default; + description = description; + }); + mkEnableTreesitterOption = mkEnableDefaultOption config.vim.languages.enableTreesitter; + mkEnableLspOption = mkEnableDefaultOption config.vim.languages.enableLSP; + + # --- Arg Collation Functions -- + collateArgs.lsp.texlab.build = { + tectonic = buildConfig: let + selfConfig = buildConfig.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 [] + ) + ); + custom = buildConfig: buildConfig.custom.args; + }; in { options.vim.languages.tex = { enable = mkEnableOption "Tex support"; @@ -45,11 +148,11 @@ in { # Treesitter options for latex and bibtex flavours of tex. treesitter = { latex = { - enable = mkEnableOption "Latex treesitter" // { default = config.vim.languages.enableTreesitter; }; + enable = mkEnableTreesitterOption "Whether to enable Latex treesitter"; package = mkGrammarOption pkgs "latex"; }; bibtex = { - enable = mkEnableOption "Bibtex treesitter" // { default = config.vim.languages.enableTreesitter; }; + enable = mkEnableTreesitterOption "Whether to enable Bibtex treesitter"; package = mkGrammarOption pkgs "bibtex"; }; }; @@ -62,7 +165,7 @@ in { # Each lsp group must have an enable option of its own. lsp = { texlab = { - enable = mkEnableOption "Tex LSP support (texlab)" // { default = config.vim.languages.enableLSP; }; + enable = mkEnableLspOption "Whether to enable Tex LSP support (texlab)"; package = mkOption { type = package; @@ -71,36 +174,141 @@ in { }; build = { - package = mkOption { - type = package; - default = pkgs.tectonic; - description = "build/compiler package"; - }; - executable = mkOption { - type = str; - default = "tectonic"; - description = "The executable name from the build package that will be used to build/compile the tex."; - }; - args = mkOption { - type = listOf str; - default = [ - "-X" - "compile" - "%f" - "--synctex" - "--keep-logs" - "--keep-intermediates" - ]; - description = '' - Defines additional arguments that are passed to the configured LaTeX build tool. - Note that flags and their arguments need to be separate elements in this array. - To pass the arguments -foo bar to a build tool, args needs to be ["-foo" "bar"]. - The placeholder `%f` will be replaced by the server. + tectonic = { + enable = mkEnableDefaultOption true "Whether to enable Tex Compilation Via Tectonic"; - Placeholders: - - `%f`: The path of the TeX file to compile. + 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 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. + ''; + }; }; + + custom = { + enable = mkEnableDefaultOption false "Whether to enable using a custom build package"; + package = mkOption { + type = package; + default = pkgs.tectonic; + description = "build/compiler package"; + }; + executable = mkOption { + type = str; + default = "tectonic"; + description = "The executable name from the build package that will be used to build/compile the tex."; + }; + args = mkOption { + type = listOf str; + default = [ + "-X" + "compile" + "%f" + "--synctex" + "--keep-logs" + "--keep-intermediates" + ]; + description = '' + Defines additional arguments that are passed to the configured LaTeX build tool. + Note that flags and their arguments need to be separate elements in this array. + To pass the arguments -foo bar to a build tool, args needs to be ["-foo" "bar"]. + The placeholder `%f` will be replaced by the server. + + Placeholders: + - `%f`: The path of the TeX file to compile. + ''; + }; + }; + forwardSearchAfter = mkOption { type = bool; default = false; @@ -289,9 +497,11 @@ in { # LSP (mkIf (any (x: x.enable) (attrValues cfg.lsp)) ( - { vim.lsp.lspconfig.enable = true; } # Enable lspconfig when any of the lsps are enabled + { + vim.lsp.lspconfig.enable = true; + } # Enable lspconfig when any of the lsps are enabled // (mkMerge [ - # Texlab + # ----- Texlab ----- ( let tl = cfg.lsp.texlab; @@ -318,23 +528,73 @@ in { then "true" else "false"; + # -- Build -- + buildConfig = let + # This function will sort through the builder options of ...texlab.build and count how many + # builders have been enabled and get the attrs of the last enabled builder. + getBuilder = { + enabledBuildersCount ? 0, + enabledBuilderName ? "", + index ? 0, + builderNamesList ? ( + filter ( + x: let + y = tl.build.${x}; + in (isAttrs y && hasAttr "enable" y) + ) (attrNames tl.build) + ), + }: let + currentBuilderName = elemAt builderNamesList index; + currentBuilder = tl.build.${currentBuilderName}; + nextIndex = index + 1; + currentState = { + enabledBuildersCount = + if currentBuilder.enable + then enabledBuildersCount + 1 + else enabledBuildersCount; + enabledBuilderName = + if currentBuilder.enable + then currentBuilderName + else enabledBuilderName; + }; + in + if length builderNamesList > nextIndex + then + getBuilder ({ + inherit builderNamesList; + index = nextIndex; + } + // currentState) + else currentState; + + getBuilderResults = getBuilder {}; + builder = tl.build.${getBuilderResults.enabledBuilderName}; + builderArgs = collateArgs.lsp.texlab.build.${getBuilderResults.enabledBuilderName} tl.build; + in + if getBuilderResults.enabledBuildersCount == 0 + then "" + else if getBuilderResults.enabledBuildersCount > 1 + then throw "Texlab does not support having more than 1 builders enabled!" + else '' + build = { + executable = "${builder.package}/bin/${builder.executable}", + args = ${listToLua builderArgs false}, + forwardSearchAfter = ${boolToLua build.forwardSearchAfter}, + onSave = ${boolToLua build.onSave}, + useFileList = ${boolToLua build.useFileList}, + auxDirectory = ${stringToLua build.auxDirectory true}, + logDirectory = ${stringToLua build.logDirectory true}, + pdfDirectory = ${stringToLua build.pdfDirectory true}, + filename = ${stringToLua build.filename true}, + }, + ''; in (mkIf tl.enable { vim.lsp.lspconfig.sources.texlab = '' lspconfig.texlab.setup { cmd = { "${tl.package}/bin/texlab" }, settings = { texlab = { - build = { - executable = "${build.package}/bin/${build.executable}", - args = ${listToLua build.args false}, - forwardSearchAfter = ${boolToLua build.forwardSearchAfter}, - onSave = ${boolToLua build.onSave}, - useFileList = ${boolToLua build.useFileList}, - auxDirectory = ${stringToLua build.auxDirectory true}, - logDirectory = ${stringToLua build.logDirectory true}, - pdfDirectory = ${stringToLua build.pdfDirectory true}, - filename = ${stringToLua build.filename true}, - }, + ${buildConfig} forwardSearch = { executable = "${tl.forwardSearch.package}/bin/${tl.forwardSearch.executable}", args = ${listToLua tl.forwardSearch.args true} From 1f08c4eda7608b182512222dbacccf665595ef8a Mon Sep 17 00:00:00 2001 From: isaacST08 Date: Thu, 23 Jan 2025 16:08:31 -0700 Subject: [PATCH 2/6] Starting modularizing tex.nix into smaller sections --- modules/plugins/languages/default.nix | 2 +- .../languages/{tex.nix => tex/default.nix} | 45 ++++++++++--------- modules/plugins/languages/tex/treesitter.nix | 39 ++++++++++++++++ 3 files changed, 65 insertions(+), 21 deletions(-) rename modules/plugins/languages/{tex.nix => tex/default.nix} (96%) create mode 100644 modules/plugins/languages/tex/treesitter.nix diff --git a/modules/plugins/languages/default.nix b/modules/plugins/languages/default.nix index 4f717309..5313ccba 100644 --- a/modules/plugins/languages/default.nix +++ b/modules/plugins/languages/default.nix @@ -35,7 +35,7 @@ in { ./svelte.nix ./tailwind.nix ./terraform.nix - ./tex.nix + ./tex ./ts.nix ./typst.nix ./vala.nix diff --git a/modules/plugins/languages/tex.nix b/modules/plugins/languages/tex/default.nix similarity index 96% rename from modules/plugins/languages/tex.nix rename to modules/plugins/languages/tex/default.nix index e39a4be3..54811783 100644 --- a/modules/plugins/languages/tex.nix +++ b/modules/plugins/languages/tex/default.nix @@ -142,20 +142,25 @@ custom = buildConfig: buildConfig.custom.args; }; in { + + imports = [ + ./treesitter.nix + ]; + options.vim.languages.tex = { enable = mkEnableOption "Tex support"; - # Treesitter options for latex and bibtex flavours of tex. - treesitter = { - latex = { - enable = mkEnableTreesitterOption "Whether to enable Latex treesitter"; - package = mkGrammarOption pkgs "latex"; - }; - bibtex = { - enable = mkEnableTreesitterOption "Whether to enable Bibtex treesitter"; - package = mkGrammarOption pkgs "bibtex"; - }; - }; + # # Treesitter options for latex and bibtex flavours of tex. + # treesitter = { + # latex = { + # enable = mkEnableTreesitterOption "Whether to enable Latex treesitter"; + # package = mkGrammarOption pkgs "latex"; + # }; + # bibtex = { + # enable = mkEnableTreesitterOption "Whether to enable Bibtex treesitter"; + # package = mkGrammarOption pkgs "bibtex"; + # }; + # }; # LSP options # Because tex LSPs also including building/compiling tex, they have @@ -485,15 +490,15 @@ in { }; config = mkIf cfg.enable (mkMerge [ - # Treesitter - (mkIf cfg.treesitter.latex.enable { - vim.treesitter.enable = true; - vim.treesitter.grammars = [cfg.treesitter.latex.package]; - }) - (mkIf cfg.treesitter.bibtex.enable { - vim.treesitter.enable = true; - vim.treesitter.grammars = [cfg.treesitter.bibtex.package]; - }) + # # Treesitter + # (mkIf cfg.treesitter.latex.enable { + # vim.treesitter.enable = true; + # vim.treesitter.grammars = [cfg.treesitter.latex.package]; + # }) + # (mkIf cfg.treesitter.bibtex.enable { + # vim.treesitter.enable = true; + # vim.treesitter.grammars = [cfg.treesitter.bibtex.package]; + # }) # LSP (mkIf (any (x: x.enable) (attrValues cfg.lsp)) ( diff --git a/modules/plugins/languages/tex/treesitter.nix b/modules/plugins/languages/tex/treesitter.nix new file mode 100644 index 00000000..3b70165e --- /dev/null +++ b/modules/plugins/languages/tex/treesitter.nix @@ -0,0 +1,39 @@ +{ + config, + pkgs, + lib, + ... +}: +let + inherit (lib.options) mkEnableOption; + inherit (lib.modules) mkIf mkMerge; + inherit (lib.nvim.types) mkGrammarOption; + + cfg = config.vim.languages.tex; + + mkEnableTreesitterOption = + description: mkEnableOption description // { default = config.vim.languages.enableTreesitter; }; +in +{ + options.vim.languages.tex.treesitter = { + latex = { + enable = mkEnableTreesitterOption "Whether to enable Latex treesitter"; + package = mkGrammarOption pkgs "latex"; + }; + bibtex = { + enable = mkEnableTreesitterOption "Whether to enable Bibtex treesitter"; + package = mkGrammarOption pkgs "bibtex"; + }; + }; + + config = mkIf cfg.enable (mkMerge [ + (mkIf cfg.treesitter.latex.enable { + vim.treesitter.enable = true; + vim.treesitter.grammars = [ cfg.treesitter.latex.package ]; + }) + (mkIf cfg.treesitter.bibtex.enable { + vim.treesitter.enable = true; + vim.treesitter.grammars = [ cfg.treesitter.bibtex.package ]; + }) + ]); +} From c3291ab71c9052e55a8dd8e33f99bec4e5e3eaea Mon Sep 17 00:00:00 2001 From: isaacST08 Date: Thu, 23 Jan 2025 16:34:57 -0700 Subject: [PATCH 3/6] Moved lsp config into its own module --- modules/plugins/languages/tex/default.nix | 965 +++++++++--------- modules/plugins/languages/tex/lsp/default.nix | 528 ++++++++++ 2 files changed, 1011 insertions(+), 482 deletions(-) create mode 100644 modules/plugins/languages/tex/lsp/default.nix diff --git a/modules/plugins/languages/tex/default.nix b/modules/plugins/languages/tex/default.nix index 54811783..116403d1 100644 --- a/modules/plugins/languages/tex/default.nix +++ b/modules/plugins/languages/tex/default.nix @@ -52,99 +52,100 @@ cfg = config.vim.languages.tex; # --- Enable Options --- - mkEnableDefaultOption = default: description: (mkOption { - type = bool; - default = default; - example = !default; - description = description; - }); - mkEnableTreesitterOption = mkEnableDefaultOption config.vim.languages.enableTreesitter; - mkEnableLspOption = mkEnableDefaultOption config.vim.languages.enableLSP; + # mkEnableDefaultOption = default: description: (mkOption { + # type = bool; + # default = default; + # example = !default; + # description = description; + # }); + # mkEnableTreesitterOption = mkEnableDefaultOption config.vim.languages.enableTreesitter; + # mkEnableLspOption = mkEnableDefaultOption config.vim.languages.enableLSP; - # --- Arg Collation Functions -- - collateArgs.lsp.texlab.build = { - tectonic = buildConfig: let - selfConfig = buildConfig.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 [] - ) - ); - custom = buildConfig: buildConfig.custom.args; - }; + # # --- Arg Collation Functions -- + # collateArgs.lsp.texlab.build = { + # tectonic = buildConfig: let + # selfConfig = buildConfig.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 [] + # ) + # ); + # custom = buildConfig: buildConfig.custom.args; + # }; in { imports = [ ./treesitter.nix + ./lsp ]; options.vim.languages.tex = { @@ -168,286 +169,286 @@ in { # more sense to group one into its own group of options. # # Each lsp group must have an enable option of its own. - lsp = { - texlab = { - enable = mkEnableLspOption "Whether to enable Tex LSP support (texlab)"; - - package = mkOption { - type = package; - default = pkgs.texlab; - description = "texlab package"; - }; - - build = { - tectonic = { - enable = mkEnableDefaultOption true "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 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. - ''; - }; - }; - - custom = { - enable = mkEnableDefaultOption false "Whether to enable using a custom build package"; - package = mkOption { - type = package; - default = pkgs.tectonic; - description = "build/compiler package"; - }; - executable = mkOption { - type = str; - default = "tectonic"; - description = "The executable name from the build package that will be used to build/compile the tex."; - }; - args = mkOption { - type = listOf str; - default = [ - "-X" - "compile" - "%f" - "--synctex" - "--keep-logs" - "--keep-intermediates" - ]; - description = '' - Defines additional arguments that are passed to the configured LaTeX build tool. - Note that flags and their arguments need to be separate elements in this array. - To pass the arguments -foo bar to a build tool, args needs to be ["-foo" "bar"]. - The placeholder `%f` will be replaced by the server. - - Placeholders: - - `%f`: The path of the TeX file to compile. - ''; - }; - }; - - forwardSearchAfter = mkOption { - type = bool; - default = false; - description = "Set this property to true if you want to execute a forward search after a build."; - }; - onSave = mkOption { - type = bool; - default = false; - description = "Set this property to true if you want to compile the project after saving a file."; - }; - useFileList = mkOption { - type = bool; - default = false; - description = '' - When set to true, the server will use the .fls files produced by the TeX engine as an additional input for the project detection. - - Note that enabling this property might have an impact on performance. - ''; - }; - auxDirectory = mkOption { - type = str; - default = "."; - description = '' - When not using latexmk, provides a way to define the directory containing the .aux files. - Note that you need to set the aux directory in latex.build.args too. - - When using a latexmkrc file, texlab will automatically infer the correct setting. - ''; - }; - logDirectory = mkOption { - type = str; - default = "."; - description = '' - When not using latexmk, provides a way to define the directory containing the build log files. - Note that you need to change the output directory in your build arguments too. - - When using a latexmkrc file, texlab will automatically infer the correct setting. - ''; - }; - pdfDirectory = mkOption { - type = str; - default = "."; - description = '' - When not using latexmk, provides a way to define the directory containing the output files. - Note that you need to set the output directory in latex.build.args too. - - When using a latexmkrc file, texlab will automatically infer the correct setting. - ''; - }; - filename = mkOption { - type = str; - default = ""; - description = '' - Allows overriding the default file name of the build artifact. This setting is used to find the correct PDF file to open during forward search. - ''; - }; - }; - - forwardSearch = { - enable = mkOption { - type = bool; - default = false; - example = true; - description = '' - Whether to enable forward search. - - Enable this option if you want to have the compiled document appear in your chosen PDF viewer. - - For some options see [here](https://github.com/latex-lsp/texlab/wiki/Previewing). - Note this is not all the options, but can act as a guide to help you allong with custom configs. - ''; - }; - package = mkOption { - type = package; - default = pkgs.okular; - description = '' - The package to use as your PDF viewer. - This viewer needs to support Synctex. - ''; - }; - executable = mkOption { - type = str; - default = "okular"; - description = '' - Defines the executable of the PDF previewer. The previewer needs to support SyncTeX. - ''; - }; - args = mkOption { - type = listOf str; - default = [ - "--unique" - "file:%p#src:%l%f" - ]; - description = '' - Defines additional arguments that are passed to the configured previewer to perform the forward search. - The placeholders %f, %p, %l will be replaced by the server. - - Placeholders: - - %f: The path of the current TeX file. - - %p: The path of the current PDF file. - - %l: The current line number. - ''; - }; - }; - - extraLuaSettings = mkOption { - type = str; - default = ""; - example = '' - formatterLineLength = 80, - ''; - description = '' - For any options that do not have options provided through nvf this can be used to add them. - Options already declared in nvf config will NOT be overridden. - - Options will be placed in: - ``` - lspconfig.texlab.setup { - settings = { - texlab = { - ... - - ... - - } - } - } - ``` - ''; - }; - }; - - # Add other LSPs here - }; + # lsp = { + # texlab = { + # enable = mkEnableLspOption "Whether to enable Tex LSP support (texlab)"; + # + # package = mkOption { + # type = package; + # default = pkgs.texlab; + # description = "texlab package"; + # }; + # + # build = { + # tectonic = { + # enable = mkEnableDefaultOption true "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 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. + # ''; + # }; + # }; + # + # custom = { + # enable = mkEnableDefaultOption false "Whether to enable using a custom build package"; + # package = mkOption { + # type = package; + # default = pkgs.tectonic; + # description = "build/compiler package"; + # }; + # executable = mkOption { + # type = str; + # default = "tectonic"; + # description = "The executable name from the build package that will be used to build/compile the tex."; + # }; + # args = mkOption { + # type = listOf str; + # default = [ + # "-X" + # "compile" + # "%f" + # "--synctex" + # "--keep-logs" + # "--keep-intermediates" + # ]; + # description = '' + # Defines additional arguments that are passed to the configured LaTeX build tool. + # Note that flags and their arguments need to be separate elements in this array. + # To pass the arguments -foo bar to a build tool, args needs to be ["-foo" "bar"]. + # The placeholder `%f` will be replaced by the server. + # + # Placeholders: + # - `%f`: The path of the TeX file to compile. + # ''; + # }; + # }; + # + # forwardSearchAfter = mkOption { + # type = bool; + # default = false; + # description = "Set this property to true if you want to execute a forward search after a build."; + # }; + # onSave = mkOption { + # type = bool; + # default = false; + # description = "Set this property to true if you want to compile the project after saving a file."; + # }; + # useFileList = mkOption { + # type = bool; + # default = false; + # description = '' + # When set to true, the server will use the .fls files produced by the TeX engine as an additional input for the project detection. + # + # Note that enabling this property might have an impact on performance. + # ''; + # }; + # auxDirectory = mkOption { + # type = str; + # default = "."; + # description = '' + # When not using latexmk, provides a way to define the directory containing the .aux files. + # Note that you need to set the aux directory in latex.build.args too. + # + # When using a latexmkrc file, texlab will automatically infer the correct setting. + # ''; + # }; + # logDirectory = mkOption { + # type = str; + # default = "."; + # description = '' + # When not using latexmk, provides a way to define the directory containing the build log files. + # Note that you need to change the output directory in your build arguments too. + # + # When using a latexmkrc file, texlab will automatically infer the correct setting. + # ''; + # }; + # pdfDirectory = mkOption { + # type = str; + # default = "."; + # description = '' + # When not using latexmk, provides a way to define the directory containing the output files. + # Note that you need to set the output directory in latex.build.args too. + # + # When using a latexmkrc file, texlab will automatically infer the correct setting. + # ''; + # }; + # filename = mkOption { + # type = str; + # default = ""; + # description = '' + # Allows overriding the default file name of the build artifact. This setting is used to find the correct PDF file to open during forward search. + # ''; + # }; + # }; + # + # forwardSearch = { + # enable = mkOption { + # type = bool; + # default = false; + # example = true; + # description = '' + # Whether to enable forward search. + # + # Enable this option if you want to have the compiled document appear in your chosen PDF viewer. + # + # For some options see [here](https://github.com/latex-lsp/texlab/wiki/Previewing). + # Note this is not all the options, but can act as a guide to help you allong with custom configs. + # ''; + # }; + # package = mkOption { + # type = package; + # default = pkgs.okular; + # description = '' + # The package to use as your PDF viewer. + # This viewer needs to support Synctex. + # ''; + # }; + # executable = mkOption { + # type = str; + # default = "okular"; + # description = '' + # Defines the executable of the PDF previewer. The previewer needs to support SyncTeX. + # ''; + # }; + # args = mkOption { + # type = listOf str; + # default = [ + # "--unique" + # "file:%p#src:%l%f" + # ]; + # description = '' + # Defines additional arguments that are passed to the configured previewer to perform the forward search. + # The placeholders %f, %p, %l will be replaced by the server. + # + # Placeholders: + # - %f: The path of the current TeX file. + # - %p: The path of the current PDF file. + # - %l: The current line number. + # ''; + # }; + # }; + # + # extraLuaSettings = mkOption { + # type = str; + # default = ""; + # example = '' + # formatterLineLength = 80, + # ''; + # description = '' + # For any options that do not have options provided through nvf this can be used to add them. + # Options already declared in nvf config will NOT be overridden. + # + # Options will be placed in: + # ``` + # lspconfig.texlab.setup { + # settings = { + # texlab = { + # ... + # + # ... + # + # } + # } + # } + # ``` + # ''; + # }; + # }; + # + # # Add other LSPs here + # }; extraOpts = { texFlavor = { @@ -501,120 +502,120 @@ in { # }) # LSP - (mkIf (any (x: x.enable) (attrValues cfg.lsp)) ( - { - vim.lsp.lspconfig.enable = true; - } # Enable lspconfig when any of the lsps are enabled - // (mkMerge [ - # ----- Texlab ----- - ( - let - tl = cfg.lsp.texlab; - build = tl.build; - - listToLua = list: nullOnEmpty: - if length list == 0 - then - if nullOnEmpty - then "null" - else "{ }" - else "{ ${concatStringsSep ", " (map (x: ''"${toString x}"'') list)} }"; - - stringToLua = string: nullOnEmpty: - if string == "" - then - if nullOnEmpty - then "null" - else "" - else ''"${string}"''; - - boolToLua = boolean: - if boolean - then "true" - else "false"; - - # -- Build -- - buildConfig = let - # This function will sort through the builder options of ...texlab.build and count how many - # builders have been enabled and get the attrs of the last enabled builder. - getBuilder = { - enabledBuildersCount ? 0, - enabledBuilderName ? "", - index ? 0, - builderNamesList ? ( - filter ( - x: let - y = tl.build.${x}; - in (isAttrs y && hasAttr "enable" y) - ) (attrNames tl.build) - ), - }: let - currentBuilderName = elemAt builderNamesList index; - currentBuilder = tl.build.${currentBuilderName}; - nextIndex = index + 1; - currentState = { - enabledBuildersCount = - if currentBuilder.enable - then enabledBuildersCount + 1 - else enabledBuildersCount; - enabledBuilderName = - if currentBuilder.enable - then currentBuilderName - else enabledBuilderName; - }; - in - if length builderNamesList > nextIndex - then - getBuilder ({ - inherit builderNamesList; - index = nextIndex; - } - // currentState) - else currentState; - - getBuilderResults = getBuilder {}; - builder = tl.build.${getBuilderResults.enabledBuilderName}; - builderArgs = collateArgs.lsp.texlab.build.${getBuilderResults.enabledBuilderName} tl.build; - in - if getBuilderResults.enabledBuildersCount == 0 - then "" - else if getBuilderResults.enabledBuildersCount > 1 - then throw "Texlab does not support having more than 1 builders enabled!" - else '' - build = { - executable = "${builder.package}/bin/${builder.executable}", - args = ${listToLua builderArgs false}, - forwardSearchAfter = ${boolToLua build.forwardSearchAfter}, - onSave = ${boolToLua build.onSave}, - useFileList = ${boolToLua build.useFileList}, - auxDirectory = ${stringToLua build.auxDirectory true}, - logDirectory = ${stringToLua build.logDirectory true}, - pdfDirectory = ${stringToLua build.pdfDirectory true}, - filename = ${stringToLua build.filename true}, - }, - ''; - in (mkIf tl.enable { - vim.lsp.lspconfig.sources.texlab = '' - lspconfig.texlab.setup { - cmd = { "${tl.package}/bin/texlab" }, - settings = { - texlab = { - ${buildConfig} - forwardSearch = { - executable = "${tl.forwardSearch.package}/bin/${tl.forwardSearch.executable}", - args = ${listToLua tl.forwardSearch.args true} - }, - ${tl.extraLuaSettings} - } - } - } - ''; - }) - ) - - # Add other LSPs here - ]) - )) + # (mkIf (any (x: x.enable) (attrValues cfg.lsp)) ( + # { + # vim.lsp.lspconfig.enable = true; + # } # Enable lspconfig when any of the lsps are enabled + # // (mkMerge [ + # # ----- Texlab ----- + # ( + # let + # tl = cfg.lsp.texlab; + # build = tl.build; + # + # listToLua = list: nullOnEmpty: + # if length list == 0 + # then + # if nullOnEmpty + # then "null" + # else "{ }" + # else "{ ${concatStringsSep ", " (map (x: ''"${toString x}"'') list)} }"; + # + # stringToLua = string: nullOnEmpty: + # if string == "" + # then + # if nullOnEmpty + # then "null" + # else "" + # else ''"${string}"''; + # + # boolToLua = boolean: + # if boolean + # then "true" + # else "false"; + # + # # -- Build -- + # buildConfig = let + # # This function will sort through the builder options of ...texlab.build and count how many + # # builders have been enabled and get the attrs of the last enabled builder. + # getBuilder = { + # enabledBuildersCount ? 0, + # enabledBuilderName ? "", + # index ? 0, + # builderNamesList ? ( + # filter ( + # x: let + # y = tl.build.${x}; + # in (isAttrs y && hasAttr "enable" y) + # ) (attrNames tl.build) + # ), + # }: let + # currentBuilderName = elemAt builderNamesList index; + # currentBuilder = tl.build.${currentBuilderName}; + # nextIndex = index + 1; + # currentState = { + # enabledBuildersCount = + # if currentBuilder.enable + # then enabledBuildersCount + 1 + # else enabledBuildersCount; + # enabledBuilderName = + # if currentBuilder.enable + # then currentBuilderName + # else enabledBuilderName; + # }; + # in + # if length builderNamesList > nextIndex + # then + # getBuilder ({ + # inherit builderNamesList; + # index = nextIndex; + # } + # // currentState) + # else currentState; + # + # getBuilderResults = getBuilder {}; + # builder = tl.build.${getBuilderResults.enabledBuilderName}; + # builderArgs = collateArgs.lsp.texlab.build.${getBuilderResults.enabledBuilderName} tl.build; + # in + # if getBuilderResults.enabledBuildersCount == 0 + # then "" + # else if getBuilderResults.enabledBuildersCount > 1 + # then throw "Texlab does not support having more than 1 builders enabled!" + # else '' + # build = { + # executable = "${builder.package}/bin/${builder.executable}", + # args = ${listToLua builderArgs false}, + # forwardSearchAfter = ${boolToLua build.forwardSearchAfter}, + # onSave = ${boolToLua build.onSave}, + # useFileList = ${boolToLua build.useFileList}, + # auxDirectory = ${stringToLua build.auxDirectory true}, + # logDirectory = ${stringToLua build.logDirectory true}, + # pdfDirectory = ${stringToLua build.pdfDirectory true}, + # filename = ${stringToLua build.filename true}, + # }, + # ''; + # in (mkIf tl.enable { + # vim.lsp.lspconfig.sources.texlab = '' + # lspconfig.texlab.setup { + # cmd = { "${tl.package}/bin/texlab" }, + # settings = { + # texlab = { + # ${buildConfig} + # forwardSearch = { + # executable = "${tl.forwardSearch.package}/bin/${tl.forwardSearch.executable}", + # args = ${listToLua tl.forwardSearch.args true} + # }, + # ${tl.extraLuaSettings} + # } + # } + # } + # ''; + # }) + # ) + # + # # Add other LSPs here + # ]) + # )) # Extra Lua config options (mkIf cfg.extraOpts.texFlavor.enable { diff --git a/modules/plugins/languages/tex/lsp/default.nix b/modules/plugins/languages/tex/lsp/default.nix new file mode 100644 index 00000000..3c48d515 --- /dev/null +++ b/modules/plugins/languages/tex/lsp/default.nix @@ -0,0 +1,528 @@ +{ + config, + pkgs, + lib, + ... +}: let + inherit (lib.options) mkEnableOption mkOption; + inherit (lib.modules) mkIf mkMerge; + inherit + (lib.types) + bool + either + enum + ints + listOf + oneOf + package + str + ; + inherit (lib.nvim.types) mkGrammarOption; + inherit + (builtins) + any + attrNames + attrValues + concatLists + concatStringsSep + elem + elemAt + filter + hasAttr + isAttrs + length + map + throw + toString + ; + + cfg = config.vim.languages.tex; + + # --- Enable Options --- + mkEnableDefaultOption = default: description: (mkOption { + type = bool; + default = default; + example = !default; + description = description; + }); + mkEnableLspOption = mkEnableDefaultOption config.vim.languages.enableLSP; + + # --- Arg Collation Functions -- + collateArgs.lsp.texlab.build = { + tectonic = buildConfig: let + selfConfig = buildConfig.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 [] + ) + ); + custom = buildConfig: buildConfig.custom.args; + }; +in { + options.vim.languages.tex.lsp = { + texlab = { + enable = mkEnableLspOption "Whether to enable Tex LSP support (texlab)"; + + package = mkOption { + type = package; + default = pkgs.texlab; + description = "texlab package"; + }; + + build = { + tectonic = { + enable = mkEnableDefaultOption true "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 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. + ''; + }; + }; + + custom = { + enable = mkEnableDefaultOption false "Whether to enable using a custom build package"; + package = mkOption { + type = package; + default = pkgs.tectonic; + description = "build/compiler package"; + }; + executable = mkOption { + type = str; + default = "tectonic"; + description = "The executable name from the build package that will be used to build/compile the tex."; + }; + args = mkOption { + type = listOf str; + default = [ + "-X" + "compile" + "%f" + "--synctex" + "--keep-logs" + "--keep-intermediates" + ]; + description = '' + Defines additional arguments that are passed to the configured LaTeX build tool. + Note that flags and their arguments need to be separate elements in this array. + To pass the arguments -foo bar to a build tool, args needs to be ["-foo" "bar"]. + The placeholder `%f` will be replaced by the server. + + Placeholders: + - `%f`: The path of the TeX file to compile. + ''; + }; + }; + + forwardSearchAfter = mkOption { + type = bool; + default = false; + description = "Set this property to true if you want to execute a forward search after a build."; + }; + onSave = mkOption { + type = bool; + default = false; + description = "Set this property to true if you want to compile the project after saving a file."; + }; + useFileList = mkOption { + type = bool; + default = false; + description = '' + When set to true, the server will use the .fls files produced by the TeX engine as an additional input for the project detection. + + Note that enabling this property might have an impact on performance. + ''; + }; + auxDirectory = mkOption { + type = str; + default = "."; + description = '' + When not using latexmk, provides a way to define the directory containing the .aux files. + Note that you need to set the aux directory in latex.build.args too. + + When using a latexmkrc file, texlab will automatically infer the correct setting. + ''; + }; + logDirectory = mkOption { + type = str; + default = "."; + description = '' + When not using latexmk, provides a way to define the directory containing the build log files. + Note that you need to change the output directory in your build arguments too. + + When using a latexmkrc file, texlab will automatically infer the correct setting. + ''; + }; + pdfDirectory = mkOption { + type = str; + default = "."; + description = '' + When not using latexmk, provides a way to define the directory containing the output files. + Note that you need to set the output directory in latex.build.args too. + + When using a latexmkrc file, texlab will automatically infer the correct setting. + ''; + }; + filename = mkOption { + type = str; + default = ""; + description = '' + Allows overriding the default file name of the build artifact. This setting is used to find the correct PDF file to open during forward search. + ''; + }; + }; + + forwardSearch = { + enable = mkOption { + type = bool; + default = false; + example = true; + description = '' + Whether to enable forward search. + + Enable this option if you want to have the compiled document appear in your chosen PDF viewer. + + For some options see [here](https://github.com/latex-lsp/texlab/wiki/Previewing). + Note this is not all the options, but can act as a guide to help you allong with custom configs. + ''; + }; + package = mkOption { + type = package; + default = pkgs.okular; + description = '' + The package to use as your PDF viewer. + This viewer needs to support Synctex. + ''; + }; + executable = mkOption { + type = str; + default = "okular"; + description = '' + Defines the executable of the PDF previewer. The previewer needs to support SyncTeX. + ''; + }; + args = mkOption { + type = listOf str; + default = [ + "--unique" + "file:%p#src:%l%f" + ]; + description = '' + Defines additional arguments that are passed to the configured previewer to perform the forward search. + The placeholders %f, %p, %l will be replaced by the server. + + Placeholders: + - %f: The path of the current TeX file. + - %p: The path of the current PDF file. + - %l: The current line number. + ''; + }; + }; + + extraLuaSettings = mkOption { + type = str; + default = ""; + example = '' + formatterLineLength = 80, + ''; + description = '' + For any options that do not have options provided through nvf this can be used to add them. + Options already declared in nvf config will NOT be overridden. + + Options will be placed in: + ``` + lspconfig.texlab.setup { + settings = { + texlab = { + ... + + ... + + } + } + } + ``` + ''; + }; + }; + + # Add other LSPs here + }; + + # config = mkIf cfg.enable (mkMerge [ + # (mkIf (any (x: x.enable) (attrValues cfg.lsp)) ( + config = mkIf (cfg.enable && (any (x: x.enable) (attrValues cfg.lsp))) ( + { + vim.lsp.lspconfig.enable = true; + } # Enable lspconfig when any of the lsps are enabled + // (mkMerge [ + # ----- Texlab ----- + ( + let + tl = cfg.lsp.texlab; + build = tl.build; + + listToLua = list: nullOnEmpty: + if length list == 0 + then + if nullOnEmpty + then "null" + else "{ }" + else "{ ${concatStringsSep ", " (map (x: ''"${toString x}"'') list)} }"; + + stringToLua = string: nullOnEmpty: + if string == "" + then + if nullOnEmpty + then "null" + else "" + else ''"${string}"''; + + boolToLua = boolean: + if boolean + then "true" + else "false"; + + # -- Build -- + buildConfig = let + # This function will sort through the builder options of ...texlab.build and count how many + # builders have been enabled and get the attrs of the last enabled builder. + getBuilder = { + enabledBuildersCount ? 0, + enabledBuilderName ? "", + index ? 0, + builderNamesList ? ( + filter ( + x: let + y = tl.build.${x}; + in (isAttrs y && hasAttr "enable" y) + ) (attrNames tl.build) + ), + }: let + currentBuilderName = elemAt builderNamesList index; + currentBuilder = tl.build.${currentBuilderName}; + nextIndex = index + 1; + currentState = { + enabledBuildersCount = + if currentBuilder.enable + then enabledBuildersCount + 1 + else enabledBuildersCount; + enabledBuilderName = + if currentBuilder.enable + then currentBuilderName + else enabledBuilderName; + }; + in + if length builderNamesList > nextIndex + then + getBuilder ({ + inherit builderNamesList; + index = nextIndex; + } + // currentState) + else currentState; + + getBuilderResults = getBuilder {}; + builder = tl.build.${getBuilderResults.enabledBuilderName}; + builderArgs = collateArgs.lsp.texlab.build.${getBuilderResults.enabledBuilderName} tl.build; + in + if getBuilderResults.enabledBuildersCount == 0 + then "" + else if getBuilderResults.enabledBuildersCount > 1 + then throw "Texlab does not support having more than 1 builders enabled!" + else '' + build = { + executable = "${builder.package}/bin/${builder.executable}", + args = ${listToLua builderArgs false}, + forwardSearchAfter = ${boolToLua build.forwardSearchAfter}, + onSave = ${boolToLua build.onSave}, + useFileList = ${boolToLua build.useFileList}, + auxDirectory = ${stringToLua build.auxDirectory true}, + logDirectory = ${stringToLua build.logDirectory true}, + pdfDirectory = ${stringToLua build.pdfDirectory true}, + filename = ${stringToLua build.filename true}, + }, + ''; + in (mkIf tl.enable { + vim.lsp.lspconfig.sources.texlab = '' + lspconfig.texlab.setup { + cmd = { "${tl.package}/bin/texlab" }, + settings = { + texlab = { + ${buildConfig} + forwardSearch = { + executable = "${tl.forwardSearch.package}/bin/${tl.forwardSearch.executable}", + args = ${listToLua tl.forwardSearch.args true} + }, + ${tl.extraLuaSettings} + } + } + } + ''; + }) + ) + + # Add other LSPs here + ]) + ); +} From 9b401be571372c80796d37759ff02e1bc2326929 Mon Sep 17 00:00:00 2001 From: isaacST08 Date: Thu, 23 Jan 2025 16:54:21 -0700 Subject: [PATCH 4/6] Migrated texlab into its own module --- modules/plugins/languages/tex/lsp/default.nix | 951 +++++++++--------- modules/plugins/languages/tex/lsp/texlab.nix | 512 ++++++++++ 2 files changed, 989 insertions(+), 474 deletions(-) create mode 100644 modules/plugins/languages/tex/lsp/texlab.nix diff --git a/modules/plugins/languages/tex/lsp/default.nix b/modules/plugins/languages/tex/lsp/default.nix index 3c48d515..ffffe5cf 100644 --- a/modules/plugins/languages/tex/lsp/default.nix +++ b/modules/plugins/languages/tex/lsp/default.nix @@ -39,375 +39,378 @@ cfg = config.vim.languages.tex; # --- Enable Options --- - mkEnableDefaultOption = default: description: (mkOption { - type = bool; - default = default; - example = !default; - description = description; - }); - mkEnableLspOption = mkEnableDefaultOption config.vim.languages.enableLSP; + # mkEnableDefaultOption = default: description: (mkOption { + # type = bool; + # default = default; + # example = !default; + # description = description; + # }); + # mkEnableLspOption = mkEnableDefaultOption config.vim.languages.enableLSP; - # --- Arg Collation Functions -- - collateArgs.lsp.texlab.build = { - tectonic = buildConfig: let - selfConfig = buildConfig.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 [] - ) - ); - custom = buildConfig: buildConfig.custom.args; - }; + # # --- Arg Collation Functions -- + # collateArgs.lsp.texlab.build = { + # tectonic = buildConfig: let + # selfConfig = buildConfig.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 [] + # ) + # ); + # custom = buildConfig: buildConfig.custom.args; + # }; in { - options.vim.languages.tex.lsp = { - texlab = { - enable = mkEnableLspOption "Whether to enable Tex LSP support (texlab)"; - - package = mkOption { - type = package; - default = pkgs.texlab; - description = "texlab package"; - }; - - build = { - tectonic = { - enable = mkEnableDefaultOption true "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 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. - ''; - }; - }; - - custom = { - enable = mkEnableDefaultOption false "Whether to enable using a custom build package"; - package = mkOption { - type = package; - default = pkgs.tectonic; - description = "build/compiler package"; - }; - executable = mkOption { - type = str; - default = "tectonic"; - description = "The executable name from the build package that will be used to build/compile the tex."; - }; - args = mkOption { - type = listOf str; - default = [ - "-X" - "compile" - "%f" - "--synctex" - "--keep-logs" - "--keep-intermediates" - ]; - description = '' - Defines additional arguments that are passed to the configured LaTeX build tool. - Note that flags and their arguments need to be separate elements in this array. - To pass the arguments -foo bar to a build tool, args needs to be ["-foo" "bar"]. - The placeholder `%f` will be replaced by the server. - - Placeholders: - - `%f`: The path of the TeX file to compile. - ''; - }; - }; - - forwardSearchAfter = mkOption { - type = bool; - default = false; - description = "Set this property to true if you want to execute a forward search after a build."; - }; - onSave = mkOption { - type = bool; - default = false; - description = "Set this property to true if you want to compile the project after saving a file."; - }; - useFileList = mkOption { - type = bool; - default = false; - description = '' - When set to true, the server will use the .fls files produced by the TeX engine as an additional input for the project detection. - - Note that enabling this property might have an impact on performance. - ''; - }; - auxDirectory = mkOption { - type = str; - default = "."; - description = '' - When not using latexmk, provides a way to define the directory containing the .aux files. - Note that you need to set the aux directory in latex.build.args too. - - When using a latexmkrc file, texlab will automatically infer the correct setting. - ''; - }; - logDirectory = mkOption { - type = str; - default = "."; - description = '' - When not using latexmk, provides a way to define the directory containing the build log files. - Note that you need to change the output directory in your build arguments too. - - When using a latexmkrc file, texlab will automatically infer the correct setting. - ''; - }; - pdfDirectory = mkOption { - type = str; - default = "."; - description = '' - When not using latexmk, provides a way to define the directory containing the output files. - Note that you need to set the output directory in latex.build.args too. - - When using a latexmkrc file, texlab will automatically infer the correct setting. - ''; - }; - filename = mkOption { - type = str; - default = ""; - description = '' - Allows overriding the default file name of the build artifact. This setting is used to find the correct PDF file to open during forward search. - ''; - }; - }; - - forwardSearch = { - enable = mkOption { - type = bool; - default = false; - example = true; - description = '' - Whether to enable forward search. - - Enable this option if you want to have the compiled document appear in your chosen PDF viewer. - - For some options see [here](https://github.com/latex-lsp/texlab/wiki/Previewing). - Note this is not all the options, but can act as a guide to help you allong with custom configs. - ''; - }; - package = mkOption { - type = package; - default = pkgs.okular; - description = '' - The package to use as your PDF viewer. - This viewer needs to support Synctex. - ''; - }; - executable = mkOption { - type = str; - default = "okular"; - description = '' - Defines the executable of the PDF previewer. The previewer needs to support SyncTeX. - ''; - }; - args = mkOption { - type = listOf str; - default = [ - "--unique" - "file:%p#src:%l%f" - ]; - description = '' - Defines additional arguments that are passed to the configured previewer to perform the forward search. - The placeholders %f, %p, %l will be replaced by the server. - - Placeholders: - - %f: The path of the current TeX file. - - %p: The path of the current PDF file. - - %l: The current line number. - ''; - }; - }; - - extraLuaSettings = mkOption { - type = str; - default = ""; - example = '' - formatterLineLength = 80, - ''; - description = '' - For any options that do not have options provided through nvf this can be used to add them. - Options already declared in nvf config will NOT be overridden. - - Options will be placed in: - ``` - lspconfig.texlab.setup { - settings = { - texlab = { - ... - - ... - - } - } - } - ``` - ''; - }; - }; + imports = [ + ./texlab.nix + ]; + # options.vim.languages.tex.lsp = { + # texlab = { + # enable = mkEnableLspOption "Whether to enable Tex LSP support (texlab)"; + # + # package = mkOption { + # type = package; + # default = pkgs.texlab; + # description = "texlab package"; + # }; + # + # build = { + # tectonic = { + # enable = mkEnableDefaultOption true "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 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. + # ''; + # }; + # }; + # + # custom = { + # enable = mkEnableDefaultOption false "Whether to enable using a custom build package"; + # package = mkOption { + # type = package; + # default = pkgs.tectonic; + # description = "build/compiler package"; + # }; + # executable = mkOption { + # type = str; + # default = "tectonic"; + # description = "The executable name from the build package that will be used to build/compile the tex."; + # }; + # args = mkOption { + # type = listOf str; + # default = [ + # "-X" + # "compile" + # "%f" + # "--synctex" + # "--keep-logs" + # "--keep-intermediates" + # ]; + # description = '' + # Defines additional arguments that are passed to the configured LaTeX build tool. + # Note that flags and their arguments need to be separate elements in this array. + # To pass the arguments -foo bar to a build tool, args needs to be ["-foo" "bar"]. + # The placeholder `%f` will be replaced by the server. + # + # Placeholders: + # - `%f`: The path of the TeX file to compile. + # ''; + # }; + # }; + # + # forwardSearchAfter = mkOption { + # type = bool; + # default = false; + # description = "Set this property to true if you want to execute a forward search after a build."; + # }; + # onSave = mkOption { + # type = bool; + # default = false; + # description = "Set this property to true if you want to compile the project after saving a file."; + # }; + # useFileList = mkOption { + # type = bool; + # default = false; + # description = '' + # When set to true, the server will use the .fls files produced by the TeX engine as an additional input for the project detection. + # + # Note that enabling this property might have an impact on performance. + # ''; + # }; + # auxDirectory = mkOption { + # type = str; + # default = "."; + # description = '' + # When not using latexmk, provides a way to define the directory containing the .aux files. + # Note that you need to set the aux directory in latex.build.args too. + # + # When using a latexmkrc file, texlab will automatically infer the correct setting. + # ''; + # }; + # logDirectory = mkOption { + # type = str; + # default = "."; + # description = '' + # When not using latexmk, provides a way to define the directory containing the build log files. + # Note that you need to change the output directory in your build arguments too. + # + # When using a latexmkrc file, texlab will automatically infer the correct setting. + # ''; + # }; + # pdfDirectory = mkOption { + # type = str; + # default = "."; + # description = '' + # When not using latexmk, provides a way to define the directory containing the output files. + # Note that you need to set the output directory in latex.build.args too. + # + # When using a latexmkrc file, texlab will automatically infer the correct setting. + # ''; + # }; + # filename = mkOption { + # type = str; + # default = ""; + # description = '' + # Allows overriding the default file name of the build artifact. This setting is used to find the correct PDF file to open during forward search. + # ''; + # }; + # }; + # + # forwardSearch = { + # enable = mkOption { + # type = bool; + # default = false; + # example = true; + # description = '' + # Whether to enable forward search. + # + # Enable this option if you want to have the compiled document appear in your chosen PDF viewer. + # + # For some options see [here](https://github.com/latex-lsp/texlab/wiki/Previewing). + # Note this is not all the options, but can act as a guide to help you allong with custom configs. + # ''; + # }; + # package = mkOption { + # type = package; + # default = pkgs.okular; + # description = '' + # The package to use as your PDF viewer. + # This viewer needs to support Synctex. + # ''; + # }; + # executable = mkOption { + # type = str; + # default = "okular"; + # description = '' + # Defines the executable of the PDF previewer. The previewer needs to support SyncTeX. + # ''; + # }; + # args = mkOption { + # type = listOf str; + # default = [ + # "--unique" + # "file:%p#src:%l%f" + # ]; + # description = '' + # Defines additional arguments that are passed to the configured previewer to perform the forward search. + # The placeholders %f, %p, %l will be replaced by the server. + # + # Placeholders: + # - %f: The path of the current TeX file. + # - %p: The path of the current PDF file. + # - %l: The current line number. + # ''; + # }; + # }; + # + # extraLuaSettings = mkOption { + # type = str; + # default = ""; + # example = '' + # formatterLineLength = 80, + # ''; + # description = '' + # For any options that do not have options provided through nvf this can be used to add them. + # Options already declared in nvf config will NOT be overridden. + # + # Options will be placed in: + # ``` + # lspconfig.texlab.setup { + # settings = { + # texlab = { + # ... + # + # ... + # + # } + # } + # } + # ``` + # ''; + # }; + # }; # Add other LSPs here - }; + # }; # config = mkIf cfg.enable (mkMerge [ # (mkIf (any (x: x.enable) (attrValues cfg.lsp)) ( @@ -415,114 +418,114 @@ in { { vim.lsp.lspconfig.enable = true; } # Enable lspconfig when any of the lsps are enabled - // (mkMerge [ - # ----- Texlab ----- - ( - let - tl = cfg.lsp.texlab; - build = tl.build; - - listToLua = list: nullOnEmpty: - if length list == 0 - then - if nullOnEmpty - then "null" - else "{ }" - else "{ ${concatStringsSep ", " (map (x: ''"${toString x}"'') list)} }"; - - stringToLua = string: nullOnEmpty: - if string == "" - then - if nullOnEmpty - then "null" - else "" - else ''"${string}"''; - - boolToLua = boolean: - if boolean - then "true" - else "false"; - - # -- Build -- - buildConfig = let - # This function will sort through the builder options of ...texlab.build and count how many - # builders have been enabled and get the attrs of the last enabled builder. - getBuilder = { - enabledBuildersCount ? 0, - enabledBuilderName ? "", - index ? 0, - builderNamesList ? ( - filter ( - x: let - y = tl.build.${x}; - in (isAttrs y && hasAttr "enable" y) - ) (attrNames tl.build) - ), - }: let - currentBuilderName = elemAt builderNamesList index; - currentBuilder = tl.build.${currentBuilderName}; - nextIndex = index + 1; - currentState = { - enabledBuildersCount = - if currentBuilder.enable - then enabledBuildersCount + 1 - else enabledBuildersCount; - enabledBuilderName = - if currentBuilder.enable - then currentBuilderName - else enabledBuilderName; - }; - in - if length builderNamesList > nextIndex - then - getBuilder ({ - inherit builderNamesList; - index = nextIndex; - } - // currentState) - else currentState; - - getBuilderResults = getBuilder {}; - builder = tl.build.${getBuilderResults.enabledBuilderName}; - builderArgs = collateArgs.lsp.texlab.build.${getBuilderResults.enabledBuilderName} tl.build; - in - if getBuilderResults.enabledBuildersCount == 0 - then "" - else if getBuilderResults.enabledBuildersCount > 1 - then throw "Texlab does not support having more than 1 builders enabled!" - else '' - build = { - executable = "${builder.package}/bin/${builder.executable}", - args = ${listToLua builderArgs false}, - forwardSearchAfter = ${boolToLua build.forwardSearchAfter}, - onSave = ${boolToLua build.onSave}, - useFileList = ${boolToLua build.useFileList}, - auxDirectory = ${stringToLua build.auxDirectory true}, - logDirectory = ${stringToLua build.logDirectory true}, - pdfDirectory = ${stringToLua build.pdfDirectory true}, - filename = ${stringToLua build.filename true}, - }, - ''; - in (mkIf tl.enable { - vim.lsp.lspconfig.sources.texlab = '' - lspconfig.texlab.setup { - cmd = { "${tl.package}/bin/texlab" }, - settings = { - texlab = { - ${buildConfig} - forwardSearch = { - executable = "${tl.forwardSearch.package}/bin/${tl.forwardSearch.executable}", - args = ${listToLua tl.forwardSearch.args true} - }, - ${tl.extraLuaSettings} - } - } - } - ''; - }) - ) - - # Add other LSPs here - ]) + # // (mkMerge [ + # # ----- Texlab ----- + # ( + # let + # tl = cfg.lsp.texlab; + # build = tl.build; + # + # listToLua = list: nullOnEmpty: + # if length list == 0 + # then + # if nullOnEmpty + # then "null" + # else "{ }" + # else "{ ${concatStringsSep ", " (map (x: ''"${toString x}"'') list)} }"; + # + # stringToLua = string: nullOnEmpty: + # if string == "" + # then + # if nullOnEmpty + # then "null" + # else "" + # else ''"${string}"''; + # + # boolToLua = boolean: + # if boolean + # then "true" + # else "false"; + # + # # -- Build -- + # buildConfig = let + # # This function will sort through the builder options of ...texlab.build and count how many + # # builders have been enabled and get the attrs of the last enabled builder. + # getBuilder = { + # enabledBuildersCount ? 0, + # enabledBuilderName ? "", + # index ? 0, + # builderNamesList ? ( + # filter ( + # x: let + # y = tl.build.${x}; + # in (isAttrs y && hasAttr "enable" y) + # ) (attrNames tl.build) + # ), + # }: let + # currentBuilderName = elemAt builderNamesList index; + # currentBuilder = tl.build.${currentBuilderName}; + # nextIndex = index + 1; + # currentState = { + # enabledBuildersCount = + # if currentBuilder.enable + # then enabledBuildersCount + 1 + # else enabledBuildersCount; + # enabledBuilderName = + # if currentBuilder.enable + # then currentBuilderName + # else enabledBuilderName; + # }; + # in + # if length builderNamesList > nextIndex + # then + # getBuilder ({ + # inherit builderNamesList; + # index = nextIndex; + # } + # // currentState) + # else currentState; + # + # getBuilderResults = getBuilder {}; + # builder = tl.build.${getBuilderResults.enabledBuilderName}; + # builderArgs = collateArgs.lsp.texlab.build.${getBuilderResults.enabledBuilderName} tl.build; + # in + # if getBuilderResults.enabledBuildersCount == 0 + # then "" + # else if getBuilderResults.enabledBuildersCount > 1 + # then throw "Texlab does not support having more than 1 builders enabled!" + # else '' + # build = { + # executable = "${builder.package}/bin/${builder.executable}", + # args = ${listToLua builderArgs false}, + # forwardSearchAfter = ${boolToLua build.forwardSearchAfter}, + # onSave = ${boolToLua build.onSave}, + # useFileList = ${boolToLua build.useFileList}, + # auxDirectory = ${stringToLua build.auxDirectory true}, + # logDirectory = ${stringToLua build.logDirectory true}, + # pdfDirectory = ${stringToLua build.pdfDirectory true}, + # filename = ${stringToLua build.filename true}, + # }, + # ''; + # in (mkIf tl.enable { + # vim.lsp.lspconfig.sources.texlab = '' + # lspconfig.texlab.setup { + # cmd = { "${tl.package}/bin/texlab" }, + # settings = { + # texlab = { + # ${buildConfig} + # forwardSearch = { + # executable = "${tl.forwardSearch.package}/bin/${tl.forwardSearch.executable}", + # args = ${listToLua tl.forwardSearch.args true} + # }, + # ${tl.extraLuaSettings} + # } + # } + # } + # ''; + # }) + # ) + # + # # Add other LSPs here + # ]) ); } diff --git a/modules/plugins/languages/tex/lsp/texlab.nix b/modules/plugins/languages/tex/lsp/texlab.nix new file mode 100644 index 00000000..cd7b85dc --- /dev/null +++ b/modules/plugins/languages/tex/lsp/texlab.nix @@ -0,0 +1,512 @@ +{ + config, + pkgs, + lib, + ... +}: let + inherit (lib.options) mkEnableOption mkOption; + inherit (lib.modules) mkIf mkMerge; + inherit + (lib.types) + bool + either + enum + ints + listOf + oneOf + package + str + ; + inherit (lib.nvim.types) mkGrammarOption; + inherit + (builtins) + any + attrNames + attrValues + concatLists + concatStringsSep + elem + elemAt + filter + hasAttr + isAttrs + length + map + throw + toString + ; + + cfg = config.vim.languages.tex; + + # --- Enable Options --- + mkEnableDefaultOption = default: description: (mkOption { + type = bool; + default = default; + example = !default; + description = description; + }); + mkEnableLspOption = mkEnableDefaultOption config.vim.languages.enableLSP; + + # --- Arg Collation Functions -- + collateArgs.lsp.texlab.build = { + tectonic = buildConfig: let + selfConfig = buildConfig.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 [] + ) + ); + custom = buildConfig: buildConfig.custom.args; + }; +in { + options.vim.languages.tex.lsp.texlab = { + enable = mkEnableLspOption "Whether to enable Tex LSP support (texlab)"; + + package = mkOption { + type = package; + default = pkgs.texlab; + description = "texlab package"; + }; + + build = { + tectonic = { + enable = mkEnableDefaultOption true "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 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. + ''; + }; + }; + + custom = { + enable = mkEnableDefaultOption false "Whether to enable using a custom build package"; + package = mkOption { + type = package; + default = pkgs.tectonic; + description = "build/compiler package"; + }; + executable = mkOption { + type = str; + default = "tectonic"; + description = "The executable name from the build package that will be used to build/compile the tex."; + }; + args = mkOption { + type = listOf str; + default = [ + "-X" + "compile" + "%f" + "--synctex" + "--keep-logs" + "--keep-intermediates" + ]; + description = '' + Defines additional arguments that are passed to the configured LaTeX build tool. + Note that flags and their arguments need to be separate elements in this array. + To pass the arguments -foo bar to a build tool, args needs to be ["-foo" "bar"]. + The placeholder `%f` will be replaced by the server. + + Placeholders: + - `%f`: The path of the TeX file to compile. + ''; + }; + }; + + forwardSearchAfter = mkOption { + type = bool; + default = false; + description = "Set this property to true if you want to execute a forward search after a build."; + }; + onSave = mkOption { + type = bool; + default = false; + description = "Set this property to true if you want to compile the project after saving a file."; + }; + useFileList = mkOption { + type = bool; + default = false; + description = '' + When set to true, the server will use the .fls files produced by the TeX engine as an additional input for the project detection. + + Note that enabling this property might have an impact on performance. + ''; + }; + auxDirectory = mkOption { + type = str; + default = "."; + description = '' + When not using latexmk, provides a way to define the directory containing the .aux files. + Note that you need to set the aux directory in latex.build.args too. + + When using a latexmkrc file, texlab will automatically infer the correct setting. + ''; + }; + logDirectory = mkOption { + type = str; + default = "."; + description = '' + When not using latexmk, provides a way to define the directory containing the build log files. + Note that you need to change the output directory in your build arguments too. + + When using a latexmkrc file, texlab will automatically infer the correct setting. + ''; + }; + pdfDirectory = mkOption { + type = str; + default = "."; + description = '' + When not using latexmk, provides a way to define the directory containing the output files. + Note that you need to set the output directory in latex.build.args too. + + When using a latexmkrc file, texlab will automatically infer the correct setting. + ''; + }; + filename = mkOption { + type = str; + default = ""; + description = '' + Allows overriding the default file name of the build artifact. This setting is used to find the correct PDF file to open during forward search. + ''; + }; + }; + + forwardSearch = { + enable = mkOption { + type = bool; + default = false; + example = true; + description = '' + Whether to enable forward search. + + Enable this option if you want to have the compiled document appear in your chosen PDF viewer. + + For some options see [here](https://github.com/latex-lsp/texlab/wiki/Previewing). + Note this is not all the options, but can act as a guide to help you allong with custom configs. + ''; + }; + package = mkOption { + type = package; + default = pkgs.okular; + description = '' + The package to use as your PDF viewer. + This viewer needs to support Synctex. + ''; + }; + executable = mkOption { + type = str; + default = "okular"; + description = '' + Defines the executable of the PDF previewer. The previewer needs to support SyncTeX. + ''; + }; + args = mkOption { + type = listOf str; + default = [ + "--unique" + "file:%p#src:%l%f" + ]; + description = '' + Defines additional arguments that are passed to the configured previewer to perform the forward search. + The placeholders %f, %p, %l will be replaced by the server. + + Placeholders: + - %f: The path of the current TeX file. + - %p: The path of the current PDF file. + - %l: The current line number. + ''; + }; + }; + + extraLuaSettings = mkOption { + type = str; + default = ""; + example = '' + formatterLineLength = 80, + ''; + description = '' + For any options that do not have options provided through nvf this can be used to add them. + Options already declared in nvf config will NOT be overridden. + + Options will be placed in: + ``` + lspconfig.texlab.setup { + settings = { + texlab = { + ... + + ... + + } + } + } + ``` + ''; + }; + }; + + config = mkIf (cfg.enable && (cfg.lsp.texlab.enable)) ( + let + tl = cfg.lsp.texlab; + build = tl.build; + + listToLua = list: nullOnEmpty: + if length list == 0 + then + if nullOnEmpty + then "null" + else "{ }" + else "{ ${concatStringsSep ", " (map (x: ''"${toString x}"'') list)} }"; + + stringToLua = string: nullOnEmpty: + if string == "" + then + if nullOnEmpty + then "null" + else "" + else ''"${string}"''; + + boolToLua = boolean: + if boolean + then "true" + else "false"; + + # -- Build -- + buildConfig = let + # This function will sort through the builder options of ...texlab.build and count how many + # builders have been enabled and get the attrs of the last enabled builder. + getBuilder = { + enabledBuildersCount ? 0, + enabledBuilderName ? "", + index ? 0, + builderNamesList ? ( + filter ( + x: let + y = tl.build.${x}; + in (isAttrs y && hasAttr "enable" y) + ) (attrNames tl.build) + ), + }: let + currentBuilderName = elemAt builderNamesList index; + currentBuilder = tl.build.${currentBuilderName}; + nextIndex = index + 1; + currentState = { + enabledBuildersCount = + if currentBuilder.enable + then enabledBuildersCount + 1 + else enabledBuildersCount; + enabledBuilderName = + if currentBuilder.enable + then currentBuilderName + else enabledBuilderName; + }; + in + if length builderNamesList > nextIndex + then + getBuilder ({ + inherit builderNamesList; + index = nextIndex; + } + // currentState) + else currentState; + + getBuilderResults = getBuilder {}; + builder = tl.build.${getBuilderResults.enabledBuilderName}; + builderArgs = collateArgs.lsp.texlab.build.${getBuilderResults.enabledBuilderName} tl.build; + in + if getBuilderResults.enabledBuildersCount == 0 + then "" + else if getBuilderResults.enabledBuildersCount > 1 + then throw "Texlab does not support having more than 1 builders enabled!" + else '' + build = { + executable = "${builder.package}/bin/${builder.executable}", + args = ${listToLua builderArgs false}, + forwardSearchAfter = ${boolToLua build.forwardSearchAfter}, + onSave = ${boolToLua build.onSave}, + useFileList = ${boolToLua build.useFileList}, + auxDirectory = ${stringToLua build.auxDirectory true}, + logDirectory = ${stringToLua build.logDirectory true}, + pdfDirectory = ${stringToLua build.pdfDirectory true}, + filename = ${stringToLua build.filename true}, + }, + ''; + in { + vim.lsp.lspconfig.sources.texlab = '' + lspconfig.texlab.setup { + cmd = { "${tl.package}/bin/texlab" }, + settings = { + texlab = { + ${buildConfig} + forwardSearch = { + executable = "${tl.forwardSearch.package}/bin/${tl.forwardSearch.executable}", + args = ${listToLua tl.forwardSearch.args true} + }, + ${tl.extraLuaSettings} + } + } + } + ''; + } + ); +} From 48674a46fa8134232b70412566f96f9e276b278f Mon Sep 17 00:00:00 2001 From: isaacST08 Date: Thu, 23 Jan 2025 17:05:25 -0700 Subject: [PATCH 5/6] Cleanup residue from modularization --- modules/plugins/languages/tex/default.nix | 563 +----------------- modules/plugins/languages/tex/lsp/default.nix | 523 +--------------- modules/plugins/languages/tex/lsp/texlab.nix | 22 +- modules/plugins/languages/tex/treesitter.nix | 13 +- 4 files changed, 27 insertions(+), 1094 deletions(-) diff --git a/modules/plugins/languages/tex/default.nix b/modules/plugins/languages/tex/default.nix index 116403d1..944f43f2 100644 --- a/modules/plugins/languages/tex/default.nix +++ b/modules/plugins/languages/tex/default.nix @@ -1,148 +1,14 @@ -# TODO: -# - Add Texlab LSP settings: -# - chktex -# - diagnosticsDelay -# - diagnostics -# - symbols -# - formatterLineLength -# - bibtexFormatter -# - latexFormatter -# - latexindent -# - completion -# - inlayHints -# - experimental { config, - pkgs, lib, ... }: let - inherit (lib.options) mkEnableOption mkOption; inherit (lib.modules) mkIf mkMerge; - inherit - (lib.types) - bool - either - enum - ints - listOf - oneOf - package - str - ; - inherit (lib.nvim.types) mkGrammarOption; - inherit - (builtins) - any - attrNames - attrValues - concatLists - concatStringsSep - elem - elemAt - filter - hasAttr - isAttrs - length - map - throw - toString - ; + inherit (lib.options) mkEnableOption mkOption; + inherit (lib.types) bool str; cfg = config.vim.languages.tex; - - # --- Enable Options --- - # mkEnableDefaultOption = default: description: (mkOption { - # type = bool; - # default = default; - # example = !default; - # description = description; - # }); - # mkEnableTreesitterOption = mkEnableDefaultOption config.vim.languages.enableTreesitter; - # mkEnableLspOption = mkEnableDefaultOption config.vim.languages.enableLSP; - - # # --- Arg Collation Functions -- - # collateArgs.lsp.texlab.build = { - # tectonic = buildConfig: let - # selfConfig = buildConfig.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 [] - # ) - # ); - # custom = buildConfig: buildConfig.custom.args; - # }; in { - imports = [ ./treesitter.nix ./lsp @@ -151,305 +17,6 @@ in { options.vim.languages.tex = { enable = mkEnableOption "Tex support"; - # # Treesitter options for latex and bibtex flavours of tex. - # treesitter = { - # latex = { - # enable = mkEnableTreesitterOption "Whether to enable Latex treesitter"; - # package = mkGrammarOption pkgs "latex"; - # }; - # bibtex = { - # enable = mkEnableTreesitterOption "Whether to enable Bibtex treesitter"; - # package = mkGrammarOption pkgs "bibtex"; - # }; - # }; - - # LSP options - # Because tex LSPs also including building/compiling tex, they have - # more options that are only specific to them and thus it makes - # more sense to group one into its own group of options. - # - # Each lsp group must have an enable option of its own. - # lsp = { - # texlab = { - # enable = mkEnableLspOption "Whether to enable Tex LSP support (texlab)"; - # - # package = mkOption { - # type = package; - # default = pkgs.texlab; - # description = "texlab package"; - # }; - # - # build = { - # tectonic = { - # enable = mkEnableDefaultOption true "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 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. - # ''; - # }; - # }; - # - # custom = { - # enable = mkEnableDefaultOption false "Whether to enable using a custom build package"; - # package = mkOption { - # type = package; - # default = pkgs.tectonic; - # description = "build/compiler package"; - # }; - # executable = mkOption { - # type = str; - # default = "tectonic"; - # description = "The executable name from the build package that will be used to build/compile the tex."; - # }; - # args = mkOption { - # type = listOf str; - # default = [ - # "-X" - # "compile" - # "%f" - # "--synctex" - # "--keep-logs" - # "--keep-intermediates" - # ]; - # description = '' - # Defines additional arguments that are passed to the configured LaTeX build tool. - # Note that flags and their arguments need to be separate elements in this array. - # To pass the arguments -foo bar to a build tool, args needs to be ["-foo" "bar"]. - # The placeholder `%f` will be replaced by the server. - # - # Placeholders: - # - `%f`: The path of the TeX file to compile. - # ''; - # }; - # }; - # - # forwardSearchAfter = mkOption { - # type = bool; - # default = false; - # description = "Set this property to true if you want to execute a forward search after a build."; - # }; - # onSave = mkOption { - # type = bool; - # default = false; - # description = "Set this property to true if you want to compile the project after saving a file."; - # }; - # useFileList = mkOption { - # type = bool; - # default = false; - # description = '' - # When set to true, the server will use the .fls files produced by the TeX engine as an additional input for the project detection. - # - # Note that enabling this property might have an impact on performance. - # ''; - # }; - # auxDirectory = mkOption { - # type = str; - # default = "."; - # description = '' - # When not using latexmk, provides a way to define the directory containing the .aux files. - # Note that you need to set the aux directory in latex.build.args too. - # - # When using a latexmkrc file, texlab will automatically infer the correct setting. - # ''; - # }; - # logDirectory = mkOption { - # type = str; - # default = "."; - # description = '' - # When not using latexmk, provides a way to define the directory containing the build log files. - # Note that you need to change the output directory in your build arguments too. - # - # When using a latexmkrc file, texlab will automatically infer the correct setting. - # ''; - # }; - # pdfDirectory = mkOption { - # type = str; - # default = "."; - # description = '' - # When not using latexmk, provides a way to define the directory containing the output files. - # Note that you need to set the output directory in latex.build.args too. - # - # When using a latexmkrc file, texlab will automatically infer the correct setting. - # ''; - # }; - # filename = mkOption { - # type = str; - # default = ""; - # description = '' - # Allows overriding the default file name of the build artifact. This setting is used to find the correct PDF file to open during forward search. - # ''; - # }; - # }; - # - # forwardSearch = { - # enable = mkOption { - # type = bool; - # default = false; - # example = true; - # description = '' - # Whether to enable forward search. - # - # Enable this option if you want to have the compiled document appear in your chosen PDF viewer. - # - # For some options see [here](https://github.com/latex-lsp/texlab/wiki/Previewing). - # Note this is not all the options, but can act as a guide to help you allong with custom configs. - # ''; - # }; - # package = mkOption { - # type = package; - # default = pkgs.okular; - # description = '' - # The package to use as your PDF viewer. - # This viewer needs to support Synctex. - # ''; - # }; - # executable = mkOption { - # type = str; - # default = "okular"; - # description = '' - # Defines the executable of the PDF previewer. The previewer needs to support SyncTeX. - # ''; - # }; - # args = mkOption { - # type = listOf str; - # default = [ - # "--unique" - # "file:%p#src:%l%f" - # ]; - # description = '' - # Defines additional arguments that are passed to the configured previewer to perform the forward search. - # The placeholders %f, %p, %l will be replaced by the server. - # - # Placeholders: - # - %f: The path of the current TeX file. - # - %p: The path of the current PDF file. - # - %l: The current line number. - # ''; - # }; - # }; - # - # extraLuaSettings = mkOption { - # type = str; - # default = ""; - # example = '' - # formatterLineLength = 80, - # ''; - # description = '' - # For any options that do not have options provided through nvf this can be used to add them. - # Options already declared in nvf config will NOT be overridden. - # - # Options will be placed in: - # ``` - # lspconfig.texlab.setup { - # settings = { - # texlab = { - # ... - # - # ... - # - # } - # } - # } - # ``` - # ''; - # }; - # }; - # - # # Add other LSPs here - # }; - extraOpts = { texFlavor = { enable = mkOption { @@ -491,132 +58,6 @@ in { }; config = mkIf cfg.enable (mkMerge [ - # # Treesitter - # (mkIf cfg.treesitter.latex.enable { - # vim.treesitter.enable = true; - # vim.treesitter.grammars = [cfg.treesitter.latex.package]; - # }) - # (mkIf cfg.treesitter.bibtex.enable { - # vim.treesitter.enable = true; - # vim.treesitter.grammars = [cfg.treesitter.bibtex.package]; - # }) - - # LSP - # (mkIf (any (x: x.enable) (attrValues cfg.lsp)) ( - # { - # vim.lsp.lspconfig.enable = true; - # } # Enable lspconfig when any of the lsps are enabled - # // (mkMerge [ - # # ----- Texlab ----- - # ( - # let - # tl = cfg.lsp.texlab; - # build = tl.build; - # - # listToLua = list: nullOnEmpty: - # if length list == 0 - # then - # if nullOnEmpty - # then "null" - # else "{ }" - # else "{ ${concatStringsSep ", " (map (x: ''"${toString x}"'') list)} }"; - # - # stringToLua = string: nullOnEmpty: - # if string == "" - # then - # if nullOnEmpty - # then "null" - # else "" - # else ''"${string}"''; - # - # boolToLua = boolean: - # if boolean - # then "true" - # else "false"; - # - # # -- Build -- - # buildConfig = let - # # This function will sort through the builder options of ...texlab.build and count how many - # # builders have been enabled and get the attrs of the last enabled builder. - # getBuilder = { - # enabledBuildersCount ? 0, - # enabledBuilderName ? "", - # index ? 0, - # builderNamesList ? ( - # filter ( - # x: let - # y = tl.build.${x}; - # in (isAttrs y && hasAttr "enable" y) - # ) (attrNames tl.build) - # ), - # }: let - # currentBuilderName = elemAt builderNamesList index; - # currentBuilder = tl.build.${currentBuilderName}; - # nextIndex = index + 1; - # currentState = { - # enabledBuildersCount = - # if currentBuilder.enable - # then enabledBuildersCount + 1 - # else enabledBuildersCount; - # enabledBuilderName = - # if currentBuilder.enable - # then currentBuilderName - # else enabledBuilderName; - # }; - # in - # if length builderNamesList > nextIndex - # then - # getBuilder ({ - # inherit builderNamesList; - # index = nextIndex; - # } - # // currentState) - # else currentState; - # - # getBuilderResults = getBuilder {}; - # builder = tl.build.${getBuilderResults.enabledBuilderName}; - # builderArgs = collateArgs.lsp.texlab.build.${getBuilderResults.enabledBuilderName} tl.build; - # in - # if getBuilderResults.enabledBuildersCount == 0 - # then "" - # else if getBuilderResults.enabledBuildersCount > 1 - # then throw "Texlab does not support having more than 1 builders enabled!" - # else '' - # build = { - # executable = "${builder.package}/bin/${builder.executable}", - # args = ${listToLua builderArgs false}, - # forwardSearchAfter = ${boolToLua build.forwardSearchAfter}, - # onSave = ${boolToLua build.onSave}, - # useFileList = ${boolToLua build.useFileList}, - # auxDirectory = ${stringToLua build.auxDirectory true}, - # logDirectory = ${stringToLua build.logDirectory true}, - # pdfDirectory = ${stringToLua build.pdfDirectory true}, - # filename = ${stringToLua build.filename true}, - # }, - # ''; - # in (mkIf tl.enable { - # vim.lsp.lspconfig.sources.texlab = '' - # lspconfig.texlab.setup { - # cmd = { "${tl.package}/bin/texlab" }, - # settings = { - # texlab = { - # ${buildConfig} - # forwardSearch = { - # executable = "${tl.forwardSearch.package}/bin/${tl.forwardSearch.executable}", - # args = ${listToLua tl.forwardSearch.args true} - # }, - # ${tl.extraLuaSettings} - # } - # } - # } - # ''; - # }) - # ) - # - # # Add other LSPs here - # ]) - # )) - # Extra Lua config options (mkIf cfg.extraOpts.texFlavor.enable { vim.globals.tex_flavor = "${cfg.extraOpts.texFlavor.flavor}"; diff --git a/modules/plugins/languages/tex/lsp/default.nix b/modules/plugins/languages/tex/lsp/default.nix index ffffe5cf..affb272a 100644 --- a/modules/plugins/languages/tex/lsp/default.nix +++ b/modules/plugins/languages/tex/lsp/default.nix @@ -1,531 +1,18 @@ { config, - pkgs, lib, ... }: let - inherit (lib.options) mkEnableOption mkOption; - inherit (lib.modules) mkIf mkMerge; - inherit - (lib.types) - bool - either - enum - ints - listOf - oneOf - package - str - ; - inherit (lib.nvim.types) mkGrammarOption; - inherit - (builtins) - any - attrNames - attrValues - concatLists - concatStringsSep - elem - elemAt - filter - hasAttr - isAttrs - length - map - throw - toString - ; + inherit (lib.modules) mkIf; + inherit (builtins) any attrValues; cfg = config.vim.languages.tex; - - # --- Enable Options --- - # mkEnableDefaultOption = default: description: (mkOption { - # type = bool; - # default = default; - # example = !default; - # description = description; - # }); - # mkEnableLspOption = mkEnableDefaultOption config.vim.languages.enableLSP; - - # # --- Arg Collation Functions -- - # collateArgs.lsp.texlab.build = { - # tectonic = buildConfig: let - # selfConfig = buildConfig.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 [] - # ) - # ); - # custom = buildConfig: buildConfig.custom.args; - # }; in { imports = [ ./texlab.nix ]; - # options.vim.languages.tex.lsp = { - # texlab = { - # enable = mkEnableLspOption "Whether to enable Tex LSP support (texlab)"; - # - # package = mkOption { - # type = package; - # default = pkgs.texlab; - # description = "texlab package"; - # }; - # - # build = { - # tectonic = { - # enable = mkEnableDefaultOption true "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 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. - # ''; - # }; - # }; - # - # custom = { - # enable = mkEnableDefaultOption false "Whether to enable using a custom build package"; - # package = mkOption { - # type = package; - # default = pkgs.tectonic; - # description = "build/compiler package"; - # }; - # executable = mkOption { - # type = str; - # default = "tectonic"; - # description = "The executable name from the build package that will be used to build/compile the tex."; - # }; - # args = mkOption { - # type = listOf str; - # default = [ - # "-X" - # "compile" - # "%f" - # "--synctex" - # "--keep-logs" - # "--keep-intermediates" - # ]; - # description = '' - # Defines additional arguments that are passed to the configured LaTeX build tool. - # Note that flags and their arguments need to be separate elements in this array. - # To pass the arguments -foo bar to a build tool, args needs to be ["-foo" "bar"]. - # The placeholder `%f` will be replaced by the server. - # - # Placeholders: - # - `%f`: The path of the TeX file to compile. - # ''; - # }; - # }; - # - # forwardSearchAfter = mkOption { - # type = bool; - # default = false; - # description = "Set this property to true if you want to execute a forward search after a build."; - # }; - # onSave = mkOption { - # type = bool; - # default = false; - # description = "Set this property to true if you want to compile the project after saving a file."; - # }; - # useFileList = mkOption { - # type = bool; - # default = false; - # description = '' - # When set to true, the server will use the .fls files produced by the TeX engine as an additional input for the project detection. - # - # Note that enabling this property might have an impact on performance. - # ''; - # }; - # auxDirectory = mkOption { - # type = str; - # default = "."; - # description = '' - # When not using latexmk, provides a way to define the directory containing the .aux files. - # Note that you need to set the aux directory in latex.build.args too. - # - # When using a latexmkrc file, texlab will automatically infer the correct setting. - # ''; - # }; - # logDirectory = mkOption { - # type = str; - # default = "."; - # description = '' - # When not using latexmk, provides a way to define the directory containing the build log files. - # Note that you need to change the output directory in your build arguments too. - # - # When using a latexmkrc file, texlab will automatically infer the correct setting. - # ''; - # }; - # pdfDirectory = mkOption { - # type = str; - # default = "."; - # description = '' - # When not using latexmk, provides a way to define the directory containing the output files. - # Note that you need to set the output directory in latex.build.args too. - # - # When using a latexmkrc file, texlab will automatically infer the correct setting. - # ''; - # }; - # filename = mkOption { - # type = str; - # default = ""; - # description = '' - # Allows overriding the default file name of the build artifact. This setting is used to find the correct PDF file to open during forward search. - # ''; - # }; - # }; - # - # forwardSearch = { - # enable = mkOption { - # type = bool; - # default = false; - # example = true; - # description = '' - # Whether to enable forward search. - # - # Enable this option if you want to have the compiled document appear in your chosen PDF viewer. - # - # For some options see [here](https://github.com/latex-lsp/texlab/wiki/Previewing). - # Note this is not all the options, but can act as a guide to help you allong with custom configs. - # ''; - # }; - # package = mkOption { - # type = package; - # default = pkgs.okular; - # description = '' - # The package to use as your PDF viewer. - # This viewer needs to support Synctex. - # ''; - # }; - # executable = mkOption { - # type = str; - # default = "okular"; - # description = '' - # Defines the executable of the PDF previewer. The previewer needs to support SyncTeX. - # ''; - # }; - # args = mkOption { - # type = listOf str; - # default = [ - # "--unique" - # "file:%p#src:%l%f" - # ]; - # description = '' - # Defines additional arguments that are passed to the configured previewer to perform the forward search. - # The placeholders %f, %p, %l will be replaced by the server. - # - # Placeholders: - # - %f: The path of the current TeX file. - # - %p: The path of the current PDF file. - # - %l: The current line number. - # ''; - # }; - # }; - # - # extraLuaSettings = mkOption { - # type = str; - # default = ""; - # example = '' - # formatterLineLength = 80, - # ''; - # description = '' - # For any options that do not have options provided through nvf this can be used to add them. - # Options already declared in nvf config will NOT be overridden. - # - # Options will be placed in: - # ``` - # lspconfig.texlab.setup { - # settings = { - # texlab = { - # ... - # - # ... - # - # } - # } - # } - # ``` - # ''; - # }; - # }; - # Add other LSPs here - # }; - - # config = mkIf cfg.enable (mkMerge [ - # (mkIf (any (x: x.enable) (attrValues cfg.lsp)) ( - config = mkIf (cfg.enable && (any (x: x.enable) (attrValues cfg.lsp))) ( - { - vim.lsp.lspconfig.enable = true; - } # Enable lspconfig when any of the lsps are enabled - # // (mkMerge [ - # # ----- Texlab ----- - # ( - # let - # tl = cfg.lsp.texlab; - # build = tl.build; - # - # listToLua = list: nullOnEmpty: - # if length list == 0 - # then - # if nullOnEmpty - # then "null" - # else "{ }" - # else "{ ${concatStringsSep ", " (map (x: ''"${toString x}"'') list)} }"; - # - # stringToLua = string: nullOnEmpty: - # if string == "" - # then - # if nullOnEmpty - # then "null" - # else "" - # else ''"${string}"''; - # - # boolToLua = boolean: - # if boolean - # then "true" - # else "false"; - # - # # -- Build -- - # buildConfig = let - # # This function will sort through the builder options of ...texlab.build and count how many - # # builders have been enabled and get the attrs of the last enabled builder. - # getBuilder = { - # enabledBuildersCount ? 0, - # enabledBuilderName ? "", - # index ? 0, - # builderNamesList ? ( - # filter ( - # x: let - # y = tl.build.${x}; - # in (isAttrs y && hasAttr "enable" y) - # ) (attrNames tl.build) - # ), - # }: let - # currentBuilderName = elemAt builderNamesList index; - # currentBuilder = tl.build.${currentBuilderName}; - # nextIndex = index + 1; - # currentState = { - # enabledBuildersCount = - # if currentBuilder.enable - # then enabledBuildersCount + 1 - # else enabledBuildersCount; - # enabledBuilderName = - # if currentBuilder.enable - # then currentBuilderName - # else enabledBuilderName; - # }; - # in - # if length builderNamesList > nextIndex - # then - # getBuilder ({ - # inherit builderNamesList; - # index = nextIndex; - # } - # // currentState) - # else currentState; - # - # getBuilderResults = getBuilder {}; - # builder = tl.build.${getBuilderResults.enabledBuilderName}; - # builderArgs = collateArgs.lsp.texlab.build.${getBuilderResults.enabledBuilderName} tl.build; - # in - # if getBuilderResults.enabledBuildersCount == 0 - # then "" - # else if getBuilderResults.enabledBuildersCount > 1 - # then throw "Texlab does not support having more than 1 builders enabled!" - # else '' - # build = { - # executable = "${builder.package}/bin/${builder.executable}", - # args = ${listToLua builderArgs false}, - # forwardSearchAfter = ${boolToLua build.forwardSearchAfter}, - # onSave = ${boolToLua build.onSave}, - # useFileList = ${boolToLua build.useFileList}, - # auxDirectory = ${stringToLua build.auxDirectory true}, - # logDirectory = ${stringToLua build.logDirectory true}, - # pdfDirectory = ${stringToLua build.pdfDirectory true}, - # filename = ${stringToLua build.filename true}, - # }, - # ''; - # in (mkIf tl.enable { - # vim.lsp.lspconfig.sources.texlab = '' - # lspconfig.texlab.setup { - # cmd = { "${tl.package}/bin/texlab" }, - # settings = { - # texlab = { - # ${buildConfig} - # forwardSearch = { - # executable = "${tl.forwardSearch.package}/bin/${tl.forwardSearch.executable}", - # args = ${listToLua tl.forwardSearch.args true} - # }, - # ${tl.extraLuaSettings} - # } - # } - # } - # ''; - # }) - # ) - # - # # Add other LSPs here - # ]) - ); + config = mkIf (cfg.enable && (any (x: x.enable) (attrValues cfg.lsp))) { + vim.lsp.lspconfig.enable = true; # Enable lspconfig when any of the lsps are enabled + }; } diff --git a/modules/plugins/languages/tex/lsp/texlab.nix b/modules/plugins/languages/tex/lsp/texlab.nix index cd7b85dc..0f21aa3a 100644 --- a/modules/plugins/languages/tex/lsp/texlab.nix +++ b/modules/plugins/languages/tex/lsp/texlab.nix @@ -1,28 +1,36 @@ +# TODO: +# - Add Texlab LSP settings: +# - chktex +# - diagnosticsDelay +# - diagnostics +# - symbols +# - formatterLineLength +# - bibtexFormatter +# - latexFormatter +# - latexindent +# - completion +# - inlayHints +# - experimental { config, pkgs, lib, ... }: let - inherit (lib.options) mkEnableOption mkOption; - inherit (lib.modules) mkIf mkMerge; + inherit (lib.options) mkOption; + inherit (lib.modules) mkIf; inherit (lib.types) bool - either enum ints listOf - oneOf package str ; - inherit (lib.nvim.types) mkGrammarOption; inherit (builtins) - any attrNames - attrValues concatLists concatStringsSep elem diff --git a/modules/plugins/languages/tex/treesitter.nix b/modules/plugins/languages/tex/treesitter.nix index 3b70165e..44459afb 100644 --- a/modules/plugins/languages/tex/treesitter.nix +++ b/modules/plugins/languages/tex/treesitter.nix @@ -3,18 +3,15 @@ pkgs, lib, ... -}: -let +}: let inherit (lib.options) mkEnableOption; inherit (lib.modules) mkIf mkMerge; inherit (lib.nvim.types) mkGrammarOption; cfg = config.vim.languages.tex; - mkEnableTreesitterOption = - description: mkEnableOption description // { default = config.vim.languages.enableTreesitter; }; -in -{ + mkEnableTreesitterOption = description: mkEnableOption description // {default = config.vim.languages.enableTreesitter;}; +in { options.vim.languages.tex.treesitter = { latex = { enable = mkEnableTreesitterOption "Whether to enable Latex treesitter"; @@ -29,11 +26,11 @@ in config = mkIf cfg.enable (mkMerge [ (mkIf cfg.treesitter.latex.enable { vim.treesitter.enable = true; - vim.treesitter.grammars = [ cfg.treesitter.latex.package ]; + vim.treesitter.grammars = [cfg.treesitter.latex.package]; }) (mkIf cfg.treesitter.bibtex.enable { vim.treesitter.enable = true; - vim.treesitter.grammars = [ cfg.treesitter.bibtex.package ]; + vim.treesitter.grammars = [cfg.treesitter.bibtex.package]; }) ]); } From 44959a0c8af7ee0dea46dded0e560a657a8400a8 Mon Sep 17 00:00:00 2001 From: isaacST08 Date: Thu, 23 Jan 2025 19:35:00 -0700 Subject: [PATCH 6/6] Created build module --- .../languages/tex/build/builders/custom.nix | 86 +++ .../languages/tex/build/builders/default.nix | 65 ++ .../languages/tex/build/builders/tectonic.nix | 231 +++++++ .../plugins/languages/tex/build/default.nix | 107 +++ modules/plugins/languages/tex/default.nix | 1 + modules/plugins/languages/tex/lsp/texlab.nix | 632 +++++++++--------- 6 files changed, 820 insertions(+), 302 deletions(-) create mode 100644 modules/plugins/languages/tex/build/builders/custom.nix create mode 100644 modules/plugins/languages/tex/build/builders/default.nix create mode 100644 modules/plugins/languages/tex/build/builders/tectonic.nix create mode 100644 modules/plugins/languages/tex/build/default.nix diff --git a/modules/plugins/languages/tex/build/builders/custom.nix b/modules/plugins/languages/tex/build/builders/custom.nix new file mode 100644 index 00000000..680d37a9 --- /dev/null +++ b/modules/plugins/languages/tex/build/builders/custom.nix @@ -0,0 +1,86 @@ +{ + config, + pkgs, + lib, + ... +}: let + inherit (lib.options) mkOption; + inherit (lib.modules) mkIf; + inherit + (lib.types) + bool + enum + ints + listOf + package + str + ; + inherit + (builtins) + attrNames + concatLists + concatStringsSep + elem + elemAt + filter + hasAttr + isAttrs + length + map + throw + toString + ; + + cfg = config.vim.languages.tex; + + # --- Enable Options --- + mkEnableDefaultOption = default: description: (mkOption { + type = bool; + default = default; + example = !default; + description = description; + }); + + collateArgs = buildConfig: buildConfig.builders.custom.args; +in { + options.vim.languages.tex.build.builders.custom = { + enable = mkEnableDefaultOption false "Whether to enable using a custom build package"; + package = mkOption { + type = package; + default = pkgs.tectonic; + description = "build/compiler package"; + }; + executable = mkOption { + type = str; + default = "tectonic"; + description = "The executable name from the build package that will be used to build/compile the tex."; + }; + args = mkOption { + type = listOf str; + default = [ + "-X" + "compile" + "%f" + "--synctex" + "--keep-logs" + "--keep-intermediates" + ]; + description = '' + Defines additional arguments that are passed to the configured LaTeX build tool. + Note that flags and their arguments need to be separate elements in this array. + To pass the arguments -foo bar to a build tool, args needs to be ["-foo" "bar"]. + The placeholder `%f` will be replaced by the server. + + Placeholders: + - `%f`: The path of the TeX file to compile. + ''; + }; + }; + + config = mkIf (cfg.enable && cfg.build.builders.custom.enable) { + vim.languages.tex.build.builder = { + name = "custom"; + args = collateArgs cfg.build; + }; + }; +} diff --git a/modules/plugins/languages/tex/build/builders/default.nix b/modules/plugins/languages/tex/build/builders/default.nix new file mode 100644 index 00000000..da00fbdb --- /dev/null +++ b/modules/plugins/languages/tex/build/builders/default.nix @@ -0,0 +1,65 @@ +{ + config, + pkgs, + lib, + ... +}: +let + inherit (lib.options) mkOption mkEnableOption; + inherit + (lib.types) + bool + enum + ints + listOf + package + str + ; + inherit + (builtins) + attrNames + concatLists + concatStringsSep + elem + elemAt + filter + hasAttr + isAttrs + length + map + throw + toString + ; + + cfg = config.vim.languages.tex; +in +{ + imports = [ + ./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"; + }; + args = mkOption { + type = listOf str; + default = []; + description = "The list of args to pass to the builder"; + }; + package = mkOption { + type = package; + default = cfg.build.builders.tectonic.package; + description = "The tex builder package to use"; + }; + executable = mkOption { + type = str; + default = cfg.build.builders.tectonic.executable; + description = "The tex builder executable to use"; + }; + }; +} + diff --git a/modules/plugins/languages/tex/build/builders/tectonic.nix b/modules/plugins/languages/tex/build/builders/tectonic.nix new file mode 100644 index 00000000..0ec8bea0 --- /dev/null +++ b/modules/plugins/languages/tex/build/builders/tectonic.nix @@ -0,0 +1,231 @@ +{ + config, + pkgs, + lib, + ... +}: let + inherit (lib.options) mkOption mkEnableOption; + inherit (lib.modules) mkIf; + inherit + (lib.types) + bool + enum + ints + listOf + package + str + ; + inherit + (builtins) + attrNames + concatLists + concatStringsSep + elem + elemAt + filter + hasAttr + isAttrs + length + map + throw + toString + ; + + cfg = config.vim.languages.tex; + + # --- Enable Options --- + mkEnableDefaultOption = default: description: (mkOption { + type = bool; + default = default; + example = !default; + description = description; + }); + mkEnableLspOption = mkEnableDefaultOption config.vim.languages.enableLSP; + + # --- 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 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; + }; + }; +} diff --git a/modules/plugins/languages/tex/build/default.nix b/modules/plugins/languages/tex/build/default.nix new file mode 100644 index 00000000..0882565e --- /dev/null +++ b/modules/plugins/languages/tex/build/default.nix @@ -0,0 +1,107 @@ +{ + config, + pkgs, + lib, + ... +}: let + inherit (lib.options) mkOption; + inherit (lib.modules) mkIf; + inherit + (lib.types) + bool + enum + ints + listOf + package + str + ; + inherit + (builtins) + attrNames + concatLists + concatStringsSep + elem + elemAt + filter + hasAttr + isAttrs + length + map + throw + toString + ; + + cfg = config.vim.languages.tex; + + # --- Enable Options --- + mkEnableDefaultOption = default: description: (mkOption { + type = bool; + default = default; + example = !default; + description = description; + }); + mkEnableLspOption = mkEnableDefaultOption config.vim.languages.enableLSP; +in { + imports = [ + ./builders + ]; + + options.vim.languages.tex.build = { + forwardSearchAfter = mkOption { + type = bool; + default = false; + description = "Set this property to true if you want to execute a forward search after a build."; + }; + onSave = mkOption { + type = bool; + default = false; + description = "Set this property to true if you want to compile the project after saving a file."; + }; + useFileList = mkOption { + type = bool; + default = false; + description = '' + When set to true, the server will use the .fls files produced by the TeX engine as an additional input for the project detection. + + Note that enabling this property might have an impact on performance. + ''; + }; + auxDirectory = mkOption { + type = str; + default = "."; + description = '' + When not using latexmk, provides a way to define the directory containing the .aux files. + Note that you need to set the aux directory in latex.build.args too. + + When using a latexmkrc file, texlab will automatically infer the correct setting. + ''; + }; + logDirectory = mkOption { + type = str; + default = "."; + description = '' + When not using latexmk, provides a way to define the directory containing the build log files. + Note that you need to change the output directory in your build arguments too. + + When using a latexmkrc file, texlab will automatically infer the correct setting. + ''; + }; + pdfDirectory = mkOption { + type = str; + default = "."; + description = '' + When not using latexmk, provides a way to define the directory containing the output files. + Note that you need to set the output directory in latex.build.args too. + + When using a latexmkrc file, texlab will automatically infer the correct setting. + ''; + }; + filename = mkOption { + type = str; + default = ""; + description = '' + Allows overriding the default file name of the build artifact. This setting is used to find the correct PDF file to open during forward search. + ''; + }; + }; +} diff --git a/modules/plugins/languages/tex/default.nix b/modules/plugins/languages/tex/default.nix index 944f43f2..98ac5f1c 100644 --- a/modules/plugins/languages/tex/default.nix +++ b/modules/plugins/languages/tex/default.nix @@ -12,6 +12,7 @@ in { imports = [ ./treesitter.nix ./lsp + ./build ]; options.vim.languages.tex = { diff --git a/modules/plugins/languages/tex/lsp/texlab.nix b/modules/plugins/languages/tex/lsp/texlab.nix index 0f21aa3a..498a6017 100644 --- a/modules/plugins/languages/tex/lsp/texlab.nix +++ b/modules/plugins/languages/tex/lsp/texlab.nix @@ -56,85 +56,85 @@ mkEnableLspOption = mkEnableDefaultOption config.vim.languages.enableLSP; # --- Arg Collation Functions -- - collateArgs.lsp.texlab.build = { - tectonic = buildConfig: let - selfConfig = buildConfig.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 [] - ) - ); - custom = buildConfig: buildConfig.custom.args; - }; + # collateArgs.lsp.texlab.build = { + # tectonic = buildConfig: let + # selfConfig = buildConfig.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 [] + # ) + # ); + # custom = buildConfig: buildConfig.custom.args; # Moved + # }; in { options.vim.languages.tex.lsp.texlab = { enable = mkEnableLspOption "Whether to enable Tex LSP support (texlab)"; @@ -145,199 +145,200 @@ in { description = "texlab package"; }; - build = { - tectonic = { - enable = mkEnableDefaultOption true "Whether to enable Tex Compilation Via Tectonic"; + # build = { + # tectonic = { + # enable = mkEnableDefaultOption true "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 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. + # ''; + # }; + # }; - package = mkOption { - type = package; - default = pkgs.tectonic; - description = "tectonic package"; - }; + # # Moved + # custom = { + # enable = mkEnableDefaultOption false "Whether to enable using a custom build package"; + # package = mkOption { + # type = package; + # default = pkgs.tectonic; + # description = "build/compiler package"; + # }; + # executable = mkOption { + # type = str; + # default = "tectonic"; + # description = "The executable name from the build package that will be used to build/compile the tex."; + # }; + # args = mkOption { + # type = listOf str; + # default = [ + # "-X" + # "compile" + # "%f" + # "--synctex" + # "--keep-logs" + # "--keep-intermediates" + # ]; + # description = '' + # Defines additional arguments that are passed to the configured LaTeX build tool. + # Note that flags and their arguments need to be separate elements in this array. + # To pass the arguments -foo bar to a build tool, args needs to be ["-foo" "bar"]. + # The placeholder `%f` will be replaced by the server. + # + # Placeholders: + # - `%f`: The path of the TeX file to compile. + # ''; + # }; + # }; - 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 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. - ''; - }; - }; - - custom = { - enable = mkEnableDefaultOption false "Whether to enable using a custom build package"; - package = mkOption { - type = package; - default = pkgs.tectonic; - description = "build/compiler package"; - }; - executable = mkOption { - type = str; - default = "tectonic"; - description = "The executable name from the build package that will be used to build/compile the tex."; - }; - args = mkOption { - type = listOf str; - default = [ - "-X" - "compile" - "%f" - "--synctex" - "--keep-logs" - "--keep-intermediates" - ]; - description = '' - Defines additional arguments that are passed to the configured LaTeX build tool. - Note that flags and their arguments need to be separate elements in this array. - To pass the arguments -foo bar to a build tool, args needs to be ["-foo" "bar"]. - The placeholder `%f` will be replaced by the server. - - Placeholders: - - `%f`: The path of the TeX file to compile. - ''; - }; - }; - - forwardSearchAfter = mkOption { - type = bool; - default = false; - description = "Set this property to true if you want to execute a forward search after a build."; - }; - onSave = mkOption { - type = bool; - default = false; - description = "Set this property to true if you want to compile the project after saving a file."; - }; - useFileList = mkOption { - type = bool; - default = false; - description = '' - When set to true, the server will use the .fls files produced by the TeX engine as an additional input for the project detection. - - Note that enabling this property might have an impact on performance. - ''; - }; - auxDirectory = mkOption { - type = str; - default = "."; - description = '' - When not using latexmk, provides a way to define the directory containing the .aux files. - Note that you need to set the aux directory in latex.build.args too. - - When using a latexmkrc file, texlab will automatically infer the correct setting. - ''; - }; - logDirectory = mkOption { - type = str; - default = "."; - description = '' - When not using latexmk, provides a way to define the directory containing the build log files. - Note that you need to change the output directory in your build arguments too. - - When using a latexmkrc file, texlab will automatically infer the correct setting. - ''; - }; - pdfDirectory = mkOption { - type = str; - default = "."; - description = '' - When not using latexmk, provides a way to define the directory containing the output files. - Note that you need to set the output directory in latex.build.args too. - - When using a latexmkrc file, texlab will automatically infer the correct setting. - ''; - }; - filename = mkOption { - type = str; - default = ""; - description = '' - Allows overriding the default file name of the build artifact. This setting is used to find the correct PDF file to open during forward search. - ''; - }; - }; + # forwardSearchAfter = mkOption { + # type = bool; + # default = false; + # description = "Set this property to true if you want to execute a forward search after a build."; + # }; + # onSave = mkOption { + # type = bool; + # default = false; + # description = "Set this property to true if you want to compile the project after saving a file."; + # }; + # useFileList = mkOption { + # type = bool; + # default = false; + # description = '' + # When set to true, the server will use the .fls files produced by the TeX engine as an additional input for the project detection. + # + # Note that enabling this property might have an impact on performance. + # ''; + # }; + # auxDirectory = mkOption { + # type = str; + # default = "."; + # description = '' + # When not using latexmk, provides a way to define the directory containing the .aux files. + # Note that you need to set the aux directory in latex.build.args too. + # + # When using a latexmkrc file, texlab will automatically infer the correct setting. + # ''; + # }; + # logDirectory = mkOption { + # type = str; + # default = "."; + # description = '' + # When not using latexmk, provides a way to define the directory containing the build log files. + # Note that you need to change the output directory in your build arguments too. + # + # When using a latexmkrc file, texlab will automatically infer the correct setting. + # ''; + # }; + # pdfDirectory = mkOption { + # type = str; + # default = "."; + # description = '' + # When not using latexmk, provides a way to define the directory containing the output files. + # Note that you need to set the output directory in latex.build.args too. + # + # When using a latexmkrc file, texlab will automatically infer the correct setting. + # ''; + # }; + # filename = mkOption { + # type = str; + # default = ""; + # description = '' + # Allows overriding the default file name of the build artifact. This setting is used to find the correct PDF file to open during forward search. + # ''; + # }; + # }; forwardSearch = { enable = mkOption { @@ -416,7 +417,7 @@ in { config = mkIf (cfg.enable && (cfg.lsp.texlab.enable)) ( let tl = cfg.lsp.texlab; - build = tl.build; + builder = cfg.build.builder; listToLua = list: nullOnEmpty: if length list == 0 @@ -443,60 +444,87 @@ in { buildConfig = let # This function will sort through the builder options of ...texlab.build and count how many # builders have been enabled and get the attrs of the last enabled builder. - getBuilder = { + # getBuilder = { + # enabledBuildersCount ? 0, + # enabledBuilderName ? "", + # index ? 0, + # builderNamesList ? ( + # filter ( + # x: let + # y = cfg.build.builders.${x}; + # in (isAttrs y && hasAttr "enable" y) + # ) (attrNames cfg.build.builders) + # ), + # }: let + # currentBuilderName = elemAt builderNamesList index; + # currentBuilder = tl.build.${currentBuilderName}; + # nextIndex = index + 1; + # currentState = { + # enabledBuildersCount = + # if currentBuilder.enable + # then enabledBuildersCount + 1 + # else enabledBuildersCount; + # enabledBuilderName = + # if currentBuilder.enable + # then currentBuilderName + # else enabledBuilderName; + # }; + # in + # if length builderNamesList > nextIndex + # then + # getBuilder ({ + # inherit builderNamesList; + # index = nextIndex; + # } + # // currentState) + # else currentState; + getEnabledBuildersCount = { enabledBuildersCount ? 0, - enabledBuilderName ? "", index ? 0, builderNamesList ? ( filter ( x: let - y = tl.build.${x}; + y = cfg.build.builders.${x}; in (isAttrs y && hasAttr "enable" y) - ) (attrNames tl.build) + ) (attrNames cfg.build.builders) ), }: let currentBuilderName = elemAt builderNamesList index; - currentBuilder = tl.build.${currentBuilderName}; + currentBuilder = cfg.build.builders.${currentBuilderName}; nextIndex = index + 1; - currentState = { - enabledBuildersCount = - if currentBuilder.enable - then enabledBuildersCount + 1 - else enabledBuildersCount; - enabledBuilderName = - if currentBuilder.enable - then currentBuilderName - else enabledBuilderName; - }; + newEnabledBuildersCount = + if currentBuilder.enable + then enabledBuildersCount + 1 + else enabledBuildersCount; in if length builderNamesList > nextIndex then - getBuilder ({ + getEnabledBuildersCount { inherit builderNamesList; + enabledBuildersCount = newEnabledBuildersCount; index = nextIndex; } - // currentState) - else currentState; + else newEnabledBuildersCount; - getBuilderResults = getBuilder {}; - builder = tl.build.${getBuilderResults.enabledBuilderName}; - builderArgs = collateArgs.lsp.texlab.build.${getBuilderResults.enabledBuilderName} tl.build; + enabledBuildersCount = getEnabledBuildersCount {}; + # builder = tl.build.${getBuilderResults.enabledBuilderName}; + # builderArgs = collateArgs.lsp.texlab.build.${getBuilderResults.enabledBuilderName} tl.build; in - if getBuilderResults.enabledBuildersCount == 0 + if enabledBuildersCount == 0 then "" - else if getBuilderResults.enabledBuildersCount > 1 + else if enabledBuildersCount > 1 then throw "Texlab does not support having more than 1 builders enabled!" else '' build = { executable = "${builder.package}/bin/${builder.executable}", - args = ${listToLua builderArgs false}, - forwardSearchAfter = ${boolToLua build.forwardSearchAfter}, - onSave = ${boolToLua build.onSave}, - useFileList = ${boolToLua build.useFileList}, - auxDirectory = ${stringToLua build.auxDirectory true}, - logDirectory = ${stringToLua build.logDirectory true}, - pdfDirectory = ${stringToLua build.pdfDirectory true}, - filename = ${stringToLua build.filename true}, + args = ${listToLua builder.args false}, + forwardSearchAfter = ${boolToLua cfg.build.forwardSearchAfter}, + onSave = ${boolToLua cfg.build.onSave}, + useFileList = ${boolToLua cfg.build.useFileList}, + auxDirectory = ${stringToLua cfg.build.auxDirectory true}, + logDirectory = ${stringToLua cfg.build.logDirectory true}, + pdfDirectory = ${stringToLua cfg.build.pdfDirectory true}, + filename = ${stringToLua cfg.build.filename true}, }, ''; in {