在 Debian 安装 Neovim
我使用 AppImage 安装方式,在我的机器上,通过 apt-get 安装,Neovim 版本为 0.3.4,无法运行 Lua 配置脚本,所以使用 AppImage 安装最新版 Neovim。
配置 Neovim
配置目录结构
Neovim 配置目录 ~/.config/nvim 结构如下:
.
├── init.lua
├── lua
│ ├── base.lua
│ └── plugin
│ ├── lsp.lua
│ ├── lualine.lua
│ ├── mason.lua
│ ├── theme.lua
│ └── plugins.lua
└── plugin
└── packer_compiled.lua
init.lua(入口)
init.lua 为 Neovim 的初始化脚本,会在 Neovim 启动时自动运行,我们通过 init.lua 加载其他 Lua 配置脚本,文件内容如下:
require("base") -- 加载基本配置
require("plugin.plugins") -- 加载插件管理器
require("plugin.theme") -- 加载主题配置
require("plugin.lualine") -- 加载 lualine 配置
-- 加载 lsp 相关插件
require("plugin.mason")
require("plugin.lsp")
base.lua
base.lua 放置一些 Neovim 的基本配置,文件内容如下:
-- 外观
vim.opt.number = true
vim.opt.showmode = true
vim.opt.showcmd = true
vim.o.wrap = false
vim.opt.cursorline = true
vim.opt.termguicolors = true
vim.opt.background = 'dark'
-- 编码
vim.opt.encoding = "utf-8"
-- 缩进
vim.opt.autoindent = true
vim.opt.smartindent = true
vim.opt.tabstop = 2
vim.opt.shiftwidth = 4
vim.opt.expandtab = true
vim.opt.softtabstop = 2
-- 搜索
vim.opt.hlsearch = true
vim.opt.ignorecase = true
对于其他配置可参考:
plugins.lua(插件管理器)
我使用 Packer 作为 Neovim 包管理器(Packer 安装方法)。plugins.lua 文件内容如下:
local status, packer = pcall(require, "packer")
if (not status) then
print("packer is not installed")
return
end
vim.cmd [[packadd packer.nvim]]
packer.startup(function(use)
use 'wbthomason/packer.nvim'
use {
'nvim-lualine/lualine.nvim',
requires = {
'nvim-tree/nvim-web-devicons',
opt = true
}
}
use {
'svrana/neosolarized.nvim',
requires = {'tjdevries/colorbuddy.nvim'}
}
use 'scrooloose/nerdtree'
use 'kyazdani42/nvim-web-devicons' -- File icons
-- lsp 相关插件
use 'neovim/nvim-lspconfig'
-- mason lsp 包管理器
use 'williamboman/mason.nvim'
use 'williamboman/mason-lspconfig.nvim'
-- formatting & linting
use("jayp0521/mason-null-ls.nvim")
use 'jose-elias-alvarez/null-ls.nvim'
-- 自动补全相关插件
use 'hrsh7th/cmp-buffer'
use 'hrsh7th/cmp-nvim-lsp'
use 'hrsh7th/nvim-cmp'
use 'hrsh7th/cmp-path'
use 'hrsh7th/cmp-cmdline'
use 'L3MON4D3/LuaSnip'
use 'saadparwaiz1/cmp_luasnip'
end)
LSP 相关配置
LSP 配置参考:
使用 Mason 作为 Neovim LSP 的包管理器,可以使用 Mason 方便地安装相关编程语言的 LSP 包,这里安装 LSP gopls、Linter golangci-lint 和 Formatter goimports。
mason.lua 文件内容如下:
-- import mason plugin safely
local mason_status, mason = pcall(require, "mason")
if not mason_status then
print("load mason failed")
return
end
mason.setup()
-- import mason-lspconfig plugin safely
local mason_lspconfig_status, mason_lspconfig = pcall(require, "mason-lspconfig")
if not mason_lspconfig_status then
print("load mason-lspconfig failed")
return
end
mason_lspconfig.setup({
-- list of servers for mason to install
ensure_installed = {"gopls"},
-- auto-install configured servers (with lspconfig)
automatic_installation = true -- not the same as ensure_installed
})
-- import mason-null-ls plugin safely
local mason_null_ls_status, mason_null_ls = pcall(require, "mason-null-ls")
if not mason_null_ls_status then
print("load mason-null-ls failed")
return
end
mason_null_ls.setup({
-- list of formatters & linters for mason to install
ensure_installed = {"golangci-lint", "goimports"},
-- auto-install configured formatters & linters (with null-ls)
automatic_installation = true
})
lsp.lua 的文件内容如下:
local status, lspconfig = pcall(require, "lspconfig")
if not status then
print("load lspconfig failed")
return
end
-- Set up nvim-cmp.
local cmp = require 'cmp'
cmp.setup({
snippet = {
-- REQUIRED - you must specify a snippet engine
expand = function(args)
require('luasnip').lsp_expand(args.body) -- For `luasnip` users.
end,
},
window = {
completion = cmp.config.window.bordered(),
documentation = cmp.config.window.bordered(),
},
mapping = cmp.mapping.preset.insert({
['<C-b>'] = cmp.mapping.scroll_docs(-4),
['<C-f>'] = cmp.mapping.scroll_docs(4),
['<C-Space>'] = cmp.mapping.complete(),
['<C-e>'] = cmp.mapping.abort(),
['<CR>'] = cmp.mapping.confirm({ select = true }), -- Accept currently selected item. Set `select` to `false` to only confirm explicitly selected items.
}),
sources = cmp.config.sources(
{ { name = 'nvim_lsp' }, { name = 'luasnip' } },
{ { name = 'buffer' } }
)
})
-- Set configuration for specific filetype.
cmp.setup.filetype('gitcommit', {
sources = cmp.config.sources({ { name = 'cmp_git' } }, { { name = 'buffer' } })
})
-- Use buffer source for `/` and `?` (if you enabled `native_menu`, this won't work anymore).
cmp.setup.cmdline({ '/', '?' }, {
mapping = cmp.mapping.preset.cmdline(),
sources = {
{ name = 'buffer' }
}
})
-- Use cmdline & path source for ':' (if you enabled `native_menu`, this won't work anymore).
cmp.setup.cmdline(':', {
mapping = cmp.mapping.preset.cmdline(),
sources = cmp.config.sources({
{ name = 'path' }
}, {
{ name = 'cmdline' }
})
})
-- import cmp-nvim-lsp plugin safely
local cmp_nvim_lsp_status, cmp_nvim_lsp = pcall(require, "cmp_nvim_lsp")
if not cmp_nvim_lsp_status then
print("load cmp_nvim_lsp failed")
return
end
-- used to enable autocompletion (assign to every lsp server config)
local capabilities = cmp_nvim_lsp.default_capabilities()
local on_attach = function(client, bufnr)
-- 保存退出时自动格式化代码
if client.server_capabilities.documentFormattingProvider then
vim.api.nvim_create_autocmd("BufWritePre", {
group = vim.api.nvim_create_augroup("Format", { clear = true }),
buffer = bufnr,
callback = function() vim.lsp.buf.format() end
})
end
vim.keymap.set("n", "gd", "<cmd>lua vim.lsp.buf.definition()<CR>", opts) -- 跳转至定义处
vim.keymap.set("n", "ff", "<cmd>lua vim.lsp.buf.format()<CR>", opts) -- 格式化代码
end
lspconfig["gopls"].setup {
capabilities = capabilities,
on_attach = on_attach,
}
lspconfig["lua_ls"].setup {
on_attach = on_attach,
settings = {
Lua = {
diagnostic = {
globals = { "vim" },
},
workspace = {
library = vim.api.nvim_get_runtime_file("", true),
checkThirdParty = false
},
}
}
}
主题与状态栏配置
主题与状态栏配置参考:
使用主题 neosolarized,theme.lua 的文件内容如下:
local status, n = pcall(require, "neosolarized")
if (not status) then return end
n.setup({
comment_italics = true,
})
local cb = require('colorbuddy.init')
local Color = cb.Color
local colors = cb.colors
local Group = cb.Group
local groups = cb.groups
local styles = cb.styles
Color.new('black', '#000000')
Group.new('CursorLine', colors.none, colors.base03, styles.NONE, colors.base1)
Group.new('CursorLineNr', colors.yellow, colors.black, styles.NONE, colors.base1)
Group.new('Visual', colors.none, colors.base03, styles.reverse)
local cError = groups.Error.fg
local cInfo = groups.Information.fg
local cWarn = groups.Warning.fg
local cHint = groups.Hint.fg
Group.new("DiagnosticVirtualTextError", cError, cError:dark():dark():dark():dark(), styles.NONE)
Group.new("DiagnosticVirtualTextInfo", cInfo, cInfo:dark():dark():dark(), styles.NONE)
Group.new("DiagnosticVirtualTextWarn", cWarn, cWarn:dark():dark():dark(), styles.NONE)
Group.new("DiagnosticVirtualTextHint", cHint, cHint:dark():dark():dark(), styles.NONE)
Group.new("DiagnosticUnderlineError", colors.none, colors.none, styles.undercurl, cError)
Group.new("DiagnosticUnderlineWarn", colors.none, colors.none, styles.undercurl, cWarn)
Group.new("DiagnosticUnderlineInfo", colors.none, colors.none, styles.undercurl, cInfo)
Group.new("DiagnosticUnderlineHint", colors.none, colors.none, styles.undercurl, cHint)
Neovim 状态栏使用插件 lualine,lualine.lua 的文件内容如下:
local status, lualine = pcall(require, "lualine")
if (not status) then return end
lualine.setup {
options = {
icons_enabled = true,
theme = 'solarized_dark',
section_separators = { left = '', right = '' },
component_separators = { left = '', right = '' },
disabled_filetypes = {}
},
sections = {
lualine_a = { 'mode' },
lualine_b = { 'branch' },
lualine_c = { {
'filename',
file_status = true, -- displays file status (readonly status, modified status)
path = 0 -- 0 = just filename, 1 = relative path, 2 = absolute path
} },
lualine_x = {
{ 'diagnostics', sources = { "nvim_diagnostic" }, symbols = { error = ' ', warn = ' ', info = ' ',
hint = ' ' } },
'encoding',
'filetype'
},
lualine_y = { 'progress' },
lualine_z = { 'location' }
},
inactive_sections = {
lualine_a = {},
lualine_b = {},
lualine_c = { {
'filename',
file_status = true, -- displays file status (readonly status, modified status)
path = 1 -- 0 = just filename, 1 = relative path, 2 = absolute path
} },
lualine_x = { 'location' },
lualine_y = {},
lualine_z = {}
},
tabline = {},
extensions = { 'fugitive' }
}