Debian Neovim Golang 简易开发配置

1,144 阅读3分钟

仓库地址:github.com/xuedishangd…

在 Debian 安装 Neovim

Neovim 安装文档

我使用 AppImage 安装方式,在我的机器上,通过 apt-get 安装,Neovim 版本为 0.3.4,无法运行 Lua 配置脚本,所以使用 AppImage 安装最新版 Neovim。

配置 Neovim

  1. Vim script 转 Lua 配置
  2. Neovim Lua 文档

配置目录结构

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

对于其他配置可参考:

  1. Vim 配置入门
  2. Neovim Lua Vim 模块文档

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 配置参考:

  1. nvim-cmp 配置
  2. cmp-nvim-lsp 配置
  3. Lua LSP 配置
  4. github.com/bryant-vide…

使用 Mason 作为 Neovim LSP 的包管理器,可以使用 Mason 方便地安装相关编程语言的 LSP 包,这里安装 LSP gopls、Linter golangci-lint 和 Formatter goimports

image.png image.png image.png

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
            },
        }
    }
}

主题与状态栏配置

主题与状态栏配置参考:

github.com/craftzdog/d…

使用主题 neosolarizedtheme.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 状态栏使用插件 lualinelualine.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' }
}