强曰为道

与天地相似,故不违。知周乎万物,而道济天下,故不过。旁行而不流,乐天知命,故不忧.
文档目录

10 - Lua 配置与 API

“Lua is not just an alternative to VimScript — it’s Neovim’s superpower.”

10.1 为什么用 Lua

10.1.1 Lua vs VimScript

维度VimScriptLua
性能较慢LuaJIT(极快)
语法独特、老旧简洁、现代
数据结构list/dicttable(统一)
异步有限libuv 全面支持
调试困难标准工具链
生态插件为主代码为主
学习资源丰富快速增长

10.1.2 在 Neovim 中使用 Lua

" VimScript 中调用 Lua
lua print("Hello from Lua")
lua require("my_module")
lua << EOF
local msg = "Hello"
print(msg)
EOF

" Lua 代码中调用 Vim 命令
lua vim.cmd("echo 'hi'")
lua vim.cmd([[set number]])

10.2 init.lua 入口

10.2.1 基本结构

-- ~/.config/nvim/init.lua

-- 设置 Leader 键(必须在插件加载前)
vim.g.mapleader = " "
vim.g.maplocalleader = "\\"

-- 加载配置模块
require("config.options")
require("config.keymaps")
require("config.autocmds")

-- 加载插件(lazy.nvim)
require("config.lazy")

10.2.2 模块化结构

~/.config/nvim/
├── init.lua
├── lua/
│   ├── config/
│   │   ├── options.lua     -- 选项设置
│   │   ├── keymaps.lua     -- 快捷键
│   │   ├── autocmds.lua    -- 自动命令
│   │   └── lazy.lua        -- lazy.nvim 配置
│   ├── plugins/
│   │   ├── colorscheme.lua
│   │   ├── editor.lua
│   │   ├── lsp.lua
│   │   └── ui.lua
│   └── utils/
│       └── helpers.lua

10.3 vim.opt — 选项设置

local opt = vim.opt

-- 行号
opt.number = true
opt.relativenumber = true

-- 缩进
opt.tabstop = 4
opt.shiftwidth = 4
opt.expandtab = true
opt.smartindent = true

-- 搜索
opt.ignorecase = true
opt.smartcase = true
opt.hlsearch = true
opt.incsearch = true

-- 外观
opt.termguicolors = true
opt.signcolumn = "yes"
opt.cursorline = true
opt.scrolloff = 8
opt.wrap = false
opt.showmode = false

-- 分割窗口
opt.splitbelow = true
opt.splitright = true

-- 性能
opt.updatetime = 250
opt.timeoutlen = 300

-- 文件
opt.swapfile = false
opt.backup = false
opt.undofile = true
opt.clipboard = "unnamedplus"

-- 补全
opt.completeopt = { "menu", "menuone", "noselect" }
opt.pumheight = 10

10.4 vim.keymap.set — 快捷键

10.4.1 基本用法

local map = vim.keymap.set

-- 普通模式
map("n", "<leader>w", "<cmd>w<CR>", { desc = "保存文件" })
map("n", "<leader>q", "<cmd>q<CR>", { desc = "退出" })

-- 插入模式
map("i", "jk", "<Esc>", { desc = "退出插入模式" })

-- 可视模式
map("v", "<", "<gv", { desc = "缩进后保持选中" })
map("v", ">", ">gv", { desc = "反缩进后保持选中" })

-- 命令模式
map("c", "<C-a>", "<Home>", { desc = "跳到行首" })
map("c", "<C-e>", "<End>", { desc = "跳到行尾" })

10.4.2 选项

map("n", "<leader>f", function()
    vim.lsp.buf.format()
end, {
    desc = "格式化文件",       -- 描述(用于 which-key 等)
    silent = true,             -- 不显示命令
    noremap = true,            -- 非递归
    nowait = true,             -- 不等待后续按键
    buffer = true,             -- 仅当前缓冲区
    expr = false,              -- 是否表达式映射
})

10.4.3 Lua 函数映射

-- 直接使用 Lua 函数
map("n", "<leader>ff", function()
    require("telescope.builtin").find_files()
end, { desc = "查找文件" })

-- 带参数的函数
map("n", "<leader>g", function()
    local word = vim.fn.expand("<cword>")
    vim.cmd("vimgrep " .. word .. " **/*")
end, { desc = "搜索单词" })

10.5 vim.api — 核心 API

10.5.1 常用 API

-- 获取当前行
local line = vim.api.nvim_get_current_line()

-- 设置当前行
vim.api.nvim_set_current_line("new content")

-- 获取光标位置 (0-indexed)
local row, col = unpack(vim.api.nvim_win_get_cursor(0))

-- 设置光标位置
vim.api.nvim_win_set_cursor(0, {1, 0})  -- 第1行,第0列

-- 获取缓冲区行数
local line_count = vim.api.nvim_buf_line_count(0)

-- 获取缓冲区内容
local lines = vim.api.nvim_buf_get_lines(0, 0, -1, false)

-- 设置缓冲区内容
vim.api.nvim_buf_set_lines(0, 0, -1, false, {"line1", "line2"})

-- 获取当前缓冲区号
local buf = vim.api.nvim_get_current_buf()

-- 创建缓冲区
local buf = vim.api.nvim_create_buf(true, true)  -- 列入缓冲区列表, 可修改

-- 删除缓冲区
vim.api.nvim_buf_delete(buf, { force = true })

10.5.2 窗口 API

-- 获取当前窗口
local win = vim.api.nvim_get_current_win()

-- 创建浮动窗口
local buf = vim.api.nvim_create_buf(false, true)
local win = vim.api.nvim_open_win(buf, true, {
    relative = "editor",
    width = 60,
    height = 20,
    row = 5,
    col = 10,
    style = "minimal",
    border = "rounded",
})

-- 关闭窗口
vim.api.nvim_win_close(win, true)

10.5.3 选项 API

-- 获取选项
local ts = vim.api.nvim_get_option_value("tabstop", {})

-- 设置选项
vim.api.nvim_set_option_value("tabstop", 2, {})

-- 缓冲区局部选项
vim.api.nvim_set_option_value("shiftwidth", 2, { buf = 0 })

10.5.4 高亮 API

-- 创建高亮组
vim.api.nvim_set_hl(0, "MyHighlight", {
    fg = "#ff0000",
    bg = "#000000",
    bold = true,
    italic = true,
})

-- 获取高亮
local hl = vim.api.nvim_get_hl(0, { name = "Normal" })

10.6 vim.fn — Vim 函数

-- 调用 Vim 内置函数
local home = vim.fn.expand("~")
local files = vim.fn.glob("**/*.lua")
local file = vim.fn.expand("%:p")
local line_num = vim.fn.line(".")
local col_num = vim.fn.col(".")
local word = vim.fn.expand("<cword>")

-- 系统命令
local result = vim.fn.system("git status")
local branch = vim.fn.system("git branch --show-current"):gsub("\n", "")

-- 用户输入
local input = vim.fn.input("Enter value: ")
local choice = vim.fn.confirm("Continue?", "&Yes\n&No", 1)

-- 文件操作
vim.fn.mkdir(vim.fn.fnamemodify(file, ":h"), "p")
vim.fn.writefile({"line1", "line2"}, "/tmp/output.txt")

10.7 vim.cmd — Ex 命令

-- 单条命令
vim.cmd("echo 'Hello'")
vim.cmd("set number")
vim.cmd("colorscheme gruvbox")

-- 多行命令块
vim.cmd([[
    highlight MyGroup guifg=#ff0000
    autocmd BufWritePre * %s/\s\+$//e
]])

-- 带变量的命令
vim.cmd("colorscheme " .. colorscheme_name)

10.8 自动命令(Lua 方式)

-- 创建自动命令
vim.api.nvim_create_autocmd("BufWritePre", {
    pattern = "*.py",
    callback = function()
        vim.cmd("%s/\\s\\+$//e")
    end,
    desc = "保存时去除尾部空格",
})

-- 创建自动命令组
local group = vim.api.nvim_create_augroup("MyGroup", { clear = true })

vim.api.nvim_create_autocmd("FileType", {
    group = group,
    pattern = { "python", "javascript" },
    callback = function()
        vim.opt_local.tabstop = 2
        vim.opt_local.shiftwidth = 2
    end,
    desc = "设置 Python/JS 缩进",
})

vim.api.nvim_create_autocmd("TextYankPost", {
    group = group,
    callback = function()
        vim.highlight.on_yank({ higroup = "IncSearch", timeout = 500 })
    end,
    desc = "高亮复制的文本",
})

10.9 用户命令

-- 创建用户命令
vim.api.nvim_create_user_command("Greet", function(opts)
    print("Hello, " .. opts.args .. "!")
end, {
    nargs = 1,
    desc = "打招呼",
})

-- 带补全的命令
vim.api.nvim_create_user_command("SetColor", function(opts)
    vim.cmd("colorscheme " .. opts.args)
end, {
    nargs = 1,
    complete = function()
        return { "gruvbox", "catppuccin", "tokyonight", "dracula" }
    end,
    desc = "设置颜色主题",
})

-- 调用
" :Greet World
" :SetColor catppuccin

10.10 Neovim 独有功能

10.10.1 虚拟文本(Virtual Text)

-- 在行末显示虚拟文本
local ns = vim.api.nvim_create_namespace("my_namespace")
vim.api.nvim_buf_set_extmark(0, ns, 0, -1, {
    virt_text = {{"[info]", "Comment"}},
    virt_text_pos = "eol",
})

10.10.2 浮动窗口

local function show_float(content)
    local buf = vim.api.nvim_create_buf(false, true)
    vim.api.nvim_buf_set_lines(buf, 0, -1, false, content)
    vim.api.nvim_open_win(buf, false, {
        relative = "cursor",
        width = 40,
        height = #content,
        row = 1,
        col = 0,
        style = "minimal",
        border = "rounded",
        focusable = false,
    })
end

show_float({"Hello", "World", "From Float"})

10.10.3 vim.ui

-- 替换选择菜单
vim.ui.select({"Option A", "Option B", "Option C"}, {
    prompt = "Choose:",
}, function(choice)
    if choice then
        print("Selected: " .. choice)
    end
end)

-- 替换输入框
vim.ui.input({
    prompt = "Enter value: ",
    default = "default",
}, function(input)
    if input then
        print("Input: " .. input)
    end
end)

10.10.4 绘图(Decorations)

-- 设置标记
local ns = vim.api.nvim_create_namespace("marks")
vim.api.nvim_buf_set_extmark(0, ns, 5, 0, {
    sign_text = "➤",
    sign_hl_group = "DiagnosticSignHint",
})

10.11 业务场景

场景Lua 方式
配置选项vim.opt.xxx = value
键位映射vim.keymap.set(...)
自动命令vim.api.nvim_create_autocmd(...)
用户命令vim.api.nvim_create_user_command(...)
浮动窗口vim.api.nvim_open_win(...)
插件配置return { "plugin", opts = {...} }

10.12 总结

模块用途
vim.opt选项设置
vim.keymap快捷键映射
vim.apiNeovim 核心 API
vim.fnVim 函数调用
vim.cmdEx 命令
vim.lspLSP 客户端 API
vim.treesitterTree-sitter API
vim.uiUI 选择/输入
vim.diagnostic诊断 API

下一步第 11 章 - 插件管理 → 学习使用 lazy.nvim 管理 Neovim 插件生态。


扩展阅读