Skip to main content

Lua and Python Setup

Lua Setup (for Neovim Config Development)​

Lua is Neovim's native config language, so proper Lua IDE support is critical for maintaining your own config.

Required LSP Server​

# lua_ls (Lua Language Server) — installed via Mason
:MasonInstall lua-language-server

Lua LSP Configuration​

In your LSP config:
lspconfig.lua_ls.setup({
on_attach = on_attach,
capabilities = capabilities,
settings = {
Lua = {
runtime = { version = "LuaJIT" },
diagnostics = {
globals = { "vim" }, -- don't warn about 'vim' global
},
workspace = {
library = vim.api.nvim_get_runtime_file("", true),
checkThirdParty = false,
},
completion = {
callSnippet = "Replace",
},
telemetry = { enable = false },
},
},
})

neodev.nvim — Better Neovim API Completions​

Add as dependency to nvim-lspconfig:
{
"folke/neodev.nvim",
opts = {
library = {
enabled = true,
runtime = true,
types = true,
plugins = true, -- include installed plugins in completion
},
},
},

Lua Formatter​

# Install stylua
cargo install stylua
# or:
brew install stylua
none-ls source:
null_ls.builtins.formatting.stylua,

.stylua.toml Config​

.stylua.toml
indent_type = "Spaces"
indent_width = 2
column_width = 100
quote_style = "AutoPreferDouble"

Python Setup​

Required Tools​

# LSP server
pip install pyright # or: :MasonInstall pyright

# Formatters
pip install black isort

# Linters
pip install flake8 pylint

# Type stubs (for better completions)
pip install types-requests types-PyYAML

Python LSP Configuration​

lspconfig.pyright.setup({
on_attach = on_attach,
capabilities = capabilities,
settings = {
python = {
analysis = {
typeCheckingMode = "basic", -- "off" | "basic" | "strict"
autoSearchPaths = true,
useLibraryCodeForTypes = true,
diagnosticMode = "workspace", -- analyze entire project
autoImportCompletions = true,
},
},
},
})

Python Formatters and Linters (none-ls)​

null_ls.setup({
sources = {
-- Formatters
null_ls.builtins.formatting.black.with({
extra_args = { "--line-length", "88" },
}),
null_ls.builtins.formatting.isort.with({
extra_args = { "--profile", "black" },
}),

-- Linters
null_ls.builtins.diagnostics.flake8.with({
extra_args = { "--max-line-length", "88", "--extend-ignore", "E203" },
}),
},
})

.flake8 Config​

`ini title=".flake8" [flake8] max-line-length = 88 extend-ignore = E203, W503 exclude = .git, pycache, .venv, dist


### Virtual Environment Awareness

```lua title="lua/config/autocmds.lua"
-- Auto-activate Python venv
vim.api.nvim_create_autocmd("BufEnter", {
pattern = "*.py",
callback = function()
local venv = vim.fn.finddir(".venv", vim.fn.getcwd() .. ";")
if venv ~= "" then
local python = venv .. "/bin/python"
if vim.fn.executable(python) == 1 then
vim.g.python3_host_prog = python
end
end
end,
})

In LazyVim​

LazyVim Context

LazyVim utilizes its powerful Extras system to configure programming languages instantly. Instead of manually configuring pyright, ull-ls, or eodev, you can activate predefined modules that install and configure the community's best practices out of the box.

AspectVanilla NeovimLazyVim
Lua SetupManual
eodev, lua_ls, stylua setupFully configured out-of-the-box (uses lazydev.nvim and lua_ls)
Python SetupManual pyright, lack, lake8 configEnable via :LazyExtras → lang.python
Python FormattingRequires
ull-ls configurationThe python extra configures
uff or lack/isort automatically
Virtual EnvironmentsCustom autocmd logicManaged automatically by the python extra (often via env-selector)

Enabling Python Support in LazyVim​

  1. Open Neovim.
  2. Run :LazyExtras.
  3. Scroll to lang.python and press x to enable it.
  4. (Optional) Enable est.core to get automatic Python testing support (pytest/unittest via Neotest).

Once lang.python is enabled, LazyVim will use Mason to automatically download the Python language servers (like pyright or asedpyright), formatters, and linters required for a full Python IDE experience. Virtual environments will be correctly picked up by the configured LSP, avoiding false positive import errors.

What's Next​