--- Set Leader Key (Needs to be set before the plugins are loaded/required) vim.g.mapleader = ' ' vim.g.maplocalleader = ' ' --- Plugin Manager local lazypath = vim.fn.stdpath("data") .. "/lazy/lazy.nvim" if not vim.loop.fs_stat(lazypath) then vim.fn.system({ "git", "clone", "--filter=blob:none", "https://github.com/folke/lazy.nvim.git", "--branch=stable", -- latest stable release lazypath, }) end vim.opt.rtp:prepend(lazypath) -- Add Plugins require("lazy").setup({ -- Stats { 'wakatime/vim-wakatime', lazy = false }, -- Theme { "catppuccin/nvim", name = "catppuccin.vim", priority = 1000, config = function() vim.g.catppuccin_flavor = "macchiato" vim.cmd [[colorscheme catppuccin]] end, }, -- Syntax highlighting support "elkowar/yuck.vim", "fladson/vim-kitty", -- Use "gc" to comment visual regions/lines { "numToStr/Comment.nvim", opts = {} }, -- Detect tabstop and shiftwidth automatically -- "tpope/vim-sleuth", -- Add indentation guides even on blank lines ??? { "lukas-reineke/indent-blankline.nvim", main = "ibl", opts = {}, }, -- Status line { "nvim-lualine/lualine.nvim", opts = { options = { icons_enabled = true, theme = "palenight", component_separators = "|", section_separators = "", }, }, }, -- LSP (Configuration under "lspconfig") { "neovim/nvim-lspconfig", dependencies = { -- Automatically install LSPs to stdpath for neovim { "williamboman/mason.nvim", config = true }, "williamboman/mason-lspconfig.nvim", -- Useful status updates for LSP -- NOTE: `opts = {}` is the same as calling `require('fidget').setup({})` { "j-hui/fidget.nvim", tag = "legacy", opts = {} }, -- Additional lua configuration, makes nvim stuff amazing! "folke/neodev.nvim", }, }, -- Autocomplete { "hrsh7th/nvim-cmp", dependencies = { -- Snippet Engine & its associated nvim-cmp source 'L3MON4D3/LuaSnip', 'saadparwaiz1/cmp_luasnip', -- Adds LSP completion capabilities 'hrsh7th/cmp-nvim-lsp', -- Adds a number of user-friendly snippets 'rafamadriz/friendly-snippets', }, }, -- Show available command { "folke/which-key.nvim", event = "VeryLazy", init = function() vim.o.timeout = true vim.o.timeoutlen = 300 end, opts = {} }, -- Fuzzy Finder (files, lsp, etc) { "nvim-telescope/telescope.nvim", branch = "0.1.x", dependencies = { "nvim-lua/plenary.nvim", { 'nvim-telescope/telescope-fzf-native.nvim', -- NOTE: If you are having trouble with this installation, -- refer to the README for telescope-fzf-native for more instructions. build = 'make', cond = function() return vim.fn.executable 'make' == 1 end, }, }, }, -- Highlight, edit, and navigate code { 'nvim-treesitter/nvim-treesitter', dependencies = { 'nvim-treesitter/nvim-treesitter-textobjects', }, build = ':TSUpdate', }, -- Git "tpope/vim-fugitive", --"tpope/vim-rhubarb", { "lewis6991/gitsigns.nvim", opts = { -- See `:help gitsigns.txt` signs = { add = { text = "+" }, change = { text = "~" }, delete = { text = "_" }, topdelete = { text = "‾" }, changedelete = { text = "~" }, }, on_attach = function(bufnr) vim.keymap.set("n", "hp", require("gitsigns").preview_hunk, { buffer = bufnr, desc = "Preview git hunk" }) -- don't override the built-in and fugitive keymaps local gs = package.loaded.gitsigns vim.keymap.set({ "n", "v" }, "]c", function() if vim.wo.diff then return "]c" end vim.schedule(function() gs.next_hunk() end) return "" end, { expr = true, buffer = bufnr, desc = "Jump to next hunk" }) vim.keymap.set({ "n", "v" }, "[c", function() if vim.wo.diff then return "[c" end vim.schedule(function() gs.prev_hunk() end) return "" end, { expr = true, buffer = bufnr, desc = "Jump to previous hunk" }) end, }, }, }) -- Tab vim.opt.tabstop = 2 vim.opt.softtabstop = 2 vim.opt.shiftwidth = 2 vim.opt.expandtab = true --- Show line numbers vim.opt.number = true --- Relative line numbers vim.opt.relativenumber = true --- Go to next/previous line vim.opt.whichwrap = "<,>,[,]" --- Enable mouse vim.opt.mouse = "a" --- Sync clipboard with OS vim.opt.clipboard = "unnamedplus" --- Enable break indent vim.opt.breakindent = true --- Save undo history vim.opt.undofile = true --- Case-insensetive search vim.opt.ignorecase = true vim.opt.smartcase = true --- Keep signcolum vim.wo.signcolumn = "yes" --- Set completeopt to have a better completion experience vim.opt.completeopt = "menuone,noselect" --- [[ Basic Keymaps ]] -- Center view when jumping have the view vim.keymap.set("n", "", "zz") vim.keymap.set("n", "", "zz") -- Center view when search vim.keymap.set("n", "n", "nzz") vim.keymap.set("n", "N", "Nzz") -- Create file or directory vim.keymap.set('n', 'cf', [[:e =expand("%:h") .. '/']], { desc = "[f] Create file", noremap = true }) vim.keymap.set('n', 'cd', [[:!mkdir =expand("%:p:h") .. '/']], { desc = "[d] Create directory", noremap = true }) -- Open explorer vim.keymap.set("n", "oe", ":Ex", { desc = "[e] Open the explorer" }) -- Keymaps for better default experience vim.keymap.set({ "n", "v" }, "", "", { silent = true }) -- Remap for dealing with word wrap vim.keymap.set("n", "k", "v:count == 0 ? 'gk' : 'k'", { expr = true, silent = true }) vim.keymap.set("n", "j", "v:count == 0 ? 'gj' : 'j'", { expr = true, silent = true }) -- Change Tab/Window Focus vim.keymap.set("n", "", "h") vim.keymap.set("n", "", "j") vim.keymap.set("n", "", "k") vim.keymap.set("n", "", "l") --- [[ Highlight on yank ]] -- See `:help vim.highlight.on_yank()` local highlight_group = vim.api.nvim_create_augroup("YankHighlight", { clear = true }) vim.api.nvim_create_autocmd("TextYankPost", { callback = function() vim.highlight.on_yank() end, group = highlight_group, pattern = "*", }) --- [[ Configure Telescope ]] -- See `:help telescope` and `:help telescope.setup()` require("telescope").setup { defaults = { mappings = { i = { [""] = false, [""] = false, }, }, }, } -- Enable telescope fzf native, if installed pcall(require("telescope").load_extension, "fzf") -- See `:help telescope.builtin` vim.keymap.set("n", "?", require("telescope.builtin").oldfiles, { desc = "[?] Find recently opened files" }) vim.keymap.set("n", "", require("telescope.builtin").buffers, { desc = "[ ] Find existing buffers" }) vim.keymap.set("n", "/", function() -- You can pass additional configuration to telescope to change theme, layout, etc. require("telescope.builtin").current_buffer_fuzzy_find(require("telescope.themes").get_dropdown { winblend = 10, previewer = false, }) end, { desc = "[/] Fuzzily search in current buffer" }) vim.keymap.set("n", "gf", require("telescope.builtin").git_files, { desc = "Search [G]it [F]iles" }) vim.keymap.set("n", "sf", require("telescope.builtin").find_files, { desc = "[S]earch [F]iles" }) vim.keymap.set("n", "sh", require("telescope.builtin").help_tags, { desc = "[S]earch [H]elp" }) vim.keymap.set("n", "sw", require("telescope.builtin").grep_string, { desc = "[S]earch current [W]ord" }) vim.keymap.set("n", "sg", require("telescope.builtin").live_grep, { desc = "[S]earch by [G]rep" }) vim.keymap.set("n", "sd", require("telescope.builtin").diagnostics, { desc = "[S]earch [D]iagnostics" }) vim.keymap.set("n", "sr", require("telescope.builtin").resume, { desc = "[S]earch [R]esume" }) --- [[ Configure Treesitter ]] -- See `:help nvim-treesitter` -- Defer Treesitter setup after first render to improve startup time of "nvim {filename}" vim.defer_fn(function() require("nvim-treesitter.configs").setup { -- Add languages to be installed here that you want installed for treesitter ensure_installed = { "c", "cpp", "go", "lua", "python", "rust", "tsx", "javascript", "typescript", "vimdoc", "vim" }, -- Autoinstall languages that are not installed. Defaults to false (but you can change for yourself!) auto_install = false, highlight = { enable = true }, indent = { enable = true }, incremental_selection = { enable = true, keymaps = { init_selection = "", node_incremental = "", scope_incremental = "", node_decremental = "", }, }, textobjects = { select = { enable = true, lookahead = true, -- Automatically jump forward to textobj, similar to targets.vim keymaps = { -- You can use the capture groups defined in textobjects.scm ["aa"] = "@parameter.outer", ["ia"] = "@parameter.inner", ["af"] = "@function.outer", ["if"] = "@function.inner", ["ac"] = "@class.outer", ["ic"] = "@class.inner", }, }, move = { enable = true, set_jumps = true, -- whether to set jumps in the jumplist goto_next_start = { ["]m"] = "@function.outer", ["]]"] = "@class.outer", }, goto_next_end = { ["]M"] = "@function.outer", ["]["] = "@class.outer", }, goto_previous_start = { ["[m"] = "@function.outer", ["[["] = "@class.outer", }, goto_previous_end = { ["[M"] = "@function.outer", ["[]"] = "@class.outer", }, }, swap = { enable = true, swap_next = { ["a"] = "@parameter.inner", }, swap_previous = { ["A"] = "@parameter.inner", }, }, }, } end, 0) -- Diagnostic keymaps vim.keymap.set("n", "[d", vim.diagnostic.goto_prev, { desc = "Go to previous diagnostic message" }) vim.keymap.set("n", "]d", vim.diagnostic.goto_next, { desc = "Go to next diagnostic message" }) vim.keymap.set("n", "e", vim.diagnostic.open_float, { desc = "Open floating diagnostic message" }) vim.keymap.set("n", "q", vim.diagnostic.setloclist, { desc = "Open diagnostics list" }) --- [[ Configure LSP ]] -- This function gets run when an LSP connects to a particular buffer. local on_attach = function(_, bufnr) -- Sets the mode, buffer and description for us each time. local nmap = function(keys, func, desc) if desc then desc = "LSP: " .. desc end vim.keymap.set("n", keys, func, { buffer = bufnr, desc = desc }) end nmap("rn", vim.lsp.buf.rename, "[R]e[n]ame") nmap("ca", vim.lsp.buf.code_action, "[C]ode [A]ction") nmap("gd", vim.lsp.buf.definition, "[G]oto [D]efinition") nmap("gr", require("telescope.builtin").lsp_references, "[G]oto [R]eferences") nmap("gI", require("telescope.builtin").lsp_implementations, "[G]oto [I]mplementation") nmap("D", vim.lsp.buf.type_definition, "Type [D]efinition") nmap("ds", require("telescope.builtin").lsp_document_symbols, "[D]ocument [S]ymbols") nmap("ws", require("telescope.builtin").lsp_dynamic_workspace_symbols, "[W]orkspace [S]ymbols") -- See `:help K` for why this keymap nmap("K", vim.lsp.buf.hover, "Hover Documentation") nmap("", vim.lsp.buf.signature_help, "Signature Documentation") -- Lesser used LSP functionality nmap("gD", vim.lsp.buf.declaration, "[G]oto [D]eclaration") nmap("wa", vim.lsp.buf.add_workspace_folder, "[W]orkspace [A]dd Folder") nmap("wr", vim.lsp.buf.remove_workspace_folder, "[W]orkspace [R]emove Folder") nmap("wl", function() print(vim.inspect(vim.lsp.buf.list_workspace_folders())) end, "[W]orkspace [L]ist Folders") -- Create a command `:Format` local to the LSP buffer vim.api.nvim_buf_create_user_command(bufnr, "Format", function(_) vim.lsp.buf.format() end, { desc = "Format current buffer with LSP" }) -- Auto format on save vim.cmd [[autocmd BufWritePre lua vim.lsp.buf.format()]] -- or vim.cmd [[autocmd BufWritePre * lua vim.lsp.buf.format()]] end -- document existing key chains require("which-key").register({ ["c"] = { name = "[C]ode", _ = "which_key_ignore" }, ["d"] = { name = "[D]ocument", _ = "which_key_ignore" }, ["g"] = { name = "[G]it", _ = "which_key_ignore" }, ["h"] = { name = "More git", _ = "which_key_ignore" }, ["r"] = { name = "[R]ename", _ = "which_key_ignore" }, ["s"] = { name = "[S]earch", _ = "which_key_ignore" }, ["w"] = { name = "[W]orkspace", _ = "which_key_ignore" }, }) -- Enable the following language servers -- If you want to override the default filetypes that your language server will attach to you can -- define the property "filetypes" to the map in question. local servers = { rust_analyzer = {}, lemminx = {}, yamlls = {}, bashls = {}, jsonls = {}, clangd = {}, cssls = {}, jdtls = {}, html = {}, lua_ls = { Lua = { workspace = { checkThirdParty = false }, telemetry = { enable = false }, }, }, } -- Setup neovim lua configuration require("neodev").setup() -- nvim-cmp supports additional completion capabilities, so broadcast that to servers local capabilities = vim.lsp.protocol.make_client_capabilities() capabilities = require("cmp_nvim_lsp").default_capabilities(capabilities) -- Ensure the servers above are installed local mason_lspconfig = require "mason-lspconfig" mason_lspconfig.setup { ensure_installed = vim.tbl_keys(servers), } mason_lspconfig.setup_handlers { function(server_name) require("lspconfig")[server_name].setup { capabilities = capabilities, on_attach = on_attach, settings = servers[server_name], filetypes = (servers[server_name] or {}).filetypes, } end } --- [[ Configure nvim-cmp ]] -- See `:help cmp` local cmp = require "cmp" local luasnip = require "luasnip" require("luasnip.loaders.from_vscode").lazy_load() luasnip.config.setup {} cmp.setup { snippet = { expand = function(args) luasnip.lsp_expand(args.body) end, }, mapping = cmp.mapping.preset.insert { [""] = cmp.mapping.select_next_item(), [""] = cmp.mapping.select_prev_item(), [""] = cmp.mapping.scroll_docs(-4), [""] = cmp.mapping.scroll_docs(4), [""] = cmp.mapping.complete {}, [""] = cmp.mapping.confirm { behavior = cmp.ConfirmBehavior.Replace, select = true, }, [""] = cmp.mapping(function(fallback) if cmp.visible() then cmp.select_next_item() elseif luasnip.expand_or_locally_jumpable() then luasnip.expand_or_jump() else fallback() end end, { "i", "s" }), [""] = cmp.mapping(function(fallback) if cmp.visible() then cmp.select_prev_item() elseif luasnip.locally_jumpable(-1) then luasnip.jump(-1) else fallback() end end, { "i", "s" }), }, sources = { { name = "nvim_lsp" }, { name = "luasnip" }, }, } -- The line beneath this is called `modeline`. See `:help modeline` -- vim: ts=2 sts=2 sw=2 et