Skip to content

Instantly share code, notes, and snippets.

@lazydao
Last active January 27, 2026 12:40
Show Gist options
  • Select an option

  • Save lazydao/b4e89d079538bd34966c5aab630ef273 to your computer and use it in GitHub Desktop.

Select an option

Save lazydao/b4e89d079538bd34966c5aab630ef273 to your computer and use it in GitHub Desktop.
NeoVim
vim.opt.runtimepath:append(vim.fn.expand("~/.vim"))
-- 禁用 netrw,避免与 nvim-tree 冲突
vim.g.loaded_netrw = 1
vim.g.loaded_netrwPlugin = 1
-- 插件管理
vim.cmd([[
call plug#begin('~/.vim/plugged')
Plug 'neovim/nvim-lspconfig'
Plug 'hrsh7th/nvim-cmp'
Plug 'hrsh7th/cmp-nvim-lsp'
Plug 'hrsh7th/cmp-buffer'
Plug 'hrsh7th/cmp-path'
Plug 'hrsh7th/cmp-cmdline'
Plug 'hrsh7th/cmp-vsnip'
Plug 'hrsh7th/vim-vsnip'
Plug 'tpope/vim-fugitive'
Plug 'airblade/vim-gitgutter'
Plug 'spin6lock/vim_sproto'
Plug 'nvim-tree/nvim-tree.lua'
Plug 'nvim-tree/nvim-web-devicons'
Plug 'sbdchd/neoformat'
Plug 'nvim-lualine/lualine.nvim'
Plug 'echasnovski/mini.move'
Plug 'kepano/flexoki-neovim', { 'as': 'flexoki' }
Plug 'nvim-lua/plenary.nvim'
Plug 'nvim-telescope/telescope.nvim'
call plug#end()
]])
-- 界面设置
vim.opt.termguicolors = true -- 启用真彩色支持
vim.opt.background = "dark" -- "dark" | "light"
vim.opt.cursorline = true -- 高亮当前行
vim.opt.number = true -- 显示行号
vim.opt.relativenumber = true -- 相对行号显示
-- 主题设置
vim.cmd("colorscheme flexoki")
-- 缩进设置
vim.opt.expandtab = true
vim.opt.tabstop = 4
vim.opt.shiftwidth = 4
vim.opt.softtabstop = 4
vim.opt.autoindent = true
vim.opt.smarttab = true -- 插入 tab 时使用 shiftwidth
-- 搜索设置
vim.opt.ignorecase = true
vim.opt.smartcase = true
vim.opt.incsearch = true
vim.opt.hlsearch = true
vim.opt.backspace = { "indent", "eol", "start" }
-- 实用设置
vim.opt.scrolloff = 8 -- 保持光标周围始终有8行显示
vim.opt.sidescrolloff = 8 -- 水平滚动时保持8列显示
-- 其他设置
vim.opt.laststatus = 3
vim.opt.clipboard = "unnamedplus"
vim.opt.lazyredraw = true -- 延迟重绘以提高性能
vim.opt.mouse = 'a' -- 启用鼠标支持
-- lualine 配置
require('lualine').setup({})
-- mini.move 配置
require('mini.move').setup({})
-- nvim-cmp 配置
local cmp = require("cmp")
cmp.setup({
snippet = {
expand = function(args)
vim.fn["vsnip#anonymous"](args.body)
end,
},
mapping = cmp.mapping.preset.insert({
["<Tab>"] = cmp.mapping.select_next_item({ behavior = cmp.SelectBehavior.Insert }),
["<S-Tab>"] = cmp.mapping.select_prev_item({ behavior = cmp.SelectBehavior.Insert }),
["<C-b>"] = cmp.mapping.scroll_docs(-4),
["<C-f>"] = cmp.mapping.scroll_docs(4),
["<C-e>"] = cmp.mapping.abort(),
--["<CR>"] = cmp.mapping.confirm({ select = true }),
["<CR>"] = cmp.mapping(function(fallback)
if cmp.visible() and cmp.get_selected_entry() then
-- 如果补全菜单可见,并且确实选择了一个条目,则确认它
cmp.confirm({ select = true }) -- select = true 在这里是安全的,因为我们已经检查过有选中项
else
-- 否则,执行默认的回车行为(换行)
fallback()
end
end, { "i", "s" }), -- 应用于 insert 和 select 模式
}),
sources = cmp.config.sources({
{ name = "nvim_lsp" },
{ name = "vsnip" },
}, {
{ name = "buffer" },
}),
})
cmp.setup.cmdline({ "/", "?" }, {
mapping = cmp.mapping.preset.cmdline(),
sources = { { name = "buffer" } },
})
cmp.setup.cmdline(":", {
mapping = cmp.mapping.preset.cmdline(),
sources = cmp.config.sources({
{ name = "path" },
}, {
{ name = "cmdline" },
}),
})
local capabilities = require("cmp_nvim_lsp").default_capabilities()
local function lua_root_dir(fname)
-- 如果传进来的不是字符串(比如 0 / bufnr),改成当前 buffer 的文件名
if type(fname) ~= "string" or fname == "" then
fname = vim.api.nvim_buf_get_name(0)
end
if fname == "" then
return nil
end
local markers = {
".luarc.json", ".luarc.jsonc", ".luacheckrc",
".stylua.toml", "stylua.toml", ".git",
}
local root_file = vim.fs.find(markers, { path = vim.fs.dirname(fname), upward = true })[1]
if root_file then
return vim.fs.dirname(root_file)
end
local parent = vim.fs.dirname(fname)
local home = vim.loop.os_homedir()
if parent and parent ~= home then
return parent
end
return nil
end
local function try_setup_with_vim_lsp_config()
if type(vim.lsp) ~= "table" or vim.lsp.config == nil or type(vim.lsp.enable) ~= "function" then
return false
end
local ok = pcall(function()
vim.lsp.config("lua_ls", {
capabilities = capabilities,
root_dir = lua_root_dir,
})
vim.lsp.config("pyright", {
capabilities = capabilities,
})
end)
if not ok then
return false
end
ok = pcall(vim.lsp.enable, "lua_ls")
if not ok then
return false
end
ok = pcall(vim.lsp.enable, "pyright")
if not ok then
if type(vim.lsp.disable) == "function" then
pcall(vim.lsp.disable, "lua_ls")
end
return false
end
return true
end
if not try_setup_with_vim_lsp_config() then
local lspconfig = require("lspconfig")
lspconfig.lua_ls.setup({
capabilities = capabilities,
root_dir = lua_root_dir,
})
lspconfig.pyright.setup({ capabilities = capabilities })
end
-- nvim-tree 配置
require("nvim-tree").setup({})
-- Neoformat 配置
vim.g.neoformat_enabled_python = { 'ruff' }
vim.g.neoformat_python_ruff = {
exe = 'ruff',
args = { 'format', '-' },
stdin = 1
}
vim.g.neoformat_enabled_lua = { 'stylua' }
vim.g.neoformat_lua_stylua = {
exe = 'stylua',
args = { '--search-parent-directories', '-' },
stdin = 1
}
-- 缩短 git blame 输出
-- Current fugitive does not read g:fugitive_blame_options, so add flags in the command.
local blame_flags = '--abbrev=8 --date=short -w'
-- 快捷键配置
-- nvim-tree 快捷键:隐藏、聚焦
vim.keymap.set("n", "<leader>t", ":NvimTreeToggle<CR>", { silent = true })
vim.keymap.set("n", "<leader>n", ":NvimTreeFocus<CR>", { silent = true })
-- Git blame
vim.keymap.set("n", "<leader>gb", ":Git blame " .. blame_flags .. "<CR>", { silent = true, desc = "Git Blame" })
vim.keymap.set("n", "<leader>gB", function()
local line = vim.fn.line(".")
vim.cmd(("Git blame %s -L %d,%d"):format(blame_flags, line, line))
end, { silent = true, desc = "Git Blame (current line)" })
-- 窗口切换
vim.keymap.set('n', '<C-h>', '<C-w>h')
vim.keymap.set('n', '<C-j>', '<C-w>j')
vim.keymap.set('n', '<C-k>', '<C-w>k')
vim.keymap.set('n', '<C-l>', '<C-w>l')
-- 快速保存
vim.keymap.set('n', '<leader>w', ':w<CR>')
vim.keymap.set('n', '<leader>q', ':q<CR>')
-- Telescope 配置
local builtin = require("telescope.builtin")
-- 文件搜索(类似 VS Code Ctrl+P)
vim.keymap.set("n", "<leader>ff", builtin.find_files, { desc = "Find Files" })
vim.keymap.set("n", "<C-p>", builtin.find_files, { desc = "Find Files" })
-- 全局搜索文本(类似 VS Code Ctrl+Shift+F,需要 ripgrep)
vim.keymap.set("n", "<leader>fg", builtin.live_grep, { desc = "Live Grep" })
-- 搜索已打开的 buffer
vim.keymap.set("n", "<leader>fb", builtin.buffers, { desc = "Buffers" })
-- 搜索帮助文档
vim.keymap.set("n", "<leader>fh", builtin.help_tags, { desc = "Help Tags" })

Neovim 使用说明(精简版)

安装 Neovim

参考官方文档:https://github.com/neovim/neovim/blob/master/INSTALL.md

插件管理(vim-plug)

常用命令:

:checkhealth     " 检查环境与配置
:PlugInstall    " 安装插件
:PlugUpdate     " 更新插件
:PlugDiff       " 查看本次更新的变更
:PlugClean      " 删除已移除的插件

注意:以上命令 只管理插件仓库,不会更新 ruff / pyright / stylua / ripgrep 等外部工具。


环境依赖(Linux / Ubuntu 示例)

sudo apt update
sudo apt install -y curl git python3 python3-venv python3-pip python3-pynvim pipx
sudo apt install -y ripgrep
sudo apt install -y fd-find || true
sudo apt install -y universal-ctags || sudo apt install -y exuberant-ctags

剪贴板支持(按环境选择):

# X11
sudo apt install -y xclip
# Wayland
sudo apt install -y wl-clipboard

LSP / 格式化工具:

sudo apt install -y nodejs npm
sudo npm install -g pyright
pipx install ruff
cargo install stylua

建议终端字体使用 Nerd Font(如 JetBrainsMono Nerd Font),否则图标可能显示异常。


常用快捷键速查

<leader> 默认是 \

基础导航

快捷键 说明
h j k l 左 / 下 / 上 / 右
gg / G 文件首 / 文件尾
Ctrl-o / Ctrl-i 跳转历史 后 / 前
% 匹配括号
zz 当前行居中

窗口

快捷键 说明
Ctrl-w h/j/k/l 窗口切换
Ctrl-w = 窗口等宽

Telescope(搜索)

快捷键 说明
Ctrl-p 查找文件
<leader>ff 查找文件
<leader>fg 全局搜索(ripgrep)
<leader>fb 已打开 buffer
<leader>fh 帮助文档

文件树(nvim-tree)

快捷键 说明
<leader>t 显示/隐藏文件树
<leader>n 聚焦文件树

Git

快捷键 说明
<leader>gb Git blame
[c / ]c 上/下一个 git hunk

编辑 / LSP

快捷键 说明
<leader>f 格式化(Neoformat)
[d / ]d 上/下一个诊断
K 显示悬浮文档(LSP)

终端

快捷键 说明
Ctrl-\ Ctrl-n 从终端回到普通模式

备注

  • 插件目录与 Vim 共用(~/.vim/plugged

  • Neovim 通过 runtimepath 追加 ~/.vim

  • 若插件更新后异常,优先检查:

    • :checkhealth
    • Neovim 版本是否过低
    • 外部依赖是否缺失或过旧
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment