neovim config
1--[[
2
3=====================================================================
4==================== READ THIS BEFORE CONTINUING ====================
5=====================================================================
6======== .-----. ========
7======== .----------------------. | === | ========
8======== |.-""""""""""""""""""-.| |-----| ========
9======== || || | === | ========
10======== || KICKSTART.NVIM || |-----| ========
11======== || || | === | ========
12======== || || |-----| ========
13======== ||:Tutor || |:::::| ========
14======== |'-..................-'| |____o| ========
15======== `"")----------------(""` ___________ ========
16======== /::::::::::| |::::::::::\ \ no mouse \ ========
17======== /:::========| |==hjkl==:::\ \ required \ ========
18======== '""""""""""""' '""""""""""""' '""""""""""' ========
19======== ========
20=====================================================================
21=====================================================================
22
23What is Kickstart?
24
25 Kickstart.nvim is *not* a distribution.
26
27 Kickstart.nvim is a starting point for your own configuration.
28 The goal is that you can read every line of code, top-to-bottom, understand
29 what your configuration is doing, and modify it to suit your needs.
30
31 Once you've done that, you can start exploring, configuring and tinkering to
32 make Neovim your own! That might mean leaving Kickstart just the way it is for a while
33 or immediately breaking it into modular pieces. It's up to you!
34
35 If you don't know anything about Lua, I recommend taking some time to read through
36 a guide. One possible example which will only take 10-15 minutes:
37 - https://learnxinyminutes.com/docs/lua/
38
39 After understanding a bit more about Lua, you can use `:help lua-guide` as a
40 reference for how Neovim integrates Lua.
41 - :help lua-guide
42 - (or HTML version): https://neovim.io/doc/user/lua-guide.html
43
44Kickstart Guide:
45
46 TODO: The very first thing you should do is to run the command `:Tutor` in Neovim.
47
48 If you don't know what this means, type the following:
49 - <escape key>
50 - :
51 - Tutor
52 - <enter key>
53
54 (If you already know the Neovim basics, you can skip this step.)
55
56 Once you've completed that, you can continue working through **AND READING** the rest
57 of the kickstart init.lua.
58
59 Next, run AND READ `:help`.
60 This will open up a help window with some basic information
61 about reading, navigating and searching the builtin help documentation.
62
63 This should be the first place you go to look when you're stuck or confused
64 with something. It's one of my favorite Neovim features.
65
66 MOST IMPORTANTLY, we provide a keymap "<space>sh" to [s]earch the [h]elp documentation,
67 which is very useful when you're not exactly sure of what you're looking for.
68
69 I have left several `:help X` comments throughout the init.lua
70 These are hints about where to find more information about the relevant settings,
71 plugins or Neovim features used in Kickstart.
72
73 NOTE: Look for lines like this
74
75 Throughout the file. These are for you, the reader, to help you understand what is happening.
76 Feel free to delete them once you know what you're doing, but they should serve as a guide
77 for when you are first encountering a few different constructs in your Neovim config.
78
79If you experience any errors while trying to install kickstart, run `:checkhealth` for more info.
80
81I hope you enjoy your Neovim journey,
82- TJ
83
84P.S. You can delete this when you're done too. It's your config now! :)
85--]]
86
87-- Set <space> as the leader key
88-- See `:help mapleader`
89-- NOTE: Must happen before plugins are loaded (otherwise wrong leader will be used)
90vim.g.mapleader = ' '
91vim.g.maplocalleader = ' '
92
93-- Set to true if you have a Nerd Font installed and selected in the terminal
94vim.g.have_nerd_font = false
95
96-- [[ Setting options ]]
97-- See `:help vim.o`
98-- NOTE: You can change these options as you wish!
99-- For more options, you can see `:help option-list`
100
101-- Make line numbers default
102vim.o.number = true
103-- You can also add relative line numbers, to help with jumping.
104-- Experiment for yourself to see if you like it!
105-- vim.o.relativenumber = true
106
107-- Enable mouse mode, can be useful for resizing splits for example!
108vim.o.mouse = 'a'
109
110-- Don't show the mode, since it's already in the status line
111vim.o.showmode = false
112
113-- Sync clipboard between OS and Neovim.
114-- Schedule the setting after `UiEnter` because it can increase startup-time.
115-- Remove this option if you want your OS clipboard to remain independent.
116-- See `:help 'clipboard'`
117vim.schedule(function() vim.o.clipboard = 'unnamedplus' end)
118
119-- Enable break indent
120vim.o.breakindent = true
121
122-- Enable undo/redo changes even after closing and reopening a file
123vim.o.undofile = true
124
125-- Case-insensitive searching UNLESS \C or one or more capital letters in the search term
126vim.o.ignorecase = true
127vim.o.smartcase = true
128
129-- Keep signcolumn on by default
130vim.o.signcolumn = 'yes'
131
132-- Decrease update time
133vim.o.updatetime = 250
134
135-- Decrease mapped sequence wait time
136vim.o.timeoutlen = 300
137
138-- Configure how new splits should be opened
139vim.o.splitright = true
140vim.o.splitbelow = true
141
142-- Sets how neovim will display certain whitespace characters in the editor.
143-- See `:help 'list'`
144-- and `:help 'listchars'`
145--
146-- Notice listchars is set using `vim.opt` instead of `vim.o`.
147-- It is very similar to `vim.o` but offers an interface for conveniently interacting with tables.
148-- See `:help lua-options`
149-- and `:help lua-guide-options`
150vim.o.list = true
151vim.opt.listchars = { tab = '» ', trail = '·', nbsp = '␣' }
152
153-- Preview substitutions live, as you type!
154vim.o.inccommand = 'split'
155
156-- Show which line your cursor is on
157vim.o.cursorline = true
158
159-- Minimal number of screen lines to keep above and below the cursor.
160vim.o.scrolloff = 10
161
162-- if performing an operation that would fail due to unsaved changes in the buffer (like `:q`),
163-- instead raise a dialog asking if you wish to save the current file(s)
164-- See `:help 'confirm'`
165vim.o.confirm = true
166
167-- [[ Basic Keymaps ]]
168-- See `:help vim.keymap.set()`
169
170-- Clear highlights on search when pressing <Esc> in normal mode
171-- See `:help hlsearch`
172vim.keymap.set('n', '<Esc>', '<cmd>nohlsearch<CR>')
173
174-- Diagnostic Config & Keymaps
175-- See :help vim.diagnostic.Opts
176vim.diagnostic.config {
177 update_in_insert = false,
178 severity_sort = true,
179 float = { border = 'rounded', source = 'if_many' },
180 underline = { severity = { min = vim.diagnostic.severity.WARN } },
181
182 -- Can switch between these as you prefer
183 virtual_text = true, -- Text shows up at the end of the line
184 virtual_lines = false, -- Text shows up underneath the line, with virtual lines
185
186 -- Auto open the float, so you can easily read the errors when jumping with `[d` and `]d`
187 jump = { float = true },
188}
189
190vim.keymap.set('n', '<leader>q', vim.diagnostic.setloclist, { desc = 'Open diagnostic [Q]uickfix list' })
191
192-- Exit terminal mode in the builtin terminal with a shortcut that is a bit easier
193-- for people to discover. Otherwise, you normally need to press <C-\><C-n>, which
194-- is not what someone will guess without a bit more experience.
195--
196-- NOTE: This won't work in all terminal emulators/tmux/etc. Try your own mapping
197-- or just use <C-\><C-n> to exit terminal mode
198vim.keymap.set('t', '<Esc><Esc>', '<C-\\><C-n>', { desc = 'Exit terminal mode' })
199
200-- TIP: Disable arrow keys in normal mode
201-- vim.keymap.set('n', '<left>', '<cmd>echo "Use h to move!!"<CR>')
202-- vim.keymap.set('n', '<right>', '<cmd>echo "Use l to move!!"<CR>')
203-- vim.keymap.set('n', '<up>', '<cmd>echo "Use k to move!!"<CR>')
204-- vim.keymap.set('n', '<down>', '<cmd>echo "Use j to move!!"<CR>')
205
206-- Keybinds to make split navigation easier.
207-- Use CTRL+<hjkl> to switch between windows
208--
209-- See `:help wincmd` for a list of all window commands
210vim.keymap.set('n', '<C-h>', '<C-w><C-h>', { desc = 'Move focus to the left window' })
211vim.keymap.set('n', '<C-l>', '<C-w><C-l>', { desc = 'Move focus to the right window' })
212vim.keymap.set('n', '<C-j>', '<C-w><C-j>', { desc = 'Move focus to the lower window' })
213vim.keymap.set('n', '<C-k>', '<C-w><C-k>', { desc = 'Move focus to the upper window' })
214
215-- NOTE: Some terminals have colliding keymaps or are not able to send distinct keycodes
216-- vim.keymap.set("n", "<C-S-h>", "<C-w>H", { desc = "Move window to the left" })
217-- vim.keymap.set("n", "<C-S-l>", "<C-w>L", { desc = "Move window to the right" })
218-- vim.keymap.set("n", "<C-S-j>", "<C-w>J", { desc = "Move window to the lower" })
219-- vim.keymap.set("n", "<C-S-k>", "<C-w>K", { desc = "Move window to the upper" })
220
221-- [[ Basic Autocommands ]]
222-- See `:help lua-guide-autocommands`
223
224-- Highlight when yanking (copying) text
225-- Try it with `yap` in normal mode
226-- See `:help vim.hl.on_yank()`
227vim.api.nvim_create_autocmd('TextYankPost', {
228 desc = 'Highlight when yanking (copying) text',
229 group = vim.api.nvim_create_augroup('kickstart-highlight-yank', { clear = true }),
230 callback = function() vim.hl.on_yank() end,
231})
232
233-- [[ Install `lazy.nvim` plugin manager ]]
234-- See `:help lazy.nvim.txt` or https://github.com/folke/lazy.nvim for more info
235local lazypath = vim.fn.stdpath 'data' .. '/lazy/lazy.nvim'
236if not (vim.uv or vim.loop).fs_stat(lazypath) then
237 local lazyrepo = 'https://github.com/folke/lazy.nvim.git'
238 local out = vim.fn.system { 'git', 'clone', '--filter=blob:none', '--branch=stable', lazyrepo, lazypath }
239 if vim.v.shell_error ~= 0 then error('Error cloning lazy.nvim:\n' .. out) end
240end
241
242---@type vim.Option
243local rtp = vim.opt.rtp
244rtp:prepend(lazypath)
245
246-- [[ Configure and install plugins ]]
247--
248-- To check the current status of your plugins, run
249-- :Lazy
250--
251-- You can press `?` in this menu for help. Use `:q` to close the window
252--
253-- To update plugins you can run
254-- :Lazy update
255--
256-- NOTE: Here is where you install your plugins.
257require('lazy').setup({
258 -- NOTE: Plugins can be added via a link or github org/name. To run setup automatically, use `opts = {}`
259 { 'NMAC427/guess-indent.nvim', opts = {} },
260
261 -- Alternatively, use `config = function() ... end` for full control over the configuration.
262 -- If you prefer to call `setup` explicitly, use:
263 -- {
264 -- 'lewis6991/gitsigns.nvim',
265 -- config = function()
266 -- require('gitsigns').setup({
267 -- -- Your gitsigns configuration here
268 -- })
269 -- end,
270 -- }
271 --
272 -- Here is a more advanced example where we pass configuration
273 -- options to `gitsigns.nvim`.
274 --
275 -- See `:help gitsigns` to understand what the configuration keys do
276 { -- Adds git related signs to the gutter, as well as utilities for managing changes
277 'lewis6991/gitsigns.nvim',
278 ---@module 'gitsigns'
279 ---@type Gitsigns.Config
280 ---@diagnostic disable-next-line: missing-fields
281 opts = {
282 signs = {
283 add = { text = '+' }, ---@diagnostic disable-line: missing-fields
284 change = { text = '~' }, ---@diagnostic disable-line: missing-fields
285 delete = { text = '_' }, ---@diagnostic disable-line: missing-fields
286 topdelete = { text = '‾' }, ---@diagnostic disable-line: missing-fields
287 changedelete = { text = '~' }, ---@diagnostic disable-line: missing-fields
288 },
289 },
290 },
291
292 -- NOTE: Plugins can also be configured to run Lua code when they are loaded.
293 --
294 -- This is often very useful to both group configuration, as well as handle
295 -- lazy loading plugins that don't need to be loaded immediately at startup.
296 --
297 -- For example, in the following configuration, we use:
298 -- event = 'VimEnter'
299 --
300 -- which loads which-key before all the UI elements are loaded. Events can be
301 -- normal autocommands events (`:help autocmd-events`).
302 --
303 -- Then, because we use the `opts` key (recommended), the configuration runs
304 -- after the plugin has been loaded as `require(MODULE).setup(opts)`.
305
306 { -- Useful plugin to show you pending keybinds.
307 'folke/which-key.nvim',
308 event = 'VimEnter',
309 ---@module 'which-key'
310 ---@type wk.Opts
311 ---@diagnostic disable-next-line: missing-fields
312 opts = {
313 -- delay between pressing a key and opening which-key (milliseconds)
314 delay = 0,
315 icons = { mappings = vim.g.have_nerd_font },
316
317 -- Document existing key chains
318 spec = {
319 { '<leader>s', group = '[S]earch', mode = { 'n', 'v' } },
320 { '<leader>t', group = '[T]oggle' },
321 { '<leader>h', group = 'Git [H]unk', mode = { 'n', 'v' } },
322 { 'gr', group = 'LSP Actions', mode = { 'n' } },
323 },
324 },
325 },
326
327 -- NOTE: Plugins can specify dependencies.
328 --
329 -- The dependencies are proper plugin specifications as well - anything
330 -- you do for a plugin at the top level, you can do for a dependency.
331 --
332 -- Use the `dependencies` key to specify the dependencies of a particular plugin
333
334 { -- Fuzzy Finder (files, lsp, etc)
335 'nvim-telescope/telescope.nvim',
336 -- By default, Telescope is included and acts as your picker for everything.
337
338 -- If you would like to switch to a different picker (like snacks, or fzf-lua)
339 -- you can disable the Telescope plugin by setting enabled to false and enable
340 -- your replacement picker by requiring it explicitly (e.g. 'custom.plugins.snacks')
341
342 -- Note: If you customize your config for yourself,
343 -- it’s best to remove the Telescope plugin config entirely
344 -- instead of just disabling it here, to keep your config clean.
345 enabled = true,
346 event = 'VimEnter',
347 dependencies = {
348 'nvim-lua/plenary.nvim',
349 { -- If encountering errors, see telescope-fzf-native README for installation instructions
350 'nvim-telescope/telescope-fzf-native.nvim',
351
352 -- `build` is used to run some command when the plugin is installed/updated.
353 -- This is only run then, not every time Neovim starts up.
354 build = 'make',
355
356 -- `cond` is a condition used to determine whether this plugin should be
357 -- installed and loaded.
358 cond = function() return vim.fn.executable 'make' == 1 end,
359 },
360 { 'nvim-telescope/telescope-ui-select.nvim' },
361
362 -- Useful for getting pretty icons, but requires a Nerd Font.
363 { 'nvim-tree/nvim-web-devicons', enabled = vim.g.have_nerd_font },
364 },
365 config = function()
366 -- Telescope is a fuzzy finder that comes with a lot of different things that
367 -- it can fuzzy find! It's more than just a "file finder", it can search
368 -- many different aspects of Neovim, your workspace, LSP, and more!
369 --
370 -- The easiest way to use Telescope, is to start by doing something like:
371 -- :Telescope help_tags
372 --
373 -- After running this command, a window will open up and you're able to
374 -- type in the prompt window. You'll see a list of `help_tags` options and
375 -- a corresponding preview of the help.
376 --
377 -- Two important keymaps to use while in Telescope are:
378 -- - Insert mode: <c-/>
379 -- - Normal mode: ?
380 --
381 -- This opens a window that shows you all of the keymaps for the current
382 -- Telescope picker. This is really useful to discover what Telescope can
383 -- do as well as how to actually do it!
384
385 -- [[ Configure Telescope ]]
386 -- See `:help telescope` and `:help telescope.setup()`
387 require('telescope').setup {
388 -- You can put your default mappings / updates / etc. in here
389 -- All the info you're looking for is in `:help telescope.setup()`
390 --
391 -- defaults = {
392 -- mappings = {
393 -- i = { ['<c-enter>'] = 'to_fuzzy_refine' },
394 -- },
395 -- },
396 -- pickers = {}
397 extensions = {
398 ['ui-select'] = { require('telescope.themes').get_dropdown() },
399 },
400 }
401
402 -- Enable Telescope extensions if they are installed
403 pcall(require('telescope').load_extension, 'fzf')
404 pcall(require('telescope').load_extension, 'ui-select')
405
406 -- See `:help telescope.builtin`
407 local builtin = require 'telescope.builtin'
408 vim.keymap.set('n', '<leader>sh', builtin.help_tags, { desc = '[S]earch [H]elp' })
409 vim.keymap.set('n', '<leader>sk', builtin.keymaps, { desc = '[S]earch [K]eymaps' })
410 vim.keymap.set('n', '<leader>sf', builtin.find_files, { desc = '[S]earch [F]iles' })
411 vim.keymap.set('n', '<leader>ss', builtin.builtin, { desc = '[S]earch [S]elect Telescope' })
412 vim.keymap.set({ 'n', 'v' }, '<leader>sw', builtin.grep_string, { desc = '[S]earch current [W]ord' })
413 vim.keymap.set('n', '<leader>sg', builtin.live_grep, { desc = '[S]earch by [G]rep' })
414 vim.keymap.set('n', '<leader>sd', builtin.diagnostics, { desc = '[S]earch [D]iagnostics' })
415 vim.keymap.set('n', '<leader>sr', builtin.resume, { desc = '[S]earch [R]esume' })
416 vim.keymap.set('n', '<leader>s.', builtin.oldfiles, { desc = '[S]earch Recent Files ("." for repeat)' })
417 vim.keymap.set('n', '<leader>sc', builtin.commands, { desc = '[S]earch [C]ommands' })
418 vim.keymap.set('n', '<leader><leader>', builtin.buffers, { desc = '[ ] Find existing buffers' })
419
420 -- This runs on LSP attach per buffer (see main LSP attach function in 'neovim/nvim-lspconfig' config for more info,
421 -- it is better explained there). This allows easily switching between pickers if you prefer using something else!
422 vim.api.nvim_create_autocmd('LspAttach', {
423 group = vim.api.nvim_create_augroup('telescope-lsp-attach', { clear = true }),
424 callback = function(event)
425 local buf = event.buf
426
427 -- Find references for the word under your cursor.
428 vim.keymap.set('n', 'grr', builtin.lsp_references, { buffer = buf, desc = '[G]oto [R]eferences' })
429
430 -- Jump to the implementation of the word under your cursor.
431 -- Useful when your language has ways of declaring types without an actual implementation.
432 vim.keymap.set('n', 'gri', builtin.lsp_implementations, { buffer = buf, desc = '[G]oto [I]mplementation' })
433
434 -- Jump to the definition of the word under your cursor.
435 -- This is where a variable was first declared, or where a function is defined, etc.
436 -- To jump back, press <C-t>.
437 vim.keymap.set('n', 'grd', builtin.lsp_definitions, { buffer = buf, desc = '[G]oto [D]efinition' })
438
439 -- Fuzzy find all the symbols in your current document.
440 -- Symbols are things like variables, functions, types, etc.
441 vim.keymap.set('n', 'gO', builtin.lsp_document_symbols, { buffer = buf, desc = 'Open Document Symbols' })
442
443 -- Fuzzy find all the symbols in your current workspace.
444 -- Similar to document symbols, except searches over your entire project.
445 vim.keymap.set('n', 'gW', builtin.lsp_dynamic_workspace_symbols, { buffer = buf, desc = 'Open Workspace Symbols' })
446
447 -- Jump to the type of the word under your cursor.
448 -- Useful when you're not sure what type a variable is and you want to see
449 -- the definition of its *type*, not where it was *defined*.
450 vim.keymap.set('n', 'grt', builtin.lsp_type_definitions, { buffer = buf, desc = '[G]oto [T]ype Definition' })
451 end,
452 })
453
454 -- Override default behavior and theme when searching
455 vim.keymap.set('n', '<leader>/', function()
456 -- You can pass additional configuration to Telescope to change the theme, layout, etc.
457 builtin.current_buffer_fuzzy_find(require('telescope.themes').get_dropdown {
458 winblend = 10,
459 previewer = false,
460 })
461 end, { desc = '[/] Fuzzily search in current buffer' })
462
463 -- It's also possible to pass additional configuration options.
464 -- See `:help telescope.builtin.live_grep()` for information about particular keys
465 vim.keymap.set(
466 'n',
467 '<leader>s/',
468 function()
469 builtin.live_grep {
470 grep_open_files = true,
471 prompt_title = 'Live Grep in Open Files',
472 }
473 end,
474 { desc = '[S]earch [/] in Open Files' }
475 )
476
477 -- Shortcut for searching your Neovim configuration files
478 vim.keymap.set('n', '<leader>sn', function() builtin.find_files { cwd = vim.fn.stdpath 'config' } end, { desc = '[S]earch [N]eovim files' })
479 end,
480 },
481
482 -- LSP Plugins
483 {
484 -- Main LSP Configuration
485 'neovim/nvim-lspconfig',
486 dependencies = {
487 -- Automatically install LSPs and related tools to stdpath for Neovim
488 -- Mason must be loaded before its dependents so we need to set it up here.
489 -- NOTE: `opts = {}` is the same as calling `require('mason').setup({})`
490 {
491 'mason-org/mason.nvim',
492 ---@module 'mason.settings'
493 ---@type MasonSettings
494 ---@diagnostic disable-next-line: missing-fields
495 opts = {},
496 },
497 -- Maps LSP server names between nvim-lspconfig and Mason package names.
498 'mason-org/mason-lspconfig.nvim',
499 'WhoIsSethDaniel/mason-tool-installer.nvim',
500
501 -- Useful status updates for LSP.
502 { 'j-hui/fidget.nvim', opts = {} },
503
504 -- Allows extra capabilities provided by blink.cmp
505 'saghen/blink.cmp',
506 },
507 config = function()
508 -- Brief aside: **What is LSP?**
509 --
510 -- LSP is an initialism you've probably heard, but might not understand what it is.
511 --
512 -- LSP stands for Language Server Protocol. It's a protocol that helps editors
513 -- and language tooling communicate in a standardized fashion.
514 --
515 -- In general, you have a "server" which is some tool built to understand a particular
516 -- language (such as `gopls`, `lua_ls`, `rust_analyzer`, etc.). These Language Servers
517 -- (sometimes called LSP servers, but that's kind of like ATM Machine) are standalone
518 -- processes that communicate with some "client" - in this case, Neovim!
519 --
520 -- LSP provides Neovim with features like:
521 -- - Go to definition
522 -- - Find references
523 -- - Autocompletion
524 -- - Symbol Search
525 -- - and more!
526 --
527 -- Thus, Language Servers are external tools that must be installed separately from
528 -- Neovim. This is where `mason` and related plugins come into play.
529 --
530 -- If you're wondering about lsp vs treesitter, you can check out the wonderfully
531 -- and elegantly composed help section, `:help lsp-vs-treesitter`
532
533 -- This function gets run when an LSP attaches to a particular buffer.
534 -- That is to say, every time a new file is opened that is associated with
535 -- an lsp (for example, opening `main.rs` is associated with `rust_analyzer`) this
536 -- function will be executed to configure the current buffer
537 vim.api.nvim_create_autocmd('LspAttach', {
538 group = vim.api.nvim_create_augroup('kickstart-lsp-attach', { clear = true }),
539 callback = function(event)
540 -- NOTE: Remember that Lua is a real programming language, and as such it is possible
541 -- to define small helper and utility functions so you don't have to repeat yourself.
542 --
543 -- In this case, we create a function that lets us more easily define mappings specific
544 -- for LSP related items. It sets the mode, buffer and description for us each time.
545 local map = function(keys, func, desc, mode)
546 mode = mode or 'n'
547 vim.keymap.set(mode, keys, func, { buffer = event.buf, desc = 'LSP: ' .. desc })
548 end
549
550 -- Rename the variable under your cursor.
551 -- Most Language Servers support renaming across files, etc.
552 map('grn', vim.lsp.buf.rename, '[R]e[n]ame')
553
554 -- Execute a code action, usually your cursor needs to be on top of an error
555 -- or a suggestion from your LSP for this to activate.
556 map('gra', vim.lsp.buf.code_action, '[G]oto Code [A]ction', { 'n', 'x' })
557
558 -- WARN: This is not Goto Definition, this is Goto Declaration.
559 -- For example, in C this would take you to the header.
560 map('grD', vim.lsp.buf.declaration, '[G]oto [D]eclaration')
561
562 -- The following two autocommands are used to highlight references of the
563 -- word under your cursor when your cursor rests there for a little while.
564 -- See `:help CursorHold` for information about when this is executed
565 --
566 -- When you move your cursor, the highlights will be cleared (the second autocommand).
567 local client = vim.lsp.get_client_by_id(event.data.client_id)
568 if client and client:supports_method('textDocument/documentHighlight', event.buf) then
569 local highlight_augroup = vim.api.nvim_create_augroup('kickstart-lsp-highlight', { clear = false })
570 vim.api.nvim_create_autocmd({ 'CursorHold', 'CursorHoldI' }, {
571 buffer = event.buf,
572 group = highlight_augroup,
573 callback = vim.lsp.buf.document_highlight,
574 })
575
576 vim.api.nvim_create_autocmd({ 'CursorMoved', 'CursorMovedI' }, {
577 buffer = event.buf,
578 group = highlight_augroup,
579 callback = vim.lsp.buf.clear_references,
580 })
581
582 vim.api.nvim_create_autocmd('LspDetach', {
583 group = vim.api.nvim_create_augroup('kickstart-lsp-detach', { clear = true }),
584 callback = function(event2)
585 vim.lsp.buf.clear_references()
586 vim.api.nvim_clear_autocmds { group = 'kickstart-lsp-highlight', buffer = event2.buf }
587 end,
588 })
589 end
590
591 -- The following code creates a keymap to toggle inlay hints in your
592 -- code, if the language server you are using supports them
593 --
594 -- This may be unwanted, since they displace some of your code
595 if client and client:supports_method('textDocument/inlayHint', event.buf) then
596 map('<leader>th', function() vim.lsp.inlay_hint.enable(not vim.lsp.inlay_hint.is_enabled { bufnr = event.buf }) end, '[T]oggle Inlay [H]ints')
597 end
598 end,
599 })
600
601 -- Enable the following language servers
602 -- Feel free to add/remove any LSPs that you want here. They will automatically be installed.
603 -- See `:help lsp-config` for information about keys and how to configure
604 ---@type table<string, vim.lsp.Config>
605 local servers = {
606 -- clangd = {},
607 -- gopls = {},
608 -- pyright = {},
609 -- rust_analyzer = {},
610 --
611 -- Some languages (like typescript) have entire language plugins that can be useful:
612 -- https://github.com/pmizio/typescript-tools.nvim
613 --
614 -- But for many setups, the LSP (`ts_ls`) will work just fine
615 -- ts_ls = {},
616
617 stylua = {}, -- Used to format Lua code
618
619 -- Special Lua Config, as recommended by neovim help docs
620 lua_ls = {
621 on_init = function(client)
622 if client.workspace_folders then
623 local path = client.workspace_folders[1].name
624 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
625 end
626
627 client.config.settings.Lua = vim.tbl_deep_extend('force', client.config.settings.Lua, {
628 runtime = {
629 version = 'LuaJIT',
630 path = { 'lua/?.lua', 'lua/?/init.lua' },
631 },
632 workspace = {
633 checkThirdParty = false,
634 -- NOTE: this is a lot slower and will cause issues when working on your own configuration.
635 -- See https://github.com/neovim/nvim-lspconfig/issues/3189
636 library = vim.tbl_extend('force', vim.api.nvim_get_runtime_file('', true), {
637 '${3rd}/luv/library',
638 '${3rd}/busted/library',
639 }),
640 },
641 })
642 end,
643 settings = {
644 Lua = {},
645 },
646 },
647 }
648
649 -- Ensure the servers and tools above are installed
650 --
651 -- To check the current status of installed tools and/or manually install
652 -- other tools, you can run
653 -- :Mason
654 --
655 -- You can press `g?` for help in this menu.
656 local ensure_installed = vim.tbl_keys(servers or {})
657 vim.list_extend(ensure_installed, {
658 -- You can add other tools here that you want Mason to install
659 })
660
661 require('mason-tool-installer').setup { ensure_installed = ensure_installed }
662
663 for name, server in pairs(servers) do
664 vim.lsp.config(name, server)
665 vim.lsp.enable(name)
666 end
667 end,
668 },
669
670 { -- Autoformat
671 'stevearc/conform.nvim',
672 event = { 'BufWritePre' },
673 cmd = { 'ConformInfo' },
674 keys = {
675 {
676 '<leader>f',
677 function() require('conform').format { async = true, lsp_format = 'fallback' } end,
678 mode = '',
679 desc = '[F]ormat buffer',
680 },
681 },
682 ---@module 'conform'
683 ---@type conform.setupOpts
684 opts = {
685 notify_on_error = false,
686 format_on_save = function(bufnr)
687 -- Disable "format_on_save lsp_fallback" for languages that don't
688 -- have a well standardized coding style. You can add additional
689 -- languages here or re-enable it for the disabled ones.
690 local disable_filetypes = { c = true, cpp = true }
691 if disable_filetypes[vim.bo[bufnr].filetype] then
692 return nil
693 else
694 return {
695 timeout_ms = 500,
696 lsp_format = 'fallback',
697 }
698 end
699 end,
700 formatters_by_ft = {
701 lua = { 'stylua' },
702 -- Conform can also run multiple formatters sequentially
703 -- python = { "isort", "black" },
704 --
705 -- You can use 'stop_after_first' to run the first available formatter from the list
706 -- javascript = { "prettierd", "prettier", stop_after_first = true },
707 },
708 },
709 },
710
711 { -- Autocompletion
712 'saghen/blink.cmp',
713 event = 'VimEnter',
714 version = '1.*',
715 dependencies = {
716 -- Snippet Engine
717 {
718 'L3MON4D3/LuaSnip',
719 version = '2.*',
720 build = (function()
721 -- Build Step is needed for regex support in snippets.
722 -- This step is not supported in many windows environments.
723 -- Remove the below condition to re-enable on windows.
724 if vim.fn.has 'win32' == 1 or vim.fn.executable 'make' == 0 then return end
725 return 'make install_jsregexp'
726 end)(),
727 dependencies = {
728 -- `friendly-snippets` contains a variety of premade snippets.
729 -- See the README about individual language/framework/plugin snippets:
730 -- https://github.com/rafamadriz/friendly-snippets
731 -- {
732 -- 'rafamadriz/friendly-snippets',
733 -- config = function()
734 -- require('luasnip.loaders.from_vscode').lazy_load()
735 -- end,
736 -- },
737 },
738 opts = {},
739 },
740 },
741 ---@module 'blink.cmp'
742 ---@type blink.cmp.Config
743 opts = {
744 keymap = {
745 -- 'default' (recommended) for mappings similar to built-in completions
746 -- <c-y> to accept ([y]es) the completion.
747 -- This will auto-import if your LSP supports it.
748 -- This will expand snippets if the LSP sent a snippet.
749 -- 'super-tab' for tab to accept
750 -- 'enter' for enter to accept
751 -- 'none' for no mappings
752 --
753 -- For an understanding of why the 'default' preset is recommended,
754 -- you will need to read `:help ins-completion`
755 --
756 -- No, but seriously. Please read `:help ins-completion`, it is really good!
757 --
758 -- All presets have the following mappings:
759 -- <tab>/<s-tab>: move to right/left of your snippet expansion
760 -- <c-space>: Open menu or open docs if already open
761 -- <c-n>/<c-p> or <up>/<down>: Select next/previous item
762 -- <c-e>: Hide menu
763 -- <c-k>: Toggle signature help
764 --
765 -- See :h blink-cmp-config-keymap for defining your own keymap
766 preset = 'default',
767
768 -- For more advanced Luasnip keymaps (e.g. selecting choice nodes, expansion) see:
769 -- https://github.com/L3MON4D3/LuaSnip?tab=readme-ov-file#keymaps
770 },
771
772 appearance = {
773 -- 'mono' (default) for 'Nerd Font Mono' or 'normal' for 'Nerd Font'
774 -- Adjusts spacing to ensure icons are aligned
775 nerd_font_variant = 'mono',
776 },
777
778 completion = {
779 -- By default, you may press `<c-space>` to show the documentation.
780 -- Optionally, set `auto_show = true` to show the documentation after a delay.
781 documentation = { auto_show = false, auto_show_delay_ms = 500 },
782 },
783
784 sources = {
785 default = { 'lsp', 'path', 'snippets' },
786 },
787
788 snippets = { preset = 'luasnip' },
789
790 -- Blink.cmp includes an optional, recommended rust fuzzy matcher,
791 -- which automatically downloads a prebuilt binary when enabled.
792 --
793 -- By default, we use the Lua implementation instead, but you may enable
794 -- the rust implementation via `'prefer_rust_with_warning'`
795 --
796 -- See :h blink-cmp-config-fuzzy for more information
797 fuzzy = { implementation = 'lua' },
798
799 -- Shows a signature help window while you type arguments for a function
800 signature = { enabled = true },
801 },
802 },
803
804 { -- You can easily change to a different colorscheme.
805 -- Change the name of the colorscheme plugin below, and then
806 -- change the command in the config to whatever the name of that colorscheme is.
807 --
808 -- If you want to see what colorschemes are already installed, you can use `:Telescope colorscheme`.
809 'folke/tokyonight.nvim',
810 priority = 1000, -- Make sure to load this before all the other start plugins.
811 config = function()
812 ---@diagnostic disable-next-line: missing-fields
813 require('tokyonight').setup {
814 styles = {
815 comments = { italic = false }, -- Disable italics in comments
816 },
817 }
818
819 -- Load the colorscheme here.
820 -- Like many other themes, this one has different styles, and you could load
821 -- any other, such as 'tokyonight-storm', 'tokyonight-moon', or 'tokyonight-day'.
822 vim.cmd.colorscheme 'tokyonight-night'
823 end,
824 },
825
826 -- Highlight todo, notes, etc in comments
827 {
828 'folke/todo-comments.nvim',
829 event = 'VimEnter',
830 dependencies = { 'nvim-lua/plenary.nvim' },
831 ---@module 'todo-comments'
832 ---@type TodoOptions
833 ---@diagnostic disable-next-line: missing-fields
834 opts = { signs = false },
835 },
836
837 { -- Collection of various small independent plugins/modules
838 'nvim-mini/mini.nvim',
839 config = function()
840 -- Better Around/Inside textobjects
841 --
842 -- Examples:
843 -- - va) - [V]isually select [A]round [)]paren
844 -- - yinq - [Y]ank [I]nside [N]ext [Q]uote
845 -- - ci' - [C]hange [I]nside [']quote
846 require('mini.ai').setup { n_lines = 500 }
847
848 -- Add/delete/replace surroundings (brackets, quotes, etc.)
849 --
850 -- - saiw) - [S]urround [A]dd [I]nner [W]ord [)]Paren
851 -- - sd' - [S]urround [D]elete [']quotes
852 -- - sr)' - [S]urround [R]eplace [)] [']
853 require('mini.surround').setup()
854
855 -- Simple and easy statusline.
856 -- You could remove this setup call if you don't like it,
857 -- and try some other statusline plugin
858 local statusline = require 'mini.statusline'
859 -- set use_icons to true if you have a Nerd Font
860 statusline.setup { use_icons = vim.g.have_nerd_font }
861
862 -- You can configure sections in the statusline by overriding their
863 -- default behavior. For example, here we set the section for
864 -- cursor location to LINE:COLUMN
865 ---@diagnostic disable-next-line: duplicate-set-field
866 statusline.section_location = function() return '%2l:%-2v' end
867
868 -- ... and there is more!
869 -- Check out: https://github.com/nvim-mini/mini.nvim
870 end,
871 },
872
873 { -- Highlight, edit, and navigate code
874 'nvim-treesitter/nvim-treesitter',
875 lazy = false,
876 build = ':TSUpdate',
877 branch = 'main',
878 -- [[ Configure Treesitter ]] See `:help nvim-treesitter-intro`
879 config = function()
880 local parsers = { 'bash', 'c', 'diff', 'html', 'lua', 'luadoc', 'markdown', 'markdown_inline', 'query', 'vim', 'vimdoc' }
881 require('nvim-treesitter').install(parsers)
882 vim.api.nvim_create_autocmd('FileType', {
883 callback = function(args)
884 local buf, filetype = args.buf, args.match
885
886 local language = vim.treesitter.language.get_lang(filetype)
887 if not language then return end
888
889 -- check if parser exists and load it
890 if not vim.treesitter.language.add(language) then return end
891 -- enables syntax highlighting and other treesitter features
892 vim.treesitter.start(buf, language)
893
894 -- enables treesitter based folds
895 -- for more info on folds see `:help folds`
896 -- vim.wo.foldexpr = 'v:lua.vim.treesitter.foldexpr()'
897 -- vim.wo.foldmethod = 'expr'
898
899 -- enables treesitter based indentation
900 vim.bo.indentexpr = "v:lua.require'nvim-treesitter'.indentexpr()"
901 end,
902 })
903 end,
904 },
905
906 -- The following comments only work if you have downloaded the kickstart repo, not just copy pasted the
907 -- init.lua. If you want these files, they are in the repository, so you can just download them and
908 -- place them in the correct locations.
909
910 -- NOTE: Next step on your Neovim journey: Add/Configure additional plugins for Kickstart
911 --
912 -- Here are some example plugins that I've included in the Kickstart repository.
913 -- Uncomment any of the lines below to enable them (you will need to restart nvim).
914 --
915 -- require 'kickstart.plugins.debug',
916 -- require 'kickstart.plugins.indent_line',
917 -- require 'kickstart.plugins.lint',
918 -- require 'kickstart.plugins.autopairs',
919 -- require 'kickstart.plugins.neo-tree',
920 -- require 'kickstart.plugins.gitsigns', -- adds gitsigns recommend keymaps
921
922 -- NOTE: The import below can automatically add your own plugins, configuration, etc from `lua/custom/plugins/*.lua`
923 -- This is the easiest way to modularize your config.
924 --
925 -- Uncomment the following line and add your plugins to `lua/custom/plugins/*.lua` to get going.
926 -- { import = 'custom.plugins' },
927 --
928 -- For additional information with loading, sourcing and examples see `:help lazy.nvim-🔌-plugin-spec`
929 -- Or use telescope!
930 -- In normal mode type `<space>sh` then write `lazy.nvim-plugin`
931 -- you can continue same window with `<space>sr` which resumes last telescope search
932}, { ---@diagnostic disable-line: missing-fields
933 ui = {
934 -- If you are using a Nerd Font: set icons to an empty table which will use the
935 -- default lazy.nvim defined Nerd Font icons, otherwise define a unicode icons table
936 icons = vim.g.have_nerd_font and {} or {
937 cmd = '⌘',
938 config = '🛠',
939 event = '📅',
940 ft = '📂',
941 init = '⚙',
942 keys = '🗝',
943 plugin = '🔌',
944 runtime = '💻',
945 require = '🌙',
946 source = '📄',
947 start = '🚀',
948 task = '📌',
949 lazy = '💤 ',
950 },
951 },
952})
953
954-- The line beneath this is called `modeline`. See `:help modeline`
955-- vim: ts=2 sts=2 sw=2 et