plugins/image: migrate to mkNeovimPlugin

This commit is contained in:
Gaetan Lepage 2025-03-20 13:33:28 +01:00 committed by Gaétan Lepage
parent c5967bf6a5
commit 279d2570b5
3 changed files with 157 additions and 157 deletions

View file

@ -1,37 +1,44 @@
{ {
lib, lib,
helpers,
config,
pkgs, pkgs,
... ...
}: }:
with lib;
let let
cfg = config.plugins.image; inherit (lib) types;
inherit (lib.nixvim) defaultNullOpts;
in in
{ lib.nixvim.plugins.mkNeovimPlugin {
meta.maintainers = [ maintainers.GaetanLepage ]; name = "image";
packPathName = "image.nvim";
package = "image-nvim";
options.plugins.image = lib.nixvim.plugins.neovim.extraOptionsOptions // { maintainers = [ lib.maintainers.GaetanLepage ];
enable = mkEnableOption "image.nvim";
package = lib.mkPackageOption pkgs "image.nvim" { # TODO: Added 2025-03-20. Remove after 25.05
default = [ inherit (import ./deprecations.nix lib)
"vimPlugins" deprecateExtraOptions
"image-nvim" optionsRenamedToSettings
]; imports
}; ;
extraOptions = {
curlPackage = lib.mkPackageOption pkgs "curl" { curlPackage = lib.mkPackageOption pkgs "curl" {
nullable = true; nullable = true;
}; };
ueberzugPackage = lib.mkPackageOption pkgs "ueberzugpp" { ueberzugPackage = lib.mkOption {
nullable = true; type = with types; nullOr package;
default = pkgs.ueberzugpp;
defaultText = lib.literalExpression "pkgs.ueberzugpp";
description = ''
Package to automatically install if `settings.backend.backend` is set to `"ueberzug"`.
'';
}; };
};
settingsOptions = {
backend = backend =
helpers.defaultNullOpts.mkEnumFirstDefault defaultNullOpts.mkEnumFirstDefault
[ [
"kitty" "kitty"
"ueberzug" "ueberzug"
@ -42,146 +49,104 @@ in
- kitty - best in class, works great and is very snappy - kitty - best in class, works great and is very snappy
- ueberzug - backed by ueberzugpp, supports any terminal, but has lower performance - ueberzug - backed by ueberzugpp, supports any terminal, but has lower performance
- Supports multiple images thanks to @jstkdng. - Supports multiple images thanks to @jstkdng.
> [!Note]
> When choosing the `"ueberzug"` backend, nixvim will automatically add `ueberzugpp` as a dependency.
> Set `ueberzugPackage = null` to disable this behavior.
''; '';
integrations = integrations =
let defaultNullOpts.mkAttrsOf types.anything
mkIntegrationOptions = integrationName: filetypesDefault: { {
enabled = helpers.defaultNullOpts.mkBool true '' markdown.enabled = true;
Whether to enable the markdown integration. typst.enabled = true;
''; neorg.enabled = true;
syslang.enabled = true;
html.enabled = false;
css.enabled = false;
}
''
Per-filetype integrations.
'';
clearInInsertMode = helpers.defaultNullOpts.mkBool false '' max_width = defaultNullOpts.mkUnsignedInt null ''
Clears the image when entering insert mode. Image maximum width.
''; '';
downloadRemoteImages = helpers.defaultNullOpts.mkBool true '' max_height = defaultNullOpts.mkUnsignedInt null ''
Whether to download remote images. Image maximum height.
''; '';
onlyRenderImageAtCursor = helpers.defaultNullOpts.mkBool false '' max_width_window_percentage = defaultNullOpts.mkUnsignedInt 100 ''
Whether to limit rendering to the image at the current cursor position.
'';
filetypes = helpers.defaultNullOpts.mkListOf types.str filetypesDefault ''
Markdown extensions (ie. quarto) can go here.
'';
resolveImagePath = helpers.mkNullOrLuaFn' {
description = "Configures how to resolve image paths.";
example = lib.literalExpression ''
lib.nixvim.mkRaw '''
function(document_path, image_path, fallback)
-- document_path is the path to the file that contains the image
-- image_path is the potentially relative path to the image. For markdown, it's `![](this text)`
-- fallback is the default behavior
return fallback(document_path, image_path)
end
''';
'';
};
};
in
mapAttrs mkIntegrationOptions {
markdown = [
"markdown"
"vimwiki"
];
neorg = [ "norg" ];
syslang = [ "syslang" ];
};
maxWidth = helpers.mkNullOrOption types.ints.unsigned "Image maximum width.";
maxHeight = helpers.mkNullOrOption types.ints.unsigned "Image maximum height.";
maxWidthWindowPercentage = helpers.mkNullOrOption types.ints.unsigned ''
Image maximum width as a percentage of the window width. Image maximum width as a percentage of the window width.
''; '';
maxHeightWindowPercentage = helpers.defaultNullOpts.mkUnsignedInt 50 '' max_height_window_percentage = defaultNullOpts.mkUnsignedInt 50 ''
Image maximum height as a percentage of the window height. Image maximum height as a percentage of the window height.
''; '';
windowOverlapClearEnabled = helpers.defaultNullOpts.mkBool false '' window_overlap_clear_enabled = defaultNullOpts.mkBool false ''
Toggles images when windows are overlapped. Toggles images when windows are overlapped.
''; '';
windowOverlapClearFtIgnore = window_overlap_clear_ft_ignore =
helpers.defaultNullOpts.mkListOf types.str defaultNullOpts.mkListOf types.str
[ [
"cmp_menu" "cmp_menu"
"cmp_docs" "cmp_docs"
"" "snacks_notif"
"scrollview"
"scrollview_sign"
] ]
'' ''
Toggles images when windows are overlapped. Toggles images when windows are overlapped.
''; '';
editorOnlyRenderWhenFocused = helpers.defaultNullOpts.mkBool false '' editor_only_render_when_focused = defaultNullOpts.mkBool false ''
Auto show/hide images when the editor gains/looses focus. Auto show/hide images when the editor gains/looses focus.
''; '';
tmuxShowOnlyInActiveWindow = helpers.defaultNullOpts.mkBool false '' tmux_show_only_in_active_window = defaultNullOpts.mkBool false ''
Auto show/hide images in the correct Tmux window (needs visual-activity off). Auto show/hide images in the correct Tmux window (needs visual-activity off).
''; '';
hijackFilePatterns = hijack_file_patterns =
helpers.defaultNullOpts.mkListOf types.str defaultNullOpts.mkListOf types.str
[ [
"*.png" "*.png"
"*.jpg" "*.jpg"
"*.jpeg" "*.jpeg"
"*.gif" "*.gif"
"*.webp" "*.webp"
"*.avif"
] ]
'' ''
Render image files as images when opened. Render image files as images when opened.
''; '';
}; };
config = mkIf cfg.enable { settingsExample = {
extraPlugins = [ cfg.package ]; backend = "kitty";
extraLuaPackages = ps: [ ps.magick ]; max_width = 100;
max_height = 12;
max_height_window_percentage.__raw = "math.huge";
max_width_window_percentage.__raw = "math.huge";
window_overlap_clear_enabled = true;
window_overlap_clear_ft_ignore = [
"cmp_menu"
"cmp_docs"
""
];
};
extraConfig = cfg: {
extraPackages = [ extraPackages = [
# In theory, we could remove that if the user explicitly disables `downloadRemoteImages` for # In theory, we could remove that if the user explicitly disables `downloadRemoteImages` for
# all integrations but shipping `curl` is not too heavy. # all integrations but shipping `curl` is not too heavy.
cfg.curlPackage cfg.curlPackage
] ++ optional (cfg.backend == "ueberzug") cfg.ueberzugPackage;
extraConfigLua = ] ++ lib.optional (cfg.settings.backend == "ueberzug") cfg.ueberzugPackage;
let
setupOptions = extraLuaPackages = ps: [ ps.magick ];
with cfg;
{
inherit backend;
integrations =
let
processIntegrationOptions = v: {
inherit (v) enabled;
clear_in_insert_mode = v.clearInInsertMode;
download_remote_images = v.downloadRemoteImages;
only_render_image_at_cursor = v.onlyRenderImageAtCursor;
inherit (v) filetypes;
resolve_image_path = v.resolveImagePath;
};
in
mapAttrs (_: processIntegrationOptions) integrations;
max_width = maxWidth;
max_height = maxHeight;
max_width_window_percentage = maxWidthWindowPercentage;
max_height_window_percentage = maxHeightWindowPercentage;
window_overlap_clear_enabled = windowOverlapClearEnabled;
window_overlap_clear_ft_ignore = windowOverlapClearFtIgnore;
editor_only_render_when_focused = editorOnlyRenderWhenFocused;
tmux_show_only_in_active_window = tmuxShowOnlyInActiveWindow;
hijack_file_patterns = hijackFilePatterns;
}
// cfg.extraOptions;
in
''
require('image').setup(${lib.nixvim.toLuaObject setupOptions})
'';
}; };
} }

View file

@ -0,0 +1,21 @@
lib: {
deprecateExtraOptions = true;
optionsRenamedToSettings = [
"backend"
"maxWidth"
"maxHeight"
"maxWidthWindowPercentage"
"maxHeightWindowPercentage"
"windowOverlapClearEnabled"
"windowOverlapClearFtIgnore"
"editorOnlyRenderWhenFocused"
"tmuxShowOnlyInActiveWindow"
"hijackFilePatterns"
];
imports = [
(lib.mkRemovedOptionModule [ "plugins" "image" "integrations" ] ''
Nixvim(plugins.image): The option `integrations` has been renamed to `settings.integrations`.
Warning: sub-options now have the same name as upstream (`clear_in_insert_mode`...).
'')
];
}

View file

@ -15,52 +15,66 @@
plugins.image = { plugins.image = {
enable = true; enable = true;
backend = "kitty"; settings = {
integrations = { backend = "kitty";
markdown = { processor = "magick_rock";
enabled = true; integrations = {
clearInInsertMode = false; markdown.enabled = true;
downloadRemoteImages = true; typst.enabled = true;
onlyRenderImageAtCursor = false; neorg.enabled = true;
filetypes = [ syslang.enabled = true;
"markdown" html.enabled = false;
"vimwiki" css.enabled = false;
];
};
neorg = {
enabled = true;
clearInInsertMode = false;
downloadRemoteImages = true;
onlyRenderImageAtCursor = false;
filetypes = [ "norg" ];
};
syslang = {
enabled = true;
clearInInsertMode = false;
downloadRemoteImages = true;
onlyRenderImageAtCursor = false;
filetypes = [ "syslang" ];
}; };
max_width = null;
max_height = null;
max_width_window_percentage = 100;
max_height_window_percentage = 50;
scale_factor = 1.0;
kitty_method = "normal";
window_overlap_clear_enabled = false;
window_overlap_clear_ft_ignore = [
"cmp_menu"
"cmp_docs"
"snacks_notif"
"scrollview"
"scrollview_sign"
];
editor_only_render_when_focused = false;
tmux_show_only_in_active_window = false;
hijack_file_patterns = [
"*.png"
"*.jpg"
"*.jpeg"
"*.gif"
"*.webp"
"*.avif"
];
};
};
};
example = {
# At runtime, the plugin tries to get the size of the terminal which doesn't exist in the
# headless environment.
test.runNvim = false;
plugins.image = {
enable = true;
settings = {
backend = "kitty";
max_width = 100;
max_height = 12;
max_height_window_percentage.__raw = "math.huge";
max_width_window_percentage.__raw = "math.huge";
window_overlap_clear_enabled = true;
window_overlap_clear_ft_ignore = [
"cmp_menu"
"cmp_docs"
""
];
}; };
maxWidth = null;
maxHeight = null;
maxWidthWindowPercentage = null;
maxHeightWindowPercentage = 50;
windowOverlapClearEnabled = false;
windowOverlapClearFtIgnore = [
"cmp_menu"
"cmp_docs"
""
];
editorOnlyRenderWhenFocused = false;
tmuxShowOnlyInActiveWindow = false;
hijackFilePatterns = [
"*.png"
"*.jpg"
"*.jpeg"
"*.gif"
"*.webp"
];
}; };
}; };
@ -71,7 +85,7 @@
plugins.image = { plugins.image = {
enable = true; enable = true;
backend = "ueberzug"; settings.backend = "ueberzug";
}; };
}; };
@ -80,7 +94,7 @@
plugins.image = { plugins.image = {
enable = true; enable = true;
backend = "kitty"; settings.backend = "kitty";
curlPackage = null; curlPackage = null;
ueberzugPackage = null; ueberzugPackage = null;
}; };