-- ============================================================ -- SECTION 1: OPTIONS -- Core Neovim settings, leaders, options, basic keymaps, basic autocmds -- ============================================================ do -- Enable faster startup by caching compiled Lua modules vim.loader.enable() -- 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 = false -- [[ 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 end -- ============================================================ -- SECTION 2: KEYMAPS -- basic keymaps -- ============================================================ do -- [[ 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', source = 'if_many' }, 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 = false, -- 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 = { on_jump = function(_, bufnr) vim.diagnostic.open_float { bufnr = bufnr, scope = 'cursor', focus = false, } end, }, } 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" }) -- [[ 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, }) end -- ============================================================ -- SECTION 3: PLUGIN MANAGER INTRO -- vim.pack intro, build hooks -- ============================================================ do -- [[ Intro to `vim.pack` ]] -- `vim.pack` is a new plugin manager built into Neovim, -- which provides a Lua interface for installing and managing plugins. -- -- See `:help vim.pack`, `:help vim.pack-examples` or the -- excellent blog post from the creator of vim.pack and mini.nvim: -- https://echasnovski.com/blog/2026-03-13-a-guide-to-vim-pack -- -- To inspect plugin state and pending updates, run -- :lua vim.pack.update(nil, { offline = true }) -- -- To update plugins, run -- :lua vim.pack.update() -- -- -- Throughout the rest of the config there will be examples -- of how to install and configure plugins using `vim.pack`. -- -- In this section we set up some autocommands to run build -- steps for certain plugins after they are installed or updated. local function run_build(name, cmd, cwd) local result = vim.system(cmd, { cwd = cwd }):wait() if result.code ~= 0 then local stderr = result.stderr or '' local stdout = result.stdout or '' local output = stderr ~= '' and stderr or stdout if output == '' then output = 'No output from build command.' end vim.notify(('Build failed for %s:\n%s'):format(name, output), vim.log.levels.ERROR) end end -- This autocommand runs after a plugin is installed or updated and -- runs the appropriate build command for that plugin if necessary. -- -- See `:help vim.pack-events` vim.api.nvim_create_autocmd('PackChanged', { callback = function(ev) local name = ev.data.spec.name local kind = ev.data.kind if kind ~= 'install' and kind ~= 'update' then return end if name == 'telescope-fzf-native.nvim' and vim.fn.executable 'make' == 1 then run_build(name, { 'make' }, ev.data.path) return end if name == 'LuaSnip' then if vim.fn.has 'win32' ~= 1 and vim.fn.executable 'make' == 1 then run_build(name, { 'make', 'install_jsregexp' }, ev.data.path) end return end if name == 'nvim-treesitter' then if not ev.data.active then vim.cmd.packadd 'nvim-treesitter' end vim.cmd 'TSUpdate' return end end, }) end ---Because most plugins are hosted on GitHub, you can use the helper ---function to have less repetition in the following sections. ---@param repo string ---@return string local function gh(repo) return 'https://github.com/' .. repo end -- ============================================================ -- SECTION 4: UI / CORE UX PLUGINS -- Extracted to lua/kickstart/plugins/{guess-indent,gitsigns,which-key,tokyonight,todo-comments,mini}.lua -- ============================================================ -- ============================================================ -- SECTION 5: SEARCH & NAVIGATION -- Extracted to lua/kickstart/plugins/telescope.lua -- ============================================================ -- ============================================================ -- ============================================================ -- SECTIONS 6-9: LSP, FORMATTING, COMPLETION, TREESITTER -- Extracted to lua/kickstart/plugins/{lsp,conform,blink,treesitter}.lua -- ============================================================ -- ============================================================ -- SECTION 10: PLUGIN REQUIRES -- Each plugin lives in lua/kickstart/plugins/.lua -- Comment/uncomment to enable/disable -- ============================================================ do -- UI & Core require 'kickstart.plugins.guess-indent' require 'kickstart.plugins.gitsigns' require 'kickstart.plugins.which-key' require 'kickstart.plugins.tokyonight' require 'kickstart.plugins.todo-comments' require 'kickstart.plugins.mini' -- Search & Navigation require 'kickstart.plugins.telescope' -- LSP require 'kickstart.plugins.lsp' -- Formatting require 'kickstart.plugins.conform' -- Autocomplete & Snippets require 'kickstart.plugins.blink' -- Treesitter require 'kickstart.plugins.treesitter' -- Optional plugins (uncomment to enable) -- require 'kickstart.plugins.neo-tree' require 'kickstart.plugins.lint' -- require 'kickstart.plugins.debug' -- require 'kickstart.plugins.autopairs' -- require 'kickstart.plugins.indent_line' end -- The line beneath this is called `modeline`. See `:help modeline` -- vim: ts=2 sts=2 sw=2 et -- [[ Custom Keymaps ]] -- Page up/down scrolling vim.keymap.set( 'n', '', function() vim.api.nvim_feedkeys(vim.api.nvim_replace_termcodes('', true, true, true), 'n', true) end, { desc = 'Page Up' } ) vim.keymap.set( 'n', '', function() vim.api.nvim_feedkeys(vim.api.nvim_replace_termcodes('', true, true, true), 'n', true) end, { desc = 'Page Down' } ) -- Save current file with Ctrl+S in insert and normal mode vim.api.nvim_set_keymap('i', '', ':wa', { noremap = true, silent = true }) vim.api.nvim_set_keymap('n', '', ':w', { noremap = true, silent = true }) -- Custom highlight groups for better syntax highlighting vim.api.nvim_set_hl(0, '@function', { fg = '#EBCB8B', bold = true }) vim.api.nvim_set_hl(0, '@function.builtin', { fg = '#EBCB8B' }) vim.api.nvim_set_hl(0, '@method', { fg = '#EBCB8B' }) vim.api.nvim_set_hl(0, '@type', { fg = '#82AAFF', italic = true }) -- Enable bicep LSP with specific configuration vim.filetype.add { extension = { bicep = 'bicep', bicepparam = 'bicepparam' } } pcall(vim.treesitter.language.register, 'bicep', 'bicepparam') vim.lsp.config('bicep', { cmd = { vim.fn.expand '~/.local/share/nvim/mason/bin/bicep-lsp' }, filetypes = { 'bicep', 'bicep-params' }, root_markers = { '.git', 'bicepconfig.json' }, workspace_required = false, })