Neovim才是史上最强IDE

目录结构

tree ~/.config/nvim
├── init.lua
├── lua
│   ├── core
│   │   ├── keymaps.lua
│   │   └── options.lua
│   └── plugins
│       ├── autopairs.lua
│       ├── bufferline.lua
│       ├── cmp.lua
│       ├── colorscheme.lua
│       ├── comment.lua
│       ├── gitsigns.lua
│       ├── lsp.lua
│       ├── lualine.lua
│       ├── nvim-tree.lua
│       ├── plugins-setup.lua
│       ├── telescope.lua
│       └── treesitter.lua
└── plugin
    └── packer_compiled.lua

基础配置

配置 init.lua 来引用各配置文件

require("plugins.plugins-setup")

require("core.options")
require("core.keymaps")

-- 插件
require("plugins.lualine")
require("plugins.nvim-tree")
require("plugins.treesitter")
require("plugins.lsp")
require("plugins.cmp")
require("plugins.comment")
require("plugins.autopairs")
require("plugins.bufferline")
require("plugins.gitsigns")
require("plugins.telescope")
require("plugins.colorscheme")

基础配置选项 options.lua

local opt = vim.opt

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

-- 缩进
opt.tabstop = 2
opt.shiftwidth = 2
opt.expandtab = true
opt.autoindent = true

-- 防止包裹
opt.wrap = false

-- 光标行
opt.cursorline = true

-- 启用鼠标
opt.mouse:append("a")

-- 系统剪切板
opt.clipboard:append("unnamedplus")

-- 默认新窗口右和下
opt.ignorecase = true
opt.smartcase = true

-- 搜索,不区分大小写,只有是搜索全大写时为全大写
opt.ignorecase = true
opt.smartcase = true

-- 外观
opt.termguicolors = true
opt.signcolumn = "yes"

配置键盘映射 keymaps.lua

-- 设置主键为空格
vim.g.mapleader = " "

local keymap = vim.keymap

--keymap.set("模式","改成某键","原有按键")

-- -------- 视觉模式 -------- --
-- 单行或多行移动
keymap.set("v","J",":m '>+1<CR>gv=gv")
keymap.set("v","K",":m '<-2<CR>gv=gv")

-- -------- 命令模式 -------- --
-- 窗口
keymap.set("n","<leader>sv","<C-w>v") -- 主键+sv 水平新增窗口
keymap.set("n","<leader>sh","<C-w>s") -- 主键+sh 垂直新增窗口

-- 取消高亮
keymap.set("n","<leader>nh",":nohl<CR>")

-- 切换buffer
keymap.set("n", "<leader>l", ":bnext<CR>") -- 主键 + l
keymap.set("n", "<leader>h", ":bprevious<CR>")

-- 快速保存、快速退出
keymap.set("n","S",":w<CR>")
keymap.set("n","Q",":q<CR>")

-- -------- 插件 -------- --
-- nvim-tree
keymap.set("n","<leader>e",":NvimTreeToggle<CR>")

插件

插件安装配置plugins-setup.lua

-- 自动安装 packer
local ensure_packer = function()
  local fn = vim.fn
  local install_path = fn.stdpath('data')..'/site/pack/packer/start/packer.nvim'
  if fn.empty(fn.glob(install_path)) > 0 then
    fn.system({'git', 'clone', '--depth', '1', 'https://github.com/wbthomason/packer.nvim', install_path})
    vim.cmd [[packadd packer.nvim]]
    return true
  end
  return false
end

local packer_bootstrap = ensure_packer()

-- 保存此文件自动执行 :PackerSync
-- lua 文件名
vim.cmd([[
  augroup packer_user_config
    autocmd!
    autocmd BufWritePost plugins-setup.lua source <afile> | PackerSync
  augroup end
]])

return require('packer').startup(function(use)
  -- 插件安装列表
  use 'wbthomason/packer.nvim'
  use 'folke/tokyonight.nvim' -- 主题
  use {
    'nvim-lualine/lualine.nvim', -- 状态栏
    requires = { 'nvim-tree/nvim-web-devicons', opt = true } -- 状态栏图标
  }
  use {
    'nvim-tree/nvim-tree.lua', -- 文档树
    requires = {
      'nvim-tree/nvim-web-devicons', -- 文档树图标
    }
  }
  use 'christoomey/vim-tmux-navigator' -- 用 ctrl-hjkl来定位窗口
  use {
    'nvim-treesitter/nvim-treesitter', -- 语法高亮
    run = function()
        local ts_update = require('nvim-treesitter.install').update({ with_sync = true })
        ts_update()
    end,
  }
  use 'p00f/nvim-ts-rainbow' -- 配合 treesitter 使不同括号用颜色区分
  -- LSP
  use {
    'williamboman/mason.nvim', -- 安装和管理 LSP 、DAP 、linters 和 formatters
    'williamboman/mason-lspconfig.nvim', -- mason.nvim 和 lspconfig 的桥梁
    'neovim/nvim-lspconfig', -- 快速配置 neovim 内置的 LSP
        }
  -- 自动补全
  use 'hrsh7th/cmp-nvim-lsp' -- 支持更多LSP的客户端
  use 'hrsh7th/cmp-buffer'  -- 缓冲词
  use 'hrsh7th/cmp-path'  -- 补全路径
  -- use 'hrsh7th/cmp-cmdline' -- 命令行解析器
  use 'hrsh7th/nvim-cmp' -- 补全插件
  -- 代码片段(snippet)引擎,用于自动补全
  use {
    "L3MON4D3/LuaSnip", -- 用Lua编写的Neovim片段引擎
    dependencies = { "rafamadriz/friendly-snippets" },  -- 针对不同语言的预配置代码段集
  }

  use "numToStr/Comment.nvim" -- gcc和gc注释
  use "windwp/nvim-autopairs" -- 自动补全括号

  use "akinsho/bufferline.nvim" -- buffer分割线
  use "lewis6991/gitsigns.nvim" -- 左则git提示

  use {
    'nvim-telescope/telescope.nvim', tag = '0.1.1',  -- 文件检索
    requires = { {'nvim-lua/plenary.nvim'} }
  }

  if packer_bootstrap then
    require('packer').sync()
  end
end)

自动补全括号 autopairs.lua

-- windwp/nvim-autopairs -- -- 自动补全括号 --
local npairs_ok, npairs = pcall(require, "nvim-autopairs")
if not npairs_ok then
  return
end

npairs.setup {
  check_ts = true,
  ts_config = {
    lua = { "string", "source" },
    javascript = { "string", "template_string" },
  },
  fast_wrap = {
    map = '<M-e>',
    chars = { '{', '[', '(', '"', "'" },
    pattern = [=[[%'%"%)%>%]%)%}%,]]=],
    end_key = '$',
    keys = 'qwertyuiopzxcvbnmasdfghjkl',
    check_comma = true,
    highlight = 'Search',
    highlight_grey='Comment'
  },
}

-- 配置这个使得自动补全会把括号带上

local cmp_autopairs = require "nvim-autopairs.completion.cmp"
local cmp_status_ok, cmp = pcall(require, "cmp")
if not cmp_status_ok then
  return
end
cmp.event:on("confirm_done", cmp_autopairs.on_confirm_done { map_char = { tex = "" } })

buffer分割线bufferline.lua

-- akinsho/bufferline.nvim -- -- buffer分割线 --
vim.opt.termguicolors = true

require("bufferline").setup {
    options = {
        -- 使用 nvim 内置lsp
        diagnostics = "nvim_lsp",
        -- 左侧让出 nvim-tree 的位置
        offsets = {
	        {
		        filetype = "NvimTree",
	            text = "File Explorer",
	            highlight = "Directory",
	            text_align = "left"
	        }
        }
    }
}

自动补全cmp.lua

-- hrsh7th/cmp-nvim-lsp -- 支持更多LSP的客户端
-- hrsh7th/cmp-buffer  -- 缓冲词
-- hrsh7th/cmp-path  -- 补全路径
-- hrsh7th/cmp-cmdline -- 命令行解析器
-- hrsh7th/cmp-cmdline -- 命令行解析器
-- hrsh7th/nvim-cmp -- 补全插件
-- L3MON4D3/LuaSnip -- 用Lua编写的Neovim片段引擎
-- rafamadriz/friendly-snippets  -- 针对不同语言的预配置代码段集
local cmp_status_ok, cmp = pcall(require, "cmp")
if not cmp_status_ok then
  return
end

local snip_status_ok, luasnip = pcall(require, "luasnip")
if not snip_status_ok then
  return
end

require("luasnip.loaders.from_vscode").lazy_load()

-- 函数检查当前光标前一个字符是否为空格,判断Backspace键是否会删除多个空白字符
local check_backspace = function()
  local col = vim.fn.col "." - 1
  return col == 0 or vim.fn.getline("."):sub(col, col):match "%s"
end


cmp.setup({
  snippet = {
    expand = function(args)
      require('luasnip').lsp_expand(args.body)
    end,
  },
  mapping = cmp.mapping.preset.insert({
    ['<C-b>'] = cmp.mapping.scroll_docs(-4),
    ['<C-f>'] = cmp.mapping.scroll_docs(4),
    ['<C-e>'] = cmp.mapping.abort(),  -- 取消补全,esc也可以退出
    ['<CR>'] = cmp.mapping.confirm({ select = true }),

    ["<Tab>"] = cmp.mapping(function(fallback)
      if cmp.visible() then
        cmp.select_next_item()
      elseif luasnip.expandable() then
        luasnip.expand()
      elseif luasnip.expand_or_jumpable() then
        luasnip.expand_or_jump()
      elseif check_backspace() then
        fallback()
      else
        fallback()
      end
    end, {
      "i",
      "s",
    }),

    ["<S-Tab>"] = cmp.mapping(function(fallback)
      if cmp.visible() then
        cmp.select_prev_item()
      elseif luasnip.jumpable(-1) then
        luasnip.jump(-1)
      else
        fallback()
      end
    end, {
      "i",
      "s",
    }),
  }),


  -- 加载自动补全插件
  -- 插件列表: https://github.com/hrsh7th/nvim-cmp/wiki/List-of-sources
  sources = cmp.config.sources({
    { name = 'nvim_lsp' },
    { name = 'luasnip' },
    { name = 'path' },
  }, {
    { name = 'buffer' },
  })
})

主题colorscheme.lua

-- folke/tokyonight.nvim -- 主题

require("tokyonight").setup({
  transparent = true, -- 启用透明背景
})
vim.cmd[[colorscheme tokyonight-moon]]

快速注释comment.lua

-- numToStr/Comment.nvim -- gcc和gc注释快速注释
require('Comment').setup()

git提示gitsigns.lua

-- lewis6991/gitsigns.nvim -- 左则git提示
require('gitsigns').setup {
  signs = {
    add = { text = '+' },
    change = { text = '~' },
    delete = { text = '_' },
    topdelete = { text = '‾' },
    changedelete = { text = '~' },
  },
}

LSP服务 lsp.lua

--williamboman/mason.nvim -- 安装和管理 LSP 、DAP 、linters 和 formatters
--williamboman/mason-lspconfig.nvim -- mason.nvim 和 lspconfig 的桥梁
--neovim/nvim-lspconfig -- 快速配置 neovim 内置的 LSP
require("mason").setup({
  ui = {
      icons = {
          package_installed = "✓",
          package_pending = "➜",
          package_uninstalled = "✗"
      }
  }
})

-- 可用的 LSP 服务: https://github.com/williamboman/mason-lspconfig.nvim#available-lsp-servers
-- 使用 :mason 安装后在下方添加相应的 LSP

-- 使用mason-lspconfig自动安装和设置LSP服务
require("mason-lspconfig").setup({
  ensure_installed = {
    "lua_ls",
    "bashls",
    "clangd",
    "cssls",
    "dockerls",
    "docker_compose_language_service",
    "golangci_lint_ls",
    "html",
    "jdtls",
    "jsonls",
    "lemminx",
    "quick_lint_js",
    "rust_analyzer",
    "vimls",
    "yamlls",
    "jedi_language_server",
  },
  automatic_installation = true,
})

-- 获取默认capabilities
local capabilities = require('cmp_nvim_lsp').default_capabilities()

-- LSP服务列表
local servers = {
  lua = { "lua_ls" },
  sh = { "bashls" },
  c = { "clangd" },
  css = { "cssls" , "lemminx" },
  docker = { "dockerls" },
  docker_compose = { "docker_compose_language_service" },
  golangci = { "golangci_lint_ls" },
  html = { "html" },
  java = { "jdtls" },
  json = { "jsonls" },
  javascript = { "quick_lint_js" },
  rust = { "rust_analyzer" },
  vim = { "vimls" },
  yaml = { "yamlls" },
  python = { "jedi_language_server" }
}

-- 为不同filetype设置不同的LSP服务
for filetype, language_servers in pairs(servers) do
  for _, lsp in ipairs(language_servers) do
    require("lspconfig")[lsp].setup {
      capabilities = capabilities,
    }
  end
end

状态栏lualine.lua

-- nvim-lualine/lualine.nvim -- 状态栏
-- nvim-tree/nvim-web-devicons -- 状态栏图标
require('lualine').setup({
  options = {
    theme = 'tokyonight'
  }
})

nvim-tree.lua

-- nvim-tree/nvim-tree.lua -- 文档树
-- nvim-tree/nvim-web-devicons -- 文档树图标
vim.g.loaded_netrw = 1
vim.g.loaded_netrwPlugin = 1

require("nvim-tree").setup {}

文件检索 telescope.lua

-- nvim-telescope/telescope.nvim  -- 文件检索
-- nvim-lua/plenary.nvim
local builtin = require('telescope.builtin')
local keymap = vim.keymap

-- 进入telescope页面会是插入模式,回到正常模式就可以用j和k来移动了

keymap.set('n', '<leader>ff', builtin.find_files, {})
keymap.set('n', '<leader>fg', builtin.live_grep, {})  -- 环境里要安装ripgrep
keymap.set('n', '<leader>fb', builtin.buffers, {})
keymap.set('n', '<leader>fh', builtin.help_tags, {})

语法高亮 treesitter.lua

-- nvim-treesitter/nvim-treesitter -- 语法高亮
require'nvim-treesitter.configs'.setup {
  -- 添加语言
  ensure_installed = {
    "bash", "javascript", "json" , "lua", "python", "c", "cpp",
    "yaml", "php", "perl" , "markdown", "java", "http", "html",
    "ini", "go", "css" , "rust", "ruby", "sql",
    "vim", "vimdoc", "query",
  },

  highlight = { enable = true },
        indent = { enable = true },

  -- 不同括号颜色区分
  rainbow = {
    enable = true,
    extended_mode = true,
    max_file_lines = nil,
  }
}

参考