-- Set as the leader key -- See `:help mapleader` -- NOTE: Must happen before plugins are loaded (otherwise wrong leader will be used) vim.g.mapleader = ' ' vim.g.maplocalleader = ' ' -- Set to true if you have a Nerd Font installed and selected in the terminal vim.g.have_nerd_font = true -- [[ Setting options ]] -- See `:help vim.o` -- NOTE: You can change these options as you wish! -- For more options, you can see `:help option-list` -- Make line numbers default vim.o.number = true -- You can also add relative line numbers, to help with jumping. -- Experiment for yourself to see if you like it! vim.o.relativenumber = true -- Enable mouse mode, can be useful for resizing splits for example! vim.o.mouse = 'a' -- Don't show the mode, since it's already in the status line vim.o.showmode = false -- Sync clipboard between OS and Neovim. -- Schedule the setting after `UiEnter` because it can increase startup-time. -- Remove this option if you want your OS clipboard to remain independent. -- See `:help 'clipboard'` vim.schedule(function() vim.o.clipboard = 'unnamedplus' end) -- Enable break indent vim.o.breakindent = true -- Enable undo/redo changes even after closing and reopening a file vim.o.undofile = true -- Case-insensitive searching UNLESS \C or one or more capital letters in the search term vim.o.ignorecase = true vim.o.smartcase = true -- Keep signcolumn on by default vim.o.signcolumn = 'yes' -- Decrease update time vim.o.updatetime = 250 -- Decrease mapped sequence wait time vim.o.timeoutlen = 300 -- Configure how new splits should be opened vim.o.splitright = true vim.o.splitbelow = true -- Sets how neovim will display certain whitespace characters in the editor. -- See `:help 'list'` -- and `:help 'listchars'` -- -- Notice listchars is set using `vim.opt` instead of `vim.o`. -- It is very similar to `vim.o` but offers an interface for conveniently interacting with tables. -- See `:help lua-options` -- and `:help lua-guide-options` vim.o.list = true vim.opt.listchars = { tab = '» ', trail = '·', nbsp = '␣' } -- Preview substitutions live, as you type! vim.o.inccommand = 'split' -- Show which line your cursor is on vim.o.cursorline = true -- Minimal number of screen lines to keep above and below the cursor. vim.o.scrolloff = 10 -- if performing an operation that would fail due to unsaved changes in the buffer (like `:q`), -- instead raise a dialog asking if you wish to save the current file(s) -- See `:help 'confirm'` vim.o.confirm = true -- [[ Basic Keymaps ]] -- See `:help vim.keymap.set()` -- Clear highlights on search when pressing in normal mode -- See `:help hlsearch` vim.keymap.set('n', '', 'nohlsearch') -- Diagnostic Config & Keymaps -- -- See :help vim.diagnostic.Opts -- vim.diagnostic.config { -- update_in_insert = false, -- severity_sort = true, -- float = { border = 'rounded', max_width = 120, max_height = 20, focusable = true }, -- underline = { severity = { min = vim.diagnostic.severity.WARN } }, -- -- -- Can switch between these as you prefer -- virtual_text = true, -- Text shows up at the end of the line -- virtual_lines = { only_current_line = true }, -- Text shows up underneath the line, with virtual lines -- -- -- Auto open the float, so you can easily read the errors when jumping with `[d` and `]d` -- jump = { float = true }, -- } -- -- vim.keymap.set('n', 'q', vim.diagnostic.setloclist, { desc = 'Open diagnostic [Q]uickfix list' }) -- Exit terminal mode in the builtin terminal with a shortcut that is a bit easier -- for people to discover. Otherwise, you normally need to press , which -- is not what someone will guess without a bit more experience. -- -- NOTE: This won't work in all terminal emulators/tmux/etc. Try your own mapping -- or just use to exit terminal mode vim.keymap.set('t', '', '', { desc = 'Exit terminal mode' }) -- TIP: Disable arrow keys in normal mode -- vim.keymap.set('n', '', 'echo "Use h to move!!"') -- vim.keymap.set('n', '', 'echo "Use l to move!!"') -- vim.keymap.set('n', '', 'echo "Use k to move!!"') -- vim.keymap.set('n', '', 'echo "Use j to move!!"') -- Keybinds to make split navigation easier. -- Use CTRL+ to switch between windows -- -- See `:help wincmd` for a list of all window commands vim.keymap.set('n', '', '', { desc = 'Move focus to the left window' }) vim.keymap.set('n', '', '', { desc = 'Move focus to the right window' }) vim.keymap.set('n', '', '', { desc = 'Move focus to the lower window' }) vim.keymap.set('n', '', '', { desc = 'Move focus to the upper window' }) -- NOTE: Some terminals have colliding keymaps or are not able to send distinct keycodes -- vim.keymap.set("n", "", "H", { desc = "Move window to the left" }) -- vim.keymap.set("n", "", "L", { desc = "Move window to the right" }) -- vim.keymap.set("n", "", "J", { desc = "Move window to the lower" }) -- vim.keymap.set("n", "", "K", { desc = "Move window to the upper" }) -- [[ Quality of life ]] vim.o.winborder = 'rounded' -- [[ Basic Autocommands ]] -- See `:help lua-guide-autocommands` -- Highlight when yanking (copying) text -- Try it with `yap` in normal mode -- See `:help vim.hl.on_yank()` 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 `lazy.nvim` plugin manager ]] -- See `:help lazy.nvim.txt` or https://github.com/folke/lazy.nvim for more info 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 error('Error cloning lazy.nvim:\n' .. out) end end ---@type vim.Option local rtp = vim.opt.rtp rtp:prepend(lazypath) -- [[ Configure and install plugins ]] -- -- To check the current status of your plugins, run -- :Lazy -- -- You can press `?` in this menu for help. Use `:q` to close the window -- -- To update plugins you can run -- :Lazy update -- -- NOTE: Here is where you install your plugins. require('lazy').setup({ -- NOTE: Plugins can be added via a link or github org/name. To run setup automatically, use `opts = {}` { 'NMAC427/guess-indent.nvim', opts = {} }, -- Alternatively, use `config = function() ... end` for full control over the configuration. -- If you prefer to call `setup` explicitly, use: -- { -- 'lewis6991/gitsigns.nvim', -- config = function() -- require('gitsigns').setup({ -- -- Your gitsigns configuration here -- }) -- end, -- } -- -- Here is a more advanced example where we pass configuration -- options to `gitsigns.nvim`. -- -- See `:help gitsigns` to understand what the configuration keys do { -- Adds git related signs to the gutter, as well as utilities for managing changes 'lewis6991/gitsigns.nvim', ---@module 'gitsigns' ---@type Gitsigns.Config ---@diagnostic disable-next-line: missing-fields opts = { signs = { add = { text = '+' }, ---@diagnostic disable-line: missing-fields change = { text = '~' }, ---@diagnostic disable-line: missing-fields delete = { text = '_' }, ---@diagnostic disable-line: missing-fields topdelete = { text = '‾' }, ---@diagnostic disable-line: missing-fields changedelete = { text = '~' }, ---@diagnostic disable-line: missing-fields }, }, }, -- NOTE: Plugins can also be configured to run Lua code when they are loaded. -- -- This is often very useful to both group configuration, as well as handle -- lazy loading plugins that don't need to be loaded immediately at startup. -- -- For example, in the following configuration, we use: -- event = 'VimEnter' -- -- which loads which-key before all the UI elements are loaded. Events can be -- normal autocommands events (`:help autocmd-events`). -- -- Then, because we use the `opts` key (recommended), the configuration runs -- after the plugin has been loaded as `require(MODULE).setup(opts)`. { -- Useful plugin to show you pending keybinds. 'folke/which-key.nvim', event = 'VimEnter', ---@module 'which-key' ---@type wk.Opts ---@diagnostic disable-next-line: missing-fields opts = { -- delay between pressing a key and opening which-key (milliseconds) delay = 0, icons = { mappings = vim.g.have_nerd_font }, preset = 'helix', -- Document existing key chains spec = { { 's', group = '[S]earch', mode = { 'n', 'v' } }, { 't', group = '[T]oggle' }, { 'h', group = 'Git [H]unk', mode = { 'n', 'v' } }, -- Enable gitsigns recommended keymaps first { 'gr', group = 'LSP Actions', mode = { 'n' } }, }, }, }, -- NOTE: Plugins can specify dependencies. -- -- The dependencies are proper plugin specifications as well - anything -- you do for a plugin at the top level, you can do for a dependency. -- -- Use the `dependencies` key to specify the dependencies of a particular plugin { 'folke/snacks.nvim', priority = 1000, lazy = false, ---@type snacks.Config opts = { bufdelete = { enabled = true }, debug = { enabled = true }, zen = { enabled = true }, bigfile = { enabled = true }, dashboard = { enabled = true }, explorer = { enabled = true }, image = { enabled = true }, indent = { enabled = true }, input = { enabled = true }, keyboard = { enabled = true }, lazygit = { enabled = true }, notifier = { enabled = true }, picker = { enabled = true }, quickfile = { enabled = true }, scope = { enabled = true }, scroll = { enabled = true }, statuscolumn = { enabled = true }, terminal = { enabled = true }, words = { enabled = true }, }, keys = { { '\\', function() Snacks.explorer() end, desc = 'snacks explorer reveal', silent = true }, { '', function() Snacks.picker.smart() end, desc = 'Smart Find Files' }, { ',', function() Snacks.picker.buffers() end, desc = 'Buffers' }, { '/', function() Snacks.picker.grep() end, desc = 'Grep' }, { ':', function() Snacks.picker.command_history() end, desc = 'Command History' }, { 'n', function() Snacks.picker.notifications() end, desc = 'Notification History' }, { 'e', function() Snacks.explorer() end, desc = 'File Explorer' }, -- find { 'fb', function() Snacks.picker.buffers() end, desc = 'Buffers' }, { 'fc', function() Snacks.picker.files { cwd = vim.fn.stdpath 'config' } end, desc = 'Find Config File' }, { 'ff', function() Snacks.picker.files() end, desc = 'Find Files' }, { 'fg', function() Snacks.picker.git_files() end, desc = 'Find Git Files' }, { 'fp', function() Snacks.picker.projects() end, desc = 'Projects' }, { 'fr', function() Snacks.picker.recent() end, desc = 'Recent' }, -- git { 'gb', function() Snacks.picker.git_branches() end, desc = 'Git Branches' }, { 'gl', function() Snacks.picker.git_log() end, desc = 'Git Log' }, { 'gL', function() Snacks.picker.git_log_line() end, desc = 'Git Log Line' }, { 'gs', function() Snacks.picker.git_status() end, desc = 'Git Status' }, { 'gS', function() Snacks.picker.git_stash() end, desc = 'Git Stash' }, { 'gd', function() Snacks.picker.git_diff() end, desc = 'Git Diff (Hunks)' }, { 'gf', function() Snacks.picker.git_log_file() end, desc = 'Git Log File' }, -- gh { 'gi', function() Snacks.picker.gh_issue() end, desc = 'GitHub Issues (open)' }, { 'gI', function() Snacks.picker.gh_issue { state = 'all' } end, desc = 'GitHub Issues (all)' }, { 'gp', function() Snacks.picker.gh_pr() end, desc = 'GitHub Pull Requests (open)' }, { 'gP', function() Snacks.picker.gh_pr { state = 'all' } end, desc = 'GitHub Pull Requests (all)' }, -- Grep { 'sb', function() Snacks.picker.lines() end, desc = 'Buffer Lines' }, { 'sB', function() Snacks.picker.grep_buffers() end, desc = 'Grep Open Buffers' }, { 'sg', function() Snacks.picker.grep() end, desc = 'Grep' }, { 'sw', function() Snacks.picker.grep_word() end, desc = 'Visual selection or word', mode = { 'n', 'x' } }, -- search { 's"', function() Snacks.picker.registers() end, desc = 'Registers' }, { 's/', function() Snacks.picker.search_history() end, desc = 'Search History' }, { 'sa', function() Snacks.picker.autocmds() end, desc = 'Autocmds' }, { 'sb', function() Snacks.picker.lines() end, desc = 'Buffer Lines' }, { 'sc', function() Snacks.picker.command_history() end, desc = 'Command History' }, { 'sC', function() Snacks.picker.commands() end, desc = 'Commands' }, { 'sd', function() Snacks.picker.diagnostics() end, desc = 'Diagnostics' }, { 'sD', function() Snacks.picker.diagnostics_buffer() end, desc = 'Buffer Diagnostics' }, { 'sh', function() Snacks.picker.help() end, desc = 'Help Pages' }, { 'sH', function() Snacks.picker.highlights() end, desc = 'Highlights' }, { 'si', function() Snacks.picker.icons() end, desc = 'Icons' }, { 'sj', function() Snacks.picker.jumps() end, desc = 'Jumps' }, { 'sk', function() Snacks.picker.keymaps() end, desc = 'Keymaps' }, { 'sl', function() Snacks.picker.loclist() end, desc = 'Location List' }, { 'sm', function() Snacks.picker.marks() end, desc = 'Marks' }, { 'sM', function() Snacks.picker.man() end, desc = 'Man Pages' }, { 'sp', function() Snacks.picker.lazy() end, desc = 'Search for Plugin Spec' }, { 'sq', function() Snacks.picker.qflist() end, desc = 'Quickfix List' }, { 'sR', function() Snacks.picker.resume() end, desc = 'Resume' }, { 'su', function() Snacks.picker.undo() end, desc = 'Undo History' }, { 'uC', function() Snacks.picker.colorschemes() end, desc = 'Colorschemes' }, -- LSP { 'gd', function() Snacks.picker.lsp_definitions() end, desc = 'Goto Definition' }, { 'gD', function() Snacks.picker.lsp_declarations() end, desc = 'Goto Declaration' }, { 'gr', function() Snacks.picker.lsp_references() end, nowait = true, desc = 'References' }, { 'gI', function() Snacks.picker.lsp_implementations() end, desc = 'Goto Implementation' }, { 'gy', function() Snacks.picker.lsp_type_definitions() end, desc = 'Goto T[y]pe Definition' }, { 'gai', function() Snacks.picker.lsp_incoming_calls() end, desc = 'C[a]lls Incoming' }, { 'gao', function() Snacks.picker.lsp_outgoing_calls() end, desc = 'C[a]lls Outgoing' }, { 'ss', function() Snacks.picker.lsp_symbols() end, desc = 'LSP Symbols' }, { 'sS', function() Snacks.picker.lsp_workspace_symbols() end, desc = 'LSP Workspace Symbols' }, -- Other { 'z', function() Snacks.zen() end, desc = 'Toggle Zen Mode' }, { 'Z', function() Snacks.zen.zoom() end, desc = 'Toggle Zoom' }, { 'n', function() Snacks.notifier.show_history() end, desc = 'Notification History' }, { 'bd', function() Snacks.bufdelete() end, desc = 'Delete Buffer' }, { 'cR', function() Snacks.rename.rename_file() end, desc = 'Rename File' }, { 'gB', function() Snacks.gitbrowse() end, desc = 'Git Browse', mode = { 'n', 'v' } }, { 'gg', function() Snacks.lazygit() end, desc = 'Lazygit' }, { 'un', function() Snacks.notifier.hide() end, desc = 'Dismiss All Notifications' }, { '', function() Snacks.terminal() end, desc = 'Toggle Terminal' }, { '', function() Snacks.terminal() end, desc = 'which_key_ignore' }, { ']]', function() Snacks.words.jump(vim.v.count1) end, desc = 'Next Reference', mode = { 'n', 't' } }, { '[[', function() Snacks.words.jump(-vim.v.count1) end, desc = 'Prev Reference', mode = { 'n', 't' } }, { 'N', desc = 'Neovim News', function() Snacks.win { file = vim.api.nvim_get_runtime_file('doc/news.txt', false)[1], width = 0.6, height = 0.6, wo = { spell = false, wrap = false, signcolumn = 'yes', statuscolumn = ' ', conceallevel = 3, }, } end, }, }, }, -- LSP Plugins { -- 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', ---@module 'mason.settings' ---@type MasonSettings ---@diagnostic disable-next-line: missing-fields opts = {}, }, 'smjonas/inc-rename.nvim', -- Maps LSP server names between nvim-lspconfig and Mason package names. 'mason-org/mason-lspconfig.nvim', 'WhoIsSethDaniel/mason-tool-installer.nvim', -- Useful status updates for LSP. { 'j-hui/fidget.nvim', opts = {} }, }, 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' }) -- 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') -- 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('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('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, }) -- Enable the following language servers -- Feel free to add/remove any LSPs that you want here. They will automatically be installed. -- See `:help lsp-config` for information about keys and how to configure ---@type table local servers = { clangd = {}, gopls = {}, ty = {}, bashls = {}, -- vtsls = {}, astro = {}, tailwindcss = { -- exclude a filetype from the default_config filetypes_exclude = { 'markdown' }, -- add additional filetypes to the default_config filetypes_include = {}, -- to fully override the default_config, change the below -- filetypes = {} -- additional settings for the server, e.g: -- tailwindCSS = { includeLanguages = { someLang = "html" } } -- can be addeded to the settings table and will be merged with -- this defaults for Phoenix projects settings = { tailwindCSS = { includeLanguages = { elixir = 'html-eex', eelixir = 'html-eex', heex = 'html-eex', }, }, }, }, jsonls = { -- lazy-load schemastore when needed before_init = function(_, new_config) new_config.settings.json.schemas = new_config.settings.json.schemas or {} vim.list_extend(new_config.settings.json.schemas, require('schemastore').json.schemas()) end, settings = { json = { format = { enable = true, }, validate = { enable = true }, }, }, }, bacon_ls = { enabled = diagnostics == 'bacon-ls', }, rust_analyzer = { enabled = false }, stylua = {}, -- Used to format Lua code -- Special Lua Config, as recommended by neovim help docs lua_ls = { on_init = function(client) if client.workspace_folders then local path = client.workspace_folders[1].name if path ~= vim.fn.stdpath 'config' and (vim.uv.fs_stat(path .. '/.luarc.json') or vim.uv.fs_stat(path .. '/.luarc.jsonc')) then return end end client.config.settings.Lua = vim.tbl_deep_extend('force', client.config.settings.Lua, { runtime = { version = 'LuaJIT', path = { 'lua/?.lua', 'lua/?/init.lua' }, }, workspace = { checkThirdParty = false, -- NOTE: this is a lot slower and will cause issues when working on your own configuration. -- See https://github.com/neovim/nvim-lspconfig/issues/3189 library = vim.tbl_extend('force', vim.api.nvim_get_runtime_file('', true), { '${3rd}/luv/library', '${3rd}/busted/library', }), }, }) end, settings = { Lua = {}, }, }, } -- 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. local ensure_installed = vim.tbl_keys(servers or {}) vim.list_extend(ensure_installed, { -- You can add other tools here that you want Mason to install }) require('mason-tool-installer').setup { ensure_installed = ensure_installed } for name, server in pairs(servers) do vim.lsp.config(name, server) vim.lsp.enable(name) end end, setup = { tailwindcss = function(_, opts) opts.filetypes = opts.filetypes or {} -- Add default filetypes vim.list_extend(opts.filetypes, vim.lsp.config.tailwindcss.filetypes) -- Remove excluded filetypes --- @param ft string opts.filetypes = vim.tbl_filter(function(ft) return not vim.tbl_contains(opts.filetypes_exclude or {}, ft) end, opts.filetypes) -- Add additional filetypes vim.list_extend(opts.filetypes, opts.filetypes_include or {}) end, }, keys = { { 'cr', function() local inc_rename = require 'inc_rename' return ':' .. inc_rename.config.cmd_name .. ' ' .. vim.fn.expand '' end, expr = true, desc = 'Rename (inc-rename.nvim)', }, }, }, { -- 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', }, }, ---@module 'conform' ---@type conform.setupOpts 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" }, typescript = { 'biome-check' }, -- 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 = { { 'rafamadriz/friendly-snippets', }, { 'onsails/lspkind.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 = 'super-tab', -- 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 }, menu = { draw = { components = { kind_icon = { text = function(ctx) return require('lspkind').symbol_map[ctx.kind] or '' end, }, }, }, }, }, sources = { default = { 'lsp', 'path', 'snippets' }, per_filetype = { sql = { 'snippets', 'dadbod', 'buffer' }, }, providers = { dadbod = { name = 'Dadbod', module = 'vim_dadbod_completion.blink' }, }, }, snippets = { preset = 'mini_snippets' }, -- 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 = 'prefer_rust_with_warning' }, -- Shows a signature help window while you type arguments for a function -- signature = { enabled = true }, }, }, -- Highlight todo, notes, etc in comments { 'folke/todo-comments.nvim', event = 'VimEnter', dependencies = { 'nvim-lua/plenary.nvim' }, ---@module 'todo-comments' ---@type TodoOptions ---@diagnostic disable-next-line: missing-fields opts = { signs = false }, }, { -- Collection of various small independent plugins/modules 'nvim-mini/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() require('mini.icons').setup() require('mini.cursorword').setup() require('mini.snippets').setup() require('mini.indentscope').setup() require('mini.tabline').setup() require('mini.extra').setup() require('mini.sessions').setup() require('mini.git').setup() require('mini.cmdline').setup() require('mini.files').setup() require('mini.visits').setup() require('mini.move').setup() require('mini.pairs').setup() require('mini.diff').setup() end, }, { 'nvim-lualine/lualine.nvim', event = 'VeryLazy', init = function() vim.g.lualine_laststatus = vim.o.laststatus if vim.fn.argc(-1) > 0 then -- set an empty statusline till lualine loads vim.o.statusline = ' ' else -- hide the statusline on the starter page vim.o.laststatus = 0 end end, opts = function() local colors = { blue = '#80a0ff', cyan = '#79dac8', black = '#080808', white = '#c6c6c6', red = '#ff5189', violet = '#d183e8', grey = '#303030', } local bubbles_theme = { normal = { a = { fg = colors.black, bg = colors.violet }, b = { fg = colors.white, bg = colors.grey }, c = { fg = colors.white }, }, insert = { a = { fg = colors.black, bg = colors.blue } }, visual = { a = { fg = colors.black, bg = colors.cyan } }, replace = { a = { fg = colors.black, bg = colors.red } }, inactive = { a = { fg = colors.white, bg = colors.black }, b = { fg = colors.white, bg = colors.black }, c = { fg = colors.white }, }, } require('lualine').setup { options = { theme = bubbles_theme, component_separators = '', section_separators = { left = '', right = '' }, }, sections = { lualine_a = { { 'mode', separator = { left = '' }, right_padding = 2 } }, lualine_b = { 'filename', 'branch' }, lualine_c = { '%=', --[[ add your center components here in place of this comment ]] }, lualine_x = {}, lualine_y = { 'filetype', 'progress' }, lualine_z = { { 'location', separator = { right = '' }, left_padding = 2 }, }, }, inactive_sections = { lualine_a = { 'filename' }, lualine_b = {}, lualine_c = {}, lualine_x = {}, lualine_y = {}, lualine_z = { 'location' }, }, tabline = {}, extensions = {}, } end, }, { -- Highlight, edit, and navigate code 'nvim-treesitter/nvim-treesitter', lazy = false, build = ':TSUpdate', branch = 'main', -- [[ Configure Treesitter ]] See `:help nvim-treesitter-intro` opts = { -- LazyVim config for treesitter indent = { enable = true }, ---@type lazyvim.TSFeat highlight = { enable = true }, ---@type lazyvim.TSFeat folds = { enable = true }, ---@type lazyvim.TSFeat ensure_installed = { 'bash', 'c', 'diff', 'html', 'javascript', 'jsdoc', 'json', 'lua', 'luadoc', 'luap', 'markdown', 'markdown_inline', 'printf', 'python', 'query', 'regex', 'toml', 'tsx', 'typescript', 'vim', 'vimdoc', 'xml', 'yaml', }, }, config = function() local parsers = { 'bash', 'c', 'diff', 'html', 'lua', 'luadoc', 'markdown', 'markdown_inline', 'query', 'vim', 'vimdoc' } require('nvim-treesitter').install(parsers) vim.api.nvim_create_autocmd('FileType', { callback = function(args) local buf, filetype = args.buf, args.match local language = vim.treesitter.language.get_lang(filetype) if not language then return end -- check if parser exists and load it if not vim.treesitter.language.add(language) then return end -- enables syntax highlighting and other treesitter features vim.treesitter.start(buf, language) -- enables treesitter based folds -- for more info on folds see `:help folds` -- vim.wo.foldexpr = 'v:lua.vim.treesitter.foldexpr()' -- vim.wo.foldmethod = 'expr' -- enables treesitter based indentation vim.bo.indentexpr = "v:lua.require'nvim-treesitter'.indentexpr()" end, }) end, }, -- The following comments only work if you have downloaded the kickstart repo, not just copy pasted the -- init.lua. If you want these files, they are in the repository, so you can just download them and -- place them in the correct locations. -- NOTE: Next step on your Neovim journey: Add/Configure additional plugins for Kickstart -- -- Here are some example plugins that I've included in the Kickstart repository. -- Uncomment any of the lines below to enable them (you will need to restart nvim). -- require 'kickstart.plugins.debug', require 'kickstart.plugins.lint', require 'kickstart.plugins.gitsigns', -- adds gitsigns recommended keymaps -- NOTE: The import below can automatically add your own plugins, configuration, etc from `lua/custom/plugins/*.lua` -- This is the easiest way to modularize your config. -- -- Uncomment the following line and add your plugins to `lua/custom/plugins/*.lua` to get going. { import = 'custom.plugins' }, -- -- For additional information with loading, sourcing and examples see `:help lazy.nvim-🔌-plugin-spec` -- Or use telescope! -- In normal mode type `sh` then write `lazy.nvim-plugin` -- you can continue same window with `sr` which resumes last telescope search }, { ---@diagnostic disable-line: missing-fields ui = { -- If you are using a Nerd Font: set icons to an empty table which will use the -- default lazy.nvim defined Nerd Font icons, otherwise define a unicode icons table icons = vim.g.have_nerd_font and {} or { cmd = '⌘', config = '🛠', event = '📅', ft = '📂', init = '⚙', keys = '🗝', plugin = '🔌', runtime = '💻', require = '🌙', source = '📄', start = '🚀', task = '📌', lazy = '💤 ', }, }, }) require('matugen').setup() -- The line beneath this is called `modeline`. See `:help modeline` -- vim: ts=2 sts=2 sw=2 et