This commit is contained in:
Isaac Shiells Thomas 2025-12-25 01:52:49 +08:00 committed by GitHub
commit 3ff6928243
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
14 changed files with 920 additions and 7 deletions

View file

@ -79,6 +79,8 @@ languages have sections under the `vim.languages` attribute.
[vim.languages.tailwind.enable](./options.html#option-vim-languages-tailwind-enable)
- Terraform:
[vim.languages.terraform.enable](./options.html#option-vim-languages-terraform-enable)
- Tex:
[vim.languages.tex.enable](./options.html#option-vim-languages-tex-enable)
- Typst:
[vim.languages.typst.enable](./options.html#option-vim-languages-typst-enable)
- Vala:

View file

@ -9,6 +9,6 @@
in {
inherit (typesDag) dagOf;
inherit (typesPlugin) pluginsOpt extraPluginType mkPluginSetupOption luaInline pluginType borderType;
inherit (typesLanguage) diagnostics mkGrammarOption;
inherit (typesLanguage) diagnostics mkGrammarOption mkEnableTreesitterOption;
inherit (customTypes) char hexColor mergelessListOf deprecatedSingleOrListOf;
}

View file

@ -1,7 +1,7 @@
{lib}: let
inherit (lib.options) mkOption mkPackageOption;
inherit (lib.attrsets) attrNames;
inherit (lib.types) listOf either enum submodule package;
inherit (lib.types) listOf either enum submodule package bool;
diagnosticSubmodule = _: {
options = {
@ -32,6 +32,13 @@
mkPackageOption pkgs ["${grammar} treesitter"] {
default = ["vimPlugins" "nvim-treesitter" "builtGrammars" grammar];
};
mkEnableTreesitterOption = defaultCondition: language:
mkOption {
type = bool;
default = defaultCondition;
description = "Whether to enable ${language} treesitter";
};
in {
inherit diagnostics diagnosticSubmodule mkGrammarOption;
inherit diagnostics diagnosticSubmodule mkGrammarOption mkEnableTreesitterOption;
}

View file

@ -38,6 +38,7 @@ in {
./svelte.nix
./tailwind.nix
./terraform.nix
./tex
./ts.nix
./typst.nix
./zig.nix

View file

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

View file

@ -0,0 +1,57 @@
# TODO: I need testing.
{
config,
lib,
pkgs,
...
}: let
# The name of the builder
name = "latexmk";
inherit (lib.modules) mkIf;
inherit (lib.nvim.config) mkBool;
inherit (lib.options) mkOption mkEnableOption;
inherit (lib.types) package str;
texCfg = config.vim.languages.tex;
cfg = texCfg.build.builders.${name};
in {
options.vim.languages.tex.build.builders.${name} = {
enable = mkEnableOption "Tex Compilation Via latexmk";
package = mkOption {
type = package;
default = pkgs.texlive.withPackages (ps: [ps.latexmk]);
description = "latexmk package";
};
executable = mkOption {
type = str;
default = "latexmk";
description = ''
The executable name from the build package that will be used to
build/compile the tex.
'';
};
# Flag options
pdfOutput = mkBool true "Insure the output file is a pdf.";
};
config = mkIf (texCfg.enable && cfg.enable) {
vim.languages.tex.build.builder = {
inherit name;
inherit (cfg) package executable;
args = (
# Flags
(lib.lists.optional cfg.pdfOutput "-pdf")
# Base args
++ [
"-quiet"
"%f"
]
);
};
};
}

View file

@ -0,0 +1,184 @@
{
config,
lib,
pkgs,
...
}: let
# The name of the builder
name = "tectonic";
inherit (builtins) concatLists elem map toString match;
inherit (lib.modules) mkIf;
inherit (lib.nvim.config) mkBool;
inherit (lib.options) mkOption mkEnableOption mkPackageOption;
inherit (lib.strings) toLower optionalString stringAsChars;
inherit (lib.types) enum ints listOf str nullOr;
texCfg = config.vim.languages.tex;
cfg = texCfg.build.builders.${name};
in {
options.vim.languages.tex.build.builders.${name} = {
enable = mkEnableOption "Tex Compilation Via Tectonic";
package = mkPackageOption pkgs "tectonic" {};
executable = mkOption {
type = str;
default = "tectonic";
description = ''
The executable name from the build package that will be used to
build/compile the tex.
'';
};
# -- Flags --
keepIntermediates = mkBool false ''
Whether to keep the intermediate files generated during processing.
If texlab is reporting build errors when there shouldn't be, disable
this option.
'';
keepLogs = mkBool true ''
Whether to keep the log files generated during processing.
Without the keepLogs flag, texlab won't be able to report compilation
warnings.
'';
onlyCached = mkBool false ''
Whether to use only resource files cached locally
'';
synctex = mkBool true "Whether to generate SyncTeX data";
untrustedInput = mkBool false ''
Whether to disable all known-insecure features if the input is untrusted
'';
# -- Options --
reruns = mkOption {
type = ints.unsigned;
default = 0;
example = 2;
description = ''
How many times to *rerun* the TeX build engine.
The build engine (if a builder is enabled) will always run at least
once.
Setting this value to 0 will disable setting this option.
'';
};
bundle = mkOption {
type = nullOr str;
default = null;
description = ''
The directory or Zip-format bundle file to find resource files instead
of the default.
'';
};
webBundle = mkOption {
type = nullOr str;
default = null;
description = ''
Use this URL to find resource files instead of the default.
'';
};
outfmt = mkOption {
type = nullOr (enum [
"pdf"
"html"
"xdv"
"aux"
"fmt"
]);
default = null;
description = ''
The kind of output to generate.
Setting this to `null` (default) will let tectonic decide the most
appropriate output format, which usually be a pdf.
'';
};
hidePaths = mkOption {
type = listOf str;
default = [];
example = [
"./secrets.tex"
"./passwords.tex"
];
description = ''
Tell the engine that no file at `<path/to/hide>` exists, if it tries
to read it.
'';
};
format = mkOption {
type = nullOr str;
default = null;
description = ''
The name of the \"format\" file used to initialize the TeX engine.
'';
};
color = mkOption {
type = nullOr (enum [
"always"
"auto"
"never"
]);
default = null;
example = "always";
description = "Enable/disable colorful log output";
};
extraOptions = mkOption {
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 (texCfg.enable && cfg.enable) {
vim.languages.tex.build.builder = {
inherit name;
inherit (cfg) package executable;
args = let
inherit (lib.lists) optional optionals;
snakeCaseToKebabCase = str: stringAsChars (x: "${optionalString ((match "[A-Z]" x) != null) "-"}${toLower x}") str;
generateOptionFlag = option: (optionals (cfg.${option} != "" && cfg.${option} != null) ["--${snakeCaseToKebabCase option}" "${toString cfg.${option}}"]);
in (
# Base args
[
"-X"
"compile"
"%f"
]
# Flags
++ (optional cfg.keepIntermediates "--keep-intermediates")
++ (optional cfg.keepLogs "--keep-logs")
++ (optional cfg.onlyCached "--only-cached")
++ (optional cfg.synctex "--synctex")
++ (optional cfg.untrustedInput "--untrusted")
# Options
++ (optionals (cfg.reruns > 0) ["--reruns" "${toString cfg.reruns}"])
++ (generateOptionFlag "bundle")
++ (generateOptionFlag "webBundle")
++ (generateOptionFlag "outfmt")
++ (concatLists (map (x: ["--hide" x]) cfg.hidePaths))
++ (generateOptionFlag "format")
++ (generateOptionFlag "color")
# Still options but these are not defined by builder specific options but
# instead synchronize options between the global build options and builder
# specific options.
++ (optionals (!(elem texCfg.build.pdfDirectory ["." ""])) ["--outdir" "${texCfg.build.pdfDirectory}"])
);
};
};
}

View file

@ -0,0 +1,140 @@
{
config,
lib,
...
}: let
inherit (builtins) filter isAttrs hasAttr attrNames length elemAt;
inherit (lib.modules) mkIf;
inherit (lib.nvim.config) mkBool;
inherit (lib.options) mkOption;
inherit (lib.types) str nullOr;
cfg = config.vim.languages.tex;
enabledBuildersCount = let
# This function will sort through the builder options and count how many
# builders have been enabled.
getEnabledBuildersCount = {
enabledBuildersCount ? 0,
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 = cfg.build.builders.${currentBuilderName};
nextIndex = index + 1;
newEnabledBuildersCount =
if currentBuilder.enable
then enabledBuildersCount + 1
else enabledBuildersCount;
in
if length builderNamesList > nextIndex
then
getEnabledBuildersCount {
inherit builderNamesList;
enabledBuildersCount = newEnabledBuildersCount;
index = nextIndex;
}
else newEnabledBuildersCount;
in (getEnabledBuildersCount {});
in {
imports = [
./builders
];
options.vim.languages.tex.build = {
enable = mkBool (enabledBuildersCount == 1) ''
Whether to enable configuring the builder.
By enabling any of the builders, this option will be automatically set.
If you enable more than one builder then an error will be thrown.
'';
forwardSearchAfter = mkBool false ''
Set this property to `true` if you want to execute a forward search after
a build.
This can also be thought of as enabling auto updating for your pdf viewer.
'';
onSave = mkBool false ''
Set this property to `true` if you want to compile the project after
saving a file.
'';
useFileList = mkBool false ''
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 = nullOr str;
default = null;
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.
'';
};
};
config = mkIf (enabledBuildersCount > 0) {
assertions = [
{
assertion = enabledBuildersCount < 2;
message = ''
The nvf-tex-language implementation does not support having more than
1 builders enabled.
'';
}
];
};
}

View file

@ -0,0 +1,79 @@
{
config,
lib,
...
}: let
inherit (lib.modules) mkIf mkMerge;
inherit (lib.nvim.config) mkBool;
inherit (lib.options) mkEnableOption mkOption;
inherit (lib.types) enum;
cfg = config.vim.languages.tex;
in {
imports = [
./build
./formatter.nix
./lsp.nix
./pdfViewer.nix
./treesitter.nix
];
options.vim.languages.tex = {
enable = mkEnableOption "Tex support";
extraOpts = {
texFlavor = {
enable = mkBool false ''
Whether to set the `vim.g.tex_flavor` (`g:tex_flavor`) option in
your Lua config.
When opening a `.tex` file vim will try to automatically try to
determine the file type from the three options: `plaintex` (for
plain TeX), `context` (for ConTeXt), or `tex` (for LaTeX).
This can either be done by a indicator line of the form `%&<format>`
on the first line or, if absent, vim will search the file for
keywords to try and determine the filetype. If no filetype can be
determined automatically then by default it will fallback to
plaintex.
This option will enable setting the tex flavor in your lua config
and you can set its value using the
`vim.languages.tex.lsp.extraOpts.texFlavor.flavor = <flavor>` in
your nvf config.
Setting this option to `false` will omit the
`vim.g.tex_flavor = <flavor>` line from your lua config entirely
(unless you manually set it elsewhere of course).
'';
flavor = mkOption {
type = enum [
"plaintex"
"context"
"tex"
];
default = "plaintex";
example = "tex";
description = ''
The flavor to set as a fallback for when vim cannot automatically
determine the tex flavor when opening a `.tex` document.
The options are: `plaintex` (for plain TeX), `context` (for
ConTeXt), or `tex` (for LaTeX).
This can be particularly useful for when using
`vim.utility.new-file-template` options for creating templates when
no context has yet been added to a new file.
'';
};
};
};
};
config = mkIf cfg.enable (mkMerge [
# Extra Lua config options
(mkIf cfg.extraOpts.texFlavor.enable {
vim.globals.tex_flavor = lib.mkDefault "${cfg.extraOpts.texFlavor.flavor}";
})
]);
}

View file

@ -0,0 +1,56 @@
{
config,
lib,
pkgs,
...
}: let
inherit (lib.options) mkEnableOption mkOption literalMD;
inherit (lib.nvim.types) deprecatedSingleOrListOf;
inherit (lib.attrsets) attrNames;
inherit (lib.modules) mkIf mkMerge;
inherit (lib.nvim.attrsets) mapListToAttrs;
cfg = config.vim.languages.tex;
defaultFormat = ["latexindent"];
formats = {
latexindent = {
command = "${pkgs.texlive.withPackages (ps: [ps.latexindent])}/bin/latexindent";
};
};
in {
options.vim.languages.tex.format = {
enable =
mkEnableOption "TeX formatting"
// {
default = !cfg.lsp.enable && config.vim.languages.enableFormat;
defaultText = literalMD ''
disabled if TeX LSP is enabled, otherwise follows {option}`vim.languages.enableFormat`
'';
};
type = mkOption {
description = "TeX formatter to use";
type = with lib.types; deprecatedSingleOrListOf "vim.language.tex.format.type" (enum (attrNames formats));
default = defaultFormat;
};
};
config = mkIf cfg.enable (mkMerge [
(mkIf cfg.format.enable {
vim.formatter.conform-nvim = {
enable = true;
setupOpts = {
formatters_by_ft.tex = cfg.format.type;
formatters =
mapListToAttrs (name: {
inherit name;
value = formats.${name};
})
cfg.format.type;
};
};
})
]);
}

View file

@ -0,0 +1,107 @@
{
config,
lib,
pkgs,
...
}: let
inherit (lib) getExe;
inherit (lib.attrsets) optionalAttrs attrNames hasAttrByPath;
inherit (lib.options) mkEnableOption mkOption;
inherit (lib.nvim.types) deprecatedSingleOrListOf;
inherit (lib.types) enum;
inherit (lib.modules) mkIf mkMerge;
inherit (lib.nvim.attrsets) mapListToAttrs;
cfg = config.vim.languages.tex;
builderCfg = cfg.build.builder;
pdfViewer = cfg.pdfViewer.viewers.${cfg.pdfViewer.name};
# **===========================================**
# || <<<<< LSP SERVERS >>>>> ||
# **===========================================**
defaultServers = ["texlab"];
servers = {
texlab = {
cmd = [(getExe pkgs.texlab)];
filetypes = ["tex" "plaintex" "context"];
root_markers = [".git"];
capabilities = {
settings.texlab = (
{
# -- Completion --
completion.matcher = "fuzzy-ignore-case";
# -- Diagnostics --
diagnosticsDelay = 300;
# -- Formatters --
formatterLineLength = 80;
bibtexFormatter = "texlab";
latexFormatter = "latexindent";
# -- Inlay Hints --
inlayHints = {
labelDefinitions = true;
labelReferences = true;
};
}
#
# -- Build --
// (optionalAttrs cfg.build.enable {
build = {
inherit
(cfg.build)
onSave
useFileList
auxDirectory
logDirectory
pdfDirectory
filename
forwardSearchAfter
;
inherit (builderCfg) args;
executable = with builderCfg; "${package}/bin/${executable}";
};
})
#
# -- Forward Search --
// (optionalAttrs (cfg.pdfViewer.enable) {
forwardSearch = {
inherit (pdfViewer) args;
executable = with pdfViewer; "${package}/bin/${executable}";
};
})
);
};
};
};
in {
options.vim.languages.tex.lsp = {
enable = mkEnableOption "TeX LSP support" // {default = config.vim.lsp.enable;};
servers = mkOption {
description = "The TeX LSP servers to use";
type = deprecatedSingleOrListOf "vim.language.tex.lsp.servers" (enum (attrNames servers));
default = defaultServers;
};
};
config = mkIf cfg.enable (mkMerge [
(mkIf cfg.lsp.enable {
vim.lsp.servers =
mapListToAttrs (name: {
inherit name;
value = servers.${name};
})
cfg.lsp.servers;
})
# Add the chktex package when texlab has config is set that requires it.
(mkIf (hasAttrByPath ["texlab" "capabilities" "settings" "chktex"] cfg.lsp.servers) {
vim.extraPackages = [(pkgs.texlive.withPackages (ps: [ps.chktex]))];
})
]);
}

View file

@ -0,0 +1,176 @@
{
config,
lib,
pkgs,
...
}: let
inherit (builtins) toString;
inherit (lib) attrNames mkEnableOption mkDefault;
inherit (lib.options) mkOption;
inherit (lib.strings) concatStringsSep;
inherit (lib.types) str package listOf enum;
cfg = config.vim.languages.tex;
# **===============================================**
# || <<<<< Default Viewers >>>>> ||
# **===============================================**
viewers = let
mkPdfViewerDefaults = {
package,
executable,
args ? [],
}: {
package = mkDefault package;
executable = mkDefault executable;
args = mkDefault args;
};
in {
okular = mkPdfViewerDefaults {
package = pkgs.kdePackages.okular;
executable = "okular";
args = [
"--unique"
"file:%p#src:%l%f"
];
};
sioyek = mkPdfViewerDefaults {
package = pkgs.sioyek;
executable = "sioyek";
args = [
"--reuse-window"
"--execute-command"
"toggle_synctex"
"--inverse-search"
"texlab inverse-search -i \"%%1\" -l %%2"
"--forward-search-file"
"%f"
"--forward-search-line"
"%l"
"%p"
];
};
qpdfview = mkPdfViewerDefaults {
package = pkgs.qpdfview;
executable = "qpdfview";
args = [
"--unique"
"%p#src:%f:%l:1"
];
};
zathura = mkPdfViewerDefaults {
package = pkgs.zathura;
executable = "zathura";
args = [
"--synctex-forward"
"%l:1:%f"
"%p"
];
};
};
# **====================================================**
# || <<<<< PDF Viewer Submodule >>>>> ||
# **====================================================**
pdfViewer = {name, ...}: {
options = {
name = mkOption {
type = str;
example = "okular";
description = ''
The name of the pdf viewer to use.
This value will be automatically set when any of the viewers are
enabled.
This value will be automatically set to the value of the parent
attribute set. ex. `...tex.pdfViewer.viewers.<name>.name = "$${name}"`
This value cannot, and should not, be changed to be different from this
parent value.
Default values already exist such as `...tex.pdfViewer.okular` but
you can override the default values or created completely custom
pdf viewers should you wish.
'';
};
package = mkOption {
type = package;
example = pkgs.kdePackages.okular;
description = "The package of the pdf viewer to use.";
};
executable = mkOption {
type = str;
default = "${toString name}";
description = ''
The executable for the pdf viewer to use.
It will be called as `<package_path>/bin/<executable>`.
By default, the name of the pdf viewer will be used.
'';
};
args = mkOption {
type = listOf str;
default = [];
description = ''
The command line arguments to use when calling the pdf viewer command.
These will be called as
`<package_path>/bin/<executable> <arg1> <arg2> ...`.
'';
};
};
# The name of the pdf viewer must be set to the parent attribute set name.
config.name = lib.mkForce name;
};
in {
# **==================================================**
# || <<<<< PDF Viewer Options >>>>> ||
# **==================================================**
options.vim.languages.tex.pdfViewer = {
enable = mkEnableOption "PDF viewer for TeX";
name = mkOption {
type = enum (attrNames cfg.pdfViewer.viewers);
default = "okular";
description = ''
The PDF viewer chosen to view compiled TeX documents.
Must be one of the names of the PDF viewers configured in
`vim.languages.tex.pdfViewer.viewers`, or one of the default configured
viewers: ${concatStringsSep ", " (attrNames cfg.pdfViewer.viewers)}.
'';
};
viewers = mkOption {
type = with lib.types; attrsOf (submodule pdfViewer);
default = {};
example = {
customOkular = {
package = pkgs.kdePackages.okular;
executable = "okular";
args = [
"--unique"
"file:%p#src:%l%f"
];
};
};
description = ''
Define the PDF viewers that can be used for viewing compiled tex documents.
'';
};
};
# Set the default pdf viewers.
config.vim.languages.tex.pdfViewer.viewers = viewers;
}

View file

@ -0,0 +1,35 @@
{
config,
pkgs,
lib,
...
}: let
inherit (lib.modules) mkIf mkMerge;
inherit (lib.nvim.types) mkGrammarOption;
mkEnableTreesitterOption = lib.nvim.types.mkEnableTreesitterOption config.vim.languages.enableTreesitter;
cfg = config.vim.languages.tex;
in {
options.vim.languages.tex.treesitter = {
latex = {
enable = mkEnableTreesitterOption "latex";
package = mkGrammarOption pkgs "latex";
};
bibtex = {
enable = mkEnableTreesitterOption "bibtex";
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];
})
]);
}

View file

@ -1682,14 +1682,14 @@
"type": "Git",
"repository": {
"type": "GitHub",
"owner": "otavioschwanck",
"owner": "isaacST08",
"repo": "new-file-template.nvim"
},
"branch": "master",
"submodules": false,
"revision": "6ac66669dbf2dc5cdee184a4fe76d22465ca67e8",
"url": "https://github.com/otavioschwanck/new-file-template.nvim/archive/6ac66669dbf2dc5cdee184a4fe76d22465ca67e8.tar.gz",
"hash": "0c7378c3w6bniclp666rq15c28akb0sjy58ayva0wpyin4k26hl3"
"revision": "dc3a58b1f490c86075c96670b9eb81370c2f2ca1",
"url": "https://github.com/isaacST08/new-file-template.nvim/archive/dc3a58b1f490c86075c96670b9eb81370c2f2ca1.tar.gz",
"hash": "0y6ip3k6bjaf32x1y1p6mmkwwdi71yvwr6klr26m252jrg8352pf"
},
"nix-develop-nvim": {
"type": "Git",