-- Run with `nvim -u repro.lua` vim.env.LAZY_STDPATH = '.repro' load(vim.fn.system 'curl -s https://raw.githubusercontent.com/folke/lazy.nvim/main/bootstrap.lua')() ---@diagnostic disable-next-line: missing-fields require('lazy.minit').repro { spec = { { 'saghen/blink.cmp', -- please test on `main` if possible -- otherwise, remove this line and set `version = '*'` version = '*', -- build = 'cargo build --release', dependencies = { 'rafamadriz/friendly-snippets' }, ---@module 'blink.cmp' ---@type blink.cmp.Config opts = { completion = { documentation = { auto_show = true }, list = { selection = { preselect = false, }, }, }, keymap = { preset = 'enter', [''] = { 'select_next', 'fallback' }, [''] = { 'select_prev', 'fallback' }, }, appearance = { nerd_font_variant = 'normal', }, sources = { -- add lazydev to your completion providers default = { 'lazydev', 'lsp', 'path', 'snippets', 'buffer' }, providers = { lazydev = { name = 'LazyDev', module = 'lazydev.integrations.blink', -- make lazydev completions top priority (see `:h blink.cmp`) score_offset = 100, }, }, }, }, opts_extend = { 'sources.default' }, }, { 'neovim/nvim-lspconfig', dependencies = { { 'folke/lazydev.nvim', opts = {} }, { 'j-hui/fidget.nvim', opts = {} }, 'saghen/blink.cmp', 'williamboman/mason.nvim', 'williamboman/mason-lspconfig.nvim', 'WhoIsSethDaniel/mason-tool-installer.nvim', }, opts = { servers = { lua_ls = {}, gdscript = { cmd = { 'ncat', '127.0.0.1', '6005' }, name = 'godot', }, }, }, config = function(_, opts) local lspconfig = require 'lspconfig' for server, config in pairs(opts.servers) do -- passing config.capabilities to blink.cmp merges with the capabilities in your -- `opts[server].capabilities, if you've defined it config.capabilities = require('blink.cmp').get_lsp_capabilities() lspconfig[server].setup(config) end vim.api.nvim_create_autocmd('LspAttach', { group = vim.api.nvim_create_augroup('kickstart-lsp-attach', { clear = true }), callback = function(event) -- Automatically highlight copies of the hovered word and then clear on cursor move local client = vim.lsp.get_client_by_id(event.data.client_id) if client and client.server_capabilities.documentHighlightProvider then vim.api.nvim_create_autocmd({ 'CursorHold', 'CursorHoldI' }, { buffer = event.buf, callback = vim.lsp.buf.document_highlight, }) vim.api.nvim_create_autocmd({ 'CursorMoved', 'CursorMovedI' }, { buffer = event.buf, callback = vim.lsp.buf.clear_references, }) end end, }) local servers = { clangd = {}, -- gopls = {}, -- pyright = {}, rust_analyzer = {}, powershell_es = {}, -- ... etc. See `:help lspconfig-all` for a list of all the pre-configured LSPs -- -- Some languages (like typescript) have entire language plugins that can be useful: -- https://github.com/pmizio/typescript-tools.nvim -- -- But for many setups, the LSP (`tsserver`) will work just fine -- tsserver = {}, -- lua_ls = { -- cmd = {...}, -- filetypes = { ...}, -- capabilities = {}, settings = { Lua = { completion = { callSnippet = 'Replace', }, -- You can toggle below to ignore Lua_LS's noisy `missing-fields` warnings diagnostics = { disable = { 'missing-fields' } }, }, }, }, } require('mason').setup() local ensure_installed = vim.tbl_keys(servers or {}) vim.list_extend(ensure_installed, { 'stylua', -- Used to format Lua code }) require('mason-tool-installer').setup { ensure_installed = ensure_installed } require('mason-lspconfig').setup { handlers = { function(server_name) local server = servers[server_name] or {} server.capabilities = require('blink.cmp').get_lsp_capabilities(server.capabilities) require('lspconfig')[server_name].setup(server) end, powershell_es = function() local lspconfig = require 'lspconfig' lspconfig.powershell_es.setup { init_options = { enableProfileLoading = false }, filetypes = { 'ps1' }, on_attach = function(client, bufnr) vim.api.nvim_buf_set_option(bufnr, 'omnifunc', 'v:lua.vim.lsp.omnifunc') end, settings = { powershell = { codeFormatting = { Preset = 'OTBS' } } }, } end, }, } end, }, { -- DAP for Godot - https://docs.godotengine.org/en/stable/tutorials/editor/external_editor.html#lsp-dap-support 'mfussenegger/nvim-dap', config = function() local dap = require 'dap' dap.adapters.godot = { type = 'server', host = '127.0.0.1', port = 6006, } dap.configurations.gdscript = { { launch_game_instance = false, launch_scene = false, name = 'Launch scene', project = '${workspaceFolder}', request = 'launch', type = 'godot', }, } end, }, { -- Useful plugin to show you pending keybinds. 'folke/which-key.nvim', event = 'VimEnter', -- Sets the loading event to 'VimEnter' opts = { icons = { -- set icon mappings to true if you have a Nerd Font mappings = vim.g.have_nerd_font, -- If you are using a Nerd Font: set icons.keys to an empty table which will use the -- default whick-key.nvim defined Nerd Font icons, otherwise define a string table keys = vim.g.have_nerd_font and {} or { Up = ' ', Down = ' ', Left = ' ', Right = ' ', C = ' ', M = ' ', D = ' ', S = ' ', CR = ' ', Esc = ' ', ScrollWheelDown = ' ', ScrollWheelUp = ' ', NL = ' ', BS = ' ', Space = ' ', Tab = ' ', F1 = '', F2 = '', F3 = '', F4 = '', F5 = '', F6 = '', F7 = '', F8 = '', F9 = '', F10 = '', F11 = '', F12 = '', }, }, -- Document existing key chains spec = { { 'c', group = '[C]ode', mode = { 'n', 'x' } }, { 'd', group = '[D]ocument' }, { 'r', group = '[R]ename' }, { 's', group = '[S]earch' }, { 'w', group = '[W]orkspace' }, { 't', group = '[T]oggle' }, { 'h', group = 'Git [H]unk', mode = { 'n', 'v' } }, }, }, }, { -- Autoformat 'stevearc/conform.nvim', lazy = false, keys = { { 'f', function() require('conform').format { async = true, lsp_fallback = true } end, mode = '', desc = '[F]ormat buffer', }, }, opts = { notify_on_error = false, format_on_save = function(bufnr) -- Disable "format_on_save lsp_fallback" for languages that don't -- have a well standardized coding style. You can add additional -- languages here or re-enable it for the disabled ones. local disable_filetypes = { c = true, cpp = true } return { timeout_ms = 500, lsp_fallback = not disable_filetypes[vim.bo[bufnr].filetype], } end, formatters_by_ft = { lua = { 'stylua' }, -- Conform can also run multiple formatters sequentially -- python = { "isort", "black" }, -- -- You can use a sub-list to tell conform to run *until* a formatter -- is found. -- javascript = { { "prettierd", "prettier" } }, }, }, }, { -- Install cutpuccin colorscheme 'catppuccin/nvim', name = 'cutppuccin', priority = 1000, }, { 'folke/todo-comments.nvim', event = 'VimEnter', dependencies = { 'nvim-lua/plenary.nvim' }, opts = { signs = false } }, { -- Collection of various small independent plugins/modules 'echasnovski/mini.nvim', config = function() -- Better Around/Inside textobjects -- -- Examples: -- - va) - [V]isually select [A]round [)]paren -- - yinq - [Y]ank [I]nside [N]ext [']quote -- - ci' - [C]hange [I]nside [']quote require('mini.ai').setup { n_lines = 500 } -- Add/delete/replace surroundings (brackets, quotes, etc.) -- -- - saiw) - [S]urround [A]dd [I]nner [W]ord [)]Paren -- - sd' - [S]urround [D]elete [']quotes -- - sr)' - [S]urround [R]eplace [)] ['] require('mini.surround').setup() -- Simple and easy statusline. -- You could remove this setup call if you don't like it, -- and try some other statusline plugin local statusline = require 'mini.statusline' -- set use_icons to true if you have a Nerd Font statusline.setup { use_icons = vim.g.have_nerd_font } -- You can configure sections in the statusline by overriding their -- default behavior. For example, here we set the section for -- cursor location to LINE:COLUMN ---@diagnostic disable-next-line: duplicate-set-field statusline.section_location = function() return '%2l:%-2v' end -- ... and there is more! -- Check out: https://github.com/echasnovski/mini.nvim end, }, { -- Highlight, edit, and navigate code 'nvim-treesitter/nvim-treesitter', build = ':TSUpdate', opts = { ensure_installed = { 'bash', 'c', 'html', 'lua', 'luadoc', 'markdown', 'markdown_inline', 'vim', 'vimdoc', 'toml', 'css' }, -- Autoinstall languages that are not installed auto_install = true, highlight = { enable = true, -- Some languages depend on vim's regex highlighting system (such as Ruby) for indent rules. -- If you are experiencing weird indenting issues, add the language to -- the list of additional_vim_regex_highlighting and disabled languages for indent. additional_vim_regex_highlighting = { 'ruby' }, }, indent = { enable = true, disable = { 'ruby' } }, }, config = function(_, opts) -- [[ Configure Treesitter ]] See `:help nvim-treesitter` ---@diagnostic disable-next-line: missing-fields require('nvim-treesitter.configs').setup(opts) -- There are additional nvim-treesitter modules that you can use to interact -- with nvim-treesitter. You should go explore a few and see what interests you: -- -- - Incremental selection: Included, see `:help nvim-treesitter-incremental-selection-mod` -- - Show your current context: https://github.com/nvim-treesitter/nvim-treesitter-context -- - Treesitter + textobjects: https://github.com/nvim-treesitter/nvim-treesitter-textobjects end, }, require 'kickstart.plugins.debug', { -- Linting 'mfussenegger/nvim-lint', event = { 'BufReadPre', 'BufNewFile' }, config = function() local lint = require 'lint' lint.linters_by_ft = { markdown = { 'markdownlint' }, } -- To allow other plugins to add linters to require('lint').linters_by_ft, -- instead set linters_by_ft like this: -- lint.linters_by_ft = lint.linters_by_ft or {} -- lint.linters_by_ft['markdown'] = { 'markdownlint' } -- -- However, note that this will enable a set of default linters, -- which will cause errors unless these tools are available: -- { -- clojure = { "clj-kondo" }, -- dockerfile = { "hadolint" }, -- inko = { "inko" }, -- janet = { "janet" }, -- json = { "jsonlint" }, -- markdown = { "vale" }, -- rst = { "vale" }, -- ruby = { "ruby" }, -- terraform = { "tflint" }, -- text = { "vale" } -- } -- -- You can disable the default linters by setting their filetypes to nil: -- lint.linters_by_ft['clojure'] = nil -- lint.linters_by_ft['dockerfile'] = nil -- lint.linters_by_ft['inko'] = nil -- lint.linters_by_ft['janet'] = nil -- lint.linters_by_ft['json'] = nil -- lint.linters_by_ft['markdown'] = nil -- lint.linters_by_ft['rst'] = nil -- lint.linters_by_ft['ruby'] = nil -- lint.linters_by_ft['terraform'] = nil -- lint.linters_by_ft['text'] = nil -- Create autocommand which carries out the actual linting -- on the specified events. local lint_augroup = vim.api.nvim_create_augroup('lint', { clear = true }) vim.api.nvim_create_autocmd({ 'BufEnter', 'BufWritePost', 'InsertLeave' }, { group = lint_augroup, callback = function() require('lint').try_lint() end, }) end, }, { -- NOTE: Yes, you can install new plugins here! 'mfussenegger/nvim-dap', -- NOTE: And you can specify dependencies as well dependencies = { -- Creates a beautiful debugger UI 'rcarriga/nvim-dap-ui', -- Required dependency for nvim-dap-ui 'nvim-neotest/nvim-nio', -- Installs the debug adapters for you 'williamboman/mason.nvim', 'jay-babu/mason-nvim-dap.nvim', -- Add your own debuggers here 'leoluz/nvim-dap-go', }, config = function() local dap = require 'dap' local dapui = require 'dapui' require('mason-nvim-dap').setup { -- Makes a best effort to setup the various debuggers with -- reasonable debug configurations automatic_setup = true, -- You can provide additional configuration to the handlers, -- see mason-nvim-dap README for more information handlers = {}, -- You'll need to check that you have the required things installed -- online, please don't ask me how to install them :) ensure_installed = { -- Update this to ensure that you have the debuggers for the langs you want 'clangd', 'json-lsp', 'rust-analyzer', 'lua-language-server', 'stylua', 'xmlformatter', }, } -- Basic debugging keymaps, feel free to change to your liking! vim.keymap.set('n', '', dap.continue, { desc = 'Debug: Start/Continue' }) vim.keymap.set('n', '', dap.step_into, { desc = 'Debug: Step Into' }) vim.keymap.set('n', '', dap.step_over, { desc = 'Debug: Step Over' }) vim.keymap.set('n', '', dap.step_out, { desc = 'Debug: Step Out' }) vim.keymap.set('n', 'b', dap.toggle_breakpoint, { desc = 'Debug: Toggle Breakpoint' }) vim.keymap.set('n', 'B', function() dap.set_breakpoint(vim.fn.input 'Breakpoint condition: ') end, { desc = 'Debug: Set Breakpoint' }) -- Dap UI setup -- For more information, see |:help nvim-dap-ui| dapui.setup { -- Set icons to characters that are more likely to work in every terminal. -- Feel free to remove or use ones that you like more! :) -- Don't feel like these are good choices. icons = { expanded = '▾', collapsed = '▸', current_frame = '*' }, controls = { icons = { pause = '⏸', play = '▶', step_into = '⏎', step_over = '⏭', step_out = '⏮', step_back = 'b', run_last = '▶▶', terminate = '⏹', disconnect = '⏏', }, }, } -- Toggle to see last session result. Without this, you can't see session output in case of unhandled exception. vim.keymap.set('n', '', dapui.toggle, { desc = 'Debug: See last session result.' }) dap.listeners.after.event_initialized['dapui_config'] = dapui.open dap.listeners.before.event_terminated['dapui_config'] = dapui.close dap.listeners.before.event_exited['dapui_config'] = dapui.close -- Install golang specific config require('dap-go').setup() end, }, { 'saghen/blink.nvim', build = 'cargo build --release', -- for delimiters keys = { -- chartoggle { ';', function() require('blink.chartoggle').toggle_char_eol ';' end, mode = { 'n', 'v' }, desc = 'Toggle ; at eol', }, { ',', function() require('blink.chartoggle').toggle_char_eol ',' end, mode = { 'n', 'v' }, desc = 'Toggle , at eol', }, --[[ -- tree { '', 'BlinkTree reveal', desc = 'Reveal current file in tree' }, { 'E', 'BlinkTree toggle', desc = 'Reveal current file in tree' }, { 'e', 'BlinkTree toggle-focus', desc = 'Toggle file tree focus' }, --]] }, -- all modules handle lazy loading internally lazy = false, opts = { chartoggle = { enabled = true }, indent = { enabled = false }, tree = { enabled = false }, }, }, { -- FZF (Telescope replacement) 'ibhagwan/fzf-lua', -- optional for icon support dependencies = { 'nvim-tree/nvim-web-devicons' }, -- or if using mini.icons/mini.nvim -- dependencies = { 'echasnovski/mini.icons' }, opts = {}, -- [[ fzf keybinds]] config = function() local fzf = require 'fzf-lua' vim.keymap.set('n', 'sw', fzf.grep_cword, { desc = '[S]earch [W]ord' }) vim.keymap.set('n', 'sf', fzf.files, { desc = '[S]earch [F]iles' }) vim.keymap.set('n', 'sg', fzf.live_grep, { desc = '[S]earch by [G]rep' }) vim.keymap.set('n', 'sg', fzf.live_grep, { desc = '[S]earch by [G]rep' }) vim.keymap.set('n', 'sr', fzf.resume, { desc = '[S]earch [R]esume' }) vim.keymap.set('n', '/', fzf.blines, { desc = '[/] Fuzzily search in current buffer' }) end, }, }, } vim.g.mapleader = ' ' vim.g.maplocalleader = ' ' vim.g.have_nerd_font = true vim.opt.number = true vim.opt.relativenumber = true vim.opt.mouse = 'a' vim.opt.showmode = false vim.schedule(function() vim.opt.clipboard = 'unnamedplus' end) vim.opt.breakindent = true vim.opt.undofile = true vim.opt.ignorecase = true vim.opt.signcolumn = 'yes' vim.opt.smartcase = true vim.opt.updatetime = 250 vim.opt.timeoutlen = 1500 vim.opt.splitright = true vim.opt.list = true vim.opt.inccommand = 'split' vim.opt.cursorline = true vim.opt.scrolloff = 10 vim.opt.listchars = { tab = ' ', trail = '·', nbsp = '␣' } vim.opt.splitbelow = true vim.opt.winborder = 'rounded' vim.opt.hlsearch = true vim.keymap.set('n', '', 'nohlsearch') 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.highlight.on_yank() end, }) vim.cmd.colorscheme 'catppuccin-mocha' vim.cmd.hi 'Comment gui=none' -- health.lua local check_version = function() local verstr = string.format('%s.%s.%s', vim.version().major, vim.version().minor, vim.version().patch) if not vim.version.cmp then vim.health.error(string.format("Neovim out of date: '%s'. Upgrade to latest stable or nightly", verstr)) return end if vim.version.cmp(vim.version(), { 0, 9, 4 }) >= 0 then vim.health.ok(string.format("Neovim version is: '%s'", verstr)) else vim.health.error(string.format("Neovim out of date: '%s'. Upgrade to latest stable or nightly", verstr)) end end local check_external_reqs = function() -- Basic utils: `git`, `make`, `unzip` for _, exe in ipairs { 'git', 'make', 'unzip', 'rg' } do local is_executable = vim.fn.executable(exe) == 1 if is_executable then vim.health.ok(string.format("Found executable: '%s'", exe)) else vim.health.warn(string.format("Could not find executable: '%s'", exe)) end end return true end return { check = function() vim.health.start 'kickstart.nvim' vim.health.info [[NOTE: Not every warning is a 'must-fix' in `:checkhealth` Fix only warnings for plugins and languages you intend to use. Mason will give warnings for languages that are not installed. You do not need to install, unless you want to use those languages!]] local uv = vim.uv or vim.loop vim.health.info('System Information: ' .. vim.inspect(uv.os_uname())) check_version() check_external_reqs() end, }