├── ftplugin ├── css.lua ├── html.lua ├── javascript.lua └── Makefile.lua ├── .gitignore ├── README.md ├── LICENSE ├── lua └── plugins │ ├── 20-treesitter.lua │ ├── 20-git.lua │ ├── 10-editor.lua │ └── 50-lsp.lua └── init.lua /ftplugin/css.lua: -------------------------------------------------------------------------------- 1 | vim.bo.tabstop = 2 2 | -------------------------------------------------------------------------------- /ftplugin/html.lua: -------------------------------------------------------------------------------- 1 | vim.bo.tabstop = 2 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /lazy-lock.json 2 | /custom.lua 3 | -------------------------------------------------------------------------------- /ftplugin/javascript.lua: -------------------------------------------------------------------------------- 1 | vim.bo.tabstop = 2 2 | -------------------------------------------------------------------------------- /ftplugin/Makefile.lua: -------------------------------------------------------------------------------- 1 | vim.bo.expandtab = false 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # My config of Neovim 2 | 3 | Here is my config of neovim. 4 | 5 | ## Usage 6 | 7 | Just clone this repository into directory `~/.config/nvim/` and start neovim. [lazy.nvim](https://github.com/folke/lazy.nvim) will auto install itself and other plugins at startup. 8 | 9 | ``` 10 | git clone ~/.config/nvim 11 | ``` 12 | 13 | By default, this config will only include a few plugins, which suit for mataining other than editing frequently. 14 | 15 | A custom config (`custom.lua`) file placed aside with `init.lua` is optional, it's content like below. 16 | 17 | ``` 18 | return { 19 | full_feature = true, # enable all configured plugins 20 | proxy_url = "http://localhost:8888", # setup proxy for some plugins (like treesitter) 21 | } 22 | ``` 23 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 Leafee 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /lua/plugins/20-treesitter.lua: -------------------------------------------------------------------------------- 1 | local full_ensure = { 2 | "bash", 3 | "c", 4 | "cmake", 5 | "cpp", 6 | "css", 7 | "diff", 8 | "dockerfile", 9 | "git_config", 10 | "git_rebase", 11 | "gitattributes", 12 | "gitcommit", 13 | "gitignore", 14 | "go", 15 | "gomod", 16 | "gosum", 17 | "html", 18 | "java", 19 | "javascript", 20 | "json", 21 | "json5", 22 | "jsonc", 23 | "lua", 24 | "luadoc", 25 | "luau", 26 | "make", 27 | "markdown", 28 | "markdown_inline", 29 | "python", 30 | "rust", 31 | "scss", 32 | "sql", 33 | "toml", 34 | "vim", 35 | "vimdoc", 36 | "yaml" 37 | } 38 | 39 | local basic_ensure = { 40 | "toml", 41 | "json", 42 | "json5", 43 | "jsonc", 44 | "yaml", 45 | } 46 | 47 | if custom.full_feature then 48 | ensure = full_ensure 49 | else 50 | ensure = basic_ensure 51 | end 52 | 53 | return { 54 | "nvim-treesitter/nvim-treesitter", 55 | name = "nvim-treesitter", 56 | build = ":TSUpdate", 57 | opts = { 58 | indent = { enable = true }, 59 | highlight = { enable = true }, 60 | ensure_installed = ensure, 61 | auto_install = true, 62 | sync_install = false, 63 | }, 64 | config = function (this, opts) 65 | require(this.name .. ".configs").setup(opts); 66 | if custom.proxy_url ~= "" then 67 | require(this.name .. ".install").command_extra_args = { 68 | curl = { "--proxy", custom.proxy_url } 69 | } 70 | end 71 | end 72 | } 73 | -------------------------------------------------------------------------------- /init.lua: -------------------------------------------------------------------------------- 1 | -- enable read config from CWD 2 | vim.o.exrc = true 3 | 4 | vim.o.tabstop = 4 5 | vim.o.shiftwidth = 0 6 | vim.o.softtabstop = -1 7 | vim.o.shiftround = true 8 | 9 | vim.o.list = true 10 | vim.o.relativenumber = true 11 | vim.o.number = true 12 | 13 | vim.o.expandtab = true 14 | vim.o.autoindent = true 15 | vim.o.smartindent = true 16 | 17 | vim.keymap.set("n", "\\q", "wincmd q", { silent = true }) 18 | vim.keymap.set("n", "zh", "wincmd h", { silent = true }) 19 | vim.keymap.set("n", "zj", "wincmd j", { silent = true }) 20 | vim.keymap.set("n", "zk", "wincmd k", { silent = true }) 21 | vim.keymap.set("n", "zl", "wincmd l", { silent = true }) 22 | 23 | vim.keymap.set("n", "zn", "bnext", { silent = true }) 24 | vim.keymap.set("n", "zp", "bprevious", { silent = true }) 25 | vim.keymap.set("n", "zx", "bdelete", { silent = true }) 26 | 27 | vim.g.mapleader = " " 28 | vim.g.maplocalleader = " " 29 | 30 | -- Load custom config 31 | custom = { 32 | full_feature = false, 33 | proxy_url = "", 34 | } 35 | 36 | local custom_config_path = vim.fn.stdpath("config") .. "/custom.lua" 37 | local ok, t = pcall(dofile, custom_config_path) 38 | if ok then 39 | for k, v in pairs(t) do 40 | custom[k] = v 41 | end 42 | end 43 | 44 | -- Use lazy.nvim as plugin manager, and load plugin's config 45 | local lazypath = vim.fn.stdpath("data") .. "/lazy/lazy.nvim" 46 | if not vim.loop.fs_stat(lazypath) then 47 | vim.fn.system({ 48 | "git", 49 | "clone", 50 | "--filter=blob:none", 51 | "https://github.com/folke/lazy.nvim.git", 52 | "--branch=stable", -- latest stable release 53 | lazypath, 54 | }) 55 | end 56 | vim.opt.rtp:prepend(lazypath) 57 | require("lazy").setup("plugins") 58 | -------------------------------------------------------------------------------- /lua/plugins/20-git.lua: -------------------------------------------------------------------------------- 1 | return { 2 | "lewis6991/gitsigns.nvim", 3 | main = "gitsigns", 4 | enabled = custom.full_feature, 5 | opts = { 6 | on_attach = function(bufnr) 7 | local gs = package.loaded.gitsigns 8 | local function m(mode, l, r, opts) 9 | opts = opts or {} 10 | opts.buffer = bufnr 11 | vim.keymap.set(mode, l, r, opts) 12 | end 13 | 14 | m("n", "]h", function() 15 | if vim.wo.diff then return "]c" end 16 | vim.schedule(function() gs.next_hunk() end) 17 | return "" 18 | end, {expr=true}) 19 | 20 | m('n', '[h', function() 21 | if vim.wo.diff then return '[c' end 22 | vim.schedule(function() gs.prev_hunk() end) 23 | return '' 24 | end, {expr=true}) 25 | 26 | m('n', 'hs', gs.stage_hunk) 27 | m('n', 'hr', gs.reset_hunk) 28 | m('v', 'hs', function() gs.stage_hunk {vim.fn.line("."), vim.fn.line("v")} end) 29 | m('v', 'hr', function() gs.reset_hunk {vim.fn.line("."), vim.fn.line("v")} end) 30 | m('n', 'hS', gs.stage_buffer) 31 | m('n', 'hu', gs.undo_stage_hunk) 32 | m('n', 'hR', gs.reset_buffer) 33 | m('n', 'hp', gs.preview_hunk) 34 | m('n', 'hb', function() gs.blame_line{full=true} end) 35 | -- m('n', 'tb', gs.toggle_current_line_blame) 36 | m('n', 'hd', gs.diffthis) 37 | m('n', 'hD', function() gs.diffthis('~') end) 38 | -- m('n', 'td', gs.toggle_deleted) 39 | end, 40 | }, 41 | config = function (lazyplug, opts) 42 | require(lazyplug.main).setup(opts) 43 | end, 44 | } 45 | -------------------------------------------------------------------------------- /lua/plugins/10-editor.lua: -------------------------------------------------------------------------------- 1 | return { 2 | { 3 | "sainnhe/gruvbox-material", 4 | config = function(_, _) 5 | vim.o.termguicolors = true 6 | vim.g.background = "dark" 7 | vim.cmd("colorscheme gruvbox-material") 8 | end 9 | }, 10 | { 11 | "lukas-reineke/indent-blankline.nvim", 12 | main = "ibl", 13 | opts = { }, 14 | }, 15 | { 16 | "famiu/bufdelete.nvim", 17 | lazy = false, 18 | keys = { 19 | { "zx", "Bdelete", mode = "n" }, 20 | }, 21 | }, 22 | { 23 | "karb94/neoscroll.nvim", 24 | enabled = custom.full_feature, 25 | main = "neoscroll", 26 | opts = { }, 27 | }, 28 | { 29 | "akinsho/bufferline.nvim", 30 | enabled = custom.full_feature, 31 | main = "bufferline", 32 | opts = { 33 | options = { 34 | numbers = "both", 35 | diagnostics = "nvim_lsp", 36 | separator_style = "slant", 37 | offsets = { 38 | { 39 | filetype = "NvimTree", 40 | text = "File Explorer", 41 | text_align = "center", 42 | separator = true, 43 | }, 44 | }, 45 | hover = { 46 | delay = 200, 47 | reveal = { "close" }, 48 | }, 49 | } 50 | }, 51 | }, 52 | { 53 | "nvim-lualine/lualine.nvim", 54 | enabled = custom.full_feature, 55 | dependencies = { 56 | "nvim-tree/nvim-web-devicons" 57 | }, 58 | main = "lualine", 59 | opts = { }, 60 | init = function(_) 61 | vim.o.mousemoveevent = true 62 | end, 63 | }, 64 | { 65 | "nvim-tree/nvim-tree.lua", 66 | enabled = custom.full_feature, 67 | dependencies = { 68 | "nvim-tree/nvim-web-devicons" 69 | }, 70 | main = "nvim-tree", 71 | opts = { }, 72 | lazy = false, 73 | keys = { 74 | { "t", "NvimTreeFocus", mode = "n" }, 75 | }, 76 | init = function(_) 77 | vim.g.loaded_netrw = 1 78 | vim.g.loaded_netrwPlugin = 1 79 | 80 | vim.api.nvim_create_autocmd("QuitPre", { 81 | callback = function() 82 | local invalid_win = {} 83 | local wins = vim.api.nvim_list_wins() 84 | for _, w in ipairs(wins) do 85 | local bufname = vim.api.nvim_buf_get_name(vim.api.nvim_win_get_buf(w)) 86 | if bufname:match("NvimTree_") ~= nil then 87 | table.insert(invalid_win, w) 88 | end 89 | end 90 | if #invalid_win == #wins - 1 then 91 | -- Should quit, so we close all invalid windows. 92 | for _, w in ipairs(invalid_win) do vim.api.nvim_win_close(w, true) end 93 | end 94 | end 95 | }) 96 | end, 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /lua/plugins/50-lsp.lua: -------------------------------------------------------------------------------- 1 | function setup_keymap_lsp() 2 | -- -- Global mappings. 3 | -- -- See `:help vim.diagnostic.*` for documentation on any of the below functions 4 | -- vim.keymap.set("n", "e", vim.diagnostic.open_float) 5 | -- vim.keymap.set("n", "[d", vim.diagnostic.goto_prev) 6 | -- vim.keymap.set("n", "]d", vim.diagnostic.goto_next) 7 | -- vim.keymap.set("n", "q", vim.diagnostic.setloclist) 8 | 9 | vim.api.nvim_create_autocmd("LspAttach", { 10 | group = vim.api.nvim_create_augroup("UserLspConfig", {}), 11 | callback = function(ev) 12 | -- Enable completion triggered by 13 | vim.bo[ev.buf].omnifunc = "v:lua.vim.lsp.omnifunc" 14 | 15 | -- Buffer local mappings. 16 | -- See `:help vim.lsp.*` for documentation on any of the below functions 17 | local opts = { buffer = ev.buf } 18 | vim.keymap.set("n", "gD", vim.lsp.buf.declaration, opts) 19 | vim.keymap.set("n", "gd", vim.lsp.buf.definition, opts) 20 | vim.keymap.set("n", "gi", vim.lsp.buf.implementation, opts) 21 | vim.keymap.set("n", "gr", vim.lsp.buf.references, opts) 22 | vim.keymap.set("n", "K", vim.lsp.buf.hover, opts) 23 | vim.keymap.set("n", "", vim.lsp.buf.signature_help, opts) 24 | vim.keymap.set("n", "wa", vim.lsp.buf.add_workspace_folder, opts) 25 | vim.keymap.set("n", "wr", vim.lsp.buf.remove_workspace_folder, opts) 26 | vim.keymap.set("n", "wl", function() 27 | print(vim.inspect(vim.lsp.buf.list_workspace_folders())) 28 | end, opts) 29 | vim.keymap.set("n", "D", vim.lsp.buf.type_definition, opts) 30 | vim.keymap.set("n", "rn", vim.lsp.buf.rename, opts) 31 | vim.keymap.set({ "n", "v" }, "ca", vim.lsp.buf.code_action, opts) 32 | vim.keymap.set("n", "f", function() 33 | vim.lsp.buf.format { async = true } 34 | end, opts) 35 | end, 36 | }) 37 | end 38 | 39 | return { 40 | { 41 | "neovim/nvim-lspconfig", 42 | enabled = custom.full_feature, 43 | dependencies = { 44 | "hrsh7th/nvim-cmp", 45 | "hrsh7th/cmp-nvim-lsp", 46 | "hrsh7th/cmp-buffer", 47 | "hrsh7th/cmp-path", 48 | "hrsh7th/cmp-cmdline", 49 | "L3MON4D3/LuaSnip", 50 | }, 51 | lazy = false, 52 | config = function (_, opts) 53 | local capabilities = require("cmp_nvim_lsp").default_capabilities() 54 | 55 | local servers = { "clangd", "rust_analyzer", "pyright", "gopls", "quick_lint_js" } 56 | for _, lsp in ipairs(servers) do 57 | require("lspconfig")[lsp].setup{ 58 | capabilities = capabilities, 59 | } 60 | end 61 | 62 | local luasnip = require("luasnip") 63 | local cmp = require("cmp") 64 | cmp.setup({ 65 | snippet = { 66 | expand = function(args) 67 | luasnip.lsp_expand(args.body) 68 | end, 69 | }, 70 | mapping = cmp.mapping.preset.insert({ 71 | [""] = cmp.mapping.scroll_docs(-4), 72 | [""] = cmp.mapping.scroll_docs(4), 73 | [""] = cmp.mapping.complete(), 74 | [""] = cmp.mapping.abort(), 75 | [""] = cmp.mapping.confirm({ select = true }), 76 | }), 77 | sources = cmp.config.sources({ 78 | { name = "nvim_lsp" }, 79 | { name = "buffer" }, 80 | { name = "luasnip" }, 81 | }), 82 | }) 83 | cmp.setup.cmdline(":", { 84 | mapping = cmp.mapping.preset.cmdline(), 85 | sources = cmp.config.sources({ 86 | { name = "path" } 87 | }, { 88 | { name = "cmdline" } 89 | }) 90 | }) 91 | 92 | setup_keymap_lsp() 93 | end, 94 | keys = { 95 | { "e", vim.diagnostic.open_float, mode = "n" }, 96 | { "[d", vim.diagnostic.goto_prev, mode = "n" }, 97 | { "]d", vim.diagnostic.goto_next, mode = "n" }, 98 | { "q", vim.diagnostic.setloclist, mode = "n" } 99 | }, 100 | }, 101 | } 102 | --------------------------------------------------------------------------------