Neovim Basics

The fork that changed everything. Neovim is not just a refactor; it is a complete reimagining of what Vim can be.

By embedding LuaJIT directly into the editor core, Neovim unlocked a level of performance and extensibility that Vimscript could never achieve. In this chapter, we will leave the legacy behind and start building a modern, high-performance editor configuration from scratch using Lua.

1. The Architecture of Speed

Neovim’s power comes from its architecture. Unlike Vim, which was a monolithic C codebase tightly coupled to the terminal UI, Neovim decouples the editor core from the interface.

Neovim Architecture

Neovim Core (C) LuaJIT Runtime MsgPack RPC API Terminal UI (TUI) GUI (Qt/Electron) Lua Plugins
Key Insight: Neovim treats the UI as just another plugin. This allows for GUIs, browser integrations, and even embedding Neovim inside VS Code!

2. Speaking Lua

Neovim exposes a global vim object in Lua. This is your gateway to the editor internals.

1. Options (vim.opt)

This is the equivalent of :set.

-- Vimscript: set number
vim.opt.number = true

-- Vimscript: set relativenumber
vim.opt.relativenumber = true

-- Vimscript: set tabstop=4
vim.opt.tabstop = 4

-- Vimscript: set nowrap
vim.opt.wrap = false

2. Global Variables (vim.g)

Equivalent to :let g:variable = value. Most commonly used for setting the Leader Key.

-- Vimscript: let mapleader = " "
vim.g.mapleader = " "

3. Key Mappings (vim.keymap.set)

The modern replacement for nnoremap, inoremap, etc.

-- Syntax: vim.keymap.set(mode, lhs, rhs, opts)

-- Normal mode: <Leader>w saves the file
vim.keymap.set("n", "<Leader>w", ":write<CR>", { desc = "Save file" })

-- Insert mode: jk exits insert mode
vim.keymap.set("i", "jk", "<Esc>", { desc = "Exit insert mode" })

3. Interactive: Lua Config Playground

Experiment with basic Neovim options. Toggle the switches to generate the corresponding Lua configuration code.

Editor Options

Generated `init.lua`

-- Neovim Configuration
vim.opt.wrap = true
vim.opt.hlsearch = true

4. File Structure

Stop dumping everything into one file. Lua allows for a clean, modular structure.

~/.config/nvim/
├── init.lua           # Entry point
├── lua/
│   └── user/          # Your custom module namespace
│       ├── core/
│       │   ├── options.lua
│       │   └── keymaps.lua
│       └── plugins/   # We'll cover this in Chapter 3

In your init.lua, you simply require the modules:

-- ~/.config/nvim/init.lua
require("user.core.options")
require("user.core.keymaps")

This keeps your configuration organized and maintainable as it grows.

5. Why switch?

Feature Vim Neovim
Language Vimscript (Slow, obscure) Lua (Fast, widely used)
Plugins Synchronous (blocks UI) Asynchronous (smooth UI)
LSP Requires heavy plugins Built-in native client
Treesitter No Built-in (Better highlighting)
Defaults Conservative Modern (sensible defaults)

[!TIP] Pro Tip: Use vim.opt.termguicolors = true to enable 24-bit True Color support in the terminal. This is essential for modern themes like Tokyo Night or Catppuccin.

6. Next Steps

Now that we have the basics down, it’s time to unlock the real power of Neovim: the built-in Language Server Protocol client. In the next chapter, we’ll turn Neovim into a full-fledged IDE.