NeoVim轻量级IDE

备注

我曾经花费了大量时间来参考网上文章配置vim和nvim,但是一则浪费时间,二则随着时间推移各种配置方法层出不穷且很容易过时。所以现在采用AI自动生成配置,避免浪费精力,集中注意力在真正的开发工作上。

我在构建 MacBook Air 11" Late 2010 上使用的 alpine-dev Podman image ,采用了gemini提供的一个快速构建nvim的IDE的 init.lua ,只需要将该配置文件复制到 ~/.config/nvim/init.lua 然后启动 nvim 就能够快速完成一个轻量级IDE:

~/.config/nvim/init.lua
  1-- =============================================================================
  2-- 1. 基础体验优化
  3-- =============================================================================
  4vim.g.mapleader = " "              -- 设置 Leader 键为空格
  5vim.opt.number = true              -- 显示行号
  6vim.opt.relativenumber = true      -- 显示相对行号
  7vim.opt.termguicolors = true       -- 开启 24 位真彩色支持
  8vim.opt.shiftwidth = 4             -- 缩进空格数
  9vim.opt.tabstop = 4
 10vim.opt.expandtab = true           -- Tab 转空格
 11vim.opt.signcolumn = "yes"         -- 始终显示左侧警告/报错标记列
 12
 13-- =============================================================================
 14-- 2. 健壮的 lazy.nvim 自动安装逻辑
 15-- =============================================================================
 16local lazypath = vim.fn.stdpath("data") .. "/lazy/lazy.nvim"
 17if not (vim.uv or vim.loop).fs_stat(lazypath) then
 18  local lazyrepo = "https://github.com/folke/lazy.nvim.git"
 19  local out = vim.fn.system({ "git", "clone", "--filter=blob:none", "--branch=stable", lazyrepo, lazypath })
 20  if vim.v.shell_error ~= 0 then
 21    vim.api.nvim_echo({
 22      { "Failed to clone lazy.nvim:\n", "ErrorMsg" },
 23      { out, "WarningMsg" },
 24      { "\nPress any key to exit..." },
 25    }, true, {})
 26    vim.fn.getchar()
 27    os.exit(1)
 28  end
 29end
 30vim.opt.rtp:prepend(lazypath)
 31
 32local status_ok, lazy = pcall(require, "lazy")
 33if not status_ok then return end
 34
 35-- =============================================================================
 36-- 3. 插件配置列表
 37-- =============================================================================
 38lazy.setup({
 39  -- 【主题】:Tokyo Night
 40  {
 41    "folke/tokyonight.nvim",
 42    lazy = false,
 43    priority = 1000,
 44    config = function()
 45      vim.cmd([[colorscheme tokyonight-night]])
 46    end,
 47  },
 48
 49  -- 【文件导航栏】:neo-tree
 50  {
 51    "nvim-neo-tree/neo-tree.nvim",
 52    branch = "v3.x",
 53    dependencies = {
 54      "nvim-lua/plenary.nvim",
 55      "nvim-tree/nvim-web-devicons", -- 文件图标支持
 56      "MunifTanjim/nui.nvim",
 57    },
 58    config = function()
 59      require("neo-tree").setup({
 60        close_if_last_window = true, -- 如果只剩下文件树窗口,自动退出 nvim
 61        filesystem = {
 62          filtered_items = {
 63            visible = true,          -- 显示隐藏文件(如 .gitignore, .config 等)
 64          },
 65          follow_current_file = {
 66            enabled = true,          -- 打开文件时,文件树自动定位到当前文件
 67          },
 68        },
 69      })
 70
 71      -- 快捷键设置:
 72      -- 按 <Ctrl + n> 切换文件树显隐
 73      vim.keymap.set("n", "<C-n>", ":Neotree toggle<CR>", { silent = true })
 74      -- 按 <Leader + e>(即 空格 + e)也可以切换文件树
 75      vim.keymap.set("n", "<leader>e", ":Neotree toggle<CR>", { silent = true })
 76    end,
 77  },
 78
 79  -- 【语法高亮】:Treesitter
 80  {
 81    "nvim-treesitter/nvim-treesitter",
 82    build = ":TSUpdate",
 83    config = function()
 84      local ts_ok, ts_configs = pcall(require, "nvim-treesitter.configs")
 85      if not ts_ok then return end
 86      ts_configs.setup({
 87        ensure_installed = { "c", "ruby", "python", "rust", "markdown", "markdown_inline", "bash", "lua" },
 88        highlight = { enable = true },
 89      })
 90    end,
 91  },
 92
 93  -- 【LSP 配置库】
 94  "neovim/nvim-lspconfig",
 95
 96  -- 【自动补全引擎与 UI 弹窗】
 97  {
 98    "hrsh7th/nvim-cmp",
 99    dependencies = {
100      "hrsh7th/cmp-nvim-lsp",     -- LSP 补全源
101      "hrsh7th/cmp-buffer",       -- 当前 Buffer 词汇补全
102      "hrsh7th/cmp-path",         -- 文件路径补全
103      "L3MON4D3/LuaSnip",         -- 代码片段引擎
104    },
105    config = function()
106      local cmp = require("cmp")
107      cmp.setup({
108        snippet = {
109          expand = function(args) require("luasnip").lsp_expand(args.body) end,
110        },
111        mapping = cmp.mapping.preset.insert({
112          ["<C-k>"] = cmp.mapping.select_prev_item(),
113          ["<C-j>"] = cmp.mapping.select_next_item(),
114          ["<C-Space>"] = cmp.mapping.complete(),
115          ["<CR>"] = cmp.mapping.confirm({ select = true }),
116          ["<Tab>"] = cmp.mapping.select_next_item(),
117        }),
118        sources = cmp.config.sources({
119          { name = "nvim_lsp" },
120          { name = "path" },
121          { name = "buffer" },
122        }),
123      })
124    end,
125  },
126
127  -- 【状态栏】
128  {
129    "nvim-lualine/lualine.nvim",
130    config = function() require("lualine").setup() end,
131  },
132})
133
134-- =============================================================================
135-- 4. 绑定 Dockerfile 中内置的 LSP
136-- =============================================================================
137local capabilities = {}
138local cmp_lsp_ok, cmp_nvim_lsp = pcall(require, "cmp_nvim_lsp")
139if cmp_lsp_ok then
140  -- 修复:修改为全小写划线命名 default_capabilities()
141  capabilities = cmp_nvim_lsp.default_capabilities()
142end
143
144local on_attach = function(client, bufnr)
145  local opts = { buffer = bufnr, silent = true }
146  vim.keymap.set("n", "gd", vim.lsp.buf.definition, opts)       -- 跳转定义
147  vim.keymap.set("n", "K",  vim.lsp.buf.hover, opts)            -- 文档悬停
148  vim.keymap.set("n", "gr", vim.lsp.buf.references, opts)       -- 查找引用
149  vim.keymap.set("n", "<leader>rn", vim.lsp.buf.rename, opts)   -- 变量重命名
150  vim.keymap.set("n", "<leader>ca", vim.lsp.buf.code_action, opts) -- 代码修复
151end
152
153local servers = { "clangd", "solargraph", "jedi_language_server", "ruff", "rust_analyzer", "marksman" }
154
155for _, server in ipairs(servers) do
156  if vim.lsp.config then
157    vim.lsp.config(server, {
158      capabilities = capabilities,
159      on_attach = on_attach,
160    })
161    vim.lsp.enable(server)
162  else
163    local lspconfig_ok, lspconfig = pcall(require, "lspconfig")
164    if lspconfig_ok then
165      lspconfig[server].setup({
166        capabilities = capabilities,
167        on_attach = on_attach,
168      })
169    end
170  end
171end

这个独立的 ~/.config/nvim/init.lua 采用单文件架构,涵盖了从插件管理、主题UI、代码高亮、侧边栏文件树到 LSP 自动补全的核心开发体验:

  • 基础体验与 UI 设定:

    • vim.g.mapleader = " " : 将空格键(Space)设为 Leader 键,符合现代 Neovim 快捷键习惯。

    • 开启行号、相对行号、24位真彩色(termguicolors)与默认 4 空格缩进。

  • 插件管理器( lazy.nvim )自动初始化:

    • 启动时检查 lazy.nvim 是否存在,若不存在则阻塞执行 git clone 自动下载。

    • 加入了错误拦截与 pcall 异常包裹,确保即使网络抖动也不会导致 Neovim 启动崩溃。

  • 精选插件组合:

    • tokyonight.nvim :主题,提供深色视觉风格。

    • neo-tree.nvim :IDE 风格的文件导航侧边栏,支持图标显示与自动追踪当前打开的文件。

    • nvim-treesitter : 基于语法树的高级语法高亮引擎,配置了 C、Ruby、Python、Rust、Markdown 等语言解析器。

    • nvim-cmp 体系: 自动补全前端 UI,融合了 LSP 接口、当前 Buffer 词汇、文件路径以及 LuaSnip 代码片段源。

    • lualine.nvim : 底部信息状态栏。

  • 绑定 alpine-dev Podman image 内置 LSP 服务:

    • 自动连接 Dockerfile 内置的 6 个系统级 LSP/Tools(clangd, solargraph, jedi_language_server, ruff, rust_analyzer, marksman)。

    • 适配 Neovim 0.11+ 的原生 vim.lsp.config API,同时兼容旧版 lspconfig 语法。

常用开发技巧与快捷键指南

所有快捷键均已在 init.lua 中配置完毕,开箱即用:

文件导航栏(Neo-tree)

文件导航栏(Neo-tree)

快捷键

功能描述

Ctrl + n 或 空格 + e

开关/折叠 左侧文件树侧边栏

Ctrl + w + w

在代码编辑区和文件树之间切换焦点

Enter (回车)

(文件树内)打开选中的文件,或展开/折叠目录

a

(文件树内)新建文件/文件夹(输入 foo.py 创建文件,输入 bar/ 创建目录)

d

(文件树内)删除当前选中的文件/目录(会弹窗确认)

r

(文件树内)重命名当前文件/目录

代码自动补全(nvim-cmp)

在插入模式(Insert Mode)下编写代码时,补全菜单会自动弹出

代码自动补全(nvim-cmp)

快捷键

功能描述

Tab 或 Ctrl + j

在补全下拉菜单中向下选择下一项

Ctrl + k

在补全下拉菜单中向上选择上一项

Enter (回车)

确认使用当前选中的补全建议

Ctrl + Space

手动强制触发补全菜单

LSP 跳转、查阅与代码重构

打开任意 C、Python、Ruby、Rust 或 Markdown 文件时,LSP 会自动在后台静默启动。把光标移动到目标变量、函数或类名上,在普通模式(Normal Mode)下操作:

LSP 跳转、查阅与代码重构

快捷键

功能描述

示例场景

gd

跳转到定义 (Go to Definition)

光标在函数调用 foo() 上,按 gd 直接切到该函数的声明/实现位置

Ctrl + o

跳回上一次位置 (Jump Back)

按 gd 跳转过去后,按 Ctrl+o 可以快速跳回原代码位置

K

查看悬停文档/函数签名 (Hover)

查看函数的参数类型、返回值说明或 Docstring 弹窗

gr

查找所有引用 (Find References)

查看整个项目中哪里调用了这个变量或函数(底栏会列出匹配行)

空格 + rn

变量/函数全局重命名 (Rename)

触发重命名弹窗,修改后整个项目里该变量的所有引用自动同步修改

空格 + ca

执行 LSP 代码修复动作 (Code Action)

当代码出现红线报错或警告时,按此键列出可用的自动修复选项

界面与编辑器基础

  • 折叠/展开:进入文件后,Treesitter 会自动识别代码块,在普通模式下按 zc 折叠代码块,按 zo 展开代码块。

  • 分屏操作:

    • :vsplit :垂直拆分窗口。

    • :split :水平拆分窗口。

    • Ctrl + w 加上方向键( h/j/k/l ):在拆分出来的各个窗口间快速移动光标。

参考

  • gemini