Skip to content

Commit

Permalink
plugins/image: init
Browse files Browse the repository at this point in the history
  • Loading branch information
GaetanLepage committed Jan 1, 2024
1 parent 99ebb5f commit e1e417b
Show file tree
Hide file tree
Showing 3 changed files with 203 additions and 0 deletions.
1 change: 1 addition & 0 deletions plugins/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@

./telescope

./ui/image.nix
./ui/noice.nix

./utils/alpha.nix
Expand Down
138 changes: 138 additions & 0 deletions plugins/ui/image.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
{
lib,
helpers,
config,
pkgs,
...
}:
with lib; let
cfg = config.plugins.image;
in {
meta.maintainers = [maintainers.GaetanLepage];

options.plugins.image =
helpers.extraOptionsOptions
// {
enable = mkEnableOption "image.nvim";

package = helpers.mkPackageOption "image.nvim" pkgs.vimPlugins.image-nvim;

backend = helpers.defaultNullOpts.mkEnumFirstDefault ["kitty" "ueberzug"] ''
All the backends support rendering inside Tmux.
- kitty - best in class, works great and is very snappy
- ueberzug - backed by ueberzugpp, supports any terminal, but has lower performance
- Supports multiple images thanks to @jstkdng.
'';

integrations = let
mkIntegrationOptions = integrationName: filetypesDefault: {
enabled = helpers.defaultNullOpts.mkBool true ''
Whether to enable the markdown integration.
'';

clearInInsertMode = helpers.defaultNullOpts.mkBool false ''
Clears the image when entering insert mode.
'';

downloadRemoteImages = helpers.defaultNullOpts.mkBool true ''
Whether to download remote images.
'';

onlyRenderImageAtCursor = helpers.defaultNullOpts.mkBool false ''
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.
'';
};
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.
'';

maxHeightWindowPercentage = helpers.defaultNullOpts.mkUnsignedInt 50 ''
Image maximum height as a percentage of the window height.
'';

windowOverlapClearEnabled = helpers.defaultNullOpts.mkBool false ''
Toggles images when windows are overlapped.
'';

windowOverlapClearFtIgnore =
helpers.defaultNullOpts.mkListOf types.str ''["cmp_menu" "cmp_docs" ""]''
''
Toggles images when windows are overlapped.
'';

editorOnlyRenderWhenFocused = helpers.defaultNullOpts.mkBool false ''
Auto show/hide images when the editor gains/looses focus.
'';

tmuxShowOnlyInActiveWindow = helpers.defaultNullOpts.mkBool false ''
Auto show/hide images in the correct Tmux window (needs visual-activity off).
'';

hijackFilePatterns =
helpers.defaultNullOpts.mkListOf types.str
''["*.png" "*.jpg" "*.jpeg" "*.gif" "*.webp"]''
''
Render image files as images when opened.
'';
};

config = mkIf cfg.enable {
extraPlugins = [cfg.package];
extraLuaPackages = ps: [ps.magick];

extraPackages =
[
# In theory, we could remove that if the user explicitly disables `downloadRemoteImages` for
# all integrations but shipping `curl` is not too heavy.
pkgs.curl
]
++ optional (cfg.backend == "ueberzug") pkgs.ueberzugpp;

extraConfigLua = let
setupOptions = 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;
};
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(${helpers.toLuaObject setupOptions})
'';
};
}
64 changes: 64 additions & 0 deletions tests/test-sources/plugins/ui/image.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
{
empty = {
# At runtime, the plugin tries to get the size of the terminal which doesn't exist in the
# headless environment.
tests.dontRun = true;

plugins.image.enable = true;
};

defaults = {
# At runtime, the plugin tries to get the size of the terminal which doesn't exist in the
# headless environment.
tests.dontRun = true;

plugins.image = {
enable = true;

backend = "kitty";
integrations = {
markdown = {
enabled = true;
clearInInsertMode = false;
downloadRemoteImages = true;
onlyRenderImageAtCursor = false;
filetypes = ["markdown" "vimwiki"];
};
neorg = {
enabled = true;
clearInInsertMode = false;
downloadRemoteImages = true;
onlyRenderImageAtCursor = false;
filetypes = ["norg"];
};
syslang = {
enabled = true;
clearInInsertMode = false;
downloadRemoteImages = true;
onlyRenderImageAtCursor = false;
filetypes = ["syslang"];
};
};
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"];
};
};

ueberzug-backend = {
# At runtime, the plugin tries to get the size of the terminal which doesn't exist in the
# headless environment.
tests.dontRun = true;

plugins.image = {
enable = true;
backend = "ueberzug";
};
};
}

0 comments on commit e1e417b

Please sign in to comment.