Skip to content

Commit

Permalink
plugins/conform-nvim: migrate to mkNeovimPlugin
Browse files Browse the repository at this point in the history
  • Loading branch information
khaneliman committed Aug 24, 2024
1 parent a1c7932 commit 89b876d
Show file tree
Hide file tree
Showing 2 changed files with 333 additions and 213 deletions.
301 changes: 205 additions & 96 deletions plugins/lsp/conform-nvim.nix
Original file line number Diff line number Diff line change
@@ -1,33 +1,113 @@
{
lib,
helpers,
config,
pkgs,
...
}:
with lib;
let
cfg = config.plugins.conform-nvim;
inherit (lib) types;
inherit (lib.nixvim) defaultNullOpts mkRaw;
in
{
options.plugins.conform-nvim = helpers.neovim-plugin.extraOptionsOptions // {
enable = mkEnableOption "conform-nvim";
lib.nixvim.neovim-plugin.mkNeovimPlugin config {
name = "conform-nvim";
luaName = "conform";
originalName = "conform.nvim";
defaultPackage = pkgs.vimPlugins.conform-nvim;

maintainers = [ lib.maintainers.khaneliman ];

# TODO: added 2024-08-23 remove after 24.11
deprecateExtraOptions = true;
optionsRenamedToSettings = [
"formatters"
"formattersByFt"
"logLevel"
"notifyOnError"
];
imports =
map
(
optionName:
lib.mkRemovedOptionModule
[
"plugins"
"conform-nvim"
optionName
]
''
Please use `plugins.conform-nvim.settings.${lib.nixvim.toSnakeCase optionName}` instead.
Note that nested options will now be snake_case, as well, to match upstream plugin configuration.
''
)
[
"formatAfterSave"
"formatOnSave"
];

settingsOptions =
let
lsp_format =
defaultNullOpts.mkEnumFirstDefault
[
"never"
"fallback"
"prefer"
"first"
"last"
]
''
Option for choosing lsp formatting preference.
package = helpers.mkPluginPackageOption "conform-nvim" pkgs.vimPlugins.conform-nvim;
- `never`: never use the LSP for formatting.
- `fallback`: LSP formatting is used when no other formatters are available.
- `prefer`: Use only LSP formatting when available.
- `first`: LSP formatting is used when available and then other formatters.
- `last`: Other formatters are used then LSP formatting when available.
'';

timeout_ms = defaultNullOpts.mkUnsignedInt 1000 "Time in milliseconds to block for formatting.";

quiet = defaultNullOpts.mkBool false "Don't show any notifications for warnings or failures.";

stop_after_first = defaultNullOpts.mkBool false "Only run the first available formatter in the list.";

# NOTE: These are the available options for the `default_format_opts` opt.
# They are also included in the `format_opts` options available to `format_after_save` and `format_on_save`.
defaultFormatSubmodule =
with types;
(submodule {
freeformType = attrsOf anything;
options = {
inherit
lsp_format
timeout_ms
quiet
stop_after_first
;
};
});
in
{
formatters_by_ft = defaultNullOpts.mkAttrsOf types.anything { } ''
Creates a table mapping filetypes to formatters.
You can run multiple formatters in a row by adding them in a list.
If you'd like to stop after the first successful formatter, set `stop_after_first`.
formattersByFt = helpers.defaultNullOpts.mkAttrsOf' {
type = types.anything;
# Unknown plugin default
description = ''
```nix
# Map of filetype to formatters
formattersByFt =
{
lua = [ "stylua" ];
# Conform will run multiple formatters sequentially
python = [ "isort" "black" ];
# Use a sub-list to run only the first available formatter
javascript = [ [ "prettierd" "prettier" ] ];
# Use stop_after_first to run only the first available formatter
javascript = {
__unkeyed-1 = "prettierd";
__unkeyed-2 = "prettier";
stop_after_first = true;
};
# Use the "*" filetype to run formatters on all filetypes.
"*" = [ "codespell" ];
# Use the "_" filetype to run formatters on filetypes that don't
Expand All @@ -36,97 +116,126 @@ in
};
```
'';
};

formatOnSave = helpers.defaultNullOpts.mkNullable' {
type =
with helpers.nixvimTypes;
either strLuaFn (submodule {
options = {
lspFallback = mkOption {
type = types.bool;
default = true;
description = "See :help conform.format for details.";
};
timeoutMs = mkOption {
type = types.int;
default = 500;
description = "See :help conform.format for details.";
};
};
});
# Unknown plugin default
description = ''
If this is set, Conform will run the formatter on save.
It will pass the table to conform.format().
This can also be a function that returns the table.
See :help conform.format for details.
format_on_save = defaultNullOpts.mkNullable' {
type = with types; either strLuaFn defaultFormatSubmodule;
pluginDefault = { };
description = ''
If this is set, Conform will run the formatter asynchronously on save.
Conform will pass the table from `format_on_save` to `conform.format()`.
This can also be a function that returns the table.
See `:help conform.format` for details.
'';
apply = v: if lib.isString v then mkRaw v else v;
};

default_format_opts = defaultNullOpts.mkNullable defaultFormatSubmodule { } ''
The default options to use when calling `conform.format()`.
'';
};

formatAfterSave = helpers.defaultNullOpts.mkNullable' {
type =
with helpers.nixvimTypes;
either strLuaFn (submodule {
options = {
lspFallback = mkOption {
type = types.bool;
default = true;
description = "See :help conform.format for details.";
};
};
});
# Unknown plugin default
description = ''
If this is set, Conform will run the formatter asynchronously after save.
It will pass the table to conform.format().
This can also be a function that returns the table.
format_after_save = defaultNullOpts.mkNullable' {
type = with types; either strLuaFn defaultFormatSubmodule;
pluginDefault = { };
description = ''
If this is set, Conform will run the formatter asynchronously after save.
Conform will pass the table from `format_after_save` to `conform.format()`.
This can also be a function that returns the table.
See `:help conform.format` for details.
'';
apply = v: if lib.isString v then mkRaw v else v;
};

log_level = defaultNullOpts.mkLogLevel "error" ''
Set the log level. Use `:ConformInfo` to see the location of the log file.
'';
};

logLevel = helpers.defaultNullOpts.mkLogLevel "error" ''
Set the log level. Use `:ConformInfo` to see the location of the log file.
'';
notify_on_error = defaultNullOpts.mkBool true "Conform will notify you when a formatter errors.";

notifyOnError = helpers.defaultNullOpts.mkBool true "Conform will notify you when a formatter errors";
notify_no_formatters = defaultNullOpts.mkBool true "Conform will notify you when no formatters are available for the buffer.";

formatters = helpers.defaultNullOpts.mkAttrsOf' {
type = types.anything;
# Unknown plugin default
description = "Custom formatters and changes to built-in formatters";
formatters =
defaultNullOpts.mkAttrsOf types.anything { }
"Custom formatters and changes to built-in formatters.";
};
};

config =
let
setupOptions =
with cfg;
{
formatters_by_ft = formattersByFt;
format_on_save =
if builtins.isAttrs formatOnSave then
{
lsp_fallback = formatOnSave.lspFallback;
timeout_ms = formatOnSave.timeoutMs;
}
else
helpers.mkRaw formatOnSave;
format_after_save =
if builtins.isAttrs formatAfterSave then
{ lsp_fallback = formatOnSave.lspFallback; }
else
helpers.mkRaw formatAfterSave;
log_level = logLevel;
notify_on_error = notifyOnError;
inherit formatters;
}
// cfg.extraOptions;
in
mkIf cfg.enable {
extraPlugins = [ cfg.package ];
settingsExample = lib.literalMD ''
```nix
{
formattersByFt = {
bash = [
"shellcheck"
"shellharden"
"shfmt"
];
cpp = [ "clang_format" ];
javascript = {
__unkeyed-1 = "prettierd";
__unkeyed-2 = "prettier";
timeout_ms = 2000;
stop_after_first = true;
};
"_" = [
"squeeze_blanks"
"trim_whitespace"
"trim_newlines"
];
};
format_on_save = # Lua
'''
function(bufnr)
if vim.g.disable_autoformat or vim.b[bufnr].disable_autoformat then
return
end
extraConfigLua = ''
require("conform").setup(${helpers.toLuaObject setupOptions})
'';
};
if slow_format_filetypes[vim.bo[bufnr].filetype] then
return
end
local function on_format(err)
if err and err:match("timeout$") then
slow_format_filetypes[vim.bo[bufnr].filetype] = true
end
end
return { timeout_ms = 200, lsp_fallback = true }, on_format
end
''';
format_after_save = # Lua
'''
function(bufnr)
if vim.g.disable_autoformat or vim.b[bufnr].disable_autoformat then
return
end
if not slow_format_filetypes[vim.bo[bufnr].filetype] then
return
end
return { lsp_fallback = true }
end
''';
log_level = "warn";
notify_on_error = false;
notify_no_formatters = false;
formatters = {
shellcheck = {
command = lib.getExe pkgs.shellcheck;
};
shfmt = {
command = lib.getExe pkgs.shfmt;
};
shellharden = {
command = lib.getExe pkgs.shellharden;
};
squeeze_blanks = {
command = lib.getExe' pkgs.coreutils "cat";
};
};
}
```
'';
}
Loading

0 comments on commit 89b876d

Please sign in to comment.