From cc3d4d53760cf5f9589bbe74314b53dbe4c2b53d Mon Sep 17 00:00:00 2001 From: Patrick Pagni Date: Thu, 28 May 2026 10:38:59 +0100 Subject: [PATCH 1/8] backup: vim.pack config before lazy.nvim migration --- TEST | 24 ++++++++++++++++++++++ config/lazy.lua | 35 +++++++++++++++++++++++++++++++++ init.lua | 27 +++++-------------------- lazy-lock.json | 5 +++++ lua/custom/plugins/claude.lua | 24 ++++++++++++++++++++++ lua/custom/plugins/init.lua | 12 ++++++----- lua/custom/plugins/lsp.lua | 18 +++++++++++++++++ lua/custom/plugins/markdown.lua | 10 ++++++++++ lua/custom/plugins/notebook.lua | 25 +++++++++++++++++++++++ lua/custom/plugins/oil.lua | 7 +++++++ lua/custom/plugins/themes.lua | 21 ++++++++++++++++++++ 11 files changed, 181 insertions(+), 27 deletions(-) create mode 100644 TEST create mode 100644 config/lazy.lua create mode 100644 lazy-lock.json create mode 100644 lua/custom/plugins/claude.lua create mode 100644 lua/custom/plugins/lsp.lua create mode 100644 lua/custom/plugins/markdown.lua create mode 100644 lua/custom/plugins/notebook.lua create mode 100644 lua/custom/plugins/oil.lua create mode 100644 lua/custom/plugins/themes.lua diff --git a/TEST b/TEST new file mode 100644 index 00000000000..12d9ac99501 --- /dev/null +++ b/TEST @@ -0,0 +1,24 @@ + 1. Move the cursor to this line. + + 2. Press [v](v) and move the cursor to the fifth item below. Notice that the + text is highlighted. + + 3. Press the `:`{normal} character. At the bottom of the screen + + `:'<,'>`{vim} + + will appear. + + 4. Type + + `w TEST`{vim} + + where TEST is a filename that does not exist yet. Verify that you see + + `:'<,'>w TEST`{vim} + + before you press ``{normal}. + + 5. Neovim will write the selected lines to the file TEST. Use `:!{unix:(ls),win:(dir)}`{vim} to see it. + Do not remove it yet! We will use it in the next lesson. + diff --git a/config/lazy.lua b/config/lazy.lua new file mode 100644 index 00000000000..f5ee74c9511 --- /dev/null +++ b/config/lazy.lua @@ -0,0 +1,35 @@ +-- Bootstrap lazy.nvim +local lazypath = vim.fn.stdpath("data") .. "/lazy/lazy.nvim" +if not (vim.uv or vim.loop).fs_stat(lazypath) then + local lazyrepo = "https://github.com/folke/lazy.nvim.git" + local out = vim.fn.system({ "git", "clone", "--filter=blob:none", "--branch=stable", lazyrepo, lazypath }) + if vim.v.shell_error ~= 0 then + vim.api.nvim_echo({ + { "Failed to clone lazy.nvim:\n", "ErrorMsg" }, + { out, "WarningMsg" }, + { "\nPress any key to exit..." }, + }, true, {}) + vim.fn.getchar() + os.exit(1) + end +end +vim.opt.rtp:prepend(lazypath) + +-- Make sure to setup `mapleader` and `maplocalleader` before +-- loading lazy.nvim so that mappings are correct. +-- This is also a good place to setup other settings (vim.opt) +vim.g.mapleader = " " +vim.g.maplocalleader = "\\" + +-- Setup lazy.nvim +require("lazy").setup({ + spec = { + -- import your plugins + { import = "plugins" }, + }, + -- Configure any other settings here. See the documentation for more details. + -- colorscheme that will be used when installing plugins. + install = { colorscheme = { "habamax" } }, + -- automatically check for plugin updates + checker = { enabled = true }, +}) diff --git a/init.lua b/init.lua index 5d29c72dc94..8243ef02540 100644 --- a/init.lua +++ b/init.lua @@ -99,7 +99,7 @@ do vim.g.maplocalleader = ' ' -- Set to true if you have a Nerd Font installed and selected in the terminal - vim.g.have_nerd_font = false + vim.g.have_nerd_font = true -- [[ Setting options ]] -- See `:help vim.o` @@ -377,24 +377,6 @@ do }, } - -- [[ 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`. - vim.pack.add { gh 'folke/tokyonight.nvim' } - ---@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 vim.pack.add { gh 'folke/todo-comments.nvim' } @@ -961,14 +943,15 @@ do -- 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.indent_line' + require 'kickstart.plugins.lint' -- require 'kickstart.plugins.autopairs' -- require 'kickstart.plugins.neo-tree' - -- require 'kickstart.plugins.gitsigns' -- adds gitsigns recommended keymaps + 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 diff --git a/lazy-lock.json b/lazy-lock.json new file mode 100644 index 00000000000..d1002b12beb --- /dev/null +++ b/lazy-lock.json @@ -0,0 +1,5 @@ +{ + "lazy.nvim": { "branch": "main", "commit": "306a05526ada86a7b30af95c5cc81ffba93fef97" }, + "mini.icons": { "branch": "main", "commit": "9c7b1b90b15bdd69c52f6e31889dbc9987c30ec4" }, + "oil.nvim": { "branch": "master", "commit": "0fcc83805ad11cf714a949c98c605ed717e0b83e" } +} diff --git a/lua/custom/plugins/claude.lua b/lua/custom/plugins/claude.lua new file mode 100644 index 00000000000..8360b0c9744 --- /dev/null +++ b/lua/custom/plugins/claude.lua @@ -0,0 +1,24 @@ +return { + "coder/claudecode.nvim", + dependencies = { "folke/snacks.nvim" }, + config = true, + keys = { + { "a", nil, desc = "AI/Claude Code" }, + { "ac", "ClaudeCode", desc = "Toggle Claude" }, + { "af", "ClaudeCodeFocus", desc = "Focus Claude" }, + { "ar", "ClaudeCode --resume", desc = "Resume Claude" }, + { "aC", "ClaudeCode --continue", desc = "Continue Claude" }, + { "am", "ClaudeCodeSelectModel", desc = "Select Claude model" }, + { "ab", "ClaudeCodeAdd %", desc = "Add current buffer" }, + { "as", "ClaudeCodeSend", mode = "v", desc = "Send to Claude" }, + { + "as", + "ClaudeCodeTreeAdd", + desc = "Add file", + ft = { "NvimTree", "neo-tree", "oil", "minifiles", "netrw" }, + }, + -- Diff management + { "aa", "ClaudeCodeDiffAccept", desc = "Accept diff" }, + { "ad", "ClaudeCodeDiffDeny", desc = "Deny diff" }, + }, +} diff --git a/lua/custom/plugins/init.lua b/lua/custom/plugins/init.lua index c05db465ea5..b9554a8fa5b 100644 --- a/lua/custom/plugins/init.lua +++ b/lua/custom/plugins/init.lua @@ -5,9 +5,11 @@ -- Iterate over all Lua files in the plugins directory and load them local plugins_dir = vim.fs.joinpath(vim.fn.stdpath 'config', 'lua', 'custom', 'plugins') -for file_name, type in vim.fs.dir(plugins_dir) do - if type == 'file' and file_name:match '%.lua$' and file_name ~= 'init.lua' then - local module = file_name:gsub('%.lua$', '') - require('custom.plugins.' .. module) - end + for file_name, type in vim.fs.dir(plugins_dir) do + if type == 'file' and file_name:match '%.lua$' and file_name ~= 'init.lua' then + local module = file_name:gsub('%.lua$', '') + require('custom.plugins.' .. module) + end end + +--return {} diff --git a/lua/custom/plugins/lsp.lua b/lua/custom/plugins/lsp.lua new file mode 100644 index 00000000000..b725d51805b --- /dev/null +++ b/lua/custom/plugins/lsp.lua @@ -0,0 +1,18 @@ +-- Define the configuration for the dbt language server +vim.lsp.config('dbt', { + -- The command to start the server + -- Ensure 'dbt-language-server' is in your system $PATH + cmd = { "dbt-language-server" }, + + -- The filetypes this server should attach to + filetypes = { "sql", "yaml" }, + + -- How to find the project root (replaces util.root_pattern) + root_markers = { "dbt_project.yml" }, + + -- General settings (standard for most servers) + settings = {}, +}) + +-- Tell Neovim to actually use/enable this server +vim.lsp.enable('dbt') diff --git a/lua/custom/plugins/markdown.lua b/lua/custom/plugins/markdown.lua new file mode 100644 index 00000000000..f06a4bcfa96 --- /dev/null +++ b/lua/custom/plugins/markdown.lua @@ -0,0 +1,10 @@ +return { + 'brianhuster/live-preview.nvim', + dependencies = { + -- You can choose one of the following pickers + 'nvim-telescope/telescope.nvim', + 'ibhagwan/fzf-lua', + 'echasnovski/mini.pick', + 'folke/snacks.nvim', + }, +} diff --git a/lua/custom/plugins/notebook.lua b/lua/custom/plugins/notebook.lua new file mode 100644 index 00000000000..d85e37b29e9 --- /dev/null +++ b/lua/custom/plugins/notebook.lua @@ -0,0 +1,25 @@ +return { + { + "benlubas/molten-nvim", + version = "^1.0.0", -- use version <2.0.0 to avoid breaking changes + dependencies = { "3rd/image.nvim" }, + build = ":UpdateRemotePlugins", + init = function() + -- these are examples, not defaults. Please see the readme + vim.g.molten_image_provider = "image.nvim" + vim.g.molten_output_win_max_height = 20 + end, + }, + { + 'willothy/wezterm.nvim', + config = true + }, + + { + "3rd/image.nvim", + build = false, -- so that it doesn't build the rock https://github.com/3rd/image.nvim/issues/91#issuecomment-2453430239 + opts = { + processor = "magick_cli", + } + } +} diff --git a/lua/custom/plugins/oil.lua b/lua/custom/plugins/oil.lua new file mode 100644 index 00000000000..0a6ec428e51 --- /dev/null +++ b/lua/custom/plugins/oil.lua @@ -0,0 +1,7 @@ +-- Initialize the icons (optional, but highly recommended for Oil) +require('mini.icons').setup({}) + +-- Initialize and configure Oil +require('oil').setup({ + -- You can add any custom oil options here later! +}) diff --git a/lua/custom/plugins/themes.lua b/lua/custom/plugins/themes.lua new file mode 100644 index 00000000000..45654b295cc --- /dev/null +++ b/lua/custom/plugins/themes.lua @@ -0,0 +1,21 @@ +-- [[ 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`. +vim.pack.add { 'folke/tokyonight.nvim' } +---@diagnostic disable-next-line: missing-fields +require('tokyonight').setup { + styles = { + comments = { italic = false }, -- Disable italics in comments + }, +} + +vim.pack.add({ + { src = "https://gitlab.com/motaz-shokry/gruvbox.nvim" } +}) + +require("gruvbox").setup() -- for configs +vim.cmd("colorscheme gruvbox-medium") -- apply the theme + From 01f1b78aedf6b888f9164196f253089bf727c9a3 Mon Sep 17 00:00:00 2001 From: Patrick Pagni Date: Thu, 28 May 2026 10:54:43 +0100 Subject: [PATCH 2/8] feat: migrate from vim.pack to lazy.nvim Replace vim.pack bootstrap and all vim.pack.add calls with lazy.nvim. Convert kickstart and custom plugin files to return lazy specs. Fix wezterm.nvim to only load when wezterm executable is present. Co-Authored-By: Claude Sonnet 4 --- init.lua | 998 +++++++++----------------- lazy-lock.json | 34 +- lua/custom/plugins/init.lua | 18 +- lua/custom/plugins/lsp.lua | 21 +- lua/custom/plugins/notebook.lua | 1 + lua/custom/plugins/oil.lua | 15 +- lua/custom/plugins/themes.lua | 36 +- lua/kickstart/plugins/gitsigns.lua | 94 +-- lua/kickstart/plugins/indent_line.lua | 11 +- lua/kickstart/plugins/lint.lua | 67 +- 10 files changed, 470 insertions(+), 825 deletions(-) diff --git a/init.lua b/init.lua index 8243ef02540..f1cb29f4eeb 100644 --- a/init.lua +++ b/init.lua @@ -248,713 +248,385 @@ do end -- ============================================================ --- SECTION 2: PLUGIN MANAGER INTRO --- vim.pack intro, build hooks +-- SECTION 2: PLUGIN MANAGER (lazy.nvim) +-- Bootstrap, install, and configure all plugins -- ============================================================ -do - -- [[ Intro to `vim.pack` ]] - -- `vim.pack` is a new plugin manager built into Neovim, - -- which provides a Lua interface for installing and managing plugins. - -- - -- See `:help vim.pack`, `:help vim.pack-examples` or the - -- excellent blog post from the creator of vim.pack and mini.nvim: - -- https://echasnovski.com/blog/2026-03-13-a-guide-to-vim-pack - -- - -- To inspect plugin state and pending updates, run - -- :lua vim.pack.update(nil, { offline = true }) - -- - -- To update plugins, run - -- :lua vim.pack.update() - -- - -- - -- Throughout the rest of the config there will be examples - -- of how to install and configure plugins using `vim.pack`. - -- - -- In this section we set up some autocommands to run build - -- steps for certain plugins after they are installed or updated. - - local function run_build(name, cmd, cwd) - local result = vim.system(cmd, { cwd = cwd }):wait() - if result.code ~= 0 then - local stderr = result.stderr or '' - local stdout = result.stdout or '' - local output = stderr ~= '' and stderr or stdout - if output == '' then output = 'No output from build command.' end - vim.notify(('Build failed for %s:\n%s'):format(name, output), vim.log.levels.ERROR) - end - end - -- This autocommand runs after a plugin is installed or updated and - -- runs the appropriate build command for that plugin if necessary. - -- - -- See `:help vim.pack-events` - vim.api.nvim_create_autocmd('PackChanged', { - callback = function(ev) - local name = ev.data.spec.name - local kind = ev.data.kind - if kind ~= 'install' and kind ~= 'update' then return end - - if name == 'telescope-fzf-native.nvim' and vim.fn.executable 'make' == 1 then - run_build(name, { 'make' }, ev.data.path) - return - end - - if name == 'LuaSnip' then - if vim.fn.has 'win32' ~= 1 and vim.fn.executable 'make' == 1 then run_build(name, { 'make', 'install_jsregexp' }, ev.data.path) end - return - end - - if name == 'nvim-treesitter' then - if not ev.data.active then vim.cmd.packadd 'nvim-treesitter' end - vim.cmd 'TSUpdate' - return - end - end, +-- Bootstrap lazy.nvim +local lazypath = vim.fn.stdpath('data') .. '/lazy/lazy.nvim' +if not (vim.uv or vim.loop).fs_stat(lazypath) then + local out = vim.fn.system({ + 'git', 'clone', '--filter=blob:none', '--branch=stable', + 'https://github.com/folke/lazy.nvim.git', lazypath, }) + if vim.v.shell_error ~= 0 then + vim.api.nvim_echo({ { 'Failed to clone lazy.nvim:\n', 'ErrorMsg' }, { out, 'WarningMsg' }, { '\nPress any key to exit...' } }, true, {}) + vim.fn.getchar() + os.exit(1) + end end +vim.opt.rtp:prepend(lazypath) ----Because most plugins are hosted on GitHub, you can use the helper ----function to have less repetition in the following sections. ----@param repo string ----@return string -local function gh(repo) return 'https://github.com/' .. repo end +require('lazy').setup({ + spec = { + -- ============================================================ + -- SECTION 3: UI / CORE UX PLUGINS + -- ============================================================ --- ============================================================ --- SECTION 3: UI / CORE UX PLUGINS --- guess-indent, gitsigns, which-key, colorscheme, todo-comments, mini modules --- ============================================================ -do - -- [[ Installing and Configuring Plugins ]] - -- - -- To install a plugin simply call `vim.pack.add` with its git url. - -- This will download the default branch of the plugin, which will usually be `main` or `master` - -- You can also have more advanced specs, which we will talk about later. - -- - -- For most plugins its not enough to install them, you also need to call their `.setup()` to start them. - -- - -- For example, lets say we want to install `guess-indent.nvim` - a plugin for - -- automatically detecting and setting the indentation. - -- - -- We first install it from https://github.com/NMAC427/guess-indent.nvim - -- and then call its `setup()` function to start it with default settings. - vim.pack.add { gh 'NMAC427/guess-indent.nvim' } - require('guess-indent').setup {} + { 'NMAC427/guess-indent.nvim', opts = {} }, - -- Because lua is a real programming language, you can also have some logic to your installation - - -- like only installing a plugin if a condition is met. - -- - -- Here we only install `nvim-web-devicons` (which adds pretty icons) if we have a Nerd Font, - -- since otherwise the icons won't display properly. - if vim.g.have_nerd_font then vim.pack.add { gh 'nvim-tree/nvim-web-devicons' } end + { + 'nvim-tree/nvim-web-devicons', + cond = vim.g.have_nerd_font, + }, - -- Here is a more advanced configuration example that passes 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 - vim.pack.add { gh 'lewis6991/gitsigns.nvim' } - 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 + { + 'lewis6991/gitsigns.nvim', + opts = { + signs = { + add = { text = '+' }, + change = { text = '~' }, + delete = { text = '_' }, + topdelete = { text = '‾' }, + changedelete = { text = '~' }, + }, + }, }, - } - -- Useful plugin to show you pending keybinds. - vim.pack.add { gh 'folke/which-key.nvim' } - 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' } }, + { + 'folke/which-key.nvim', + event = 'VimEnter', + opts = { + delay = 0, + icons = { mappings = vim.g.have_nerd_font }, + spec = { + { 's', group = '[S]earch', mode = { 'n', 'v' } }, + { 't', group = '[T]oggle' }, + { 'h', group = 'Git [H]unk', mode = { 'n', 'v' } }, + { 'gr', group = 'LSP Actions', mode = { 'n' } }, + }, + }, }, - } + { 'folke/todo-comments.nvim', opts = { signs = false } }, - -- Highlight todo, notes, etc in comments - vim.pack.add { gh 'folke/todo-comments.nvim' } - require('todo-comments').setup { signs = false } + { + 'nvim-mini/mini.nvim', + config = function() + require('mini.ai').setup { + mappings = { around_next = 'aa', inside_next = 'ii' }, + n_lines = 500, + } + require('mini.surround').setup() + local statusline = require 'mini.statusline' + statusline.setup { use_icons = vim.g.have_nerd_font } + ---@diagnostic disable-next-line: duplicate-set-field + statusline.section_location = function() return '%2l:%-2v' end + end, + }, - -- [[ mini.nvim ]] - -- A collection of various small independent plugins/modules - vim.pack.add { gh 'nvim-mini/mini.nvim' } + -- ============================================================ + -- SECTION 4: SEARCH & NAVIGATION + -- ============================================================ + + { 'nvim-lua/plenary.nvim' }, + + { + 'nvim-telescope/telescope.nvim', + event = 'VimEnter', + dependencies = { + 'nvim-lua/plenary.nvim', + 'nvim-telescope/telescope-ui-select.nvim', + { + 'nvim-telescope/telescope-fzf-native.nvim', + build = 'make', + cond = vim.fn.executable('make') == 1, + }, + }, + config = function() + require('telescope').setup { + extensions = { + ['ui-select'] = { require('telescope.themes').get_dropdown() }, + }, + } + pcall(require('telescope').load_extension, 'fzf') + pcall(require('telescope').load_extension, 'ui-select') + + 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' }) + + vim.api.nvim_create_autocmd('LspAttach', { + group = vim.api.nvim_create_augroup('telescope-lsp-attach', { clear = true }), + callback = function(event) + local buf = event.buf + vim.keymap.set('n', 'grr', builtin.lsp_references, { buffer = buf, desc = '[G]oto [R]eferences' }) + vim.keymap.set('n', 'gri', builtin.lsp_implementations, { buffer = buf, desc = '[G]oto [I]mplementation' }) + vim.keymap.set('n', 'grd', builtin.lsp_definitions, { buffer = buf, desc = '[G]oto [D]efinition' }) + vim.keymap.set('n', 'gO', builtin.lsp_document_symbols, { buffer = buf, desc = 'Open Document Symbols' }) + vim.keymap.set('n', 'gW', builtin.lsp_dynamic_workspace_symbols, { buffer = buf, desc = 'Open Workspace Symbols' }) + vim.keymap.set('n', 'grt', builtin.lsp_type_definitions, { buffer = buf, desc = '[G]oto [T]ype Definition' }) + end, + }) - -- 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, - } + vim.keymap.set('n', '/', function() + builtin.current_buffer_fuzzy_find(require('telescope.themes').get_dropdown { winblend = 10, previewer = false }) + end, { desc = '[/] Fuzzily search in current buffer' }) - -- 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 + 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' }) --- ============================================================ --- 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! - - ---@type (string|vim.pack.Spec)[] - local telescope_plugins = { - gh 'nvim-lua/plenary.nvim', - gh 'nvim-telescope/telescope.nvim', - gh 'nvim-telescope/telescope-ui-select.nvim', - } - if vim.fn.executable 'make' == 1 then table.insert(telescope_plugins, gh 'nvim-telescope/telescope-fzf-native.nvim') end - - -- NOTE: You can install multiple plugins at once - vim.pack.add(telescope_plugins) - - -- 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() }, + vim.keymap.set('n', 'sn', function() builtin.find_files { cwd = vim.fn.stdpath 'config' } end, { desc = '[S]earch [N]eovim files' }) + end, }, - } - -- 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, - }) + -- ============================================================ + -- SECTION 5: LSP + -- ============================================================ - -- 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 + { 'j-hui/fidget.nvim', opts = {} }, --- ============================================================ --- 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. - vim.pack.add { gh 'j-hui/fidget.nvim' } - 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, + { + 'neovim/nvim-lspconfig', + dependencies = { + 'mason-org/mason.nvim', + 'mason-org/mason-lspconfig.nvim', + 'WhoIsSethDaniel/mason-tool-installer.nvim', + }, + config = function() + vim.api.nvim_create_autocmd('LspAttach', { + group = vim.api.nvim_create_augroup('kickstart-lsp-attach', { clear = true }), + callback = function(event) + local map = function(keys, func, desc, mode) + mode = mode or 'n' + vim.keymap.set(mode, keys, func, { buffer = event.buf, desc = 'LSP: ' .. desc }) + end + + map('grn', vim.lsp.buf.rename, '[R]e[n]ame') + map('gra', vim.lsp.buf.code_action, '[G]oto Code [A]ction', { 'n', 'x' }) + map('grD', vim.lsp.buf.declaration, '[G]oto [D]eclaration') + + 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 + + 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, }) - vim.api.nvim_create_autocmd({ 'CursorMoved', 'CursorMovedI' }, { - buffer = event.buf, - group = highlight_augroup, - callback = vim.lsp.buf.clear_references, - }) + ---@type table + local servers = { + -- clangd = {}, + -- gopls = {}, + -- pyright = {}, + -- rust_analyzer = {}, + -- ts_ls = {}, + + stylua = {}, + + lua_ls = { + on_init = function(client) + client.server_capabilities.documentFormattingProvider = false + + 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, + 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 } }, + }, + }, + } - 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, + require('mason').setup {} + + local ensure_installed = vim.tbl_keys(servers or {}) + vim.list_extend(ensure_installed, { + -- Add extra Mason tools here }) - 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, - }) + require('mason-tool-installer').setup { ensure_installed = ensure_installed } - -- 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 + for name, server in pairs(servers) do + vim.lsp.config(name, server) + vim.lsp.enable(name) end + end, + }, - client.config.settings.Lua = vim.tbl_deep_extend('force', client.config.settings.Lua, { - runtime = { - version = 'LuaJIT', - path = { 'lua/?.lua', 'lua/?/init.lua' }, + -- ============================================================ + -- SECTION 6: FORMATTING + -- ============================================================ + + { + 'stevearc/conform.nvim', + config = function() + require('conform').setup { + notify_on_error = false, + format_on_save = function(bufnr) + 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', }, - 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', - }), + formatters_by_ft = { + -- rust = { 'rustfmt' }, + -- python = { "isort", "black" }, + -- javascript = { "prettierd", "prettier", stop_after_first = true }, }, - }) + } + vim.keymap.set({ 'n', 'v' }, 'f', function() require('conform').format { async = true } end, { desc = '[F]ormat buffer' }) end, - ---@type lspconfig.settings.lua_ls - settings = { - Lua = { - format = { enable = false }, -- Disable formatting (formatting is done by stylua) - }, - }, }, - } - - vim.pack.add { - gh 'neovim/nvim-lspconfig', - gh 'mason-org/mason.nvim', - gh 'mason-org/mason-lspconfig.nvim', - gh 'WhoIsSethDaniel/mason-tool-installer.nvim', - } - - -- 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 - --- ============================================================ --- SECTION 6: FORMATTING --- conform.nvim setup and keymap --- ============================================================ -do - -- [[ Formatting ]] - vim.pack.add { gh 'stevearc/conform.nvim' } - 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 }, - }, - } - - vim.keymap.set({ 'n', 'v' }, 'f', function() require('conform').format { async = true } end, { desc = '[F]ormat buffer' }) -end --- ============================================================ --- SECTION 7: AUTOCOMPLETE & SNIPPETS --- blink.cmp and luasnip setup --- ============================================================ -do - -- [[ Snippet Engine ]] - - -- NOTE: You can also specify plugin using a version range for its git tag. - -- See `:help vim.version.range()` for more info - vim.pack.add { { src = gh 'L3MON4D3/LuaSnip', version = vim.version.range '2.*' } } - 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() - - -- [[ Autocomplete Engine ]] - vim.pack.add { { src = gh 'saghen/blink.cmp', version = vim.version.range '1.*' } } - 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 + -- ============================================================ + -- SECTION 7: AUTOCOMPLETE & SNIPPETS + -- ============================================================ + + { + 'L3MON4D3/LuaSnip', + version = '2.*', + build = (vim.fn.has('win32') ~= 1 and vim.fn.executable('make') == 1) and 'make install_jsregexp' or nil, + config = function() + require('luasnip').setup {} + -- vim.pack.add { gh 'rafamadriz/friendly-snippets' } + -- require('luasnip.loaders.from_vscode').lazy_load() + end, }, - appearance = { - -- 'mono' (default) for 'Nerd Font Mono' or 'normal' for 'Nerd Font' - -- Adjusts spacing to ensure icons are aligned - nerd_font_variant = 'mono', + { + 'saghen/blink.cmp', + version = '1.*', + dependencies = { 'L3MON4D3/LuaSnip' }, + opts = { + keymap = { preset = 'default' }, + appearance = { nerd_font_variant = 'mono' }, + completion = { + documentation = { auto_show = false, auto_show_delay_ms = 500 }, + }, + sources = { default = { 'lsp', 'path', 'snippets' } }, + snippets = { preset = 'luasnip' }, + fuzzy = { implementation = 'lua' }, + signature = { enabled = true }, + }, }, - 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 }, - }, + -- ============================================================ + -- SECTION 8: TREESITTER + -- ============================================================ + + { + 'nvim-treesitter/nvim-treesitter', + branch = 'main', + build = ':TSUpdate', + config = function() + 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) + if not vim.treesitter.language.add(language) then return end + vim.treesitter.start(buf, language) + -- vim.wo.foldexpr = 'v:lua.vim.treesitter.foldexpr()' + -- vim.wo.foldmethod = 'expr' + local has_indent_query = vim.treesitter.query.get(language, 'indents') ~= nil + if has_indent_query then vim.bo.indentexpr = "v:lua.require'nvim-treesitter'.indentexpr()" end + end - sources = { - default = { 'lsp', 'path', 'snippets' }, + 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 + treesitter_try_attach(buf, language) + elseif vim.tbl_contains(available_parsers, language) then + require('nvim-treesitter').install(language):await(function() treesitter_try_attach(buf, language) end) + else + treesitter_try_attach(buf, language) + end + end, + }) + end, }, - snippets = { preset = 'luasnip' }, - - -- 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' }, - - -- Shows a signature help window while you type arguments for a function - signature = { enabled = true }, - } -end + -- ============================================================ + -- SECTION 9: KICKSTART OPTIONAL PLUGINS + -- ============================================================ --- ============================================================ --- SECTION 8: TREESITTER --- Parser installation, syntax highlighting, folds, indentation --- ============================================================ -do - -- [[ Configure Treesitter ]] - -- Used to highlight, edit, and navigate code - -- - -- See `:help nvim-treesitter-intro` - - -- NOTE: You can also specify a branch or a specific commit - vim.pack.add { { src = gh 'nvim-treesitter/nvim-treesitter', version = 'main' } } - - -- 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 - end + { import = 'kickstart.plugins.indent_line' }, + { import = 'kickstart.plugins.lint' }, + -- { import = 'kickstart.plugins.debug' }, + -- { import = 'kickstart.plugins.autopairs' }, + -- { import = 'kickstart.plugins.neo-tree' }, + { import = 'kickstart.plugins.gitsigns' }, - 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 + -- ============================================================ + -- CUSTOM PLUGINS + -- ============================================================ --- ============================================================ --- 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. + { import = 'custom.plugins' }, + }, - -- 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 + install = { colorscheme = { 'gruvbox-medium', 'habamax' } }, + checker = { enabled = false }, +}) -- The line beneath this is called `modeline`. See `:help modeline` -- vim: ts=2 sts=2 sw=2 et diff --git a/lazy-lock.json b/lazy-lock.json index d1002b12beb..65c7e00d456 100644 --- a/lazy-lock.json +++ b/lazy-lock.json @@ -1,5 +1,35 @@ { + "LuaSnip": { "branch": "master", "commit": "642b0c595e11608b4c18219e93b88d7637af27bc" }, + "blink.cmp": { "branch": "main", "commit": "78336bc89ee5365633bcf754d93df01678b5c08f" }, + "claudecode.nvim": { "branch": "main", "commit": "102d835c964069c9c5e37abaf05ae4f9c3ee6f00" }, + "conform.nvim": { "branch": "master", "commit": "619363c30309d29ffa631e67c8183f2a72caa373" }, + "fidget.nvim": { "branch": "main", "commit": "82404b196e73a00b1727a91903beef5ddc319d22" }, + "fzf-lua": { "branch": "main", "commit": "fea9eedc6894c44d44cbb772a5cd11c93b82d7a1" }, + "gitsigns.nvim": { "branch": "main", "commit": "dd3f588bacbeb041be6facf1742e42097f62165d" }, + "gruvbox.nvim": { "branch": "main", "commit": "c14c475585494c592ef48064ad338424f15f8bad" }, + "guess-indent.nvim": { "branch": "main", "commit": "84a4987ff36798c2fc1169cbaff67960aed9776f" }, + "image.nvim": { "branch": "master", "commit": "44e07129cd0ea0c60afa7a1991d35b5765b51a6b" }, + "indent-blankline.nvim": { "branch": "master", "commit": "d28a3f70721c79e3c5f6693057ae929f3d9c0a03" }, "lazy.nvim": { "branch": "main", "commit": "306a05526ada86a7b30af95c5cc81ffba93fef97" }, - "mini.icons": { "branch": "main", "commit": "9c7b1b90b15bdd69c52f6e31889dbc9987c30ec4" }, - "oil.nvim": { "branch": "master", "commit": "0fcc83805ad11cf714a949c98c605ed717e0b83e" } + "live-preview.nvim": { "branch": "main", "commit": "c1fcf75c5f9c9c01dd392852de44204b60f1b5b1" }, + "mason-lspconfig.nvim": { "branch": "main", "commit": "7b01e2974a47d489bb92f47a41e4c0088ea8f86e" }, + "mason-tool-installer.nvim": { "branch": "main", "commit": "443f1ef8b5e6bf47045cb2217b6f748a223cf7dc" }, + "mason.nvim": { "branch": "main", "commit": "bb639d4bf385a4d89f478b83af4d770be05ab7eb" }, + "mini.nvim": { "branch": "main", "commit": "44657837c7338e52727facc85c1d95bec1f6bd7c" }, + "mini.pick": { "branch": "main", "commit": "4522d9ab65224675df2cf1ede8c12f0410aae2be" }, + "molten-nvim": { "branch": "main", "commit": "a286aa914d9a154bc359131aab788b5a077a5a99" }, + "nvim-lint": { "branch": "master", "commit": "d48f3a76189d03b2239f6df1b2f7e3fa8353743b" }, + "nvim-lspconfig": { "branch": "master", "commit": "6f76a3eeadc2ee235d74cd7d5319e95a261084af" }, + "nvim-treesitter": { "branch": "main", "commit": "4916d6592ede8c07973490d9322f187e07dfefac" }, + "nvim-web-devicons": { "branch": "master", "commit": "dfbfaa967a6f7ec50789bead7ef87e336c1fa63c" }, + "oil.nvim": { "branch": "master", "commit": "0fcc83805ad11cf714a949c98c605ed717e0b83e" }, + "plenary.nvim": { "branch": "master", "commit": "74b06c6c75e4eeb3108ec01852001636d85a932b" }, + "snacks.nvim": { "branch": "main", "commit": "882c996cf28183f4d63640de0b4c02ec886d01f2" }, + "telescope-fzf-native.nvim": { "branch": "main", "commit": "b25b749b9db64d375d782094e2b9dce53ad53a40" }, + "telescope-ui-select.nvim": { "branch": "master", "commit": "6e51d7da30bd139a6950adf2a47fda6df9fa06d2" }, + "telescope.nvim": { "branch": "master", "commit": "7d324792b7943e4aa16ad007212e6acc6f9fe335" }, + "todo-comments.nvim": { "branch": "main", "commit": "31e3c38ce9b29781e4422fc0322eb0a21f4e8668" }, + "tokyonight.nvim": { "branch": "main", "commit": "cdc07ac78467a233fd62c493de29a17e0cf2b2b6" }, + "wezterm.nvim": { "branch": "main", "commit": "032c33b621b96cc7228955b4352b48141c482098" }, + "which-key.nvim": { "branch": "main", "commit": "3aab2147e74890957785941f0c1ad87d0a44c15a" } } diff --git a/lua/custom/plugins/init.lua b/lua/custom/plugins/init.lua index b9554a8fa5b..8f7c2a8b1f7 100644 --- a/lua/custom/plugins/init.lua +++ b/lua/custom/plugins/init.lua @@ -1,15 +1,3 @@ --- You can add your own plugins here or in other files in this directory! --- I promise not to create any merge conflicts in this directory :) --- --- See the kickstart.nvim README for more information - --- Iterate over all Lua files in the plugins directory and load them -local plugins_dir = vim.fs.joinpath(vim.fn.stdpath 'config', 'lua', 'custom', 'plugins') - for file_name, type in vim.fs.dir(plugins_dir) do - if type == 'file' and file_name:match '%.lua$' and file_name ~= 'init.lua' then - local module = file_name:gsub('%.lua$', '') - require('custom.plugins.' .. module) - end -end - ---return {} +-- Lazy auto-discovers all *.lua files in this directory. +-- This file is intentionally empty (lazy imports the other files directly). +return {} diff --git a/lua/custom/plugins/lsp.lua b/lua/custom/plugins/lsp.lua index b725d51805b..9a08ce0a922 100644 --- a/lua/custom/plugins/lsp.lua +++ b/lua/custom/plugins/lsp.lua @@ -1,18 +1,11 @@ --- Define the configuration for the dbt language server +-- dbt language server (requires dbt-language-server in $PATH) +-- Uses native Neovim LSP APIs — no extra plugin needed. vim.lsp.config('dbt', { - -- The command to start the server - -- Ensure 'dbt-language-server' is in your system $PATH - cmd = { "dbt-language-server" }, - - -- The filetypes this server should attach to - filetypes = { "sql", "yaml" }, - - -- How to find the project root (replaces util.root_pattern) - root_markers = { "dbt_project.yml" }, - - -- General settings (standard for most servers) + cmd = { 'dbt-language-server' }, + filetypes = { 'sql', 'yaml' }, + root_markers = { 'dbt_project.yml' }, settings = {}, }) - --- Tell Neovim to actually use/enable this server vim.lsp.enable('dbt') + +return {} diff --git a/lua/custom/plugins/notebook.lua b/lua/custom/plugins/notebook.lua index d85e37b29e9..8214426259c 100644 --- a/lua/custom/plugins/notebook.lua +++ b/lua/custom/plugins/notebook.lua @@ -12,6 +12,7 @@ return { }, { 'willothy/wezterm.nvim', + cond = vim.fn.executable('wezterm') == 1, config = true }, diff --git a/lua/custom/plugins/oil.lua b/lua/custom/plugins/oil.lua index 0a6ec428e51..966924f2300 100644 --- a/lua/custom/plugins/oil.lua +++ b/lua/custom/plugins/oil.lua @@ -1,7 +1,8 @@ --- Initialize the icons (optional, but highly recommended for Oil) -require('mini.icons').setup({}) - --- Initialize and configure Oil -require('oil').setup({ - -- You can add any custom oil options here later! -}) +return { + 'stevearc/oil.nvim', + dependencies = { 'nvim-mini/mini.nvim' }, + config = function() + require('mini.icons').setup() + require('oil').setup() + end, +} diff --git a/lua/custom/plugins/themes.lua b/lua/custom/plugins/themes.lua index 45654b295cc..2ac7e0b0c77 100644 --- a/lua/custom/plugins/themes.lua +++ b/lua/custom/plugins/themes.lua @@ -1,21 +1,19 @@ --- [[ 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`. -vim.pack.add { 'folke/tokyonight.nvim' } ----@diagnostic disable-next-line: missing-fields -require('tokyonight').setup { - styles = { - comments = { italic = false }, -- Disable italics in comments +return { + { + 'folke/tokyonight.nvim', + opts = { + styles = { + comments = { italic = false }, + }, + }, + }, + { + 'motaz-shokry/gruvbox.nvim', + url = 'https://gitlab.com/motaz-shokry/gruvbox.nvim', + priority = 1000, + config = function() + require('gruvbox').setup() + vim.cmd('colorscheme gruvbox-medium') + end, }, } - -vim.pack.add({ - { src = "https://gitlab.com/motaz-shokry/gruvbox.nvim" } -}) - -require("gruvbox").setup() -- for configs -vim.cmd("colorscheme gruvbox-medium") -- apply the theme - diff --git a/lua/kickstart/plugins/gitsigns.lua b/lua/kickstart/plugins/gitsigns.lua index b7e40a87cfc..5701160afd1 100644 --- a/lua/kickstart/plugins/gitsigns.lua +++ b/lua/kickstart/plugins/gitsigns.lua @@ -2,56 +2,56 @@ -- NOTE: gitsigns is already included in init.lua but contains only the base -- config. This will add also the recommended keymaps. -vim.pack.add { 'https://github.com/lewis6991/gitsigns.nvim' } +return { + 'lewis6991/gitsigns.nvim', + opts = { + on_attach = function(bufnr) + local gitsigns = require 'gitsigns' -require('gitsigns').setup { - on_attach = function(bufnr) - local gitsigns = require 'gitsigns' - - local function map(mode, l, r, opts) - opts = opts or {} - opts.buffer = bufnr - vim.keymap.set(mode, l, r, opts) - end - - -- Navigation - map('n', ']c', function() - if vim.wo.diff then - vim.cmd.normal { ']c', bang = true } - else - gitsigns.nav_hunk 'next' + local function map(mode, l, r, opts) + opts = opts or {} + opts.buffer = bufnr + vim.keymap.set(mode, l, r, opts) end - end, { desc = 'Jump to next git [c]hange' }) - map('n', '[c', function() - if vim.wo.diff then - vim.cmd.normal { '[c', bang = true } - else - gitsigns.nav_hunk 'prev' - end - end, { desc = 'Jump to previous git [c]hange' }) + -- Navigation + map('n', ']c', function() + if vim.wo.diff then + vim.cmd.normal { ']c', bang = true } + else + gitsigns.nav_hunk 'next' + end + end, { desc = 'Jump to next git [c]hange' }) + + map('n', '[c', function() + if vim.wo.diff then + vim.cmd.normal { '[c', bang = true } + else + gitsigns.nav_hunk 'prev' + end + end, { desc = 'Jump to previous git [c]hange' }) - -- Actions - -- visual mode - map('v', 'hs', function() gitsigns.stage_hunk { vim.fn.line '.', vim.fn.line 'v' } end, { desc = 'git [s]tage hunk' }) - map('v', 'hr', function() gitsigns.reset_hunk { vim.fn.line '.', vim.fn.line 'v' } end, { desc = 'git [r]eset hunk' }) - -- normal mode - map('n', 'hs', gitsigns.stage_hunk, { desc = 'git [s]tage hunk' }) - map('n', 'hr', gitsigns.reset_hunk, { desc = 'git [r]eset hunk' }) - map('n', 'hS', gitsigns.stage_buffer, { desc = 'git [S]tage buffer' }) - map('n', 'hR', gitsigns.reset_buffer, { desc = 'git [R]eset buffer' }) - map('n', 'hp', gitsigns.preview_hunk, { desc = 'git [p]review hunk' }) - map('n', 'hi', gitsigns.preview_hunk_inline, { desc = 'git preview hunk [i]nline' }) - map('n', 'hb', function() gitsigns.blame_line { full = true } end, { desc = 'git [b]lame line' }) - map('n', 'hd', gitsigns.diffthis, { desc = 'git [d]iff against index' }) - map('n', 'hD', function() gitsigns.diffthis '@' end, { desc = 'git [D]iff against last commit' }) - map('n', 'hQ', function() gitsigns.setqflist 'all' end, { desc = 'git hunk [Q]uickfix list (all files in repo)' }) - map('n', 'hq', gitsigns.setqflist, { desc = 'git hunk [q]uickfix list (all changes in this file)' }) - -- Toggles - map('n', 'tb', gitsigns.toggle_current_line_blame, { desc = '[T]oggle git show [b]lame line' }) - map('n', 'tw', gitsigns.toggle_word_diff, { desc = '[T]oggle git intra-line [w]ord diff' }) + -- Actions (visual mode) + map('v', 'hs', function() gitsigns.stage_hunk { vim.fn.line '.', vim.fn.line 'v' } end, { desc = 'git [s]tage hunk' }) + map('v', 'hr', function() gitsigns.reset_hunk { vim.fn.line '.', vim.fn.line 'v' } end, { desc = 'git [r]eset hunk' }) + -- Actions (normal mode) + map('n', 'hs', gitsigns.stage_hunk, { desc = 'git [s]tage hunk' }) + map('n', 'hr', gitsigns.reset_hunk, { desc = 'git [r]eset hunk' }) + map('n', 'hS', gitsigns.stage_buffer, { desc = 'git [S]tage buffer' }) + map('n', 'hR', gitsigns.reset_buffer, { desc = 'git [R]eset buffer' }) + map('n', 'hp', gitsigns.preview_hunk, { desc = 'git [p]review hunk' }) + map('n', 'hi', gitsigns.preview_hunk_inline, { desc = 'git preview hunk [i]nline' }) + map('n', 'hb', function() gitsigns.blame_line { full = true } end, { desc = 'git [b]lame line' }) + map('n', 'hd', gitsigns.diffthis, { desc = 'git [d]iff against index' }) + map('n', 'hD', function() gitsigns.diffthis '@' end, { desc = 'git [D]iff against last commit' }) + map('n', 'hQ', function() gitsigns.setqflist 'all' end, { desc = 'git hunk [Q]uickfix list (all files in repo)' }) + map('n', 'hq', gitsigns.setqflist, { desc = 'git hunk [q]uickfix list (all changes in this file)' }) + -- Toggles + map('n', 'tb', gitsigns.toggle_current_line_blame, { desc = '[T]oggle git show [b]lame line' }) + map('n', 'tw', gitsigns.toggle_word_diff, { desc = '[T]oggle git intra-line [w]ord diff' }) - -- Text object - map({ 'o', 'x' }, 'ih', gitsigns.select_hunk) - end, + -- Text object + map({ 'o', 'x' }, 'ih', gitsigns.select_hunk) + end, + }, } diff --git a/lua/kickstart/plugins/indent_line.lua b/lua/kickstart/plugins/indent_line.lua index 7187365656e..e445b2897ad 100644 --- a/lua/kickstart/plugins/indent_line.lua +++ b/lua/kickstart/plugins/indent_line.lua @@ -1,6 +1,5 @@ --- Add indentation guides even on blank lines - --- Enable `lukas-reineke/indent-blankline.nvim` --- See `:help ibl` -vim.pack.add { 'https://github.com/lukas-reineke/indent-blankline.nvim' } -require('ibl').setup {} +return { + 'lukas-reineke/indent-blankline.nvim', + main = 'ibl', + opts = {}, +} diff --git a/lua/kickstart/plugins/lint.lua b/lua/kickstart/plugins/lint.lua index d63054452fd..fe8bdf10340 100644 --- a/lua/kickstart/plugins/lint.lua +++ b/lua/kickstart/plugins/lint.lua @@ -1,53 +1,16 @@ --- Linting - -vim.pack.add { 'https://github.com/mfussenegger/nvim-lint' } - -local lint = require 'lint' -lint.linters_by_ft = { - markdown = { 'markdownlint' }, -- Make sure to install `markdownlint` via mason / npm -} - --- 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() - -- Only run the linter in buffers that you can modify in order to - -- avoid superfluous noise, notably within the handy LSP pop-ups that - -- describe the hovered symbol using Markdown. - if vim.bo.modifiable then lint.try_lint() end +return { + 'mfussenegger/nvim-lint', + config = function() + local lint = require 'lint' + lint.linters_by_ft = { + markdown = { 'markdownlint' }, + } + local lint_augroup = vim.api.nvim_create_augroup('lint', { clear = true }) + vim.api.nvim_create_autocmd({ 'BufEnter', 'BufWritePost', 'InsertLeave' }, { + group = lint_augroup, + callback = function() + if vim.bo.modifiable then lint.try_lint() end + end, + }) end, -}) +} From 9b59f8fdffc4a72844881a3a18669549bb79b7c0 Mon Sep 17 00:00:00 2001 From: Patrick Pagni Date: Thu, 28 May 2026 11:05:55 +0100 Subject: [PATCH 3/8] feat(treesitter): add sql and python parsers --- init.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/init.lua b/init.lua index f1cb29f4eeb..b7ed2a609bd 100644 --- a/init.lua +++ b/init.lua @@ -573,7 +573,7 @@ require('lazy').setup({ branch = 'main', build = ':TSUpdate', config = function() - local parsers = { 'bash', 'c', 'diff', 'html', 'lua', 'luadoc', 'markdown', 'markdown_inline', 'query', 'vim', 'vimdoc' } + local parsers = { 'bash', 'c', 'diff', 'html', 'lua', 'luadoc', 'markdown', 'markdown_inline', 'python', 'query', 'sql', 'vim', 'vimdoc' } require('nvim-treesitter').install(parsers) ---@param buf integer From 3c0b4bd1fc887ea290d166b7567e3941f3659cfc Mon Sep 17 00:00:00 2001 From: Patrick Pagni Date: Thu, 4 Jun 2026 16:27:06 +0100 Subject: [PATCH 4/8] feat: add fugitive, toggleterm, trouble plugins; configure oil - Add vim-fugitive, toggleterm, trouble.nvim lazy specs - Configure oil.nvim with hidden file toggle, sort, and float keymap - Add treesitter install callback for per-lang notifications - Enable arrow-key training keymaps Co-Authored-By: Claude Sonnet 4 --- init.lua | 20 ++++++++++++---- lazy-lock.json | 1 + lua/custom/plugins/fugitive.lua | 3 +++ lua/custom/plugins/oil.lua | 26 ++++++++++++++++++++- lua/custom/plugins/toggle-term.lua | 1 + lua/custom/plugins/trouble.lua | 37 ++++++++++++++++++++++++++++++ 6 files changed, 82 insertions(+), 6 deletions(-) create mode 100644 lua/custom/plugins/fugitive.lua create mode 100644 lua/custom/plugins/toggle-term.lua create mode 100644 lua/custom/plugins/trouble.lua diff --git a/init.lua b/init.lua index b7ed2a609bd..624963635d9 100644 --- a/init.lua +++ b/init.lua @@ -214,10 +214,10 @@ do 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!!"') + 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 @@ -574,7 +574,13 @@ require('lazy').setup({ build = ':TSUpdate', config = function() local parsers = { 'bash', 'c', 'diff', 'html', 'lua', 'luadoc', 'markdown', 'markdown_inline', 'python', 'query', 'sql', 'vim', 'vimdoc' } - require('nvim-treesitter').install(parsers) + require('nvim-treesitter').install(parsers, function(lang, success) + if success then + vim.notify('treesitter: installed ' .. lang, vim.log.levels.INFO) + else + vim.notify('treesitter: failed to install ' .. lang, vim.log.levels.WARN) + end + end) ---@param buf integer ---@param language string @@ -628,5 +634,9 @@ require('lazy').setup({ checker = { enabled = false }, }) + -- Open Oil in a floating window + vim.keymap.set("n", "of", "Oil --float", { desc = "Open Oil float" }) + + -- The line beneath this is called `modeline`. See `:help modeline` -- vim: ts=2 sts=2 sw=2 et diff --git a/lazy-lock.json b/lazy-lock.json index 65c7e00d456..5e76c7dd62f 100644 --- a/lazy-lock.json +++ b/lazy-lock.json @@ -30,6 +30,7 @@ "telescope.nvim": { "branch": "master", "commit": "7d324792b7943e4aa16ad007212e6acc6f9fe335" }, "todo-comments.nvim": { "branch": "main", "commit": "31e3c38ce9b29781e4422fc0322eb0a21f4e8668" }, "tokyonight.nvim": { "branch": "main", "commit": "cdc07ac78467a233fd62c493de29a17e0cf2b2b6" }, + "trouble.nvim": { "branch": "main", "commit": "bd67efe408d4816e25e8491cc5ad4088e708a69a" }, "wezterm.nvim": { "branch": "main", "commit": "032c33b621b96cc7228955b4352b48141c482098" }, "which-key.nvim": { "branch": "main", "commit": "3aab2147e74890957785941f0c1ad87d0a44c15a" } } diff --git a/lua/custom/plugins/fugitive.lua b/lua/custom/plugins/fugitive.lua new file mode 100644 index 00000000000..2c2efeb2f0d --- /dev/null +++ b/lua/custom/plugins/fugitive.lua @@ -0,0 +1,3 @@ +return { + "tpope/vim-fugitive", +} diff --git a/lua/custom/plugins/oil.lua b/lua/custom/plugins/oil.lua index 966924f2300..2a751fd6957 100644 --- a/lua/custom/plugins/oil.lua +++ b/lua/custom/plugins/oil.lua @@ -3,6 +3,30 @@ return { dependencies = { 'nvim-mini/mini.nvim' }, config = function() require('mini.icons').setup() - require('oil').setup() + require('oil').setup { + view_options = { + show_hidden = false, + is_hidden_file = function(name, bufnr) + return vim.startswith(name, '.') + end, + is_always_hidden = function(name, bufnr) + return false + end, + natural_order = false, + sort = { + { 'type', 'asc' }, + { 'name', 'asc' }, + }, + }, + keymaps = { + ['th'] = { + callback = function() + require('oil').toggle_hidden() + end, + desc = 'Toggle hidden files', + mode = 'n', + }, + }, + } end, } diff --git a/lua/custom/plugins/toggle-term.lua b/lua/custom/plugins/toggle-term.lua new file mode 100644 index 00000000000..9ac87b18e4c --- /dev/null +++ b/lua/custom/plugins/toggle-term.lua @@ -0,0 +1 @@ +return {'akinsho/toggleterm.nvim', version = "*", config = true} diff --git a/lua/custom/plugins/trouble.lua b/lua/custom/plugins/trouble.lua new file mode 100644 index 00000000000..3741f30a66a --- /dev/null +++ b/lua/custom/plugins/trouble.lua @@ -0,0 +1,37 @@ +return { + "folke/trouble.nvim", + opts = {}, -- for default options, refer to the configuration section for custom setup. + cmd = "Trouble", + keys = { + { + "xx", + "Trouble diagnostics toggle", + desc = "Diagnostics (Trouble)", + }, + { + "xX", + "Trouble diagnostics toggle filter.buf=0", + desc = "Buffer Diagnostics (Trouble)", + }, + { + "cs", + "Trouble symbols toggle focus=false", + desc = "Symbols (Trouble)", + }, + { + "cl", + "Trouble lsp toggle focus=false win.position=right", + desc = "LSP Definitions / references / ... (Trouble)", + }, + { + "xL", + "Trouble loclist toggle", + desc = "Location List (Trouble)", + }, + { + "xQ", + "Trouble qflist toggle", + desc = "Quickfix List (Trouble)", + }, + }, +} From 09ca10511726876efcf9269adb739454a4f4625c Mon Sep 17 00:00:00 2001 From: Patrick Pagni Date: Thu, 4 Jun 2026 16:42:20 +0100 Subject: [PATCH 5/8] feat(toggleterm): add Esc normal-mode mapping and lazygit float toggle Esc in terminal buffers exits insert mode without the awkward C-\C-n chord. lazygit float on tg avoids context-switching to a separate window. --- lazy-lock.json | 2 ++ lua/custom/plugins/toggle-term.lua | 19 ++++++++++++++++++- 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/lazy-lock.json b/lazy-lock.json index 5e76c7dd62f..2c6cad0dded 100644 --- a/lazy-lock.json +++ b/lazy-lock.json @@ -29,8 +29,10 @@ "telescope-ui-select.nvim": { "branch": "master", "commit": "6e51d7da30bd139a6950adf2a47fda6df9fa06d2" }, "telescope.nvim": { "branch": "master", "commit": "7d324792b7943e4aa16ad007212e6acc6f9fe335" }, "todo-comments.nvim": { "branch": "main", "commit": "31e3c38ce9b29781e4422fc0322eb0a21f4e8668" }, + "toggleterm.nvim": { "branch": "main", "commit": "50ea089fc548917cc3cc16b46a8211833b9e3c7c" }, "tokyonight.nvim": { "branch": "main", "commit": "cdc07ac78467a233fd62c493de29a17e0cf2b2b6" }, "trouble.nvim": { "branch": "main", "commit": "bd67efe408d4816e25e8491cc5ad4088e708a69a" }, + "vim-fugitive": { "branch": "master", "commit": "3b753cf8c6a4dcde6edee8827d464ba9b8c4a6f0" }, "wezterm.nvim": { "branch": "main", "commit": "032c33b621b96cc7228955b4352b48141c482098" }, "which-key.nvim": { "branch": "main", "commit": "3aab2147e74890957785941f0c1ad87d0a44c15a" } } diff --git a/lua/custom/plugins/toggle-term.lua b/lua/custom/plugins/toggle-term.lua index 9ac87b18e4c..7f929d1a692 100644 --- a/lua/custom/plugins/toggle-term.lua +++ b/lua/custom/plugins/toggle-term.lua @@ -1 +1,18 @@ -return {'akinsho/toggleterm.nvim', version = "*", config = true} +return { + 'akinsho/toggleterm.nvim', + version = '*', + opts = { + open_mapping = [[tt]], + }, + config = function(_, opts) + require('toggleterm').setup(opts) + vim.keymap.set('t', '', [[]], { desc = 'Exit terminal mode' }) + + local lazygit = require('toggleterm.terminal').Terminal:new({ + cmd = 'lazygit', + direction = 'float', + hidden = true, + }) + vim.keymap.set('n', 'tg', function() lazygit:toggle() end, { desc = 'Toggle lazygit' }) + end, +} From a942b8c562ebdb47efd7bd29d30f75d78cd7ae2e Mon Sep 17 00:00:00 2001 From: Patrick Pagni Date: Fri, 5 Jun 2026 15:43:20 +0100 Subject: [PATCH 6/8] do some stuff Prior to this change, This change --- lua/custom/plugins/oil.lua | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/lua/custom/plugins/oil.lua b/lua/custom/plugins/oil.lua index 2a751fd6957..c9491093772 100644 --- a/lua/custom/plugins/oil.lua +++ b/lua/custom/plugins/oil.lua @@ -4,6 +4,11 @@ return { config = function() require('mini.icons').setup() require('oil').setup { + float = { + border = 'rounded', + title = ' Oil ', + title_pos = 'center', + }, view_options = { show_hidden = false, is_hidden_file = function(name, bufnr) From 98c59fc1d2fe98f62ea007bea151d4b18df3f72a Mon Sep 17 00:00:00 2001 From: Patrick Pagni Date: Wed, 24 Jun 2026 17:19:17 +0100 Subject: [PATCH 7/8] add lsp_lines --- CLAUDE.md | 80 ++++++++++++++++++++++++++++++++ init.lua | 38 +++++++++------ lazy-lock.json | 1 + lua/custom/plugins/lsp_lines.lua | 21 +++++++++ 4 files changed, 127 insertions(+), 13 deletions(-) create mode 100644 CLAUDE.md create mode 100644 lua/custom/plugins/lsp_lines.lua diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 00000000000..221e424175f --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,80 @@ +# CLAUDE.md + +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. + +## Overview + +Kickstart-based Neovim config using lazy.nvim as the plugin manager. Single `init.lua` + modular custom plugins under `lua/custom/plugins/`. + +## Plugin Manager + +lazy.nvim — plugins defined as lazy specs (`return { "owner/repo", ... }`). + +Update plugins: `:Lazy update` +Check status: `:Lazy` +Install/manage LSP tools: `:Mason` + +## Structure + +``` +init.lua — Sections 1–9: foundation → plugins +lua/custom/plugins/init.lua — Auto-loads all *.lua files in same dir +lua/custom/plugins/*.lua — User-added plugins (no merge conflicts from upstream) +lua/kickstart/plugins/*.lua — Optional kickstart examples (indent_line, lint, gitsigns) +lazy-lock.json — Lockfile (commit this) +``` + +`init.lua` is organized into `do...end` blocks by section: +1. Foundation (options, keymaps, autocmds) +2. lazy.nvim bootstrap + setup +3. UI/UX (gitsigns, which-key, mini.nvim, todo-comments) +4. Search/Navigation (Telescope) +5. LSP (mason, nvim-lspconfig, fidget) +6. Formatting (conform.nvim) +7. Autocomplete & Snippets (blink.cmp + LuaSnip) +8. Treesitter +9. Optional examples + +## Custom Plugins + +| File | Purpose | +|------|---------| +| `claude.lua` | claudecode.nvim — `a*` keymaps; depends on snacks.nvim | +| `lsp.lua` | dbt language server config for SQL/YAML files | +| `markdown.lua` | live-preview.nvim | +| `notebook.lua` | molten-nvim (Jupyter), image.nvim (magick_cli), wezterm.nvim | +| `oil.lua` | oil.nvim file manager via mini.icons | +| `themes.lua` | gruvbox-medium (active), tokyonight (installed) | +| `toggle-term.lua` | toggleterm.nvim terminal toggle | + +## LSP + +Servers are configured in `init.lua:670` via `vim.lsp.config(name, server)` + `vim.lsp.enable(name)`. +Custom dbt server lives in `lua/custom/plugins/lsp.lua` — requires `dbt-language-server` in `$PATH`. +Lua formatting disabled in `lua_ls`; formatting delegated to `stylua` via conform.nvim. + +## Key Bindings (leader = ``) + +- `s*` — Telescope search +- `f` — format buffer (conform) +- `a*` — Claude Code integration +- `h*` — gitsigns hunk operations +- `t*` — toggles (inlay hints, blame, word diff) +- `gr*` — LSP actions (rename, code action, references, definitions) + +## Adding Plugins + +Drop a `.lua` file in `lua/custom/plugins/` — auto-required on next start. Use the lazy spec pattern: + +```lua +return { + "owner/repo", + opts = {}, +} +``` + +## Formatting & Linting + +- **Formatter**: conform.nvim — `f` to format; auto-format on save disabled by default (opt-in per filetype in `init.lua:760`) +- **Linter**: nvim-lint — runs on `BufEnter`/`BufWritePost`/`InsertLeave`; markdownlint for markdown +- **Treesitter**: auto-installs parsers on `FileType` event diff --git a/init.lua b/init.lua index 624963635d9..47a95bff69e 100644 --- a/init.lua +++ b/init.lua @@ -506,27 +506,39 @@ require('lazy').setup({ { 'stevearc/conform.nvim', config = function() + local prettier_ft = { + 'javascript', + 'javascriptreact', + 'typescript', + 'typescriptreact', + 'vue', + 'css', + 'scss', + 'less', + 'html', + 'json', + 'jsonc', + 'yaml', + 'markdown', + 'graphql', + } + local formatters_by_ft = {} + for _, ft in ipairs(prettier_ft) do + formatters_by_ft[ft] = { 'prettierd', 'prettier', stop_after_first = true } + end + require('conform').setup { notify_on_error = false, format_on_save = function(bufnr) - local enabled_filetypes = { - -- lua = true, - -- python = true, - } - if enabled_filetypes[vim.bo[bufnr].filetype] then - return { timeout_ms = 500 } - else - return nil + if formatters_by_ft[vim.bo[bufnr].filetype] then + return { timeout_ms = 500, lsp_format = 'fallback' } end + return nil end, default_format_opts = { lsp_format = 'fallback', }, - formatters_by_ft = { - -- rust = { 'rustfmt' }, - -- python = { "isort", "black" }, - -- javascript = { "prettierd", "prettier", stop_after_first = true }, - }, + formatters_by_ft = formatters_by_ft, } vim.keymap.set({ 'n', 'v' }, 'f', function() require('conform').format { async = true } end, { desc = '[F]ormat buffer' }) end, diff --git a/lazy-lock.json b/lazy-lock.json index 2c6cad0dded..c6d163a9df3 100644 --- a/lazy-lock.json +++ b/lazy-lock.json @@ -12,6 +12,7 @@ "indent-blankline.nvim": { "branch": "master", "commit": "d28a3f70721c79e3c5f6693057ae929f3d9c0a03" }, "lazy.nvim": { "branch": "main", "commit": "306a05526ada86a7b30af95c5cc81ffba93fef97" }, "live-preview.nvim": { "branch": "main", "commit": "c1fcf75c5f9c9c01dd392852de44204b60f1b5b1" }, + "lsp_lines.nvim": { "branch": "main", "commit": "3b57922d2d79762e6baedaf9d66d8ba71f822816" }, "mason-lspconfig.nvim": { "branch": "main", "commit": "7b01e2974a47d489bb92f47a41e4c0088ea8f86e" }, "mason-tool-installer.nvim": { "branch": "main", "commit": "443f1ef8b5e6bf47045cb2217b6f748a223cf7dc" }, "mason.nvim": { "branch": "main", "commit": "bb639d4bf385a4d89f478b83af4d770be05ab7eb" }, diff --git a/lua/custom/plugins/lsp_lines.lua b/lua/custom/plugins/lsp_lines.lua new file mode 100644 index 00000000000..1bf0d29f814 --- /dev/null +++ b/lua/custom/plugins/lsp_lines.lua @@ -0,0 +1,21 @@ +return { + "ErichDonGubler/lsp_lines.nvim", + config = function() + require("lsp_lines").setup() + + -- Disable default virtual text to prevent overlapping/duplicate diagnostic lines + vim.diagnostic.config({ + virtual_text = false, + }) + end, + -- Keymap to toggle lsp_lines + keys = { + { + "ll", + function() + require("lsp_lines").toggle() + end, + desc = "Toggle lsp_lines", + }, + }, +} From e7c217a876ceb01266a10ed34e24df27c8ac0a57 Mon Sep 17 00:00:00 2001 From: Patrick Pagni Date: Wed, 24 Jun 2026 17:45:59 +0100 Subject: [PATCH 8/8] fix: restore lazy.nvim init.lua and apply stylua Merge spliced upstream vim.pack rewrite into lazy.nvim config, breaking init.lua parse. Restore branch version, reformat all lua to satisfy stylua --check. --- config/lazy.lua | 24 +- init.lua | 398 +++-------------------------- lua/custom/plugins/claude.lua | 32 +-- lua/custom/plugins/fugitive.lua | 2 +- lua/custom/plugins/lsp.lua | 2 +- lua/custom/plugins/lsp_lines.lua | 16 +- lua/custom/plugins/markdown.lua | 16 +- lua/custom/plugins/notebook.lua | 46 ++-- lua/custom/plugins/oil.lua | 12 +- lua/custom/plugins/themes.lua | 2 +- lua/custom/plugins/toggle-term.lua | 4 +- lua/custom/plugins/trouble.lua | 40 +-- 12 files changed, 123 insertions(+), 471 deletions(-) diff --git a/config/lazy.lua b/config/lazy.lua index f5ee74c9511..594c38a1173 100644 --- a/config/lazy.lua +++ b/config/lazy.lua @@ -1,13 +1,13 @@ -- Bootstrap lazy.nvim -local lazypath = vim.fn.stdpath("data") .. "/lazy/lazy.nvim" +local lazypath = vim.fn.stdpath 'data' .. '/lazy/lazy.nvim' if not (vim.uv or vim.loop).fs_stat(lazypath) then - local lazyrepo = "https://github.com/folke/lazy.nvim.git" - local out = vim.fn.system({ "git", "clone", "--filter=blob:none", "--branch=stable", lazyrepo, lazypath }) + local lazyrepo = 'https://github.com/folke/lazy.nvim.git' + local out = vim.fn.system { 'git', 'clone', '--filter=blob:none', '--branch=stable', lazyrepo, lazypath } if vim.v.shell_error ~= 0 then vim.api.nvim_echo({ - { "Failed to clone lazy.nvim:\n", "ErrorMsg" }, - { out, "WarningMsg" }, - { "\nPress any key to exit..." }, + { 'Failed to clone lazy.nvim:\n', 'ErrorMsg' }, + { out, 'WarningMsg' }, + { '\nPress any key to exit...' }, }, true, {}) vim.fn.getchar() os.exit(1) @@ -18,18 +18,18 @@ vim.opt.rtp:prepend(lazypath) -- Make sure to setup `mapleader` and `maplocalleader` before -- loading lazy.nvim so that mappings are correct. -- This is also a good place to setup other settings (vim.opt) -vim.g.mapleader = " " -vim.g.maplocalleader = "\\" +vim.g.mapleader = ' ' +vim.g.maplocalleader = '\\' -- Setup lazy.nvim -require("lazy").setup({ +require('lazy').setup { spec = { -- import your plugins - { import = "plugins" }, + { import = 'plugins' }, }, -- Configure any other settings here. See the documentation for more details. -- colorscheme that will be used when installing plugins. - install = { colorscheme = { "habamax" } }, + install = { colorscheme = { 'habamax' } }, -- automatically check for plugin updates checker = { enabled = true }, -}) +} diff --git a/init.lua b/init.lua index 6c599580783..77f14504e64 100644 --- a/init.lua +++ b/init.lua @@ -85,7 +85,7 @@ P.S. You can delete this when you're done too. It's your config now! :) --]] -- ============================================================ --- SECTION 1: OPTIONS +-- SECTION 1: FOUNDATION -- Core Neovim settings, leaders, options, basic keymaps, basic autocmds -- ============================================================ do @@ -171,13 +171,7 @@ do -- instead raise a dialog asking if you wish to save the current file(s) -- See `:help 'confirm'` vim.o.confirm = true -end --- ============================================================ --- SECTION 2: KEYMAPS --- basic keymaps --- ============================================================ -do -- [[ Basic Keymaps ]] -- See `:help vim.keymap.set()` @@ -259,12 +253,16 @@ end -- ============================================================ -- Bootstrap lazy.nvim -local lazypath = vim.fn.stdpath('data') .. '/lazy/lazy.nvim' +local lazypath = vim.fn.stdpath 'data' .. '/lazy/lazy.nvim' if not (vim.uv or vim.loop).fs_stat(lazypath) then - local out = vim.fn.system({ - 'git', 'clone', '--filter=blob:none', '--branch=stable', - 'https://github.com/folke/lazy.nvim.git', lazypath, - }) + local out = vim.fn.system { + 'git', + 'clone', + '--filter=blob:none', + '--branch=stable', + 'https://github.com/folke/lazy.nvim.git', + lazypath, + } if vim.v.shell_error ~= 0 then vim.api.nvim_echo({ { 'Failed to clone lazy.nvim:\n', 'ErrorMsg' }, { out, 'WarningMsg' }, { '\nPress any key to exit...' } }, true, {}) vim.fn.getchar() @@ -273,7 +271,7 @@ if not (vim.uv or vim.loop).fs_stat(lazypath) then end vim.opt.rtp:prepend(lazypath) -require('lazy').setup({ +require('lazy').setup { spec = { -- ============================================================ -- SECTION 3: UI / CORE UX PLUGINS @@ -284,45 +282,6 @@ require('lazy').setup({ { 'nvim-tree/nvim-web-devicons', cond = vim.g.have_nerd_font, ----Because most plugins are hosted on GitHub, you can use the helper ----function to have less repetition in the following sections. ----@param repo string ----@return string -local function gh(repo) return 'https://github.com/' .. repo end - --- ============================================================ --- SECTION 4: UI / CORE UX PLUGINS --- guess-indent, gitsigns, which-key, colorscheme, todo-comments, mini modules --- ============================================================ -do - -- [[ Installing and Configuring Plugins ]] - -- - -- To install a plugin simply call `vim.pack.add` with its git url. - -- This will download the default branch of the plugin, which will usually be `main` or `master` - -- You can also have more advanced specs, which we will talk about later. - -- - -- For most plugins its not enough to install them, you also need to call their `.setup()` to start them. - -- - -- For example, lets say we want to install `guess-indent.nvim` - a plugin for - -- automatically detecting and setting the indentation. - -- - -- We first install it from https://github.com/NMAC427/guess-indent.nvim - -- and then call its `setup()` function to start it with default settings. - vim.pack.add { gh 'NMAC427/guess-indent.nvim' } - require('guess-indent').setup {} - - -- Here is a more advanced configuration example that passes 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 - vim.pack.add { gh 'lewis6991/gitsigns.nvim' } - 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 }, { @@ -385,7 +344,7 @@ do { 'nvim-telescope/telescope-fzf-native.nvim', build = 'make', - cond = vim.fn.executable('make') == 1, + cond = vim.fn.executable 'make' == 1, }, }, config = function() @@ -423,90 +382,22 @@ do end, }) - vim.keymap.set('n', '/', function() - builtin.current_buffer_fuzzy_find(require('telescope.themes').get_dropdown { winblend = 10, previewer = false }) - end, { desc = '[/] Fuzzily search in current buffer' }) - -- If a nerd font is available, load the icons module for pretty icons in various plugins. - if vim.g.have_nerd_font then - require('mini.icons').setup() - -- Used for backwards compatibility with plugins that require `nvim-web-devicons` (e.g. telescope.nvim) - MiniIcons.mock_nvim_web_devicons() - end - - -- 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, - } + vim.keymap.set( + 'n', + '/', + function() builtin.current_buffer_fuzzy_find(require('telescope.themes').get_dropdown { winblend = 10, previewer = false }) end, + { desc = '[/] Fuzzily search in current buffer' } + ) - 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' }) + 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' } + ) vim.keymap.set('n', 'sn', function() builtin.find_files { cwd = vim.fn.stdpath 'config' } end, { desc = '[S]earch [N]eovim files' }) end, --- ============================================================ --- SECTION 5: 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! - - ---@type (string|vim.pack.Spec)[] - local telescope_plugins = { - gh 'nvim-lua/plenary.nvim', - gh 'nvim-telescope/telescope.nvim', - gh 'nvim-telescope/telescope-ui-select.nvim', - } - if vim.fn.executable 'make' == 1 then table.insert(telescope_plugins, gh 'nvim-telescope/telescope-fzf-native.nvim') end - - -- NOTE: You can install multiple plugins at once - vim.pack.add(telescope_plugins) - - -- 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() }, }, -- ============================================================ @@ -561,109 +452,6 @@ do 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, - -- 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', follow = true } end, { desc = '[S]earch [N]eovim files' }) -end - --- ============================================================ --- SECTION 6: 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. - vim.pack.add { gh 'j-hui/fidget.nvim' } - 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, }) ---@type table @@ -752,9 +540,7 @@ do require('conform').setup { notify_on_error = false, format_on_save = function(bufnr) - if formatters_by_ft[vim.bo[bufnr].filetype] then - return { timeout_ms = 500, lsp_format = 'fallback' } - end + if formatters_by_ft[vim.bo[bufnr].filetype] then return { timeout_ms = 500, lsp_format = 'fallback' } end return nil end, default_format_opts = { @@ -764,38 +550,6 @@ do } vim.keymap.set({ 'n', 'v' }, 'f', function() require('conform').format { async = true } end, { desc = '[F]ormat buffer' }) end, --- ============================================================ --- SECTION 7: FORMATTING --- conform.nvim setup and keymap --- ============================================================ -do - -- [[ Formatting ]] - vim.pack.add { gh 'stevearc/conform.nvim' } - 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 }, }, -- ============================================================ @@ -805,60 +559,12 @@ do { 'L3MON4D3/LuaSnip', version = '2.*', - build = (vim.fn.has('win32') ~= 1 and vim.fn.executable('make') == 1) and 'make install_jsregexp' or nil, + build = (vim.fn.has 'win32' ~= 1 and vim.fn.executable 'make' == 1) and 'make install_jsregexp' or nil, config = function() require('luasnip').setup {} -- vim.pack.add { gh 'rafamadriz/friendly-snippets' } -- require('luasnip.loaders.from_vscode').lazy_load() end, --- ============================================================ --- SECTION 8: AUTOCOMPLETE & SNIPPETS --- blink.cmp and luasnip setup --- ============================================================ -do - -- [[ Snippet Engine ]] - - -- NOTE: You can also specify plugin using a version range for its git tag. - -- See `:help vim.version.range()` for more info - vim.pack.add { { src = gh 'L3MON4D3/LuaSnip', version = vim.version.range '2.*' } } - 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() - - -- [[ Autocomplete Engine ]] - vim.pack.add { { src = gh 'saghen/blink.cmp', version = vim.version.range '1.*' } } - 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 }, { @@ -943,59 +649,13 @@ do { import = 'custom.plugins' }, }, --- ============================================================ --- SECTION 9: TREESITTER --- Parser installation, syntax highlighting, folds, indentation --- ============================================================ -do - -- [[ Configure Treesitter ]] - -- Used to highlight, edit, and navigate code - -- - -- See `:help nvim-treesitter-intro` - - -- NOTE: You can also specify a branch or a specific commit - vim.pack.add { { src = gh 'nvim-treesitter/nvim-treesitter', version = 'main' } } - - -- 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 - end install = { colorscheme = { 'gruvbox-medium', 'habamax' } }, checker = { enabled = false }, -}) - - -- Open Oil in a floating window - vim.keymap.set("n", "of", "Oil --float", { desc = "Open Oil float" }) --- ============================================================ --- SECTION 10: 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. +} +-- Open Oil in a floating window +vim.keymap.set('n', 'of', 'Oil --float', { desc = 'Open Oil float' }) -- The line beneath this is called `modeline`. See `:help modeline` -- vim: ts=2 sts=2 sw=2 et diff --git a/lua/custom/plugins/claude.lua b/lua/custom/plugins/claude.lua index 8360b0c9744..9948796842b 100644 --- a/lua/custom/plugins/claude.lua +++ b/lua/custom/plugins/claude.lua @@ -1,24 +1,24 @@ return { - "coder/claudecode.nvim", - dependencies = { "folke/snacks.nvim" }, + 'coder/claudecode.nvim', + dependencies = { 'folke/snacks.nvim' }, config = true, keys = { - { "a", nil, desc = "AI/Claude Code" }, - { "ac", "ClaudeCode", desc = "Toggle Claude" }, - { "af", "ClaudeCodeFocus", desc = "Focus Claude" }, - { "ar", "ClaudeCode --resume", desc = "Resume Claude" }, - { "aC", "ClaudeCode --continue", desc = "Continue Claude" }, - { "am", "ClaudeCodeSelectModel", desc = "Select Claude model" }, - { "ab", "ClaudeCodeAdd %", desc = "Add current buffer" }, - { "as", "ClaudeCodeSend", mode = "v", desc = "Send to Claude" }, + { 'a', nil, desc = 'AI/Claude Code' }, + { 'ac', 'ClaudeCode', desc = 'Toggle Claude' }, + { 'af', 'ClaudeCodeFocus', desc = 'Focus Claude' }, + { 'ar', 'ClaudeCode --resume', desc = 'Resume Claude' }, + { 'aC', 'ClaudeCode --continue', desc = 'Continue Claude' }, + { 'am', 'ClaudeCodeSelectModel', desc = 'Select Claude model' }, + { 'ab', 'ClaudeCodeAdd %', desc = 'Add current buffer' }, + { 'as', 'ClaudeCodeSend', mode = 'v', desc = 'Send to Claude' }, { - "as", - "ClaudeCodeTreeAdd", - desc = "Add file", - ft = { "NvimTree", "neo-tree", "oil", "minifiles", "netrw" }, + 'as', + 'ClaudeCodeTreeAdd', + desc = 'Add file', + ft = { 'NvimTree', 'neo-tree', 'oil', 'minifiles', 'netrw' }, }, -- Diff management - { "aa", "ClaudeCodeDiffAccept", desc = "Accept diff" }, - { "ad", "ClaudeCodeDiffDeny", desc = "Deny diff" }, + { 'aa', 'ClaudeCodeDiffAccept', desc = 'Accept diff' }, + { 'ad', 'ClaudeCodeDiffDeny', desc = 'Deny diff' }, }, } diff --git a/lua/custom/plugins/fugitive.lua b/lua/custom/plugins/fugitive.lua index 2c2efeb2f0d..b6b4c97bc32 100644 --- a/lua/custom/plugins/fugitive.lua +++ b/lua/custom/plugins/fugitive.lua @@ -1,3 +1,3 @@ return { - "tpope/vim-fugitive", + 'tpope/vim-fugitive', } diff --git a/lua/custom/plugins/lsp.lua b/lua/custom/plugins/lsp.lua index 9a08ce0a922..efa8b90124e 100644 --- a/lua/custom/plugins/lsp.lua +++ b/lua/custom/plugins/lsp.lua @@ -6,6 +6,6 @@ vim.lsp.config('dbt', { root_markers = { 'dbt_project.yml' }, settings = {}, }) -vim.lsp.enable('dbt') +vim.lsp.enable 'dbt' return {} diff --git a/lua/custom/plugins/lsp_lines.lua b/lua/custom/plugins/lsp_lines.lua index 1bf0d29f814..bc2592f5152 100644 --- a/lua/custom/plugins/lsp_lines.lua +++ b/lua/custom/plugins/lsp_lines.lua @@ -1,21 +1,19 @@ return { - "ErichDonGubler/lsp_lines.nvim", + 'ErichDonGubler/lsp_lines.nvim', config = function() - require("lsp_lines").setup() + require('lsp_lines').setup() -- Disable default virtual text to prevent overlapping/duplicate diagnostic lines - vim.diagnostic.config({ + vim.diagnostic.config { virtual_text = false, - }) + } end, -- Keymap to toggle lsp_lines keys = { { - "ll", - function() - require("lsp_lines").toggle() - end, - desc = "Toggle lsp_lines", + 'll', + function() require('lsp_lines').toggle() end, + desc = 'Toggle lsp_lines', }, }, } diff --git a/lua/custom/plugins/markdown.lua b/lua/custom/plugins/markdown.lua index f06a4bcfa96..c2ee8ee7268 100644 --- a/lua/custom/plugins/markdown.lua +++ b/lua/custom/plugins/markdown.lua @@ -1,10 +1,10 @@ return { - 'brianhuster/live-preview.nvim', - dependencies = { - -- You can choose one of the following pickers - 'nvim-telescope/telescope.nvim', - 'ibhagwan/fzf-lua', - 'echasnovski/mini.pick', - 'folke/snacks.nvim', - }, + 'brianhuster/live-preview.nvim', + dependencies = { + -- You can choose one of the following pickers + 'nvim-telescope/telescope.nvim', + 'ibhagwan/fzf-lua', + 'echasnovski/mini.pick', + 'folke/snacks.nvim', + }, } diff --git a/lua/custom/plugins/notebook.lua b/lua/custom/plugins/notebook.lua index 8214426259c..273c95ed69c 100644 --- a/lua/custom/plugins/notebook.lua +++ b/lua/custom/plugins/notebook.lua @@ -1,26 +1,26 @@ return { - { - "benlubas/molten-nvim", - version = "^1.0.0", -- use version <2.0.0 to avoid breaking changes - dependencies = { "3rd/image.nvim" }, - build = ":UpdateRemotePlugins", - init = function() - -- these are examples, not defaults. Please see the readme - vim.g.molten_image_provider = "image.nvim" - vim.g.molten_output_win_max_height = 20 - end, - }, - { - 'willothy/wezterm.nvim', - cond = vim.fn.executable('wezterm') == 1, - config = true - }, + { + 'benlubas/molten-nvim', + version = '^1.0.0', -- use version <2.0.0 to avoid breaking changes + dependencies = { '3rd/image.nvim' }, + build = ':UpdateRemotePlugins', + init = function() + -- these are examples, not defaults. Please see the readme + vim.g.molten_image_provider = 'image.nvim' + vim.g.molten_output_win_max_height = 20 + end, + }, + { + 'willothy/wezterm.nvim', + cond = vim.fn.executable 'wezterm' == 1, + config = true, + }, - { - "3rd/image.nvim", - build = false, -- so that it doesn't build the rock https://github.com/3rd/image.nvim/issues/91#issuecomment-2453430239 - opts = { - processor = "magick_cli", - } - } + { + '3rd/image.nvim', + build = false, -- so that it doesn't build the rock https://github.com/3rd/image.nvim/issues/91#issuecomment-2453430239 + opts = { + processor = 'magick_cli', + }, + }, } diff --git a/lua/custom/plugins/oil.lua b/lua/custom/plugins/oil.lua index c9491093772..34f7ce6e088 100644 --- a/lua/custom/plugins/oil.lua +++ b/lua/custom/plugins/oil.lua @@ -11,12 +11,8 @@ return { }, view_options = { show_hidden = false, - is_hidden_file = function(name, bufnr) - return vim.startswith(name, '.') - end, - is_always_hidden = function(name, bufnr) - return false - end, + is_hidden_file = function(name, bufnr) return vim.startswith(name, '.') end, + is_always_hidden = function(name, bufnr) return false end, natural_order = false, sort = { { 'type', 'asc' }, @@ -25,9 +21,7 @@ return { }, keymaps = { ['th'] = { - callback = function() - require('oil').toggle_hidden() - end, + callback = function() require('oil').toggle_hidden() end, desc = 'Toggle hidden files', mode = 'n', }, diff --git a/lua/custom/plugins/themes.lua b/lua/custom/plugins/themes.lua index 2ac7e0b0c77..89037260cea 100644 --- a/lua/custom/plugins/themes.lua +++ b/lua/custom/plugins/themes.lua @@ -13,7 +13,7 @@ return { priority = 1000, config = function() require('gruvbox').setup() - vim.cmd('colorscheme gruvbox-medium') + vim.cmd 'colorscheme gruvbox-medium' end, }, } diff --git a/lua/custom/plugins/toggle-term.lua b/lua/custom/plugins/toggle-term.lua index 7f929d1a692..b5356f93cc3 100644 --- a/lua/custom/plugins/toggle-term.lua +++ b/lua/custom/plugins/toggle-term.lua @@ -8,11 +8,11 @@ return { require('toggleterm').setup(opts) vim.keymap.set('t', '', [[]], { desc = 'Exit terminal mode' }) - local lazygit = require('toggleterm.terminal').Terminal:new({ + local lazygit = require('toggleterm.terminal').Terminal:new { cmd = 'lazygit', direction = 'float', hidden = true, - }) + } vim.keymap.set('n', 'tg', function() lazygit:toggle() end, { desc = 'Toggle lazygit' }) end, } diff --git a/lua/custom/plugins/trouble.lua b/lua/custom/plugins/trouble.lua index 3741f30a66a..d0578c9f404 100644 --- a/lua/custom/plugins/trouble.lua +++ b/lua/custom/plugins/trouble.lua @@ -1,37 +1,37 @@ return { - "folke/trouble.nvim", + 'folke/trouble.nvim', opts = {}, -- for default options, refer to the configuration section for custom setup. - cmd = "Trouble", + cmd = 'Trouble', keys = { { - "xx", - "Trouble diagnostics toggle", - desc = "Diagnostics (Trouble)", + 'xx', + 'Trouble diagnostics toggle', + desc = 'Diagnostics (Trouble)', }, { - "xX", - "Trouble diagnostics toggle filter.buf=0", - desc = "Buffer Diagnostics (Trouble)", + 'xX', + 'Trouble diagnostics toggle filter.buf=0', + desc = 'Buffer Diagnostics (Trouble)', }, { - "cs", - "Trouble symbols toggle focus=false", - desc = "Symbols (Trouble)", + 'cs', + 'Trouble symbols toggle focus=false', + desc = 'Symbols (Trouble)', }, { - "cl", - "Trouble lsp toggle focus=false win.position=right", - desc = "LSP Definitions / references / ... (Trouble)", + 'cl', + 'Trouble lsp toggle focus=false win.position=right', + desc = 'LSP Definitions / references / ... (Trouble)', }, { - "xL", - "Trouble loclist toggle", - desc = "Location List (Trouble)", + 'xL', + 'Trouble loclist toggle', + desc = 'Location List (Trouble)', }, { - "xQ", - "Trouble qflist toggle", - desc = "Quickfix List (Trouble)", + 'xQ', + 'Trouble qflist toggle', + desc = 'Quickfix List (Trouble)', }, }, }