From 2e8d5b17cb51513ae6f1e54a65d7fac96b1b23e3 Mon Sep 17 00:00:00 2001 From: orip Date: Thu, 23 Apr 2026 21:01:25 +0300 Subject: [PATCH] Split into sections --- init.lua | 1530 ++++++++++++++++++++++++++++-------------------------- 1 file changed, 791 insertions(+), 739 deletions(-) diff --git a/init.lua b/init.lua index 565a5066..27bb5397 100644 --- a/init.lua +++ b/init.lua @@ -84,805 +84,857 @@ I hope you enjoy your Neovim journey, P.S. You can delete this when you're done too. It's your config now! :) --]] --- Enable faster startup by caching compiled Lua modules -vim.loader.enable() +-- ============================================================ +-- SECTION 1: FOUNDATION +-- 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 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 + -- 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` + -- [[ 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 + -- 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' + -- 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 + -- 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) + -- 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 break indent + vim.o.breakindent = true --- Enable undo/redo changes even after closing and reopening a file -vim.o.undofile = 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 + -- 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' + -- Keep signcolumn on by default + vim.o.signcolumn = 'yes' --- Decrease update time -vim.o.updatetime = 250 + -- Decrease update time + vim.o.updatetime = 250 --- Decrease mapped sequence wait time -vim.o.timeoutlen = 300 + -- Decrease mapped sequence wait time + vim.o.timeoutlen = 300 --- Configure how new splits should be opened -vim.o.splitright = true -vim.o.splitbelow = true + -- 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 = '␣' } + -- 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' + -- Preview substitutions live, as you type! + vim.o.inccommand = 'split' --- Show which line your cursor is on -vim.o.cursorline = true + -- 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 + -- 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 + -- 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()` + -- [[ Basic Keymaps ]] + -- See `:help vim.keymap.set()` --- Clear highlights on search when pressing in normal mode --- See `:help hlsearch` -vim.keymap.set('n', '', 'nohlsearch') + -- 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 } }, + -- 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 + -- 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 = { float = true }, -} + -- 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' }) + 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' }) + -- 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!!"') + -- 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' }) + -- 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" }) + -- 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` + -- [[ 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, -}) + -- 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 --- [[ Install plugins with `vim.pack` ]] --- 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() +-- ============================================================ +-- SECTION 2: PLUGIN MANAGER +-- vim.pack, build hooks, install/update plugins, plugin specs +-- ============================================================ +do + -- [[ Install plugins with `vim.pack` ]] + -- 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() -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) + 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, + }) + + local gh = function(repo) return 'https://github.com/' .. repo end + + ---@type (string|vim.pack.Spec)[] + local plugins = { + -- You can specify plugins with a git URL. `vim.pack` then uses the default branch (usually `main` or `master`) + gh 'NMAC427/guess-indent.nvim', + gh 'lewis6991/gitsigns.nvim', + gh 'folke/which-key.nvim', + gh 'nvim-lua/plenary.nvim', + gh 'nvim-telescope/telescope.nvim', + gh 'nvim-telescope/telescope-ui-select.nvim', + gh 'neovim/nvim-lspconfig', + gh 'mason-org/mason.nvim', + gh 'mason-org/mason-lspconfig.nvim', + gh 'WhoIsSethDaniel/mason-tool-installer.nvim', + gh 'j-hui/fidget.nvim', + gh 'stevearc/conform.nvim', + -- You can also specify plugins with a version range for semver git tags + -- See `:help vim.version.range()` for more info + { src = gh 'saghen/blink.cmp', version = vim.version.range '1.*' }, + { src = gh 'L3MON4D3/LuaSnip', version = vim.version.range '2.*' }, + gh 'folke/tokyonight.nvim', + gh 'folke/todo-comments.nvim', + gh 'nvim-mini/mini.nvim', + -- You can also specify a branch or a specific commit + { src = gh 'nvim-treesitter/nvim-treesitter', version = 'main' }, + } + + if vim.fn.executable 'make' == 1 then table.insert(plugins, gh 'nvim-telescope/telescope-fzf-native.nvim') end + + -- Useful for getting pretty icons, but requires a Nerd Font. + if vim.g.have_nerd_font then table.insert(plugins, gh 'nvim-tree/nvim-web-devicons') end + + -- NOTE: Here is where the plugins are actually installed and added to the path + vim.pack.add(plugins) +end + +-- ============================================================ +-- SECTION 3: UI / CORE UX PLUGINS +-- guess-indent, gitsigns, which-key, colorscheme, todo-comments, mini modules +-- ============================================================ +do + -- [[ Configure plugins ]] + -- For most plugins you need to call their `.setup()` to start them + -- + -- For example, here is the simplest possible setup for `guess-indent.nvim`, + -- which will automatically detect and set your indentation settings based on the current file. + require('guess-indent').setup {} + + -- Here is a more advanced example that passes configuration options to `gitsigns.nvim` + -- + -- See `:help gitsigns` to understand what each configuration key does. + -- Adds git related signs to the gutter, as well as utilities for managing changes + require('gitsigns').setup { + 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 + }, + } + + -- Useful plugin to show you pending keybinds. + require('which-key').setup { + -- Delay between pressing a key and opening which-key (milliseconds) + delay = 0, + icons = { mappings = vim.g.have_nerd_font }, + -- 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' } }, + }, + } + + -- [[ Colorscheme ]] + -- You can easily change to a different colorscheme. + -- Change the name of the colorscheme plugin below, and then + -- change the command under that to load whatever the name of that colorscheme is. + -- + -- If you want to see what colorschemes are already installed, you can use `:Telescope colorscheme`. + ---@diagnostic disable-next-line: missing-fields + require('tokyonight').setup { + styles = { + comments = { italic = false }, -- Disable italics in comments + }, + } + + -- Load the colorscheme here. + -- Like many other themes, this one has different styles, and you could load + -- any other, such as 'tokyonight-storm', 'tokyonight-moon', or 'tokyonight-day'. + vim.cmd.colorscheme 'tokyonight-night' + + -- Highlight todo, notes, etc in comments + require('todo-comments').setup { signs = false } + + -- [[ mini.nvim ]] + -- A collection of various small independent plugins/modules + + -- Better Around/Inside textobjects + -- + -- Examples: + -- - va) - [V]isually select [A]round [)]paren + -- - yiiq - [Y]ank [I]nside [I]+1 [Q]uote + -- - ci' - [C]hange [I]nside [']quote + require('mini.ai').setup { + -- NOTE: Avoid conflicts with the built-in incremental selection mappings on Neovim>=0.12 (see `:help treesitter-incremental-selection`) + mappings = { + around_next = 'aa', + inside_next = 'ii', + }, + 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/nvim-mini/mini.nvim +end + +-- ============================================================ +-- SECTION 4: SEARCH & NAVIGATION +-- Telescope setup, keymaps, LSP picker mappings +-- ============================================================ +do + -- [[ Fuzzy Finder (files, lsp, etc) ]] + -- + -- 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! + -- + -- There are lots of other alternative pickers (like snacks.picker, or fzf-lua) + -- so feel free to experiment and see what you like! + -- + -- 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! + + -- 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', 'v' }, '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', 'sc', builtin.commands, { desc = '[S]earch [C]ommands' }) + vim.keymap.set('n', '', builtin.buffers, { desc = '[ ] Find existing buffers' }) + + -- Add Telescope-based LSP pickers when an LSP attaches to a buffer. + -- If you later switch picker plugins, this is where to update these mappings. + vim.api.nvim_create_autocmd('LspAttach', { + group = vim.api.nvim_create_augroup('telescope-lsp-attach', { clear = true }), + callback = function(event) + local buf = event.buf + + -- Find references for the word under your cursor. + vim.keymap.set('n', 'grr', builtin.lsp_references, { buffer = buf, desc = '[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. + vim.keymap.set('n', 'gri', builtin.lsp_implementations, { buffer = buf, desc = '[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 . + vim.keymap.set('n', 'grd', builtin.lsp_definitions, { buffer = buf, desc = '[G]oto [D]efinition' }) + + -- Fuzzy find all the symbols in your current document. + -- Symbols are things like variables, functions, types, etc. + vim.keymap.set('n', 'gO', builtin.lsp_document_symbols, { buffer = buf, desc = 'Open Document Symbols' }) + + -- Fuzzy find all the symbols in your current workspace. + -- Similar to document symbols, except searches over your entire project. + vim.keymap.set('n', 'gW', builtin.lsp_dynamic_workspace_symbols, { buffer = buf, desc = '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*. + vim.keymap.set('n', 'grt', builtin.lsp_type_definitions, { buffer = buf, desc = '[G]oto [T]ype Definition' }) + end, + }) + + -- Override default behavior and theme when searching + 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 + +-- ============================================================ +-- SECTION 5: LSP +-- LSP keymaps, server configuration, Mason tools installations +-- ============================================================ +do + -- [[ LSP Configuration ]] + -- 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` + + -- Useful status updates for LSP. + require('fidget').setup {} + + -- 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 = {}, + -- pyright = {}, + -- rust_analyzer = {}, + -- + -- 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 = {}, + + stylua = {}, -- Used to format Lua code + + -- Special Lua Config, as recommended by neovim help docs + lua_ls = { + on_init = function(client) + client.server_capabilities.documentFormattingProvider = false -- Disable formatting (formatting is done by stylua) + + 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, + ---@type lspconfig.settings.lua_ls + settings = { + Lua = { + format = { enable = false }, -- Disable formatting (formatting is done by stylua) + }, + }, + }, + } + + -- Automatically install LSPs and related tools to stdpath for Neovim + require('mason').setup {} + + -- 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 --- 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, -}) - -local gh = function(repo) return 'https://github.com/' .. repo end - ----@type (string|vim.pack.Spec)[] -local plugins = { - -- You can specify plugins with a git URL. `vim.pack` then uses the default branch (usually `main` or `master`) - gh 'NMAC427/guess-indent.nvim', - gh 'lewis6991/gitsigns.nvim', - gh 'folke/which-key.nvim', - gh 'nvim-lua/plenary.nvim', - gh 'nvim-telescope/telescope.nvim', - gh 'nvim-telescope/telescope-ui-select.nvim', - gh 'neovim/nvim-lspconfig', - gh 'mason-org/mason.nvim', - gh 'mason-org/mason-lspconfig.nvim', - gh 'WhoIsSethDaniel/mason-tool-installer.nvim', - gh 'j-hui/fidget.nvim', - gh 'stevearc/conform.nvim', - -- You can also specify plugins with a version range for semver git tags - -- See `:help vim.version.range()` for more info - { src = gh 'saghen/blink.cmp', version = vim.version.range '1.*' }, - { src = gh 'L3MON4D3/LuaSnip', version = vim.version.range '2.*' }, - gh 'folke/tokyonight.nvim', - gh 'folke/todo-comments.nvim', - gh 'nvim-mini/mini.nvim', - -- You can also specify a branch or a specific commit - { src = gh 'nvim-treesitter/nvim-treesitter', version = 'main' }, -} - -if vim.fn.executable 'make' == 1 then table.insert(plugins, gh 'nvim-telescope/telescope-fzf-native.nvim') end - --- Useful for getting pretty icons, but requires a Nerd Font. -if vim.g.have_nerd_font then table.insert(plugins, gh 'nvim-tree/nvim-web-devicons') end - --- NOTE: Here is where the plugins are actually installed and added to the path -vim.pack.add(plugins) - --- [[ Configure plugins ]] --- For most plugins you need to call their `.setup()` to start them --- --- For example, here is the simplest possible setup for `guess-indent.nvim`, --- which will automatically detect and set your indentation settings based on the current file. -require('guess-indent').setup {} - --- Here is a more advanced example that passes configuration options to `gitsigns.nvim` --- --- See `:help gitsigns` to understand what each configuration key does. --- Adds git related signs to the gutter, as well as utilities for managing changes -require('gitsigns').setup { - 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 - }, -} - --- Useful plugin to show you pending keybinds. -require('which-key').setup { - -- Delay between pressing a key and opening which-key (milliseconds) - delay = 0, - icons = { mappings = vim.g.have_nerd_font }, - -- 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' } }, - }, -} - --- [[ Fuzzy Finder (files, lsp, etc) ]] --- --- 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! --- --- There are lots of other alternative pickers (like snacks.picker, or fzf-lua) --- so feel free to experiment and see what you like! --- --- 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! - --- 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', 'v' }, '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', 'sc', builtin.commands, { desc = '[S]earch [C]ommands' }) -vim.keymap.set('n', '', builtin.buffers, { desc = '[ ] Find existing buffers' }) - --- Add Telescope-based LSP pickers when an LSP attaches to a buffer. --- If you later switch picker plugins, this is where to update these mappings. -vim.api.nvim_create_autocmd('LspAttach', { - group = vim.api.nvim_create_augroup('telescope-lsp-attach', { clear = true }), - callback = function(event) - local buf = event.buf - - -- Find references for the word under your cursor. - vim.keymap.set('n', 'grr', builtin.lsp_references, { buffer = buf, desc = '[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. - vim.keymap.set('n', 'gri', builtin.lsp_implementations, { buffer = buf, desc = '[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 . - vim.keymap.set('n', 'grd', builtin.lsp_definitions, { buffer = buf, desc = '[G]oto [D]efinition' }) - - -- Fuzzy find all the symbols in your current document. - -- Symbols are things like variables, functions, types, etc. - vim.keymap.set('n', 'gO', builtin.lsp_document_symbols, { buffer = buf, desc = 'Open Document Symbols' }) - - -- Fuzzy find all the symbols in your current workspace. - -- Similar to document symbols, except searches over your entire project. - vim.keymap.set('n', 'gW', builtin.lsp_dynamic_workspace_symbols, { buffer = buf, desc = '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*. - vim.keymap.set('n', 'grt', builtin.lsp_type_definitions, { buffer = buf, desc = '[G]oto [T]ype Definition' }) - end, -}) - --- Override default behavior and theme when searching -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' }) - --- [[ LSP Configuration ]] --- 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` - --- Useful status updates for LSP. -require('fidget').setup {} - --- 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 = {}, - -- pyright = {}, - -- rust_analyzer = {}, - -- - -- 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 = {}, - - stylua = {}, -- Used to format Lua code - - -- Special Lua Config, as recommended by neovim help docs - lua_ls = { - on_init = function(client) - client.server_capabilities.documentFormattingProvider = false -- Disable formatting (formatting is done by stylua) - - 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 +-- ============================================================ +-- SECTION 6: FORMATTING +-- conform.nvim setup and keymap +-- ============================================================ +do + -- [[ Formatting ]] + require('conform').setup { + notify_on_error = false, + format_on_save = function(bufnr) + -- You can specify filetypes to autoformat on save here: + local enabled_filetypes = { + -- lua = true, + -- python = true, + } + if enabled_filetypes[vim.bo[bufnr].filetype] then + return { timeout_ms = 500 } + else + return nil 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, - ---@type lspconfig.settings.lua_ls - settings = { - Lua = { - format = { enable = false }, -- Disable formatting (formatting is done by stylua) - }, + default_format_opts = { + lsp_format = 'fallback', -- Use external formatters if configured below, otherwise use LSP formatting. Set to `false` to disable LSP formatting entirely. }, - }, -} + -- You can also specify external formatters in here. + formatters_by_ft = { + -- rust = { 'rustfmt' }, + -- 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 }, + }, + } --- Automatically install LSPs and related tools to stdpath for Neovim -require('mason').setup {} - --- 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) + vim.keymap.set({ 'n', 'v' }, 'f', function() require('conform').format { async = true } end, { desc = '[F]ormat buffer' }) end --- [[ Formatting ]] -require('conform').setup { - notify_on_error = false, - format_on_save = function(bufnr) - -- You can specify filetypes to autoformat on save here: - local enabled_filetypes = { - -- lua = true, - -- python = true, - } - if enabled_filetypes[vim.bo[bufnr].filetype] then - return { timeout_ms = 500 } - else - return nil - end - end, - default_format_opts = { - lsp_format = 'fallback', -- Use external formatters if configured below, otherwise use LSP formatting. Set to `false` to disable LSP formatting entirely. - }, - -- You can also specify external formatters in here. - formatters_by_ft = { - -- rust = { 'rustfmt' }, - -- 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 }, - }, -} +-- ============================================================ +-- SECTION 7: AUTOCOMPLETE & SNIPPETS +-- blink.cmp and luasnip setup +-- ============================================================ +do + -- [[ Snippet Engine ]] + require('luasnip').setup {} -vim.keymap.set({ 'n', 'v' }, 'f', function() require('conform').format { async = true } end, { desc = '[F]ormat buffer' }) - --- [[ Autocompletion Configuration ]] - --- Snippet Engine -require('luasnip').setup {} - --- `friendly-snippets` contains a variety of premade snippets. --- See the README about individual language/framework/plugin snippets: --- https://github.com/rafamadriz/friendly-snippets --- --- vim.pack.add { gh 'rafamadriz/friendly-snippets' } --- require('luasnip.loaders.from_vscode').lazy_load() - --- The autocomplete engine -require('blink.cmp').setup { - 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 `:help 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' }, - }, - - snippets = { preset = 'luasnip' }, - - -- Blink.cmp includes an optional, recommended rust fuzzy matcher, - -- which automatically downloads a prebuilt binary when enabled. + -- `friendly-snippets` contains a variety of premade snippets. + -- See the README about individual language/framework/plugin snippets: + -- https://github.com/rafamadriz/friendly-snippets -- - -- By default, we use the Lua implementation instead, but you may enable - -- the rust implementation via `'prefer_rust_with_warning'` - -- - -- See `:help blink-cmp-config-fuzzy` for more information - fuzzy = { implementation = 'lua' }, + -- vim.pack.add { gh 'rafamadriz/friendly-snippets' } + -- require('luasnip.loaders.from_vscode').lazy_load() - -- Shows a signature help window while you type arguments for a function - signature = { enabled = true }, -} + -- [[ Autocomplete Engine ]] + require('blink.cmp').setup { + 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 `:help blink-cmp-config-keymap` for defining your own keymap + preset = 'default', --- [[ Colorscheme ]] --- You can easily change to a different colorscheme. --- Change the name of the colorscheme plugin below, and then --- change the command under that to load whatever the name of that colorscheme is. --- --- If you want to see what colorschemes are already installed, you can use `:Telescope colorscheme`. ----@diagnostic disable-next-line: missing-fields -require('tokyonight').setup { - styles = { - comments = { italic = false }, -- Disable italics in comments - }, -} + -- For more advanced Luasnip keymaps (e.g. selecting choice nodes, expansion) see: + -- https://github.com/L3MON4D3/LuaSnip?tab=readme-ov-file#keymaps + }, --- Load the colorscheme here. --- Like many other themes, this one has different styles, and you could load --- any other, such as 'tokyonight-storm', 'tokyonight-moon', or 'tokyonight-day'. -vim.cmd.colorscheme 'tokyonight-night' + appearance = { + -- 'mono' (default) for 'Nerd Font Mono' or 'normal' for 'Nerd Font' + -- Adjusts spacing to ensure icons are aligned + nerd_font_variant = 'mono', + }, --- Highlight todo, notes, etc in comments -require('todo-comments').setup { signs = false } + 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 }, + }, --- [[ mini.nvim ]] --- A collection of various small independent plugins/modules + sources = { + default = { 'lsp', 'path', 'snippets' }, + }, --- Better Around/Inside textobjects --- --- Examples: --- - va) - [V]isually select [A]round [)]paren --- - yiiq - [Y]ank [I]nside [I]+1 [Q]uote --- - ci' - [C]hange [I]nside [']quote -require('mini.ai').setup { - -- NOTE: Avoid conflicts with the built-in incremental selection mappings on Neovim>=0.12 (see `:help treesitter-incremental-selection`) - mappings = { - around_next = 'aa', - inside_next = 'ii', - }, - n_lines = 500, -} + snippets = { preset = 'luasnip' }, --- 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() + -- 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 `:help blink-cmp-config-fuzzy` for more information + fuzzy = { implementation = 'lua' }, --- 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/nvim-mini/mini.nvim - --- [[ Configure Treesitter ]] --- Used to highlight, edit, and navigate code --- --- See `:help nvim-treesitter-intro` - --- Ensure basic parsers are installed -local parsers = { 'bash', 'c', 'diff', 'html', 'lua', 'luadoc', 'markdown', 'markdown_inline', 'query', 'vim', 'vimdoc' } -require('nvim-treesitter').install(parsers) - ----@param buf integer ----@param language string -local function treesitter_try_attach(buf, language) - -- Check if a parser exists and load it - if not vim.treesitter.language.add(language) then return end - -- Enable syntax highlighting and other treesitter features - vim.treesitter.start(buf, language) - - -- Enable treesitter based folds - -- For more info on folds see `:help folds` - -- vim.wo.foldexpr = 'v:lua.vim.treesitter.foldexpr()' - -- vim.wo.foldmethod = 'expr' - - -- Check if treesitter indentation is available for this language, and if so enable it - -- in case there is no indent query, the indentexpr will fallback to the vim's built in one - local has_indent_query = vim.treesitter.query.get(language, 'indents') ~= nil - - -- Enable treesitter based indentation - if has_indent_query then vim.bo.indentexpr = "v:lua.require'nvim-treesitter'.indentexpr()" end + -- Shows a signature help window while you type arguments for a function + signature = { enabled = true }, + } end -local available_parsers = require('nvim-treesitter').get_available() -vim.api.nvim_create_autocmd('FileType', { - callback = function(args) - local buf, filetype = args.buf, args.match +-- ============================================================ +-- SECTION 8: TREESITTER +-- Parser installation, syntax highlighting, folds, indentation +-- ============================================================ +do + -- [[ Configure Treesitter ]] + -- Used to highlight, edit, and navigate code + -- + -- See `:help nvim-treesitter-intro` - local language = vim.treesitter.language.get_lang(filetype) - if not language then return end + -- Ensure basic parsers are installed + local parsers = { 'bash', 'c', 'diff', 'html', 'lua', 'luadoc', 'markdown', 'markdown_inline', 'query', 'vim', 'vimdoc' } + require('nvim-treesitter').install(parsers) - local installed_parsers = require('nvim-treesitter').get_installed 'parsers' + ---@param buf integer + ---@param language string + local function treesitter_try_attach(buf, language) + -- Check if a parser exists and load it + if not vim.treesitter.language.add(language) then return end + -- Enable syntax highlighting and other treesitter features + vim.treesitter.start(buf, language) - if vim.tbl_contains(installed_parsers, language) then - -- Enable the parser if it is already installed - treesitter_try_attach(buf, language) - elseif vim.tbl_contains(available_parsers, language) then - -- If a parser is available in `nvim-treesitter`, auto-install it and enable it after the installation is done - require('nvim-treesitter').install(language):await(function() treesitter_try_attach(buf, language) end) - else - -- Try to enable treesitter features in case the parser exists but is not available from `nvim-treesitter` - treesitter_try_attach(buf, language) - end - end, -}) + -- Enable treesitter based folds + -- For more info on folds see `:help folds` + -- vim.wo.foldexpr = 'v:lua.vim.treesitter.foldexpr()' + -- vim.wo.foldmethod = 'expr' --- 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. + -- Check if treesitter indentation is available for this language, and if so enable it + -- in case there is no indent query, the indentexpr will fallback to the vim's built in one + local has_indent_query = vim.treesitter.query.get(language, 'indents') ~= nil --- 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.indent_line' --- require 'kickstart.plugins.lint' --- require 'kickstart.plugins.autopairs' --- require 'kickstart.plugins.neo-tree' --- require 'kickstart.plugins.gitsigns' -- adds gitsigns recommended keymaps + -- Enable treesitter based indentation + if has_indent_query then vim.bo.indentexpr = "v:lua.require'nvim-treesitter'.indentexpr()" end + end --- NOTE: You can add your own plugins, configuration, etc from `lua/custom/plugins/*.lua` --- --- Uncomment the following line and add your plugins to `lua/custom/plugins/*.lua` to get going. --- require 'custom.plugins' + local available_parsers = require('nvim-treesitter').get_available() + 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 + + local installed_parsers = require('nvim-treesitter').get_installed 'parsers' + + if vim.tbl_contains(installed_parsers, language) then + -- Enable the parser if it is already installed + treesitter_try_attach(buf, language) + elseif vim.tbl_contains(available_parsers, language) then + -- If a parser is available in `nvim-treesitter`, auto-install it and enable it after the installation is done + require('nvim-treesitter').install(language):await(function() treesitter_try_attach(buf, language) end) + else + -- Try to enable treesitter features in case the parser exists but is not available from `nvim-treesitter` + treesitter_try_attach(buf, language) + end + end, + }) +end + +-- ============================================================ +-- SECTION 9: OPTIONAL EXAMPLES / NEXT STEPS +-- kickstart.plugins.* examples +-- ============================================================ +do + -- 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.indent_line' + -- require 'kickstart.plugins.lint' + -- require 'kickstart.plugins.autopairs' + -- require 'kickstart.plugins.neo-tree' + -- require 'kickstart.plugins.gitsigns' -- adds gitsigns recommended keymaps + + -- NOTE: You can add your own plugins, configuration, etc from `lua/custom/plugins/*.lua` + -- + -- Uncomment the following line and add your plugins to `lua/custom/plugins/*.lua` to get going. + -- require 'custom.plugins' +end -- The line beneath this is called `modeline`. See `:help modeline` -- vim: ts=2 sts=2 sw=2 et