From 6ebffd546a9ed2e85fb94bf166c90ccff4e05d95 Mon Sep 17 00:00:00 2001 From: Austin Horstman Date: Tue, 29 Oct 2024 21:23:41 -0500 Subject: [PATCH 1/3] neovim-require-check-hook: auto discover modules to require --- doc/languages-frameworks/vim.section.md | 36 ++++- doc/redirects.json | 3 + .../vim/plugins/neovim-require-check-hook.sh | 138 ++++++++++++++++-- .../editors/vim/plugins/vim-utils.nix | 9 +- 4 files changed, 170 insertions(+), 16 deletions(-) diff --git a/doc/languages-frameworks/vim.section.md b/doc/languages-frameworks/vim.section.md index 4bb2b6e4f2550..7b3522af17c87 100644 --- a/doc/languages-frameworks/vim.section.md +++ b/doc/languages-frameworks/vim.section.md @@ -234,9 +234,17 @@ Finally, there are some plugins that are also packaged in nodePackages because t ### Testing Neovim plugins {#testing-neovim-plugins} -`nvimRequireCheck=MODULE` is a simple test which checks if Neovim can requires the lua module `MODULE` without errors. This is often enough to catch missing dependencies. +#### neovimRequireCheck {#testing-neovim-plugins-neovim-require-check} +`neovimRequireCheck` is a simple test which checks if Neovim can requires lua modules without errors. This is often enough to catch missing dependencies. -This can be manually added through plugin definition overrides in the [overrides.nix](https://github.com/NixOS/nixpkgs/blob/master/pkgs/applications/editors/vim/plugins/overrides.nix). +It accepts a single string for a module, or a list of module strings to test. +- `nvimRequireCheck = MODULE;` +- `nvimRequireCheck = [ MODULE1 MODULE2 ];` + +When `neovimRequireCheck` is not specified, we will search the plugin's directory for lua modules to attempt loading. This quick smoke test can catch obvious dependency errors that might be missed. +The check hook will fail the build if any failures are detected to encourage inspecting the logs to identify potential issues. + +If you would like to only check a specific module, this can be manually added through plugin definition overrides in the [overrides.nix](https://github.com/NixOS/nixpkgs/blob/master/pkgs/applications/editors/vim/plugins/overrides.nix). ```nix gitsigns-nvim = super.gitsigns-nvim.overrideAttrs { @@ -244,6 +252,30 @@ This can be manually added through plugin definition overrides in the [overrides nvimRequireCheck = "gitsigns"; }; ``` +Some plugins will have lua modules that require a user configuration to function properly or can contain optional lua modules that we dont want to test requiring. +We can skip specific modules using `nvimSkipModule`. Similar to `nvimRequireCheck`, it accepts a single string or a list of strings. +- `nvimSkipModule = MODULE;` +- `nvimSkipModule = [ MODULE1 MODULE2 ];` + +```nix + asyncrun-vim = super.asyncrun-vim.overrideAttrs { + nvimSkipModule = [ + # vim plugin with optional toggleterm integration + "asyncrun.toggleterm" + "asyncrun.toggleterm2" + ]; + }; +``` + +In rare cases, we might not want to actually test loading lua modules for a plugin. In those cases, we can disable `neovimRequireCheck` with `doCheck = false;`. + +This can be manually added through plugin definition overrides in the [overrides.nix](https://github.com/NixOS/nixpkgs/blob/master/pkgs/applications/editors/vim/plugins/overrides.nix). +```nix + vim-test = super.vim-test.overrideAttrs { + # Vim plugin with a test lua file + doCheck = false; + }; +``` ### Plugin optional configuration {#vim-plugin-required-snippet} diff --git a/doc/redirects.json b/doc/redirects.json index 311ca1ff4af77..dc6e46a5688a7 100644 --- a/doc/redirects.json +++ b/doc/redirects.json @@ -3760,6 +3760,9 @@ "testing-neovim-plugins": [ "index.html#testing-neovim-plugins" ], + "testing-neovim-plugins-neovim-require-check": [ + "index.html#testing-neovim-plugins-neovim-require-check" + ], "vim-plugin-required-snippet": [ "index.html#vim-plugin-required-snippet" ], diff --git a/pkgs/applications/editors/vim/plugins/neovim-require-check-hook.sh b/pkgs/applications/editors/vim/plugins/neovim-require-check-hook.sh index 1808442327a1e..d5bd1c515451b 100644 --- a/pkgs/applications/editors/vim/plugins/neovim-require-check-hook.sh +++ b/pkgs/applications/editors/vim/plugins/neovim-require-check-hook.sh @@ -1,24 +1,136 @@ #shellcheck shell=bash -# Setup hook for checking whether Python imports succeed +# Setup hook for checking whether Lua imports succeed echo "Sourcing neovim-require-check-hook.sh" -neovimRequireCheckHook () { - echo "Executing neovimRequireCheckHook" +# Discover modules automatically if nvimRequireCheck is not set +discover_modules() { + echo "Running module discovery in source directory..." + + # Create unique lists so we can organize later + modules=() - if [ -n "$nvimRequireCheck" ]; then - echo "Check whether the following module can be imported: $nvimRequireCheck" + while IFS= read -r lua_file; do + # Ignore certain infra directories + if [[ "$lua_file" =~ debug/|scripts?/|tests?/|spec/ || "$lua_file" =~ .*\meta.lua ]]; then + continue + # Ignore optional telescope and lualine modules + elif [[ "$lua_file" =~ ^lua/telescope/_extensions/(.+)\.lua || "$lua_file" =~ ^lua/lualine/(.+)\.lua ]]; then + continue + # Grab main module names + elif [[ "$lua_file" =~ ^lua/([^/]+)/init.lua$ ]]; then + echo "$lua_file" + modules+=("${BASH_REMATCH[1]}") + # Check other lua files + elif [[ "$lua_file" =~ ^lua/(.*)\.lua$ ]]; then + echo "$lua_file" + # Replace slashes with dots to form the module name + module_name="${BASH_REMATCH[1]//\//.}" + modules+=("$module_name") + elif [[ "$lua_file" =~ ^([^/.][^/]*)\.lua$ ]]; then + echo "$lua_file" + modules+=("${BASH_REMATCH[1]}") + fi + done < <(find "$src" -name '*.lua' | xargs -n 1 realpath --relative-to="$src") - # editorconfig-checker-disable - export HOME="$TMPDIR" + nvimRequireCheck=("${modules[@]}") + echo "Discovered modules: ${nvimRequireCheck[*]}" - local deps="${dependencies[*]}" - @nvimBinary@ -es --headless -n -u NONE -i NONE --clean -V1 \ - --cmd "set rtp+=$out,${deps// /,}" \ - --cmd "lua require('$nvimRequireCheck')" + if [ "${#nvimRequireCheck[@]}" -eq 0 ]; then + echo "No valid Lua modules found; skipping check" + return 1 fi + return 0 } -echo "Using neovimRequireCheckHook" -appendToVar preDistPhases neovimRequireCheckHook +# Run require checks on each module in nvimRequireCheck +run_require_checks() { + echo "Starting require checks" + check_passed=false + failed_modules=() + successful_modules=() + + export HOME="$TMPDIR" + local deps="${dependencies[*]}" + local checks="${nativeBuildInputs[*]}" + set +e + for name in "${nvimRequireCheck[@]}"; do + local skip=false + for module in "${nvimSkipModule[@]}"; do + if [[ "$module" == "$name" ]]; then + echo "$name is in list of modules to not check. Skipping..." + skip=true + break + fi + done + + if [ "$skip" = false ]; then + echo "Attempting to require module: $name" + if @nvimBinary@ -es --headless -n -u NONE -i NONE --clean -V1 \ + --cmd "set rtp+=$out,${deps// /,}" \ + --cmd "set rtp+=$out,${checks// /,}" \ + --cmd "lua require('$name')"; then + check_passed=true + successful_modules+=("$name") + echo "Successfully required module: $name" + else + echo "Failed to require module: $name" + failed_modules+=("$name") + fi + fi + done + set -e +} + +# Define color codes +GREEN="\033[0;32m" +RED="\033[0;31m" +NC="\033[0m" # No Color + +# Print summary of the require checks +print_summary() { + echo -e "\n======================================================" + if [[ "$check_passed" == "true" ]]; then + echo -e "${GREEN}Require check succeeded for the following modules:${NC}" + for module in "${successful_modules[@]}"; do + echo -e " ${GREEN}- $module${NC}" + done + echo "All lua modules were checked." + else + echo -e "${RED}No successful require checks.${NC}" + fi + + # Print any modules that failed with improved formatting and color + if [ "${#failed_modules[@]}" -gt 0 ]; then + echo -e "\n${RED}Require check failed for the following modules:${NC}" + for module in "${failed_modules[@]}"; do + echo -e " ${RED}- $module${NC}" + done + fi + echo "======================================================" + + if [ "${#failed_modules[@]}" -gt 0 ]; then + return 1 + fi +} +# Main entry point: orchestrates discovery, require checks, and summary +neovimRequireCheckHook() { + echo "Executing neovimRequireCheckHook" + if [ "${nvimRequireCheck[*]}" = "" ]; then + echo "nvimRequireCheck is empty; entering discovery mode" + # Auto-discovery mode + if ! discover_modules; then + echo "No modules found during discovery; exiting hook" + return + fi + else + echo "nvimRequireCheck is pre-populated; entering manual check mode" + fi + + run_require_checks + print_summary +} + +echo "Using neovimRequireCheckHook" +appendToVar preDistPhases neovimRequireCheckHook diff --git a/pkgs/applications/editors/vim/plugins/vim-utils.nix b/pkgs/applications/editors/vim/plugins/vim-utils.nix index 164245be176fb..d1f7bf3440e23 100644 --- a/pkgs/applications/editors/vim/plugins/vim-utils.nix +++ b/pkgs/applications/editors/vim/plugins/vim-utils.nix @@ -499,8 +499,15 @@ rec { nativeBuildInputs = oldAttrs.nativeBuildInputs or [ ] ++ lib.optionals (stdenv.buildPlatform.canExecute stdenv.hostPlatform) [ - vimCommandCheckHook vimGenDocHook + ]; + + doCheck = oldAttrs.doCheck or true; + + nativeCheckInputs = + oldAttrs.nativeCheckInputs or [ ] + ++ lib.optionals (stdenv.buildPlatform.canExecute stdenv.hostPlatform) [ + vimCommandCheckHook # many neovim plugins keep using buildVimPlugin neovimRequireCheckHook ]; From 337f61247af2561740769a7509c297dc8def9a58 Mon Sep 17 00:00:00 2001 From: Austin Horstman Date: Mon, 2 Dec 2024 09:21:22 -0600 Subject: [PATCH 2/3] vimPlugins.snacks-nvim: skip new modules --- pkgs/applications/editors/vim/plugins/overrides.nix | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/pkgs/applications/editors/vim/plugins/overrides.nix b/pkgs/applications/editors/vim/plugins/overrides.nix index 64182160f3c3e..ae4433903f445 100644 --- a/pkgs/applications/editors/vim/plugins/overrides.nix +++ b/pkgs/applications/editors/vim/plugins/overrides.nix @@ -2897,6 +2897,10 @@ in "snacks.terminal" "snacks.win" "snacks.words" + "snacks.debug" + "snacks.scratch" + # Optional trouble integration + "trouble.sources.profiler" ]; }; From 1f3f8e2cce4b58dc58c3465c89a36de2a8ba4264 Mon Sep 17 00:00:00 2001 From: Austin Horstman Date: Mon, 2 Dec 2024 09:23:07 -0600 Subject: [PATCH 3/3] vimPlugins.cmp-dictionary: skip test modules --- pkgs/applications/editors/vim/plugins/overrides.nix | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/pkgs/applications/editors/vim/plugins/overrides.nix b/pkgs/applications/editors/vim/plugins/overrides.nix index ae4433903f445..eeefd34748522 100644 --- a/pkgs/applications/editors/vim/plugins/overrides.nix +++ b/pkgs/applications/editors/vim/plugins/overrides.nix @@ -466,6 +466,13 @@ in cmp-dictionary = super.cmp-dictionary.overrideAttrs (oa: { nativeCheckInputs = oa.nativeCheckInputs ++ [ self.nvim-cmp ]; + nvimSkipModule = [ + # Test files + "cmp_dictionary.dict.external_spec" + "cmp_dictionary.dict.trie_spec" + "cmp_dictionary.lib.trie_spec" + "cmp_dictionary.lib.unknown_spec" + ]; }); cmp-digraphs = super.cmp-digraphs.overrideAttrs (oa: {