-- [[ Setting options ]] -- See `:help vim.o` -- -- Set as the leader key -- See `:help mapleader` -- NOTE: Must happen before plugins are required (otherwise wrong leader will be used) vim.g.mapleader = ' ' vim.g.maplocalleader = ' ' vim.g.have_nerd_font = true vim.o.termguicolors = true -- Set highlight on search vim.o.hlsearch = false -- Make line numbers default vim.wo.number = true -- Enable mouse mode vim.o.mouse = 'a' -- Sync clipboard between OS and Neovim. -- Remove this option if you want your OS clipboard to remain independent. -- See `:help 'clipboard'` vim.o.clipboard = 'unnamedplus' -- Enable break indent vim.o.breakindent = true -- Save undo history vim.o.undofile = true -- Case insensitive searching UNLESS /C or capital in search vim.o.ignorecase = true vim.o.smartcase = true -- Keep signcolumn on by default vim.wo.signcolumn = 'yes' -- Decrease update time vim.o.updatetime = 250 vim.o.timeout = true vim.o.timeoutlen = 300 -- Set completeopt to have a better completion experience vim.o.completeopt = 'menuone,noselect' -- NOTE: You should make sure your terminal supports this vim.o.termguicolors = true -- Set relative and absolute line numbers vim.o.relativenumber = true vim.o.number = true -- Set scroll offsets to have additional space when scrolling vim.o.scrolloff = 5 vim.o.sidescrolloff = 10 -- Set tabs to 2 spaces vim.o.tabstop = 2 vim.o.softtabstop = 2 vim.o.list = true vim.opt.listchars = { tab = '» ', trail = '·', nbsp = '␣' } vim.api.nvim_create_autocmd('TextYankPost', { desc = 'Highlight when yanking (copying) text', group = vim.api.nvim_create_augroup('kickstart-highlight-yank', { clear = true }), callback = function() vim.hl.on_yank() end, }) -- Install package manager -- https://github.com/folke/lazy.nvim -- `:help lazy.nvim.txt` for more info 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) -- NOTE: Here is where you install your plugins. -- You can configure plugins using the `config` key. -- -- You can also configure plugins after the setup call, -- as they will be available in your neovim runtime. require('lazy').setup({ -- NOTE: First, some plugins that don't require any configuration 'NMAC427/guess-indent.nvim', -- Detect tabstop and shiftwidth automatically -- Git related plugins 'tpope/vim-fugitive', 'tpope/vim-rhubarb', { -- Adds git related signs to the gutter, as well as utilities for managing changes 'lewis6991/gitsigns.nvim', opts = { signs = { add = { text = '+' }, change = { text = '~' }, delete = { text = '_' }, topdelete = { text = '‾' }, changedelete = { text = '~' }, }, }, }, -- NOTE: This is where your plugins related to LSP can be installed. -- The configuration is done below. Search for lspconfig to find it below. { -- LSP Configuration & Plugins 'neovim/nvim-lspconfig', dependencies = { -- Automatically install LSPs to stdpath for neovim 'williamboman/mason.nvim', 'williamboman/mason-lspconfig.nvim', -- Useful status updates for LSP -- NOTE: `opts = {}` is the same as calling `require('fidget').setup({})` { 'j-hui/fidget.nvim', opts = {} }, -- Additional lua configuration, makes nvim stuff amazing! 'folke/neodev.nvim', }, config = function() vim.api.nvim_create_autocmd('LspAttach', { group = vim.api.nvim_create_augroup('kickstart-lsp-attach', { clear = true }), callback = function(event) local nmap = function(keys, func, desc) if desc then desc = 'LSP: ' .. desc end vim.keymap.set('n', keys, func, { buffer = bufr, desc = desc }) end nmap('rn', vim.lsp.buf.rename, '[R]e[n]ame') nmap('', vim.lsp.buf.code_action, '[C]ode [A]ction') nmap('gd', vim.lsp.buf.definition, '[G]oto [D]efinition') nmap('grr', require('telescope.builtin').lsp_references, '[G]oto [R]eferences') nmap('grI', vim.lsp.buf.implementation, '[G]oto [I]mplementation') nmap('gri', require('telescope.builtin').lsp_implementations, '[G]oto [R]eferences') 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') -- 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' }) nmap('', function() vim.lsp.buf.format { async = true } end, 'Auto [F]ormat') end, }) end, }, { -- Autocompletion 'hrsh7th/nvim-cmp', dependencies = { 'hrsh7th/cmp-nvim-lsp', 'L3MON4D3/LuaSnip', 'saadparwaiz1/cmp_luasnip' }, }, -- Useful plugin to show you pending keybinds. { 'folke/which-key.nvim', event = 'VimEnter', opts = { mappings = true, }, spec = { { 's', group = '[S]earch' }, { 't', group = '[T]oggle' }, { 'h', group = 'Git [H]unk', mode = { 'n', 'v' } }, }, }, { -- Adds git releated signs to the gutter, as well as utilities for managing changes 'lewis6991/gitsigns.nvim', opts = { -- See `:help gitsigns.txt` signs = { add = { text = '+' }, change = { text = '~' }, delete = { text = '_' }, topdelete = { text = '‾' }, changedelete = { text = '~' }, }, }, }, { -- Theme inspired by Atom 'navarasu/onedark.nvim', priority = 1000, config = function() require('onedark').setup { style = 'warmer', transparent = true, -- code_style = { -- comments = 'none', -- }, } require('onedark').load() vim.cmd.colorscheme 'onedark' end, }, -- { -- 'morhetz/gruvbox', -- config = function() -- vim.cmd.colorscheme 'gruvbox' -- vim.o.background = 'dark' -- vim.o.termguicolors = true -- end -- }, { -- Set lualine as statusline 'nvim-lualine/lualine.nvim', -- See `:help lualine.txt` opts = { options = { icons_enabled = false, theme = 'gruvbox', component_separators = '|', section_separators = '', }, }, }, { -- Add indentation guides even on blank lines 'lukas-reineke/indent-blankline.nvim', -- Enable `lukas-reineke/indent-blankline.nvim` -- See `:help indent_blankline.txt` main = 'ibl', config = function() require('ibl').setup { indent = { char = '┊' }, whitespace = { remove_blankline_trail = true, }, } end, }, -- "gc" to comment visual regions/lines { 'numToStr/Comment.nvim', opts = {} }, -- Fuzzy Finder (files, lsp, etc) { -- Fuzzy Finder (files, lsp, etc) 'nvim-telescope/telescope.nvim', event = 'VimEnter', dependencies = { 'nvim-lua/plenary.nvim', { -- If encountering errors, see telescope-fzf-native README for installation instructions 'nvim-telescope/telescope-fzf-native.nvim', -- `build` is used to run some command when the plugin is installed/updated. -- This is only run then, not every time Neovim starts up. build = 'make', -- `cond` is a condition used to determine whether this plugin should be -- installed and loaded. cond = function() return vim.fn.executable 'make' == 1 end, }, { 'nvim-telescope/telescope-ui-select.nvim' }, -- Useful for getting pretty icons, but requires a Nerd Font. { 'nvim-tree/nvim-web-devicons', enabled = vim.g.have_nerd_font }, }, config = function() -- Telescope is a fuzzy finder that comes with a lot of different things that -- it can fuzzy find! It's more than just a "file finder", it can search -- many different aspects of Neovim, your workspace, LSP, and more! -- -- The easiest way to use Telescope, is to start by doing something like: -- :Telescope help_tags -- -- After running this command, a window will open up and you're able to -- type in the prompt window. You'll see a list of `help_tags` options and -- a corresponding preview of the help. -- -- Two important keymaps to use while in Telescope are: -- - Insert mode: -- - Normal mode: ? -- -- This opens a window that shows you all of the keymaps for the current -- Telescope picker. This is really useful to discover what Telescope can -- do as well as how to actually do it! -- [[ Configure Telescope ]] -- See `:help telescope` and `:help telescope.setup()` require('telescope').setup { -- You can put your default mappings / updates / etc. in here -- All the info you're looking for is in `:help telescope.setup()` -- -- defaults = { -- mappings = { -- i = { [''] = 'to_fuzzy_refine' }, -- }, -- }, -- pickers = {} extensions = { ['ui-select'] = { require('telescope.themes').get_dropdown(), }, }, } -- Enable Telescope extensions if they are installed pcall(require('telescope').load_extension, 'fzf') pcall(require('telescope').load_extension, 'ui-select') -- See `:help telescope.builtin` local builtin = require 'telescope.builtin' vim.keymap.set('n', 'sh', builtin.help_tags, { desc = '[S]earch [H]elp' }) vim.keymap.set('n', 'sk', builtin.keymaps, { desc = '[S]earch [K]eymaps' }) vim.keymap.set('n', 'sf', builtin.find_files, { desc = '[S]earch [F]iles' }) vim.keymap.set('n', 'ss', builtin.builtin, { desc = '[S]earch [S]elect Telescope' }) vim.keymap.set('n', 'sw', builtin.grep_string, { desc = '[S]earch current [W]ord' }) vim.keymap.set('n', 'sg', builtin.live_grep, { desc = '[S]earch by [G]rep' }) vim.keymap.set('n', 'sd', builtin.diagnostics, { desc = '[S]earch [D]iagnostics' }) vim.keymap.set('n', 'sr', builtin.resume, { desc = '[S]earch [R]esume' }) vim.keymap.set('n', 's.', builtin.oldfiles, { desc = '[S]earch Recent Files ("." for repeat)' }) vim.keymap.set('n', '', builtin.buffers, { desc = '[ ] Find existing buffers' }) -- Slightly advanced example of overriding default behavior and theme vim.keymap.set('n', '/', function() -- You can pass additional configuration to Telescope to change the theme, layout, etc. builtin.current_buffer_fuzzy_find(require('telescope.themes').get_dropdown { winblend = 10, previewer = false, }) end, { desc = '[/] Fuzzily search in current buffer' }) -- It's also possible to pass additional configuration options. -- See `:help telescope.builtin.live_grep()` for information about particular keys vim.keymap.set('n', 's/', function() builtin.live_grep { grep_open_files = true, prompt_title = 'Live Grep in Open Files', } end, { desc = '[S]earch [/] in Open Files' }) -- Shortcut for searching your Neovim configuration files vim.keymap.set('n', 'sn', function() builtin.find_files { cwd = vim.fn.stdpath 'config' } end, { desc = '[S]earch [N]eovim files' }) end, }, -- LSP Plugins { -- `lazydev` configures Lua LSP for your Neovim config, runtime and plugins -- used for completion, annotations and signatures of Neovim apis 'folke/lazydev.nvim', ft = 'lua', opts = { library = { -- Load luvit types when the `vim.uv` word is found { path = '${3rd}/luv/library', words = { 'vim%.uv' } }, }, }, }, { -- Main LSP Configuration 'neovim/nvim-lspconfig', dependencies = { -- Automatically install LSPs and related tools to stdpath for Neovim -- Mason must be loaded before its dependents so we need to set it up here. -- NOTE: `opts = {}` is the same as calling `require('mason').setup({})` { 'mason-org/mason.nvim', opts = {} }, 'mason-org/mason-lspconfig.nvim', 'WhoIsSethDaniel/mason-tool-installer.nvim', -- Useful status updates for LSP. { 'j-hui/fidget.nvim', opts = {} }, -- Allows extra capabilities provided by blink.cmp 'saghen/blink.cmp', }, config = function() -- Brief aside: **What is LSP?** -- -- LSP is an initialism you've probably heard, but might not understand what it is. -- -- LSP stands for Language Server Protocol. It's a protocol that helps editors -- and language tooling communicate in a standardized fashion. -- -- In general, you have a "server" which is some tool built to understand a particular -- language (such as `gopls`, `lua_ls`, `rust_analyzer`, etc.). These Language Servers -- (sometimes called LSP servers, but that's kind of like ATM Machine) are standalone -- processes that communicate with some "client" - in this case, Neovim! -- -- LSP provides Neovim with features like: -- - Go to definition -- - Find references -- - Autocompletion -- - Symbol Search -- - and more! -- -- Thus, Language Servers are external tools that must be installed separately from -- Neovim. This is where `mason` and related plugins come into play. -- -- If you're wondering about lsp vs treesitter, you can check out the wonderfully -- and elegantly composed help section, `:help lsp-vs-treesitter` -- This function gets run when an LSP attaches to a particular buffer. -- That is to say, every time a new file is opened that is associated with -- an lsp (for example, opening `main.rs` is associated with `rust_analyzer`) this -- function will be executed to configure the current buffer vim.api.nvim_create_autocmd('LspAttach', { group = vim.api.nvim_create_augroup('kickstart-lsp-attach', { clear = true }), callback = function(event) -- NOTE: Remember that Lua is a real programming language, and as such it is possible -- to define small helper and utility functions so you don't have to repeat yourself. -- -- In this case, we create a function that lets us more easily define mappings specific -- for LSP related items. It sets the mode, buffer and description for us each time. local map = function(keys, func, desc, mode) mode = mode or 'n' vim.keymap.set(mode, keys, func, { buffer = event.buf, desc = 'LSP: ' .. desc }) end -- Rename the variable under your cursor. -- Most Language Servers support renaming across files, etc. map('grn', vim.lsp.buf.rename, '[R]e[n]ame') -- Execute a code action, usually your cursor needs to be on top of an error -- or a suggestion from your LSP for this to activate. map('gra', vim.lsp.buf.code_action, '[G]oto Code [A]ction', { 'n', 'x' }) -- Find references for the word under your cursor. map('grr', require('telescope.builtin').lsp_references, '[G]oto [R]eferences') -- Jump to the implementation of the word under your cursor. -- Useful when your language has ways of declaring types without an actual implementation. map('gri', require('telescope.builtin').lsp_implementations, '[G]oto [I]mplementation') -- Jump to the definition of the word under your cursor. -- This is where a variable was first declared, or where a function is defined, etc. -- To jump back, press . map('grd', require('telescope.builtin').lsp_definitions, '[G]oto [D]efinition') -- WARN: This is not Goto Definition, this is Goto Declaration. -- For example, in C this would take you to the header. map('grD', vim.lsp.buf.declaration, '[G]oto [D]eclaration') -- Fuzzy find all the symbols in your current document. -- Symbols are things like variables, functions, types, etc. map('gO', require('telescope.builtin').lsp_document_symbols, 'Open Document Symbols') -- Fuzzy find all the symbols in your current workspace. -- Similar to document symbols, except searches over your entire project. map('gW', require('telescope.builtin').lsp_dynamic_workspace_symbols, 'Open Workspace Symbols') -- Jump to the type of the word under your cursor. -- Useful when you're not sure what type a variable is and you want to see -- the definition of its *type*, not where it was *defined*. map('grt', require('telescope.builtin').lsp_type_definitions, '[G]oto [T]ype Definition') map('[e', vim.diagnostic.goto_next, 'Next [e]rror') map(']e', vim.diagnostic.goto_prev, 'Prev [e]rror') -- See `:help K` for why this keymap map('', vim.lsp.buf.hover, 'Hover Documentation') map('', vim.lsp.buf.signature_help, 'Signature Documentation') -- This function resolves a difference between neovim nightly (version 0.11) and stable (version 0.10) ---@param client vim.lsp.Client ---@param method vim.lsp.protocol.Method ---@param bufnr? integer some lsp support methods only in specific files ---@return boolean local function client_supports_method(client, method, bufnr) if vim.fn.has 'nvim-0.11' == 1 then return client:supports_method(method, bufnr) else return client.supports_method(method, { bufnr = bufnr }) end end -- The following two autocommands are used to highlight references of the -- word under your cursor when your cursor rests there for a little while. -- See `:help CursorHold` for information about when this is executed -- -- When you move your cursor, the highlights will be cleared (the second autocommand). local client = vim.lsp.get_client_by_id(event.data.client_id) if client and client_supports_method(client, vim.lsp.protocol.Methods.textDocument_documentHighlight, event.buf) then local highlight_augroup = vim.api.nvim_create_augroup('kickstart-lsp-highlight', { clear = false }) vim.api.nvim_create_autocmd({ 'CursorHold', 'CursorHoldI' }, { buffer = event.buf, group = highlight_augroup, callback = vim.lsp.buf.document_highlight, }) vim.api.nvim_create_autocmd({ 'CursorMoved', 'CursorMovedI' }, { buffer = event.buf, group = highlight_augroup, callback = vim.lsp.buf.clear_references, }) vim.api.nvim_create_autocmd('LspDetach', { group = vim.api.nvim_create_augroup('kickstart-lsp-detach', { clear = true }), callback = function(event2) vim.lsp.buf.clear_references() vim.api.nvim_clear_autocmds { group = 'kickstart-lsp-highlight', buffer = event2.buf } end, }) end -- The following code creates a keymap to toggle inlay hints in your -- code, if the language server you are using supports them -- -- This may be unwanted, since they displace some of your code if client and client_supports_method(client, vim.lsp.protocol.Methods.textDocument_inlayHint, event.buf) then map('th', function() vim.lsp.inlay_hint.enable(not vim.lsp.inlay_hint.is_enabled { bufnr = event.buf }) end, '[T]oggle Inlay [H]ints') end end, }) -- Diagnostic Config -- See :help vim.diagnostic.Opts vim.diagnostic.config { severity_sort = true, float = { border = 'rounded', source = 'if_many' }, underline = { severity = vim.diagnostic.severity.ERROR }, signs = vim.g.have_nerd_font and { text = { [vim.diagnostic.severity.ERROR] = '󰅚 ', [vim.diagnostic.severity.WARN] = '󰀪 ', [vim.diagnostic.severity.INFO] = '󰋽 ', [vim.diagnostic.severity.HINT] = '󰌶 ', }, } or {}, virtual_text = { source = 'if_many', spacing = 2, format = function(diagnostic) local diagnostic_message = { [vim.diagnostic.severity.ERROR] = diagnostic.message, [vim.diagnostic.severity.WARN] = diagnostic.message, [vim.diagnostic.severity.INFO] = diagnostic.message, [vim.diagnostic.severity.HINT] = diagnostic.message, } return diagnostic_message[diagnostic.severity] end, }, } -- LSP servers and clients are able to communicate to each other what features they support. -- By default, Neovim doesn't support everything that is in the LSP specification. -- When you add blink.cmp, luasnip, etc. Neovim now has *more* capabilities. -- So, we create new capabilities with blink.cmp, and then broadcast that to the servers. local capabilities = require('blink.cmp').get_lsp_capabilities() -- Enable the following language servers -- Feel free to add/remove any LSPs that you want here. They will automatically be installed. -- -- Add any additional override configuration in the following tables. Available keys are: -- - cmd (table): Override the default command used to start the server -- - filetypes (table): Override the default list of associated filetypes for the server -- - capabilities (table): Override fields in capabilities. Can be used to disable certain LSP features. -- - settings (table): Override the default settings passed when initializing the server. -- For example, to see the options for `lua_ls`, you could go to: https://luals.github.io/wiki/settings/ local servers = { clangd = { cmd = { '~/.local/share/nvim/mason/bin/clangd', '--all-scopes-completion', '--background-index', '--clang-tidy', '--completion-parse=always', '--completion-style=bundled', '--cross-file-rename', '--debug-origin', '--enable-config', -- clangd 11+ supports reading from .clangd configuration file '--fallback-style=Qt', '--folding-ranges', '--function-arg-placeholders', '--header-insertion=iwyu', '--pch-storage=memory', -- could also be disk '--suggest-missing-includes', '-j=20', -- number of workers -- "--resource-dir=" '--log=error', }, }, gopls = {}, -- solargraph = {}, -- ruby_lsp = {}, sqlls = {}, angularls = {}, bashls = {}, cssls = {}, dockerls = {}, -- gradle_ls = {}, pyright = {}, ts_ls = {}, html = {}, jsonls = {}, -- jdtls = {}, -- rust_analyzer = {}, marksman = {}, -- volar = {}, yamlls = {}, lua_ls = { settings = { Lua = { workspace = { checkThirdParty = false }, telemetry = { enable = false }, completion = { callSnippet = 'Replace', }, }, }, }, tailwindcss = {}, } -- Ensure the servers and tools above are installed -- -- To check the current status of installed tools and/or manually install -- other tools, you can run -- :Mason -- -- You can press `g?` for help in this menu. -- -- `mason` had to be setup earlier: to configure its options see the -- `dependencies` table for `nvim-lspconfig` above. -- -- You can add other tools here that you want Mason to install -- for you, so that they are available from within Neovim. local ensure_installed = vim.tbl_keys(servers or {}) vim.list_extend(ensure_installed, { 'stylua', -- Used to format Lua code }) require('mason-tool-installer').setup { ensure_installed = ensure_installed } require('mason-lspconfig').setup { ensure_installed = {}, -- explicitly set to an empty table (Kickstart populates installs via mason-tool-installer) automatic_installation = false, handlers = { function(server_name) local server = servers[server_name] or {} -- This handles overriding only values explicitly passed -- by the server configuration above. Useful when disabling -- certain features of an LSP (for example, turning off formatting for ts_ls) server.capabilities = vim.tbl_deep_extend('force', {}, capabilities, server.capabilities or {}) require('lspconfig')[server_name].setup(server) end, }, } end, }, -- { -- -- Main LSP Configuration -- 'neovim/nvim-lspconfig', -- dependencies = { -- -- Automatically install LSPs and related tools to stdpath for Neovim -- -- Mason must be loaded before its dependents so we need to set it up here. -- -- NOTE: `opts = {}` is the same as calling `require('mason').setup({})` -- { 'mason-org/mason.nvim', opts = {} }, -- 'mason-org/mason-lspconfig.nvim', -- 'WhoIsSethDaniel/mason-tool-installer.nvim', -- -- -- Useful status updates for LSP. -- { 'j-hui/fidget.nvim', opts = {} }, -- -- -- Allows extra capabilities provided by blink.cmp -- 'saghen/blink.cmp', -- }, -- config = function() -- -- Brief aside: **What is LSP?** -- -- -- -- LSP is an initialism you've probably heard, but might not understand what it is. -- -- -- -- LSP stands for Language Server Protocol. It's a protocol that helps editors -- -- and language tooling communicate in a standardized fashion. -- -- -- -- In general, you have a "server" which is some tool built to understand a particular -- -- language (such as `gopls`, `lua_ls`, `rust_analyzer`, etc.). These Language Servers -- -- (sometimes called LSP servers, but that's kind of like ATM Machine) are standalone -- -- processes that communicate with some "client" - in this case, Neovim! -- -- -- -- LSP provides Neovim with features like: -- -- - Go to definition -- -- - Find references -- -- - Autocompletion -- -- - Symbol Search -- -- - and more! -- -- -- -- Thus, Language Servers are external tools that must be installed separately from -- -- Neovim. This is where `mason` and related plugins come into play. -- -- -- -- If you're wondering about lsp vs treesitter, you can check out the wonderfully -- -- and elegantly composed help section, `:help lsp-vs-treesitter` -- -- -- This function gets run when an LSP attaches to a particular buffer. -- -- That is to say, every time a new file is opened that is associated with -- -- an lsp (for example, opening `main.rs` is associated with `rust_analyzer`) this -- -- function will be executed to configure the current buffer -- vim.api.nvim_create_autocmd('LspAttach', { -- group = vim.api.nvim_create_augroup('kickstart-lsp-attach', { clear = true }), -- callback = function(event) -- -- NOTE: Remember that Lua is a real programming language, and as such it is possible -- -- to define small helper and utility functions so you don't have to repeat yourself. -- -- -- -- In this case, we create a function that lets us more easily define mappings specific -- -- for LSP related items. It sets the mode, buffer and description for us each time. -- local map = function(keys, func, desc, mode) -- mode = mode or 'n' -- vim.keymap.set(mode, keys, func, { buffer = event.buf, desc = 'LSP: ' .. desc }) -- end -- -- -- Rename the variable under your cursor. -- -- Most Language Servers support renaming across files, etc. -- map('rn', vim.lsp.buf.rename, '[R]e[n]ame') -- -- -- Execute a code action, usually your cursor needs to be on top of an error -- -- or a suggestion from your LSP for this to activate. -- map('ra', vim.lsp.buf.code_action, '[G]oto Code [A]ction', { 'n', 'x' }) -- -- -- Find references for the word under your cursor. -- map('rr', require('telescope.builtin').lsp_references, '[G]oto [R]eferences') -- -- -- Jump to the implementation of the word under your cursor. -- -- Useful when your language has ways of declaring types without an actual implementation. -- map('ri', require('telescope.builtin').lsp_implementations, '[G]oto [I]mplementation') -- -- -- Jump to the definition of the word under your cursor. -- -- This is where a variable was first declared, or where a function is defined, etc. -- -- To jump back, press . -- map('rd', require('telescope.builtin').lsp_definitions, '[G]oto [D]efinition') -- -- -- WARN: This is not Goto Definition, this is Goto Declaration. -- -- For example, in C this would take you to the header. -- map('rD', vim.lsp.buf.declaration, '[G]oto [D]eclaration') -- -- -- Fuzzy find all the symbols in your current document. -- -- Symbols are things like variables, functions, types, etc. -- map('O', require('telescope.builtin').lsp_document_symbols, 'Open Document Symbols') -- -- -- Fuzzy find all the symbols in your current workspace. -- -- Similar to document symbols, except searches over your entire project. -- map('W', require('telescope.builtin').lsp_dynamic_workspace_symbols, 'Open Workspace Symbols') -- -- -- Jump to the type of the word under your cursor. -- -- Useful when you're not sure what type a variable is and you want to see -- -- the definition of its *type*, not where it was *defined*. -- map('rt', require('telescope.builtin').lsp_type_definitions, '[G]oto [T]ype Definition') -- -- -- This function resolves a difference between neovim nightly (version 0.11) and stable (version 0.10) -- ---@param client vim.lsp.Client -- ---@param method vim.lsp.protocol.Method -- ---@param bufnr? integer some lsp support methods only in specific files -- ---@return boolean -- local function client_supports_method(client, method, bufnr) -- if vim.fn.has 'nvim-0.11' == 1 then -- return client:supports_method(method, bufnr) -- else -- return client.supports_method(method, { bufnr = bufnr }) -- end -- end -- -- -- The following two autocommands are used to highlight references of the -- -- word under your cursor when your cursor rests there for a little while. -- -- See `:help CursorHold` for information about when this is executed -- -- -- -- When you move your cursor, the highlights will be cleared (the second autocommand). -- local client = vim.lsp.get_client_by_id(event.data.client_id) -- if client and client_supports_method(client, vim.lsp.protocol.Methods.textDocument_documentHighlight, event.buf) then -- local highlight_augroup = vim.api.nvim_create_augroup('kickstart-lsp-highlight', { clear = false }) -- vim.api.nvim_create_autocmd({ 'CursorHold', 'CursorHoldI' }, { -- buffer = event.buf, -- group = highlight_augroup, -- callback = vim.lsp.buf.document_highlight, -- }) -- -- vim.api.nvim_create_autocmd({ 'CursorMoved', 'CursorMovedI' }, { -- buffer = event.buf, -- group = highlight_augroup, -- callback = vim.lsp.buf.clear_references, -- }) -- -- vim.api.nvim_create_autocmd('LspDetach', { -- group = vim.api.nvim_create_augroup('kickstart-lsp-detach', { clear = true }), -- callback = function(event2) -- vim.lsp.buf.clear_references() -- vim.api.nvim_clear_autocmds { group = 'kickstart-lsp-highlight', buffer = event2.buf } -- end, -- }) -- end -- -- -- The following code creates a keymap to toggle inlay hints in your -- -- code, if the language server you are using supports them -- -- -- -- This may be unwanted, since they displace some of your code -- if client and client_supports_method(client, vim.lsp.protocol.Methods.textDocument_inlayHint, event.buf) then -- map('th', function() -- vim.lsp.inlay_hint.enable(not vim.lsp.inlay_hint.is_enabled { bufnr = event.buf }) -- end, '[T]oggle Inlay [H]ints') -- end -- end, -- }) -- -- -- Diagnostic Config -- -- See :help vim.diagnostic.Opts -- vim.diagnostic.config { -- severity_sort = true, -- float = { border = 'rounded', source = 'if_many' }, -- underline = { severity = vim.diagnostic.severity.ERROR }, -- signs = vim.g.have_nerd_font and { -- text = { -- [vim.diagnostic.severity.ERROR] = '󰅚 ', -- [vim.diagnostic.severity.WARN] = '󰀪 ', -- [vim.diagnostic.severity.INFO] = '󰋽 ', -- [vim.diagnostic.severity.HINT] = '󰌶 ', -- }, -- } or {}, -- virtual_text = { -- source = 'if_many', -- spacing = 2, -- format = function(diagnostic) -- local diagnostic_message = { -- [vim.diagnostic.severity.ERROR] = diagnostic.message, -- [vim.diagnostic.severity.WARN] = diagnostic.message, -- [vim.diagnostic.severity.INFO] = diagnostic.message, -- [vim.diagnostic.severity.HINT] = diagnostic.message, -- } -- return diagnostic_message[diagnostic.severity] -- end, -- }, -- } -- -- -- LSP servers and clients are able to communicate to each other what features they support. -- -- By default, Neovim doesn't support everything that is in the LSP specification. -- -- When you add blink.cmp, luasnip, etc. Neovim now has *more* capabilities. -- -- So, we create new capabilities with blink.cmp, and then broadcast that to the servers. -- local capabilities = require('blink.cmp').get_lsp_capabilities() -- -- -- Enable the following language servers -- -- Feel free to add/remove any LSPs that you want here. They will automatically be installed. -- -- -- -- Add any additional override configuration in the following tables. Available keys are: -- -- - cmd (table): Override the default command used to start the server -- -- - filetypes (table): Override the default list of associated filetypes for the server -- -- - capabilities (table): Override fields in capabilities. Can be used to disable certain LSP features. -- -- - settings (table): Override the default settings passed when initializing the server. -- -- For example, to see the options for `lua_ls`, you could go to: https://luals.github.io/wiki/settings/ -- local servers = { -- clangd = { -- cmd = { -- '~/.local/share/nvim/mason/bin/clangd', -- '--all-scopes-completion', -- '--background-index', -- '--clang-tidy', -- '--completion-parse=always', -- '--completion-style=bundled', -- '--cross-file-rename', -- '--debug-origin', -- '--enable-config', -- clangd 11+ supports reading from .clangd configuration file -- '--fallback-style=Qt', -- '--folding-ranges', -- '--function-arg-placeholders', -- '--header-insertion=iwyu', -- '--pch-storage=memory', -- could also be disk -- '--suggest-missing-includes', -- '-j=20', -- number of workers -- -- "--resource-dir=" -- '--log=error', -- }, -- }, -- gopls = {}, -- pyright = {}, -- -- rust_analyzer = {}, -- -- ... etc. See `:help lspconfig-all` for a list of all the pre-configured LSPs -- -- -- -- Some languages (like typescript) have entire language plugins that can be useful: -- -- https://github.com/pmizio/typescript-tools.nvim -- -- -- -- But for many setups, the LSP (`ts_ls`) will work just fine -- ts_ls = {}, -- -- -- -- lua_ls = { -- -- cmd = { ... }, -- -- filetypes = { ... }, -- -- capabilities = {}, -- settings = { -- Lua = { -- completion = { -- callSnippet = 'Replace', -- }, -- -- You can toggle below to ignore Lua_LS's noisy `missing-fields` warnings -- -- diagnostics = { disable = { 'missing-fields' } }, -- }, -- }, -- }, -- } -- -- -- Ensure the servers and tools above are installed -- -- -- -- To check the current status of installed tools and/or manually install -- -- other tools, you can run -- -- :Mason -- -- -- -- You can press `g?` for help in this menu. -- -- -- -- `mason` had to be setup earlier: to configure its options see the -- -- `dependencies` table for `nvim-lspconfig` above. -- -- -- -- You can add other tools here that you want Mason to install -- -- for you, so that they are available from within Neovim. -- local ensure_installed = vim.tbl_keys(servers or {}) -- vim.list_extend(ensure_installed, { -- 'stylua', -- Used to format Lua code -- }) -- require('mason-tool-installer').setup { ensure_installed = ensure_installed } -- -- require('mason-lspconfig').setup { -- ensure_installed = {}, -- explicitly set to an empty table (Kickstart populates installs via mason-tool-installer) -- automatic_installation = false, -- handlers = { -- function(server_name) -- local server = servers[server_name] or {} -- -- This handles overriding only values explicitly passed -- -- by the server configuration above. Useful when disabling -- -- certain features of an LSP (for example, turning off formatting for ts_ls) -- server.capabilities = vim.tbl_deep_extend('force', {}, capabilities, server.capabilities or {}) -- require('lspconfig')[server_name].setup(server) -- end, -- }, -- } -- end, -- }, { -- Autoformat 'stevearc/conform.nvim', event = { 'BufWritePre' }, cmd = { 'ConformInfo' }, keys = { { 'f', function() require('conform').format { async = true, lsp_format = 'fallback' } end, mode = '', desc = '[F]ormat buffer', }, }, opts = { notify_on_error = false, format_on_save = function(bufnr) -- Disable "format_on_save lsp_fallback" for languages that don't -- have a well standardized coding style. You can add additional -- languages here or re-enable it for the disabled ones. local disable_filetypes = { c = true, cpp = true } if disable_filetypes[vim.bo[bufnr].filetype] then return nil else return { timeout_ms = 500, lsp_format = 'fallback', } end end, formatters_by_ft = { lua = { 'stylua' }, -- Conform can also run multiple formatters sequentially -- python = { "isort", "black" }, -- -- You can use 'stop_after_first' to run the first available formatter from the list -- javascript = { "prettierd", "prettier", stop_after_first = true }, }, }, }, { -- Autocompletion 'saghen/blink.cmp', event = 'VimEnter', version = '1.*', dependencies = { -- Snippet Engine { 'L3MON4D3/LuaSnip', version = '2.*', build = (function() -- Build Step is needed for regex support in snippets. -- This step is not supported in many windows environments. -- Remove the below condition to re-enable on windows. if vim.fn.has 'win32' == 1 or vim.fn.executable 'make' == 0 then return end return 'make install_jsregexp' end)(), dependencies = { -- `friendly-snippets` contains a variety of premade snippets. -- See the README about individual language/framework/plugin snippets: -- https://github.com/rafamadriz/friendly-snippets -- { -- 'rafamadriz/friendly-snippets', -- config = function() -- require('luasnip.loaders.from_vscode').lazy_load() -- end, -- }, }, opts = {}, }, 'folke/lazydev.nvim', }, --- @module 'blink.cmp' --- @type blink.cmp.Config opts = { keymap = { -- 'default' (recommended) for mappings similar to built-in completions -- to accept ([y]es) the completion. -- This will auto-import if your LSP supports it. -- This will expand snippets if the LSP sent a snippet. -- 'super-tab' for tab to accept -- 'enter' for enter to accept -- 'none' for no mappings -- -- For an understanding of why the 'default' preset is recommended, -- you will need to read `:help ins-completion` -- -- No, but seriously. Please read `:help ins-completion`, it is really good! -- -- All presets have the following mappings: -- /: move to right/left of your snippet expansion -- : Open menu or open docs if already open -- / or /: Select next/previous item -- : Hide menu -- : Toggle signature help -- -- See :h blink-cmp-config-keymap for defining your own keymap preset = 'default', -- For more advanced Luasnip keymaps (e.g. selecting choice nodes, expansion) see: -- https://github.com/L3MON4D3/LuaSnip?tab=readme-ov-file#keymaps }, appearance = { -- 'mono' (default) for 'Nerd Font Mono' or 'normal' for 'Nerd Font' -- Adjusts spacing to ensure icons are aligned nerd_font_variant = 'mono', }, completion = { -- By default, you may press `` to show the documentation. -- Optionally, set `auto_show = true` to show the documentation after a delay. documentation = { auto_show = false, auto_show_delay_ms = 500 }, }, sources = { default = { 'lsp', 'path', 'snippets', 'lazydev' }, providers = { lazydev = { module = 'lazydev.integrations.blink', score_offset = 100 }, }, }, snippets = { preset = 'luasnip' }, -- Blink.cmp includes an optional, recommended rust fuzzy matcher, -- which automatically downloads a prebuilt binary when enabled. -- -- By default, we use the Lua implementation instead, but you may enable -- the rust implementation via `'prefer_rust_with_warning'` -- -- See :h blink-cmp-config-fuzzy for more information fuzzy = { implementation = 'lua' }, -- Shows a signature help window while you type arguments for a function signature = { enabled = true }, }, }, { -- Collection of various small independent plugins/modules 'echasnovski/mini.nvim', config = function() -- Better Around/Inside textobjects -- -- Examples: -- - va) - [V]isually select [A]round [)]paren -- - yinq - [Y]ank [I]nside [N]ext [Q]uote -- - ci' - [C]hange [I]nside [']quote require('mini.ai').setup { n_lines = 500 } -- Add/delete/replace surroundings (brackets, quotes, etc.) -- -- - saiw) - [S]urround [A]dd [I]nner [W]ord [)]Paren -- - sd' - [S]urround [D]elete [']quotes -- - sr)' - [S]urround [R]eplace [)] ['] require('mini.surround').setup() -- Simple and easy statusline. -- You could remove this setup call if you don't like it, -- and try some other statusline plugin local statusline = require 'mini.statusline' -- set use_icons to true if you have a Nerd Font statusline.setup { use_icons = vim.g.have_nerd_font } -- You can configure sections in the statusline by overriding their -- default behavior. For example, here we set the section for -- cursor location to LINE:COLUMN ---@diagnostic disable-next-line: duplicate-set-field statusline.section_location = function() return '%2l:%-2v' end -- ... and there is more! -- Check out: https://github.com/echasnovski/mini.nvim end, }, { -- Highlight, edit, and navigate code 'nvim-treesitter/nvim-treesitter', build = ':TSUpdate', main = 'nvim-treesitter.configs', -- Sets main module to use for opts -- [[ Configure Treesitter ]] See `:help nvim-treesitter` opts = { ensure_installed = { 'bash', 'c', 'diff', 'html', 'lua', 'luadoc', 'markdown', 'markdown_inline', 'query', 'vim', 'vimdoc' }, -- Autoinstall languages that are not installed auto_install = true, highlight = { enable = true, -- Some languages depend on vim's regex highlighting system (such as Ruby) for indent rules. -- If you are experiencing weird indenting issues, add the language to -- the list of additional_vim_regex_highlighting and disabled languages for indent. additional_vim_regex_highlighting = { 'ruby' }, }, indent = { enable = true, disable = { 'ruby' } }, }, -- There are additional nvim-treesitter modules that you can use to interact -- with nvim-treesitter. You should go explore a few and see what interests you: -- -- - Incremental selection: Included, see `:help nvim-treesitter-incremental-selection-mod` -- - Show your current context: https://github.com/nvim-treesitter/nvim-treesitter-context -- - Treesitter + textobjects: https://github.com/nvim-treesitter/nvim-treesitter-textobjects }, -- NOTE: Next Step on Your Neovim Journey: Add/Configure additional "plugins" for kickstart -- These are some example plugins that I've included in the kickstart repository. -- Uncomment any of the lines below to enable them. require 'kickstart.plugins.autoformat', require 'kickstart.plugins.debug', -- NOTE: The import below automatically adds your own plugins, configuration, etc from `lua/custom/plugins/*.lua` -- You can use this folder to prevent any conflicts with this init.lua if you're interested in keeping -- up-to-date with whatever is in the kickstart repo. -- -- For additional information see: https://github.com/folke/lazy.nvim#-structuring-your-plugins -- -- An additional note is that if you only copied in the `init.lua`, you can just comment this line -- to get rid of the warning telling you that there are not plugins in `lua/custom/plugins/`. { import = 'custom.plugins' }, }, {}) -- Clear highlight on search vim.keymap.set('n', '', 'nohlsearch') vim.keymap.set('n', 'q', vim.diagnostic.setloclist, { desc = 'Open diagnostic [Q]uickfix list' }) -- [[ Basic Keymaps ]] -- Keymaps for better default experience -- See `:help vim.keymap.set()` 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 }) -- Map window slection vim.keymap.set('n', '', 'h', { silent = true }) vim.keymap.set('n', '', 'j', { silent = true }) vim.keymap.set('n', '', 'k', { silent = true }) vim.keymap.set('n', '', 'l', { silent = true }) -- Map copy to clipboard vim.keymap.set('v', 'y', '"+y', { silent = true }) -- [[ 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', 'b', require('telescope.builtin').buffers, { desc = 'Find existing [b]uffers' }) 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', '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' }) -- [[ Configure Treesitter ]] -- See `:help nvim-treesitter` 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', 'typescript', 'vim', 'http', 'css' }, -- Autoinstall languages that are not installed. Defaults to false (but you can change for yourself!) auto_install = true, highlight = { enable = true }, indent = { enable = true, disable = { 'python' } }, 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', }, }, }, } -- Diagnostic keymaps vim.keymap.set('n', '[d', vim.diagnostic.goto_prev) vim.keymap.set('n', ']d', vim.diagnostic.goto_next) vim.keymap.set('n', 'e', vim.diagnostic.open_float) vim.keymap.set('n', 'q', vim.diagnostic.setloclist) -- nvim-cmp setup local cmp = require 'cmp' local luasnip = require 'luasnip' luasnip.config.setup {} cmp.setup { snippet = { expand = function(args) luasnip.lsp_expand(args.body) end, }, mapping = cmp.mapping.preset.insert { [''] = 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_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.jumpable(-1) then -- luasnip.jump(-1) -- else -- fallback() -- end -- end, { 'i', 's' }), }, sources = { { name = 'nvim_lsp' }, { name = 'luasnip' }, }, } -- vim.cmd [[autocmd BufWritePre * lua vim.lsp.buf.format()]] -- The line beneath this is called `modeline`. See `:help modeline` -- vim: ts=2 sts=2 sw=2 et