Neovim + Lazy.nvim 起一个最小 IDE 配置(含 LSP / 补全 / 文件树)

Neovim 0.10+ 已经是一流的 IDE 平台:内置 LSP 客户端、Treesitter 语法、
Lua 配置。Lazy.nvim 是事实标准的插件管理器,懒加载 + 锁版本。

下面给一个 < 100 行 Lua、能开箱即用的最小配置。

1. 装 Neovim 0.10+

# Ubuntu 24.04+ apt 自带;老版本用 ppa / appimage / brew
sudo apt install -y neovim
nvim --version    # 确认 >= 0.10

2. 目录结构

~/.config/nvim/
├── init.lua
└── lua/
    ├── options.lua
    ├── keymaps.lua
    ├── plugins.lua
    └── lsp.lua

3. init.lua

-- 一键 bootstrap lazy.nvim
local lazypath = vim.fn.stdpath('data') .. '/lazy/lazy.nvim'
if not vim.uv.fs_stat(lazypath) then
  vim.fn.system({
    'git', 'clone', '--filter=blob:none',
    'https://github.com/folke/lazy.nvim.git',
    '--branch=stable', lazypath,
  })
end
vim.opt.rtp:prepend(lazypath)

require('options')
require('keymaps')
require('lazy').setup(require('plugins'))
require('lsp')

4. lua/options.lua

local o = vim.opt

o.number = true
o.relativenumber = true
o.signcolumn = 'yes'        -- 给 LSP / git 留位置
o.expandtab = true
o.shiftwidth = 2
o.tabstop = 2
o.smartindent = true
o.wrap = false
o.ignorecase = true
o.smartcase = true
o.termguicolors = true
o.cursorline = true
o.scrolloff = 8
o.updatetime = 250          -- 让 hover / diag 更快
o.clipboard = 'unnamedplus' -- 跟系统剪贴板互通
o.splitright = true
o.splitbelow = true
o.undofile = true           -- 跨 session undo
o.mouse = 'a'

5. lua/keymaps.lua

vim.g.mapleader = ' '
vim.g.maplocalleader = ' '

local map = vim.keymap.set

map('n', '<leader>w', '<cmd>w<cr>', { desc = 'Save' })
map('n', '<leader>q', '<cmd>q<cr>', { desc = 'Quit' })
map('n', '<esc>', '<cmd>nohlsearch<cr>')
map('n', '<C-h>', '<C-w>h')
map('n', '<C-j>', '<C-w>j')
map('n', '<C-k>', '<C-w>k')
map('n', '<C-l>', '<C-w>l')
map('v', '<', '<gv')        -- 缩进后保持选中
map('v', '>', '>gv')

6. lua/plugins.lua

return {
  -- 配色
  { 'catppuccin/nvim', name = 'catppuccin',
    config = function() vim.cmd.colorscheme('catppuccin-mocha') end },

  -- 文件树
  { 'nvim-tree/nvim-tree.lua',
    dependencies = { 'nvim-tree/nvim-web-devicons' },
    keys = { { '<leader>e', '<cmd>NvimTreeToggle<cr>', desc = 'File tree' } },
    config = function() require('nvim-tree').setup() end,
  },

  -- 模糊搜索
  { 'nvim-telescope/telescope.nvim',
    dependencies = { 'nvim-lua/plenary.nvim' },
    keys = {
      { '<leader>f', '<cmd>Telescope find_files<cr>', desc = 'Find files' },
      { '<leader>g', '<cmd>Telescope live_grep<cr>',  desc = 'Live grep' },
      { '<leader>b', '<cmd>Telescope buffers<cr>',    desc = 'Buffers' },
    },
  },

  -- 语法高亮(Treesitter)
  { 'nvim-treesitter/nvim-treesitter',
    build = ':TSUpdate',
    config = function()
      require('nvim-treesitter.configs').setup({
        ensure_installed = { 'lua', 'python', 'javascript', 'typescript',
                             'tsx', 'go', 'rust', 'bash', 'markdown',
                             'json', 'yaml', 'html', 'css' },
        highlight = { enable = true },
        indent = { enable = true },
      })
    end,
  },

  -- Git 集成
  { 'lewis6991/gitsigns.nvim',
    config = function() require('gitsigns').setup() end },

  -- LSP 安装管理
  { 'williamboman/mason.nvim', config = true },
  { 'williamboman/mason-lspconfig.nvim',
    dependencies = { 'mason.nvim', 'neovim/nvim-lspconfig' },
    config = function()
      require('mason-lspconfig').setup({
        ensure_installed = { 'pyright', 'ts_ls', 'lua_ls', 'gopls', 'rust_analyzer' },
      })
    end,
  },

  -- 补全
  { 'hrsh7th/nvim-cmp',
    dependencies = {
      'hrsh7th/cmp-nvim-lsp',
      'hrsh7th/cmp-buffer',
      'hrsh7th/cmp-path',
      'L3MON4D3/LuaSnip',
      'saadparwaiz1/cmp_luasnip',
    },
    config = function()
      local cmp = require('cmp')
      cmp.setup({
        snippet = { expand = function(args) require('luasnip').lsp_expand(args.body) end },
        mapping = cmp.mapping.preset.insert({
          ['<C-Space>'] = cmp.mapping.complete(),
          ['<CR>'] = cmp.mapping.confirm({ select = true }),
          ['<Tab>'] = cmp.mapping.select_next_item(),
          ['<S-Tab>'] = cmp.mapping.select_prev_item(),
        }),
        sources = cmp.config.sources({
          { name = 'nvim_lsp' },
          { name = 'luasnip' },
          { name = 'buffer' },
          { name = 'path' },
        }),
      })
    end,
  },

  -- 状态栏
  { 'nvim-lualine/lualine.nvim',
    config = function() require('lualine').setup() end },
}

7. lua/lsp.lua

local lspconfig = require('lspconfig')
local caps = require('cmp_nvim_lsp').default_capabilities()

local on_attach = function(_, buf)
  local map = function(keys, fn, desc)
    vim.keymap.set('n', keys, fn, { buffer = buf, desc = desc })
  end
  map('gd', vim.lsp.buf.definition,      'Go to definition')
  map('gr', vim.lsp.buf.references,      'References')
  map('K',  vim.lsp.buf.hover,           'Hover')
  map('<leader>rn', vim.lsp.buf.rename,  'Rename')
  map('<leader>ca', vim.lsp.buf.code_action, 'Code action')
  map('<leader>d',  vim.diagnostic.open_float, 'Show diagnostic')
end

for _, server in ipairs({ 'pyright', 'ts_ls', 'gopls', 'rust_analyzer', 'lua_ls' }) do
  lspconfig[server].setup({
    on_attach = on_attach,
    capabilities = caps,
  })
end

-- 保存时自动格式化(如果 LSP 支持)
vim.api.nvim_create_autocmd('BufWritePre', {
  callback = function() vim.lsp.buf.format({ async = false }) end,
})

8. 第一次启动

nvim
# Lazy 自动 clone 插件,等几秒
# :Mason  ← 进去能看到 LSP 安装状态

9. 升级 / 锁版本

:Lazy update   " 升级所有
:Lazy sync     " 装新加的、删旧的
:Lazy log      " 看更新历史

Lazy 会在 ~/.config/nvim/lazy-lock.json 记录每个插件的 commit hash。
进 git 让别的机器同步到完全一样的版本。

10. 排错

:checkhealth
" 列出每个组件的健康状态
" 缺什么(python3 / npm / node / fd / ripgrep)一目了然

:LspInfo
" 看当前 buffer 的 LSP 状态

踩过的坑

  • 不装 ripgrep → Telescope live_grep 不能用。sudo apt install ripgrep
  • LSP server 装了但没启动:通常因为 root marker 找不到(pyright 找
    pyproject.toml / setup.py)。在项目根目录打开 Neovim。
  • 自动 format on save 把你刚写的中文注释格式化乱:把不可信的 formatter
    关掉,或者 :noa w 跳过 autocmd。
  • 升级 Treesitter parser 时 build 失败:缺 gcc / make。装编译工具链
    sudo apt install build-essential
精确评价 共 0 人评价
可复现性
可复现 · 0 不可复现 · 0
文风
文风流畅 · 0 文风晦涩 · 0
立场
支持 · 0 反对 · 0

登录后即可对本帖作出评价。

评论区 0 条 · 所有人可在此交流

登录后参与评论。

还没有评论,来说两句。