Introduction
This guide sets up a powerful, modern development environment that combines:
- Advanced text editing with IDE-like features (Neovim)
- Enhanced shell capabilities (Zsh)
- Beautiful and informative terminal interface (Powerlevel10k)
- Intelligent code completion and analysis (LSP)
- Integrated debugging capabilities (DAP)
- Database management tools
Required Tools
Core Tools
- Neovim - A modern, highly extensible text editor that improves upon Vim
- Zsh - A shell with advanced features like improved tab completion and scripting capabilities
- Oh My Zsh - A framework that makes Zsh configuration manageable and adds useful features
- NvChad - A carefully crafted Neovim configuration that provides modern IDE features while remaining fast
- Powerlevel10k - A Zsh theme that provides useful information while remaining responsive
Language Servers & Debugging
- Mason - A package manager that makes it easy to install and manage LSP servers
- nvim-dap - Implements the Debug Adapter Protocol, enabling interactive debugging
- debugpy - Microsoft's debug adapter for Python, enables Python debugging in Neovim
Database Integration
- vim-dadbod - Database interface that supports multiple database types
- vim-dadbod-ui - User-friendly interface for database operations
Additional Dependencies
- Node.js - Required by many LSP servers and development tools
- Python - Needed for Python development and some Neovim plugins
- Git - For version control and plugin management
- build-essential - Provides necessary compilation tools
Installation Steps
1. Install Neovim
Why Neovim?
Neovim is a fork of Vim that adds modern features like:
- Asynchronous plugin execution
- Built-in LSP support
- Lua-based configuration
- Better default settings
- Active community and development
System-wide Installation
# Download the latest Neovim AppImage
curl -LO https://github.com/neovim/neovim/releases/latest/download/nvim.appimage
# Make it executable for all users
chmod a+x nvim.appimage
# Move to system bin directory for global access
sudo mv nvim.appimage /usr/bin/nvim
2. Install Required Fonts
Why Special Fonts?
We use special fonts (Nerd Fonts) because they include:
- Icons used by file explorers
- Git status symbols
- LSP diagnostic icons
- Special characters used by Powerlevel10k
Recommended fonts:
- Hack Nerd Font - Clean and readable
- FiraCode Nerd Font - Includes programming ligatures
- JetBrains Mono Nerd Font - Optimized for coding
- Source Code Pro - Adobe's professional monospace font
System-wide Font Installation
# Create font directory
sudo mkdir -p /usr/local/share/fonts/<font_name>
# Copy font files
sudo cp ~/Downloads/<font_files> /usr/local/share/fonts/<font_name>/
# Set correct ownership
sudo chown -R root: /usr/local/share/fonts/<font_name>
# Set correct permissions (readable by all users)
sudo chmod 644 /usr/local/share/fonts/<font_name>/*
# Update SELinux context if using SELinux
sudo restorecon -vFr /usr/local/share/fonts/<font_name>
# Update font cache
sudo fc-cache -v
3. Install Zsh and Powerlevel10k
Why Zsh?
Zsh provides several advantages over bash:
- Better tab completion
- Better history management
- More customizable prompts
- Extended globbing features
- Spelling correction
- Better array handling
System-wide Installation
- Install Zsh:
# Update package lists
sudo apt update
# Install Zsh
sudo apt install zsh
- Make Zsh default for new users:
sudo vim /etc/adduser.conf
# Set: DSHELL=/bin/zsh
# This ensures all new users get Zsh as their default shell
- Install Oh My Zsh system-wide:
# Clone Oh My Zsh to shared location
sudo git clone https://github.com/ohmyzsh/ohmyzsh.git /usr/share/oh-my-zsh
# Make it accessible to all users
sudo chmod -R 755 /usr/share/oh-my-zsh
# Configure system-wide Zsh settings
sudo vim /etc/zsh/zshrc
Add these lines to zshrc (enables Oh My Zsh for all users):
export ZSH="/usr/share/oh-my-zsh"
ZSH_THEME="robbyrussell"
plugins=(git)
source $ZSH/oh-my-zsh.sh
- Install Powerlevel10k system-wide:
# Clone Powerlevel10k to shared themes directory
sudo git clone --depth=1 https://github.com/romkatv/powerlevel10k.git /usr/share/oh-my-zsh/custom/themes/powerlevel10k
# Edit system Zsh configuration
sudo vim /etc/zsh/zshrc
# Change: ZSH_THEME="powerlevel10k/powerlevel10k"
- Install recommended plugins:
# Install supporting tools
sudo apt install git tmux python docker
# Install zsh-autosuggestions (provides Fish-like autosuggestions)
sudo git clone https://github.com/zsh-users/zsh-autosuggestions /usr/share/oh-my-zsh/custom/plugins/zsh-autosuggestions
# Update plugins in /etc/zsh/zshrc:
plugins=(git zsh-autosuggestions tmux python docker)
4. Install NvChad
Why NvChad?
NvChad is a carefully crafted Neovim configuration that provides:
- Fast startup times (0.02-0.07 seconds)
- Modern UI with beautiful themes
- Intelligent code completion
- Syntax highlighting
- Built-in LSP configuration
- File exploration and fuzzy finding
- Git integration
Installation Steps
- Remove existing configurations:
# Clean out any existing Neovim configurations
rm -rf ~/.config/nvim
rm -rf ~/.local/state/nvim
rm -rf ~/.local/share/nvim
- Install NvChad:
# Clone the NvChad starter configuration
git clone https://github.com/NvChad/starter ~/.config/nvim
- Install dependencies:
# Install essential build tools
sudo apt install build-essential
# Install Node.js and npm (required for many LSP servers)
sudo apt install nodejs npm
# Install Python virtual environment support
sudo apt install python3.11-venv
# Install unzip (needed for some plugin installations)
sudo apt install unzip
- Initialize NvChad:
# Start Neovim (this will trigger initial plugin installation)
nvim
# Sync plugins
:Lazy sync
# Install language servers and tools
:MasonInstallAll
- Neovim folder structure:
init.lua
- This is the entry point for the Neovim configuration.
- It loads and initializes all the settings, plugins, and customizations defined in the other configuration files.
- Typically includes calls like:
require("options") require("mappings") require("plugins") require("chadrc")
lua/options.lua
- Contains basic Neovim settings and options such as:
- Line numbering.
- Indentation.
- Mouse support.
- Example settings:
vim.opt.number = true -- Show line numbers vim.opt.relativenumber = true -- Relative line numbers vim.opt.tabstop = 4 -- Tab width vim.opt.shiftwidth = 4 -- Indentation width
lua/mappings.lua
- Defines custom key mappings (shortcuts) to enhance productivity.
- Includes mappings for:
- Opening file explorers.
- Searching.
- Navigating buffers.
- Example mapping:
vim.keymap.set("n", "<leader>ff", ":Telescope find_files<CR>", { desc = "Find Files" })
lua/chadrc.lua
- This is a user-specific configuration file to override default settings.
- It's the main customization point for users.
- Example:
return { ui = { theme = "gruvbox", }, plugins = { user = function() -- Add custom plugins return { { "junegunn/vim-easy-align" } } end, }, }
lua/configs/
- Contains configurations for specific plugins or modules.
- Each plugin may have its own configuration file here for modularity.
- Example structure:
lua/configs/ ├── lspconfig.lua ├── treesitter.lua └── telescope.lua
- These files often include calls to plugin-specific setup functions:
require("nvim-treesitter.configs").setup { ensure_installed = "maintained", highlight = { enable = true, }, }
lua/plugins/
- Manages plugin specifications for the configuration.
- Works with a plugin manager, usually
lazy.nvim
. - Includes the list of plugins to load and optional lazy-loading configurations.
- Example:
return { { "nvim-treesitter/nvim-treesitter", build = ":TSUpdate", event = "BufRead", }, { "neovim/nvim-lspconfig", config = function() require("lspconfig").pyright.setup {} end, }, }
Summary
init.lua
: Main entry point, calls all configurations.lua/options.lua
: Core Neovim settings.lua/mappings.lua
: Custom key mappings.lua/chadrc.lua
: User-specific overrides for themes, plugins, and settings.lua/configs/
: Plugin configurations.lua/plugins/
: Plugin specifications for the manager.
This modular structure keeps the configuration clean, maintainable, and extensible. Each component has a well-defined purpose, making it easier to customize and manage your Neovim setup.
- Explanation of Mason and Its Integration with Neovim, Lazy, and Mason-LspConfig
What is Mason?
-
Mason is a Neovim plugin designed to simplify the installation and management of external tools, including:
- Language Server Protocol (LSP) servers.
- Linters and formatters.
- Debugging tools.
-
Key Features:
- Provides a graphical interface for managing tools.
- Automatically handles downloading, installation, and updates.
- Supports a wide range of tools across multiple programming languages.
-
Purpose:
- It eliminates the need for manual installation of LSP servers, linters, and formatters.
- Ensures that all required tools are available and correctly configured for use in Neovim.
How Mason Connects to Neovim
-
Mason works directly with Neovim's built-in LSP client,
nvim-lspconfig
. -
It manages external tools required by Neovim to provide IDE-like features:
- LSP servers: Enable code completion, diagnostics, and other language-specific features.
- Formatters and Linters: Improve code quality and enforce consistent styles.
-
Example Workflow:
- Mason installs an LSP server (e.g.,
pyright
for Python). - Neovim uses
nvim-lspconfig
to configure and connect to the installed LSP server. - Users can write and navigate code with LSP features seamlessly integrated.
- Mason installs an LSP server (e.g.,
How Mason Connects to Lazy
-
Lazy.nvim is a plugin manager for Neovim, which manages Mason itself.
-
Mason is added as a plugin in the Lazy configuration:
return { { "williamboman/mason.nvim", build = ":MasonUpdate", config = function() require("mason").setup() end, }, }
-
Lazy's Role:
- Installs Mason and ensures it is only loaded when required.
- Enables users to manage Mason through the same plugin management workflow as other Neovim plugins.
What is Mason-LspConfig?
-
Mason-LspConfig is a companion plugin to Mason.
-
It bridges the gap between Mason and
nvim-lspconfig
by:- Automatically configuring the LSP servers installed via Mason.
- Ensuring that the servers are seamlessly integrated into Neovim's LSP client.
-
Key Features:
- Simplifies LSP server setup with auto-configuration.
- Allows for automatic installation of specified LSP servers.
-
Example Configuration:
return { { "williamboman/mason-lspconfig.nvim", dependencies = { "williamboman/mason.nvim" }, config = function() require("mason-lspconfig").setup({ ensure_installed = { "pyright", "tsserver", "gopls" }, -- LSP servers to install automatic_installation = true, }) end, }, }
-
Workflow with Mason-LspConfig:
- Mason installs the tools (e.g., LSP servers).
- Mason-LspConfig ensures that the installed servers are correctly configured with
nvim-lspconfig
. - Users gain IDE-like features without needing manual LSP setup.
Summary of Relationships
Component | Role |
---|---|
Mason | Manages installation and updates of LSP servers, formatters, and linters. |
Lazy.nvim | Handles installation and lazy-loading of Mason as a plugin. |
Neovim | Uses Mason-installed tools to provide LSP and formatting features. |
Mason-LspConfig | Connects Mason-installed LSP servers with nvim-lspconfig for seamless integration. |
This ecosystem simplifies the process of setting up a fully functional Neovim environment with IDE-like capabilities.
7. Configure LSP Support
Why LSP?
The Language Server Protocol (LSP) provides:
- Code completion
- Go to definition
- Find references
- Symbol search
- Diagnostics (errors and warnings)
- Code formatting
- Refactoring support
Install and Configure Mason LSP
Create lua/plugins/mason-lspconfig.lua
:
return {
{
"williamboman/mason-lspconfig.nvim",
dependencies = { "williamboman/mason.nvim" },
config = function()
require("mason-lspconfig").setup({
-- Install these LSP servers automatically
ensure_installed = {
"pylsp", -- Python language server
"typos-lsp", -- Spell checking
"yamlls" -- YAML support
},
automatic_installation = true,
})
end,
},
}
Configure Language Servers
Update lua/config/lspconfig.lua
:
-- Load NvChad's LSP defaults
require("nvchad.configs.lspconfig").defaults()
local lspconfig = require "lspconfig"
-- Basic servers that need minimal configuration
local servers = { "html", "cssls" }
local nvlsp = require "nvchad.configs.lspconfig"
-- Configure basic servers with default settings
for _, lsp in ipairs(servers) do
lspconfig[lsp].setup {
on_attach = nvlsp.on_attach,
on_init = nvlsp.on_init,
capabilities = nvlsp.capabilities,
}
end
-- Python LSP Configuration
lspconfig.pylsp.setup {
on_attach = nvlsp.on_attach,
on_init = nvlsp.on_init,
capabilities = nvlsp.capabilities,
settings = {
pylsp = {
plugins = {
-- Configure Python code style
pycodestyle = {
enabled = true,
maxLineLength = 200 -- Allow longer lines
},
-- Disable redundant linters
pylint = { enabled = false },
flake8 = { enabled = false },
},
},
},
}
-- Code Formatting Configuration
local conform = require("conform")
conform.setup({
formatters_by_ft = {
python = {
"black", -- Code formatter
"isort" -- Import sorter
},
},
-- Format code when saving
format_on_save = {
lsp_fallback = true,
},
})
-- Spell checking configuration
require('lspconfig').typos_lsp.setup({
filetypes = { "*" }, -- Check spelling in all file types
})
8. Add Database Support
Why Database Integration?
Having database tools integrated into your editor allows you to:
- Query databases directly from your editor
- View and edit database structures
- Execute SQL queries with completion
- Save and organize database queries
- Switch between different databases easily
Install required database engines:
sudo apt install sqlite3 # Start with SQLite support
Create lua/plugins/database-support.lua
:
return {
-- Core database support
{
"tpope/vim-dadbod",
lazy = true, -- Only load when needed
cmd = { "DB", "DBUI", "DBUIToggle", "DBUIAddConnection" },
},
-- User interface for database operations
{
"kristijanhusak/vim-dadbod-ui",
dependencies = { "tpope/vim-dadbod" },
lazy = true,
cmd = { "DBUI", "DBUIToggle" },
config = function()
-- Save queries in nvim config directory
vim.g.db_ui_save_location = "~/.config/nvim/db_ui_queries"
-- Automatically execute helper SQL statements
vim.g.db_ui_auto_execute_table_helpers = 1
-- Use Nerd Font icons
vim.g.db_ui_use_nerd_fonts = 1
-- Show database icons
vim.g.db_ui_show_database_icon = 1
end,
},
-- SQL completion support
{
"kristijanhusak/vim-dadbod-completion",
dependencies = { "tpope/vim-dadbod" },
lazy = true,
ft = { "sql" },
config = function()
-- Enable SQL completion
require("cmp").setup.buffer {
sources = {
{ name = "vim-dadbod-completion" },
},
}
end,
},
}
9. Configure Debugging Support
Why Debug Integration?
Integrated debugging provides:
- Interactive debugging within your editor
- Breakpoint management
- Variable inspection
- Call stack navigation
- Conditional breakpoints
- Watch expressions
Create the following configuration files:
1. Base DAP Configuration (lua/plugins/nvim-dap.lua
):
return {
{
"mfussenegger/nvim-dap",
config = function (_, opts)
local map = vim.keymap.set
-- Create a shortcut to toggle breakpoints
map("n", "<leader>db", "<cmd> DapToggleBreakpoint <CR>",
{ desc = "Toggle breakpoint" })
end
}
}
2. Python Debug Support (lua/plugins/nvim-dap-python.lua
):
return {
{
"mfussenegger/nvim-dap-python",
ft = "python", -- Only load for Python files
dependencies = {
"mfussenegger/nvim-dap",
"rcarriga/nvim-dap-ui"
},
config = function (_, opts)
-- Ensure debugpy is installed
local mason_registry = require("mason-registry")
local debugpy = "debugpy"
if not mason_registry.is_installed(debugpy) then
mason_registry.get_package(debugpy):install()
end
-- Set up Python debugging
local package = mason_registry.get_package(debugpy)
local install_path = package:get_install_path()
local python_path = install_path .. "/venv/bin/python"
require("dap-python").setup(python_path)
local map = vim.keymap.set
local dap_python = require('dap-python')
-- Add keybinding for debugging Python tests
map("n", "<leader>dpr", function()
dap_python.test_method()
end, { desc = "Debug Python test method" })
-- Add keybinding to switch test runners
map("n", "<leader>drt", function()
if dap_python.test_runner == "pytest" then
dap_python.test_runner = "unittest"
print("Test runner switched to: unittest")
else
dap_python.test_runner = "pytest"
print("Test runner switched to: pytest")
end
end, { desc = "Toggle Python test runner" })
end
}
}
3. Debug UI Configuration (lua/plugins/nvim-dap-ui.lua
):
return {
"rcarriga/nvim-dap-ui",
dependencies = {
"mfussenegger/nvim-dap",
"nvim-neotest/nvim-nio"
},
config = function()
local dap, dapui = require("dap"), require("dapui")
dapui.setup()
-- Automatically open UI when debugging starts
dap.listeners.before.attach["dapui_config"] = function()
dapui.open()
end
dap.listeners.before.launch["dapui_config"] = function()
dapui.open()
end
local map = vim.keymap.set
-- Add keybindings for UI control
map("n", "<leader>du", function()
dapui.toggle()
end, { desc = "Toggle DAP UI" })
map("n", "<leader>dc", function()
dapui.close()
end, { desc = "Close DAP UI" })
end
}
10. Configure Custom Key Mappings
Add these custom key mappings to lua/mappings.lua
:
10.1 Opening Command Palette
map('n', '<leader>cp', function()
require('telescope.builtin').commands()
end, { noremap = true, silent = true })
11. Enable Volt Menu
Add the following to init.lua
to enable Volt support:
-- Keyboard users
vim.keymap.set("n", "<C-t>", function()
require("menu").open("default")
end, {})
-- Mouse users + NvimTree users!
vim.keymap.set("n", "<RightMouse>", function()
vim.cmd.exec '"normal! <RightMouse>"'
local options = vim.bo.ft == "NvimTree" and "nvimtree" or "default"
require("menu").open(options, { mouse = true })
end, {})
Explanation: This enables Volt, a Neovim plugin, by adding key mappings for both keyboard (<C-t>
) and mouse (<RightMouse>
). Volt is used to provide context-sensitive menus in Neovim.
Key Mappings Reference
Mapping | Description | When to Use |
---|---|---|
<leader>db |
Toggle breakpoint | When you want to pause execution at a specific line |
<leader>dpr |
Debug Python test method | When debugging a specific Python test |
<leader>drt |
Toggle Python test runner | To switch between pytest and unittest frameworks |
<leader>du |
Toggle debug UI | To show/hide the debugging interface |
<leader>dc |
Close debug UI | To close the debugging interface |
<leader>cp |
Open command palette | To access available commands quickly |
<C-t> |
Open Volt menu (keyboard) | To access context-sensitive actions |
<RightMouse> |
Open Volt menu (context) | To access context menu with mouse |
Troubleshooting
Common Issues and Solutions
-
gcc/C compiler missing:
# Install build tools sudo apt install build-essential
Why: Many plugins have C/C++ dependencies that need compilation.
-
npm not found:
# Install Node.js and npm sudo apt install npm nodejs
Why: Required for many LSP servers and development tools.
-
Python venv creation fails:
# Install Python virtual environment support sudo apt install python3-venv python3.11-venv
Why: Python LSP and debugger need virtual environments.
-
Unzip not found:
# Install unzip utility sudo apt install unzip
Why: Required for extracting plugin files.
Verifying Installation
Run these commands to verify your setup:
-
:checkhealth
in Neovim- Checks for common configuration issues
- Verifies plugin health
- Identifies missing dependencies
-
upgrade_oh_my_zsh
- Verifies Oh My Zsh installation
- Updates Oh My Zsh if needed
-
:LspInfo
- Shows active language servers
- Displays LSP configuration status
-
:ConformInfo
- Lists available formatters
- Shows formatter configuration
Additional Resources
For more detailed information and updates, visit:
- Neovim Documentation - Official Neovim docs
- NvChad Documentation - NvChad setup and customization
- Mason Package List - Available LSP servers and tools
- Debug Adapter Protocol - Understanding DAP
- Language Server Protocol - Understanding LSP