Skip to content
Shubham Sourabh edited this page Apr 14, 2025 · 2 revisions

Neovim Setup for Java/Python on Windows (Kickstart Base)

This document outlines the process and troubleshooting steps taken to configure Neovim based on kickstart.nvim for Java and Python development on Windows 11.

Goal

To have a functional Neovim environment with LSP support (autocompletion, diagnostics, go-to-definition), syntax highlighting (Treesitter), and formatting for Java and Python development.

Core Dependencies Installed

  • Neovim: Latest stable version (e.g., 0.10.x).
  • Git: For lazy.nvim and plugin management.
  • JDK 21 (or newer): Required to RUN jdtls, even if working on older Java projects. Path needs to be configured specifically in init.lua.
  • JDK 1.8: Required for specific work projects (system JAVA_HOME points here).
  • Python 3.x: With pip.
  • Visual Studio Build Tools: Crucially, requires the "Desktop development with C++" workload installed for the C/C++ compiler (cl.exe).
  • (Optional but Recommended): Nerd Font installed and configured in the terminal (e.g., Windows Terminal).

Key Configuration Steps & Troubleshooting

This setup involved several specific challenges:

1. Treesitter C Compiler (cl.exe) Not Found

  • Problem: nvim-treesitter requires a C compiler to build language parsers (like Java, Python). Initially, :checkhealth nvim-treesitter reported ERROR cc executable not found.
  • Solution:
    1. Installed Visual Studio Build Tools ensuring the "Desktop development with C++" workload was selected.
    2. Critical Insight: The compiler (cl.exe) is added to the PATH correctly only when using the Developer Prompt for VS (e.g., "Developer PowerShell for VS 2022"). Running nvim from a standard Windows Terminal / PowerShell will not find the compiler by default.
    3. Resolution: Always launch nvim from the Developer PowerShell for VS to ensure Treesitter can find cl.exe and build parsers.

2. Completion Engine (blink.cmp vs nvim-cmp)

  • Problem: Initially attempted to use saghen/blink.cmp. This led to configuration errors (Each source... must have a "name") and internal health check errors (attempt to index a nil value). blink.cmp is not the standard completion engine used by Kickstart.
  • Solution: Switched to the standard Kickstart completion engine, hrsh7th/nvim-cmp.
    1. Removed the saghen/blink.cmp plugin block entirely from init.lua.
    2. Removed saghen/blink.cmp from the dependencies list of nvim-lspconfig.
    3. Ensured the default hrsh7th/nvim-cmp block (including its dependencies like cmp-nvim-lsp, LuaSnip, cmp_luasnip, etc., and its config = function() ... end block calling require('cmp').setup({...})) was present and active in init.lua.
    4. Updated the capabilities variable definition within the nvim-lspconfig config function to use require('cmp_nvim_lsp').default_capabilities().
    5. Ensured this capabilities variable was passed to server setups in the mason-lspconfig handlers.
  • Result: Completion errors were resolved. Note that nvim-cmp loads on InsertEnter, so it won't show in :checkhealth until triggered. Use <C-Space> for manual completion and <C-y> to accept suggestions (default Kickstart mappings).

3. Java LSP (jdtls) Runtime Requirement

  • Problem: jdtls failed to start, with errors indicating it requires Java 17+ or 21+ to run. However, the system JAVA_HOME was set to JDK 1.8 for compatibility with work projects. Running java -version in the terminal showed JDK 21 was available via PATH.
  • Solution: Explicitly configure lspconfig to launch jdtls using the desired JDK 21 installation, overriding JAVA_HOME.
    1. Find JDK 21 Path: Used PowerShell (Get-ChildItem -Path "C:\Program Files\Java" -Filter "jdk-21*" ...) to locate the actual JDK 21 installation directory (e.g., C:\Program Files\Java\jdk-21). The path to the executable is needed (e.g., C:\Program Files\Java\jdk-21\bin\java.exe). Avoid Oracle's javapath symlinks.
    2. Modify init.lua: Added a specific handler for ['jdtls'] within the require('mason-lspconfig').setup { handlers = { ... } } block.
    3. Set cmd: Inside the jdtls handler, defined the cmd table, setting the first element to the full, correct path of the JDK 21 java.exe (using double backslashes \\ in the Lua string). Kept the standard -jar, -configuration, etc., arguments using vim.fn.glob to find the Mason-installed jdtls files.
  • Result: jdtls now successfully starts using JDK 21, ignoring the system JAVA_HOME=1.8, and attaches to Java buffers.

4. jdtls Spawning Failed

  • Problem: After setting the correct Java 21 path, jdtls still failed with a generic "Spawning language server ... failed" error.
  • Solution: This was likely due to verifying paths and potentially reinstalling jdtls via Mason (:Mason, X on jdtls, i on jdtls). Ensuring the paths to java.exe, the launcher JAR (org.eclipse.equinox.launcher_*.jar), and the configuration directory (config_win) used in the cmd table were correct resolved this.

Other Configuration Notes

  • LSPs: pyright (Python) and lua_ls (Lua) were also installed via mason-lspconfig.
  • Formatting: stevearc/conform.nvim is configured. Requires installing desired formatters (e.g., stylua, black, isort, google-java-format) via Mason (:Mason) or pip and uncommenting/adding them in the formatters_by_ft table in conform's opts.
  • Theme: folke/tokyonight.nvim is used.

External Tool Recommendations (Install separately)

  • ripgrep (rg): Essential for Telescope's live_grep. (Installed via winget).
  • fd: Improves Telescope file finding performance. (Installed via winget).
  • 7-Zip: Needed by mason.nvim to extract .zip archives (some LSPs/tools). Install via winget install 7zip.7zip.
  • make: Needed for optional native builds (e.g., telescope-fzf-native, luasnip regex support). Install via choco or MSYS2, or use nmake available in the Developer Prompt.

Current Status

  • Neovim loads based on Kickstart.
  • Treesitter highlighting works for Java/Python (when run from Developer Prompt).
  • LSPs (jdtls, pyright) attach successfully. Diagnostics appear.
  • Autocompletion (nvim-cmp) is configured and should work on InsertEnter (trigger with <C-Space>, accept with <C-y>).

Navigation



Status

Work in Progress 🚧

Clone this wiki locally