diff --git a/.gitignore b/.gitignore index 90adbb3..886e0bd 100644 --- a/.gitignore +++ b/.gitignore @@ -62,3 +62,4 @@ tags # Persistent undo [._]*.un~ +/lazy-lock.json diff --git a/init.lua b/init.lua new file mode 100644 index 0000000..1fd238d --- /dev/null +++ b/init.lua @@ -0,0 +1,53 @@ +local vim = vim -- assign vim to local variable so the lua lsp is quieter + +vim.api.mapleader = "\\" -- map leader to backslash + +require("config.lazy") -- load lazy Plugin manager + +require("config.conform") -- load formatter config +require("config.cmp") -- load completion config +require("config.symbols-outline") -- load symbols outline +require("config.telescope") -- load keyboard shortcuts for telescope + +-- load language configs +require("config.lua") +require("config.java") +require("config.typescript") +require("config.python") +require("config.lsp") + +-- set up bufferline +vim.opt.termguicolors = true +require("bufferline").setup({}) + +vim.cmd("colorscheme cyberdream") -- set colorscheme + +vim.o.number = true -- show line numbers +vim.o.wildmenu = true -- enable a menu that shows tab completion otions in the status bar +vim.o.showmatch = true -- highlights matching brackets on cursor hover +vim.o.ruler = true -- show cursor position in status bar +vim.o.showcmd = true -- shows the normal mode command before it gets executed + +vim.o.encoding = "utf-8" +vim.o.fileformats = "unix,dos,mac" + +vim.o.hlsearch = true -- highlights searches +vim.o.incsearch = true -- incremental search (searches character by character) +vim.o.ignorecase = true -- ignores the case of a search +vim.o.smartcase = true -- only ignores case if there are no capital letters in search (only works after ignorecase has been set + +vim.o.tabstop = 4 -- the amount of spaces that vim will equate to a tab character +vim.o.softtabstop = 4 -- like tabstop, but for editing operations (insert mode) +vim.o.shiftwidth = 4 -- used for autoindent and << and >> operators in normal mode +vim.autoindent = true -- copies indent from current line to the next line +vim.expandtab = true -- tabs will expand to whitespace characters +vim.o.textwidth = 80 -- for readability, the standard line length is 80 +vim.o.colorcolumn = "+1,+41,+81" -- color columns relative to textwidth + +vim.o.ttimeoutlen = 20 -- timeout for a key code mapping +vim.o.timeoutlen = 1000 -- time(ms) to wait for key mappings + +vim.o.mouse = "a" -- enable mouse in all modes + +vim.cmd("syntax enable") -- turn syntax highlighting on +vim.cmd("filetype plugin indent on") -- load plugin and indent files associated with a detected filetype diff --git a/lua/config/cmp.lua b/lua/config/cmp.lua new file mode 100644 index 0000000..c216f2a --- /dev/null +++ b/lua/config/cmp.lua @@ -0,0 +1,81 @@ +local vim = vim + +-- Set up nvim-cmp. +local cmp = require("cmp") + +cmp.setup({ + snippet = { + -- REQUIRED - you must specify a snippet engine + expand = function(args) + vim.fn["vsnip#anonymous"](args.body) -- For `vsnip` users. + -- require('luasnip').lsp_expand(args.body) -- For `luasnip` users. + -- require('snippy').expand_snippet(args.body) -- For `snippy` users. + -- vim.fn["UltiSnips#Anon"](args.body) -- For `ultisnips` users. + -- vim.snippet.expand(args.body) -- For native neovim snippets (Neovim v0.10+) + + -- For `mini.snippets` users: + -- local insert = MiniSnippets.config.expand.insert or MiniSnippets.default_insert + -- insert({ body = args.body }) -- Insert at cursor + -- cmp.resubscribe({ "TextChangedI", "TextChangedP" }) + -- require("cmp.config").set_onetime({ sources = {} }) + end, + }, + window = { + completion = cmp.config.window.bordered(), + documentation = cmp.config.window.bordered(), + }, + mapping = cmp.mapping.preset.insert({ + [""] = cmp.mapping.scroll_docs(-4), + [""] = cmp.mapping.scroll_docs(4), + [""] = cmp.mapping.complete(), + [""] = cmp.mapping.abort(), + [""] = 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 = "vsnip" }, -- For vsnip users. + -- { name = 'luasnip' }, -- For luasnip users. + -- { name = 'ultisnips' }, -- For ultisnips users. + -- { name = 'snippy' }, -- For snippy users. + }, { + { name = "buffer" }, + }), +}) + +-- To use git you need to install the plugin petertriho/cmp-git and uncomment lines below +-- Set configuration for specific filetype. +--[[ cmp.setup.filetype('gitcommit', { + sources = cmp.config.sources({ + { name = 'git' }, + }, { + { name = 'buffer' }, + }) + }) + require("cmp_git").setup() ]] +-- + +-- 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" }, + }), + matching = { disallow_symbol_nonprefix_matching = false }, +}) + +-- Set up lspconfig. +-- local capabilities = require("cmp_nvim_lsp").default_capabilities() +-- Replace with each lsp server you've enabled. +--require("lspconfig")[""].setup({ +-- capabilities = capabilities, +--}) diff --git a/lua/config/conform.lua b/lua/config/conform.lua new file mode 100644 index 0000000..2b881b9 --- /dev/null +++ b/lua/config/conform.lua @@ -0,0 +1,33 @@ +local vim = vim + +require("conform").setup({ + formatters_by_ft = { + mason = { "html_beautify" }, + html = { "html_beautify" }, + xml = { "xmllint" }, + javascript = { "prettier" }, + json = { "js_beautify" }, + java = { "prettier" }, + python = { "black" }, + lua = { "stylua" }, + }, + format_on_save = { + timeout_ms = 5000, + lsp = "fallback", + }, +}) + +local format = function(args) + local range = nil + if args and args.count ~= -1 then + local end_line = vim.api.nvim_buf_get_lines(0, args.line2 - 1, args.line2, true)[1] + range = { + start = { args.line1, 0 }, + ["end"] = { args.line2, end_line:len() }, + } + end + require("conform").format({ async = true, lsp_format = "fallback", range = range }) +end +vim.api.nvim_create_user_command("Format", format, { range = true }) +vim.keymap.set("n", "ft", format, { noremap = true, silent = true }, "Format buffer") +vim.keymap.set("v", "ft", "Format", { noremap = true, silent = true }, "Format range") diff --git a/lua/config/java.lua b/lua/config/java.lua new file mode 100644 index 0000000..d53a74b --- /dev/null +++ b/lua/config/java.lua @@ -0,0 +1,4 @@ +local capabilities = require("cmp_nvim_lsp").default_capabilities() +require("lspconfig").jdtls.setup({ + capabilities = capabilities, +}) diff --git a/lua/config/lazy.lua b/lua/config/lazy.lua new file mode 100644 index 0000000..0750c56 --- /dev/null +++ b/lua/config/lazy.lua @@ -0,0 +1,29 @@ +-- Bootstrap lazy.nvim +local lazypath = vim.fn.stdpath("data") .. "/lazy/lazy.nvim" +if not (vim.uv or vim.loop).fs_stat(lazypath) then + local lazyrepo = "https://github.com/folke/lazy.nvim.git" + local out = vim.fn.system({ "git", "clone", "--filter=blob:none", "--branch=stable", lazyrepo, lazypath }) + if vim.v.shell_error ~= 0 then + vim.api.nvim_echo({ + { "Failed to clone lazy.nvim:\n", "ErrorMsg" }, + { out, "WarningMsg" }, + { "\nPress any key to exit..." }, + }, true, {}) + vim.fn.getchar() + os.exit(1) + end +end +vim.opt.rtp:prepend(lazypath) + +-- Setup lazy.nvim +require("lazy").setup({ + spec = { + -- import your plugins + { import = "plugins" }, + }, + -- Configure any other settings here. See the documentation for more details. + -- colorscheme that will be used when installing plugins. + install = { colorscheme = { "habamax" } }, + -- automatically check for plugin updates + checker = { enabled = true }, +}) diff --git a/lua/config/lsp.lua b/lua/config/lsp.lua new file mode 100644 index 0000000..922cf13 --- /dev/null +++ b/lua/config/lsp.lua @@ -0,0 +1,24 @@ +local vim = vim + +local noremap = function(type, rhs, lhs, bufopts, desc) + bufopts.desc = desc + vim.keymap.set(type, rhs, lhs, bufopts) +end + +local nnoremap = function(rhs, lhs, bufopts, desc) + noremap("n", rhs, lhs, bufopts, desc) +end + +local vnoremap = function(rhs, lhs, bufopts, desc) + noremap("v", rhs, lhs, bufopts, desc) +end + +local bufopts = { noremap = true, silent = true } +nnoremap("gD", vim.lsp.buf.declaration, bufopts, "Go to declaration") +nnoremap("gd", vim.lsp.buf.definition, bufopts, "Go to definition") +nnoremap("gi", vim.lsp.buf.implementation, bufopts, "Go to implementation") +nnoremap("td", vim.lsp.buf.type_definition, bufopts, "Go to type definition") +nnoremap("gr", vim.lsp.buf.references, bufopts, "Go to references") +nnoremap("rn", vim.lsp.buf.rename, bufopts, "Rename") +nnoremap("ca", vim.lsp.buf.code_action, bufopts, "Code actions") +vnoremap("ca", "lua vim.lsp.buf.range_code_action()", bufopts, "Code Actions") diff --git a/lua/config/lua.lua b/lua/config/lua.lua new file mode 100644 index 0000000..649aaba --- /dev/null +++ b/lua/config/lua.lua @@ -0,0 +1,4 @@ +local capabilities = require("cmp_nvim_lsp").default_capabilities() +require("lspconfig").lua_ls.setup({ + capabilities = capabilities, +}) diff --git a/lua/config/python.lua b/lua/config/python.lua new file mode 100644 index 0000000..867d39c --- /dev/null +++ b/lua/config/python.lua @@ -0,0 +1,4 @@ +local capabilities = require("cmp_nvim_lsp").default_capabilities() +require("lspconfig").pylsp.setup({ + capabilities = capabilities, +}) diff --git a/lua/config/symbols-outline.lua b/lua/config/symbols-outline.lua new file mode 100644 index 0000000..0cc6612 --- /dev/null +++ b/lua/config/symbols-outline.lua @@ -0,0 +1,64 @@ +local opts = { + highlight_hovered_item = true, + show_guides = true, + auto_preview = false, + position = "right", + relative_width = true, + width = 25, + auto_close = false, + show_numbers = false, + show_relative_numbers = false, + show_symbol_details = true, + preview_bg_highlight = "Pmenu", + autofold_depth = nil, + auto_unfold_hover = true, + fold_markers = { "", "" }, + wrap = false, + keymaps = { -- These keymaps can be a string or a table for multiple keys + close = { "", "q" }, + goto_location = "", + focus_location = "o", + hover_symbol = "", + toggle_preview = "K", + rename_symbol = "r", + code_actions = "a", + fold = "h", + unfold = "l", + fold_all = "W", + unfold_all = "E", + fold_reset = "R", + }, + lsp_blacklist = {}, + symbol_blacklist = {}, + symbols = { + File = { icon = "", hl = "@text.uri" }, + Module = { icon = "", hl = "@namespace" }, + Namespace = { icon = "", hl = "@namespace" }, + Package = { icon = "", hl = "@namespace" }, + Class = { icon = "𝓒", hl = "@type" }, + Method = { icon = "ƒ", hl = "@method" }, + Property = { icon = "", hl = "@method" }, + Field = { icon = "", hl = "@field" }, + Constructor = { icon = "", hl = "@constructor" }, + Enum = { icon = "ℰ", hl = "@type" }, + Interface = { icon = "ﰮ", hl = "@type" }, + Function = { icon = "", hl = "@function" }, + Variable = { icon = "", hl = "@constant" }, + Constant = { icon = "", hl = "@constant" }, + String = { icon = "𝓐", hl = "@string" }, + Number = { icon = "#", hl = "@number" }, + Boolean = { icon = "⊨", hl = "@boolean" }, + Array = { icon = "", hl = "@constant" }, + Object = { icon = "⦿", hl = "@type" }, + Key = { icon = "🔐", hl = "@type" }, + Null = { icon = "NULL", hl = "@type" }, + EnumMember = { icon = "", hl = "@field" }, + Struct = { icon = "𝓢", hl = "@type" }, + Event = { icon = "🗲", hl = "@type" }, + Operator = { icon = "+", hl = "@operator" }, + TypeParameter = { icon = "𝙏", hl = "@parameter" }, + Component = { icon = "", hl = "@function" }, + Fragment = { icon = "", hl = "@constant" }, + }, +} +require("symbols-outline").setup({ opts }) diff --git a/lua/config/telescope.lua b/lua/config/telescope.lua new file mode 100644 index 0000000..b455326 --- /dev/null +++ b/lua/config/telescope.lua @@ -0,0 +1,8 @@ +local vim = vim + +vim.keymap.set( + "n", + "f", + "Telescope find_files", + { noremap = true, silent = true, desc = "Find files" } +) diff --git a/lua/config/typescript.lua b/lua/config/typescript.lua new file mode 100644 index 0000000..6b3791e --- /dev/null +++ b/lua/config/typescript.lua @@ -0,0 +1,4 @@ +local capabilities = require("cmp_nvim_lsp").default_capabilities() +require("lspconfig").ts_ls.setup({ + capabilities = capabilities, +}) diff --git a/lua/plugins.lua b/lua/plugins.lua new file mode 100644 index 0000000..467ca30 --- /dev/null +++ b/lua/plugins.lua @@ -0,0 +1,47 @@ +return { + "tpope/vim-vinegar", + "tpope/vim-surround", + "tpope/vim-sleuth", + "tpope/vim-abolish", + "vim-airline/vim-airline", + "editorconfig/editorconfig-vim", + "mattn/emmet-vim", + "vim-airline/vim-airline-themes", + "easymotion/vim-easymotion", + "mhinz/vim-startify", + "simrat39/symbols-outline.nvim", + "neovim/nvim-lspconfig", + { + "hrsh7th/nvim-cmp", + dependencies = { + "hrsh7th/cmp-nvim-lsp", + "hrsh7th/cmp-buffer", + "hrsh7th/cmp-path", + "hrsh7th/cmp-cmdline", + "hrsh7th/cmp-vsnip", + "hrsh7th/vim-vsnip", + }, + }, + { + "nvim-telescope/telescope.nvim", + tag = "0.1.8", + dependencies = { + "nvim-lua/plenary.nvim", + "nvim-treesitter/nvim-treesitter", + }, + }, + { + "scottmckendry/cyberdream.nvim", + lazy = false, + priority = 1000, + }, + { + "akinsho/bufferline.nvim", + version = "*", + dependencies = "nvim-tree/nvim-web-devicons", + }, + { + "stevearc/conform.nvim", + opts = {}, + }, +}