├── .editorconfig ├── README.md ├── init.lua └── lua ├── config ├── keymaps.lua ├── lazy.lua └── options.lua └── plugins ├── blink-cmp.lua ├── conform.lua ├── dressing.lua ├── fzflua.lua ├── kanagawa.lua ├── lsp.lua ├── nvim-treesitter-textobjects.lua ├── nvim-treesitter.lua ├── oil.lua ├── project-fzf.lua ├── project.lua ├── rustacean.lua ├── showkeys.lua ├── sleuth-vim.lua ├── statusline.lua └── which-key.lua /.editorconfig: -------------------------------------------------------------------------------- 1 | [*.lua] 2 | indent_style=space 3 | indent_size=4 4 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Neovim from Scratch 2 | 3 | This neovim configuration is being build up incrementally from scratch on a video series on my [YouTube channel: MrJakob](https://youtube.com/c/MrJakob). 4 | 5 | You may use this configuration as an inspiration to create youre own. Follow the [Video Series](https://youtube.com/playlist?list=PLy68GuC77sURrnMNi2XR1h58m674KOvLG&si=PNSk8Y-LUbYW_Yec) to get a better understanding of where to start when rolling a Neovim configuration from scratch. 6 | 7 | If you are interested my currently used personal configuration and setup, you can always find my complete shell environment in my [dotfiles](https://github.com/jakobwesthoff/dotfiles) repository on [github](https://github.com/jakobwesthoff). 8 | 9 | ## Videos 10 | 11 | * [Neovim from Scratch - Part 1: lazy.nvim, kanagawa.nvim, oil.nvim, Statusline & Essential Settings](https://youtu.be/g1gyYttzxcI) 12 | * [Neovim from Scratch - Part 2: Supercharged Code Navigation via Treesitter, Textobjects & which-key](https://youtu.be/E4qXZv34NQQ) 13 | * [Insanely fast Neovim Navigation with fzf❤️lua | Configuration from Scratch Part 3](https://youtu.be/R3e7uAE8jjo) 14 | * [Code Intelligence in Neovim - The LSP Setup that grants you IDE Powers | Neovim from Scratch Part 4](https://youtu.be/b17g20II6SQ) 15 | * [Perfect Code Formatting with conform.nvim | Neovim Configuration from Scratch Part 5](https://youtu.be/UVO_cq3xATo) 16 | * [blink-cmp: Lightning-Fast Autocompletion Built in Rust | Neovim from Scratch Part 6](https://youtu.be/GKIxgCcKAq4) 17 | 18 | ## The Plan 19 | 20 | - [X] lazy.nvim 21 | - [X] kanagawa.nvim 22 | - [X] mini.statusline 23 | - [X] oil.nvim 24 | - [X] Basic options 25 | - [X] vim-sleuth 26 | - [X] editorconf 27 | - [X] showkeys 28 | - [X] treesitter.nvim 29 | - [X] treesitter-textobjects 30 | - [X] which-key 31 | - [X] fzflua 32 | - [X] project.nvim 33 | - [X] LSP 34 | - [X] Mason 35 | - [X] dressing.nvim 36 | - [X] conform.nvim 37 | - [X] blink-cmp 38 | -------------------------------------------------------------------------------- /init.lua: -------------------------------------------------------------------------------- 1 | require("config.lazy") 2 | -------------------------------------------------------------------------------- /lua/config/keymaps.lua: -------------------------------------------------------------------------------- 1 | vim.keymap.set("n", "-", "Oil --float", { desc = "Open Parent Directory in Oil" }) 2 | vim.keymap.set("n", "gl", function() 3 | vim.diagnostic.open_float() 4 | end, { desc = "Open Diagnostics in Float" }) 5 | 6 | vim.keymap.set("n", "cf", function() 7 | require("conform").format({ 8 | lsp_format = "fallback", 9 | }) 10 | end, { desc = "Format current file" }) 11 | 12 | -- Map fp to open projects 13 | vim.keymap.set("n", "fp", ":ProjectFzf", { noremap = true, silent = true }) 14 | -------------------------------------------------------------------------------- /lua/config/lazy.lua: -------------------------------------------------------------------------------- 1 | -- Bootstrap lazy.nvim 2 | local lazypath = vim.fn.stdpath("data") .. "/lazy/lazy.nvim" 3 | if not (vim.uv or vim.loop).fs_stat(lazypath) then 4 | local lazyrepo = "https://github.com/folke/lazy.nvim.git" 5 | local out = vim.fn.system({ "git", "clone", "--filter=blob:none", "--branch=stable", lazyrepo, lazypath }) 6 | if vim.v.shell_error ~= 0 then 7 | vim.api.nvim_echo({ 8 | { "Failed to clone lazy.nvim:\n", "ErrorMsg" }, 9 | { out, "WarningMsg" }, 10 | { "\nPress any key to exit..." }, 11 | }, true, {}) 12 | vim.fn.getchar() 13 | os.exit(1) 14 | end 15 | end 16 | vim.opt.rtp:prepend(lazypath) 17 | 18 | -- Make sure to setup `mapleader` and `maplocalleader` before 19 | -- loading lazy.nvim so that mappings are correct. 20 | -- This is also a good place to setup other settings (vim.opt) 21 | vim.g.mapleader = "," 22 | vim.g.maplocalleader = "\\" 23 | 24 | require("config.options") 25 | 26 | -- Setup lazy.nvim 27 | require("lazy").setup({ 28 | spec = { 29 | -- import your plugins 30 | { import = "plugins" }, 31 | }, 32 | -- Configure any other settings here. See the documentation for more details. 33 | -- colorscheme that will be used when installing plugins. 34 | install = { colorscheme = { "kanagawa" } }, 35 | -- automatically check for plugin updates 36 | checker = { enabled = true }, 37 | }) 38 | 39 | require("config.keymaps") 40 | 41 | -- For video recording purposes 42 | vim.cmd("ShowkeysToggle") 43 | -------------------------------------------------------------------------------- /lua/config/options.lua: -------------------------------------------------------------------------------- 1 | -- Some keyboard mappings as I don't want to break my fingers, while typing on a "german" keyboard ;) 2 | vim.opt.langmap = "+]ü[" 3 | -- Plain langmap remapping does not seem to do the trick :( 4 | vim.keymap.set("n", "ü", "[", { remap = true }) 5 | 6 | vim.opt.expandtab = true -- Convert tabs to spaces 7 | vim.opt.shiftwidth = 4 -- Amount to indent with << and >> 8 | vim.opt.tabstop = 4 -- How many spaces are shown per Tab 9 | vim.opt.softtabstop = 4 -- How many spaces are applied when pressing Tab 10 | 11 | vim.opt.smarttab = true 12 | vim.opt.smartindent = true 13 | vim.opt.autoindent = true -- Keep identation from previous line 14 | 15 | -- Enable break indent 16 | vim.opt.breakindent = true 17 | 18 | -- Always show relative line numbers 19 | vim.opt.number = true 20 | vim.opt.relativenumber = true 21 | 22 | -- Show line under cursor 23 | vim.opt.cursorline = true 24 | 25 | -- Store undos between sessions 26 | vim.opt.undofile = true 27 | 28 | -- Enable mouse mode, can be useful for resizing splits for example! 29 | vim.opt.mouse = "a" 30 | 31 | -- Don't show the mode, since it's already in the status line 32 | vim.opt.showmode = false 33 | 34 | -- Case-insensitive searching UNLESS \C or one or more capital letters in the search term 35 | vim.opt.ignorecase = true 36 | vim.opt.smartcase = true 37 | 38 | -- Keep signcolumn on by default 39 | vim.opt.signcolumn = "yes" 40 | 41 | -- Configure how new splits should be opened 42 | vim.opt.splitright = true 43 | vim.opt.splitbelow = true 44 | 45 | -- Sets how neovim will display certain whitespace characters in the editor. 46 | -- See `:help 'list'` 47 | -- and `:help 'listchars'` 48 | vim.opt.list = true 49 | vim.opt.listchars = { tab = "» ", trail = "·", nbsp = "␣" } 50 | 51 | -- Minimal number of screen lines to keep above and below the cursor. 52 | vim.opt.scrolloff = 5 53 | 54 | -------------------------------------------------------------------------------- /lua/plugins/blink-cmp.lua: -------------------------------------------------------------------------------- 1 | return { 2 | { 3 | "saghen/blink.compat", 4 | -- use the latest release, via version = '*', if you also use the latest release for blink.cmp 5 | version = "*", 6 | -- lazy.nvim will automatically load the plugin when it's required by blink.cmp 7 | lazy = true, 8 | -- make sure to set opts so that lazy.nvim calls blink.compat's setup 9 | opts = {}, 10 | }, 11 | { 12 | "saghen/blink.cmp", 13 | -- optional: provides snippets for the snippet source 14 | dependencies = { 15 | "rafamadriz/friendly-snippets", 16 | "moyiz/blink-emoji.nvim", 17 | "ray-x/cmp-sql", 18 | }, 19 | 20 | -- use a release tag to download pre-built binaries 21 | version = "1.*", 22 | -- AND/OR build from source, requires nightly: https://rust-lang.github.io/rustup/concepts/channels.html#working-with-nightly-rust 23 | -- build = 'cargo build --release', 24 | -- If you use nix, you can build from source using latest nightly rust with: 25 | -- build = 'nix run .#build-plugin', 26 | 27 | ---@module 'blink.cmp' 28 | ---@type blink.cmp.Config 29 | opts = { 30 | -- 'default' (recommended) for mappings similar to built-in completions (C-y to accept) 31 | -- 'super-tab' for mappings similar to vscode (tab to accept) 32 | -- 'enter' for enter to accept 33 | -- 'none' for no mappings 34 | -- 35 | -- All presets have the following mappings: 36 | -- C-space: Open menu or open docs if already open 37 | -- C-n/C-p or Up/Down: Select next/previous item 38 | -- C-e: Hide menu 39 | -- C-k: Toggle signature help (if signature.enabled = true) 40 | -- 41 | -- See :h blink-cmp-config-keymap for defining your own keymap 42 | keymap = { 43 | preset = "default", 44 | [""] = { "accept", "fallback" }, 45 | }, 46 | 47 | appearance = { 48 | -- 'mono' (default) for 'Nerd Font Mono' or 'normal' for 'Nerd Font' 49 | -- Adjusts spacing to ensure icons are aligned 50 | nerd_font_variant = "mono", 51 | }, 52 | 53 | -- (Default) Only show the documentation popup when manually triggered 54 | completion = { documentation = { auto_show = true } }, 55 | signature = { enabled = true }, 56 | 57 | -- Default list of enabled providers defined so that you can extend it 58 | -- elsewhere in your config, without redefining it, due to `opts_extend` 59 | sources = { 60 | default = { "lsp", "path", "snippets", "buffer", "emoji", "sql" }, 61 | providers = { 62 | emoji = { 63 | module = "blink-emoji", 64 | name = "Emoji", 65 | score_offset = 15, -- Tune by preference 66 | opts = { insert = true }, -- Insert emoji (default) or complete its name 67 | should_show_items = function() 68 | return vim.tbl_contains( 69 | -- Enable emoji completion only for git commits and markdown. 70 | -- By default, enabled for all file-types. 71 | { "gitcommit", "markdown" }, 72 | vim.o.filetype 73 | ) 74 | end, 75 | }, 76 | sql = { 77 | -- IMPORTANT: use the same name as you would for nvim-cmp 78 | name = "sql", 79 | module = "blink.compat.source", 80 | 81 | -- all blink.cmp source config options work as normal: 82 | score_offset = -3, 83 | 84 | -- this table is passed directly to the proxied completion source 85 | -- as the `option` field in nvim-cmp's source config 86 | -- 87 | -- this is NOT the same as the opts in a plugin's lazy.nvim spec 88 | opts = {}, 89 | should_show_items = function() 90 | return vim.tbl_contains( 91 | -- Enable emoji completion only for git commits and markdown. 92 | -- By default, enabled for all file-types. 93 | { "sql" }, 94 | vim.o.filetype 95 | ) 96 | end, 97 | }, 98 | }, 99 | }, 100 | 101 | -- (Default) Rust fuzzy matcher for typo resistance and significantly better performance 102 | -- You may use a lua implementation instead by using `implementation = "lua"` or fallback to the lua implementation, 103 | -- when the Rust fuzzy matcher is not available, by using `implementation = "prefer_rust"` 104 | -- 105 | -- See the fuzzy documentation for more information 106 | fuzzy = { implementation = "prefer_rust_with_warning" }, 107 | }, 108 | opts_extend = { "sources.default" }, 109 | }, 110 | } 111 | -------------------------------------------------------------------------------- /lua/plugins/conform.lua: -------------------------------------------------------------------------------- 1 | return { 2 | "stevearc/conform.nvim", 3 | opts = { 4 | formatters_by_ft = { 5 | lua = { "stylua" }, 6 | -- Conform will run multiple formatters sequentially 7 | python = { "isort", "black" }, 8 | -- You can customize some of the format options for the filetype (:help conform.format) 9 | rust = { "rustfmt" }, 10 | -- Conform will run the first available formatter 11 | javascript = { "prettierd", "prettier", stop_after_first = true }, 12 | typescript = { "prettierd", "prettier", stop_after_first = true }, 13 | }, 14 | format_on_save = { 15 | -- These options will be passed to conform.format() 16 | timeout_ms = 500, 17 | lsp_format = "fallback", 18 | }, 19 | }, 20 | } 21 | -------------------------------------------------------------------------------- /lua/plugins/dressing.lua: -------------------------------------------------------------------------------- 1 | return { 2 | 'stevearc/dressing.nvim', 3 | opts = {}, 4 | } 5 | -------------------------------------------------------------------------------- /lua/plugins/fzflua.lua: -------------------------------------------------------------------------------- 1 | return { 2 | "ibhagwan/fzf-lua", 3 | -- optional for icon support 4 | -- dependencies = { "nvim-tree/nvim-web-devicons" }, 5 | -- or if using mini.icons/mini.nvim 6 | dependencies = { "echasnovski/mini.icons" }, 7 | opts = {}, 8 | keys={ 9 | { 10 | "ff", 11 | function() require('fzf-lua').files() end, 12 | desc="Find Files in project directory" 13 | }, 14 | { 15 | "fg", 16 | function() require('fzf-lua').live_grep() end, 17 | desc="Find by grepping in project directory" 18 | }, 19 | { 20 | "fc", 21 | function() require('fzf-lua').files({cwd=vim.fn.stdpath("config")}) end, 22 | desc="Find in neovim configuration" 23 | }, 24 | { 25 | "fh", 26 | function() 27 | require("fzf-lua").helptags() 28 | end, 29 | desc = "[F]ind [H]elp", 30 | }, 31 | { 32 | "fk", 33 | function() 34 | require("fzf-lua").keymaps() 35 | end, 36 | desc = "[F]ind [K]eymaps", 37 | }, 38 | { 39 | "fb", 40 | function() 41 | require("fzf-lua").builtin() 42 | end, 43 | desc = "[F]ind [B]uiltin FZF", 44 | }, 45 | { 46 | "fw", 47 | function() 48 | require("fzf-lua").grep_cword() 49 | end, 50 | desc = "[F]ind current [W]ord", 51 | }, 52 | { 53 | "fW", 54 | function() 55 | require("fzf-lua").grep_cWORD() 56 | end, 57 | desc = "[F]ind current [W]ORD", 58 | }, 59 | { 60 | "fd", 61 | function() 62 | require("fzf-lua").diagnostics_document() 63 | end, 64 | desc = "[F]ind [D]iagnostics", 65 | }, 66 | { 67 | "fr", 68 | function() 69 | require("fzf-lua").resume() 70 | end, 71 | desc = "[F]ind [R]esume", 72 | }, 73 | { 74 | "fo", 75 | function() 76 | require("fzf-lua").oldfiles() 77 | end, 78 | desc = "[F]ind [O]ld Files", 79 | }, 80 | { 81 | "", 82 | function() 83 | require("fzf-lua").buffers() 84 | end, 85 | desc = "[,] Find existing buffers", 86 | }, 87 | { 88 | "/", 89 | function() 90 | require("fzf-lua").lgrep_curbuf() 91 | end, 92 | desc = "[/] Live grep the current buffer", 93 | }, 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /lua/plugins/kanagawa.lua: -------------------------------------------------------------------------------- 1 | return { 2 | "rebelot/kanagawa.nvim", 3 | branch="master", 4 | config=function() 5 | require('kanagawa').setup({ 6 | transparent=true, 7 | overrides=function(colors) 8 | return { 9 | ["@markup.link.url.markdown_inline"] = { link = "Special" }, -- (url) 10 | ["@markup.link.label.markdown_inline"] = { link = "WarningMsg" }, -- [label] 11 | ["@markup.italic.markdown_inline"] = { link = "Exception" }, -- *italic* 12 | ["@markup.raw.markdown_inline"] = { link = "String" }, -- `code` 13 | ["@markup.list.markdown"] = { link = "Function" }, -- + list 14 | ["@markup.quote.markdown"] = { link = "Error" }, -- > blockcode 15 | ["@markup.list.checked.markdown"] = { link = "WarningMsg" } -- - [X] checked list item 16 | } 17 | end 18 | }); 19 | vim.cmd("colorscheme kanagawa"); 20 | end, 21 | } 22 | -------------------------------------------------------------------------------- /lua/plugins/lsp.lua: -------------------------------------------------------------------------------- 1 | return { 2 | -- Main LSP Configuration 3 | "neovim/nvim-lspconfig", 4 | dependencies = { 5 | -- Automatically install LSPs and related tools to stdpath for Neovim 6 | -- Mason must be loaded before its dependents so we need to set it up here. 7 | -- NOTE: `opts = {}` is the same as calling `require('mason').setup({})` 8 | { "williamboman/mason.nvim", opts = {} }, 9 | "williamboman/mason-lspconfig.nvim", 10 | "WhoIsSethDaniel/mason-tool-installer.nvim", 11 | 12 | -- Useful status updates for LSP. 13 | { "j-hui/fidget.nvim", opts = {} }, 14 | }, 15 | config = function() 16 | -- Brief aside: **What is LSP?** 17 | -- 18 | -- LSP is an initialism you've probably heard, but might not understand what it is. 19 | -- 20 | -- LSP stands for Language Server Protocol. It's a protocol that helps editors 21 | -- and language tooling communicate in a standardized fashion. 22 | -- 23 | -- In general, you have a "server" which is some tool built to understand a particular 24 | -- language (such as `gopls`, `lua_ls`, `rust_analyzer`, etc.). These Language Servers 25 | -- (sometimes called LSP servers, but that's kind of like ATM Machine) are standalone 26 | -- processes that communicate with some "client" - in this case, Neovim! 27 | -- 28 | -- LSP provides Neovim with features like: 29 | -- - Go to definition 30 | -- - Find references 31 | -- - Autocompletion 32 | -- - Symbol Search 33 | -- - and more! 34 | -- 35 | -- Thus, Language Servers are external tools that must be installed separately from 36 | -- Neovim. This is where `mason` and related plugins come into play. 37 | -- 38 | -- If you're wondering about lsp vs treesitter, you can check out the wonderfully 39 | -- and elegantly composed help section, `:help lsp-vs-treesitter` 40 | 41 | -- This function gets run when an LSP attaches to a particular buffer. 42 | -- That is to say, every time a new file is opened that is associated with 43 | -- an lsp (for example, opening `main.rs` is associated with `rust_analyzer`) this 44 | -- function will be executed to configure the current buffer 45 | vim.api.nvim_create_autocmd("LspAttach", { 46 | group = vim.api.nvim_create_augroup("kickstart-lsp-attach", { clear = true }), 47 | callback = function(event) 48 | -- NOTE: Remember that Lua is a real programming language, and as such it is possible 49 | -- to define small helper and utility functions so you don't have to repeat yourself. 50 | -- 51 | -- In this case, we create a function that lets us more easily define mappings specific 52 | -- for LSP related items. It sets the mode, buffer and description for us each time. 53 | local map = function(keys, func, desc, mode) 54 | mode = mode or "n" 55 | vim.keymap.set(mode, keys, func, { buffer = event.buf, desc = "LSP: " .. desc }) 56 | end 57 | 58 | -- Jump to the definition of the word under your cursor. 59 | -- This is where a variable was first declared, or where a function is defined, etc. 60 | -- To jump back, press . 61 | map("gd", require("fzf-lua").lsp_definitions, "[G]oto [D]efinition") 62 | 63 | -- Find references for the word under your cursor. 64 | map("gr", require("fzf-lua").lsp_references, "[G]oto [R]eferences") 65 | 66 | -- Jump to the implementation of the word under your cursor. 67 | -- Useful when your language has ways of declaring types without an actual implementation. 68 | map("gI", require("fzf-lua").lsp_implementations, "[G]oto [I]mplementation") 69 | 70 | -- Jump to the type of the word under your cursor. 71 | -- Useful when you're not sure what type a variable is and you want to see 72 | -- the definition of its *type*, not where it was *defined*. 73 | map("D", require("fzf-lua").lsp_typedefs, "Type [D]efinition") 74 | 75 | -- Fuzzy find all the symbols in your current document. 76 | -- Symbols are things like variables, functions, types, etc. 77 | map("ds", require("fzf-lua").lsp_document_symbols, "[D]ocument [S]ymbols") 78 | 79 | -- Fuzzy find all the symbols in your current workspace. 80 | -- Similar to document symbols, except searches over your entire project. 81 | map("ws", require("fzf-lua").lsp_live_workspace_symbols, "[W]orkspace [S]ymbols") 82 | 83 | -- Rename the variable under your cursor. 84 | -- Most Language Servers support renaming across files, etc. 85 | map("cr", vim.lsp.buf.rename, "[R]e[n]ame") 86 | 87 | -- Execute a code action, usually your cursor needs to be on top of an error 88 | -- or a suggestion from your LSP for this to activate. 89 | map("ca", vim.lsp.buf.code_action, "[C]ode [A]ction", { "n", "x" }) 90 | 91 | -- WARN: This is not Goto Definition, this is Goto Declaration. 92 | -- For example, in C this would take you to the header. 93 | map("gD", vim.lsp.buf.declaration, "[G]oto [D]eclaration") 94 | 95 | -- This function resolves a difference between neovim nightly (version 0.11) and stable (version 0.10) 96 | ---@param client vim.lsp.Client 97 | ---@param method vim.lsp.protocol.Method 98 | ---@param bufnr? integer some lsp support methods only in specific files 99 | ---@return boolean 100 | local function client_supports_method(client, method, bufnr) 101 | if vim.fn.has("nvim-0.11") == 1 then 102 | return client:supports_method(method, bufnr) 103 | else 104 | return client.supports_method(method, { bufnr = bufnr }) 105 | end 106 | end 107 | 108 | -- The following two autocommands are used to highlight references of the 109 | -- word under your cursor when your cursor rests there for a little while. 110 | -- See `:help CursorHold` for information about when this is executed 111 | -- 112 | -- When you move your cursor, the highlights will be cleared (the second autocommand). 113 | local client = vim.lsp.get_client_by_id(event.data.client_id) 114 | if 115 | client 116 | and client_supports_method( 117 | client, 118 | vim.lsp.protocol.Methods.textDocument_documentHighlight, 119 | event.buf 120 | ) 121 | then 122 | local highlight_augroup = vim.api.nvim_create_augroup("kickstart-lsp-highlight", { clear = false }) 123 | vim.api.nvim_create_autocmd({ "CursorHold", "CursorHoldI" }, { 124 | buffer = event.buf, 125 | group = highlight_augroup, 126 | callback = vim.lsp.buf.document_highlight, 127 | }) 128 | 129 | vim.api.nvim_create_autocmd({ "CursorMoved", "CursorMovedI" }, { 130 | buffer = event.buf, 131 | group = highlight_augroup, 132 | callback = vim.lsp.buf.clear_references, 133 | }) 134 | 135 | vim.api.nvim_create_autocmd("LspDetach", { 136 | group = vim.api.nvim_create_augroup("kickstart-lsp-detach", { clear = true }), 137 | callback = function(event2) 138 | vim.lsp.buf.clear_references() 139 | vim.api.nvim_clear_autocmds({ group = "kickstart-lsp-highlight", buffer = event2.buf }) 140 | end, 141 | }) 142 | end 143 | 144 | -- The following code creates a keymap to toggle inlay hints in your 145 | -- code, if the language server you are using supports them 146 | -- 147 | -- This may be unwanted, since they displace some of your code 148 | if 149 | client 150 | and client_supports_method(client, vim.lsp.protocol.Methods.textDocument_inlayHint, event.buf) 151 | then 152 | map("th", function() 153 | vim.lsp.inlay_hint.enable(not vim.lsp.inlay_hint.is_enabled({ bufnr = event.buf })) 154 | end, "[T]oggle Inlay [H]ints") 155 | end 156 | end, 157 | }) 158 | 159 | -- Diagnostic Config 160 | -- See :help vim.diagnostic.Opts 161 | vim.diagnostic.config({ 162 | severity_sort = true, 163 | float = { border = "rounded", source = "if_many" }, 164 | underline = { severity = vim.diagnostic.severity.ERROR }, 165 | signs = { 166 | text = { 167 | [vim.diagnostic.severity.ERROR] = "󰅚 ", 168 | [vim.diagnostic.severity.WARN] = "󰀪 ", 169 | [vim.diagnostic.severity.INFO] = "󰋽 ", 170 | [vim.diagnostic.severity.HINT] = "󰌶 ", 171 | }, 172 | }, 173 | virtual_text = { 174 | source = "if_many", 175 | spacing = 2, 176 | format = function(diagnostic) 177 | local diagnostic_message = { 178 | [vim.diagnostic.severity.ERROR] = diagnostic.message, 179 | [vim.diagnostic.severity.WARN] = diagnostic.message, 180 | [vim.diagnostic.severity.INFO] = diagnostic.message, 181 | [vim.diagnostic.severity.HINT] = diagnostic.message, 182 | } 183 | return diagnostic_message[diagnostic.severity] 184 | end, 185 | }, 186 | }) 187 | 188 | -- LSP servers and clients are able to communicate to each other what features they support. 189 | -- By default, Neovim doesn't support everything that is in the LSP specification. 190 | -- When you add nvim-cmp, luasnip, etc. Neovim now has *more* capabilities. 191 | -- So, we create new capabilities with nvim cmp, and then broadcast that to the servers. 192 | local original_capabilities = vim.lsp.protocol.make_client_capabilities() 193 | local capabilities = require("blink.cmp").get_lsp_capabilities(original_capabilities) 194 | -- capabilities = vim.tbl_deep_extend('force', capabilities, require('cmp_nvim_lsp').default_capabilities()) 195 | 196 | -- Enable the following language servers 197 | -- Feel free to add/remove any LSPs that you want here. They will automatically be installed. 198 | -- 199 | -- Add any additional override configuration in the following tables. Available keys are: 200 | -- - cmd (table): Override the default command used to start the server 201 | -- - filetypes (table): Override the default list of associated filetypes for the server 202 | -- - capabilities (table): Override fields in capabilities. Can be used to disable certain LSP features. 203 | -- - settings (table): Override the default settings passed when initializing the server. 204 | -- For example, to see the options for `lua_ls`, you could go to: https://luals.github.io/wiki/settings/ 205 | local servers = { 206 | bashls = {}, 207 | marksman = {}, 208 | -- clangd = {}, 209 | -- gopls = {}, 210 | -- pyright = {}, 211 | -- rust_analyzer = {}, 212 | -- ... etc. See `:help lspconfig-all` for a list of all the pre-configured LSPs 213 | -- 214 | -- Some languages (like typescript) have entire language plugins that can be useful: 215 | -- https://github.com/pmizio/typescript-tools.nvim 216 | -- 217 | -- But for many setups, the LSP (`ts_ls`) will work just fine 218 | -- ts_ls = {}, 219 | -- 220 | 221 | lua_ls = { 222 | -- cmd = { ... }, 223 | -- filetypes = { ... }, 224 | -- capabilities = {}, 225 | -- settings = { 226 | -- Lua = { 227 | -- completion = { 228 | -- callSnippet = 'Replace', 229 | -- }, 230 | -- -- You can toggle below to ignore Lua_LS's noisy `missing-fields` warnings 231 | -- -- diagnostics = { disable = { 'missing-fields' } }, 232 | -- }, 233 | -- }, 234 | }, 235 | } 236 | 237 | -- Ensure the servers and tools above are installed 238 | -- 239 | -- To check the current status of installed tools and/or manually install 240 | -- other tools, you can run 241 | -- :Mason 242 | -- 243 | -- You can press `g?` for help in this menu. 244 | -- 245 | -- `mason` had to be setup earlier: to configure its options see the 246 | -- `dependencies` table for `nvim-lspconfig` above. 247 | -- 248 | -- You can add other tools here that you want Mason to install 249 | -- for you, so that they are available from within Neovim. 250 | local ensure_installed = vim.tbl_keys(servers or {}) 251 | vim.list_extend(ensure_installed, { 252 | "stylua", -- Used to format Lua code 253 | "prettierd", -- Used to format javascript and typescript code 254 | }) 255 | require("mason-tool-installer").setup({ ensure_installed = ensure_installed }) 256 | 257 | require("mason-lspconfig").setup({ 258 | ensure_installed = {}, -- explicitly set to an empty table (Kickstart populates installs via mason-tool-installer) 259 | automatic_installation = false, 260 | handlers = { 261 | function(server_name) 262 | local server = servers[server_name] or {} 263 | -- This handles overriding only values explicitly passed 264 | -- by the server configuration above. Useful when disabling 265 | -- certain features of an LSP (for example, turning off formatting for ts_ls) 266 | server.capabilities = vim.tbl_deep_extend("force", {}, capabilities, server.capabilities or {}) 267 | require("lspconfig")[server_name].setup(server) 268 | end, 269 | }, 270 | }) 271 | end, 272 | } 273 | -------------------------------------------------------------------------------- /lua/plugins/nvim-treesitter-textobjects.lua: -------------------------------------------------------------------------------- 1 | return { 2 | "nvim-treesitter/nvim-treesitter-textobjects", 3 | dependencies = { 4 | "nvim-treesitter/nvim-treesitter" 5 | }, 6 | init = function() 7 | local config = require'nvim-treesitter.configs'; 8 | config.setup({ 9 | textobjects = { 10 | select = { 11 | enable = true, 12 | 13 | -- Automatically jump forward to textobj, similar to targets.vim 14 | lookahead = true, 15 | 16 | keymaps = { 17 | -- You can use the capture groups defined in textobjects.scm 18 | ["af"] = "@function.outer", 19 | ["if"] = "@function.inner", 20 | ["ac"] = "@class.outer", 21 | ["ao"] = "@comment.outer", 22 | -- You can optionally set descriptions to the mappings (used in the desc parameter of 23 | -- nvim_buf_set_keymap) which plugins like which-key display 24 | ["ic"] = { query = "@class.inner", desc = "Select inner part of a class region" }, 25 | -- You can also use captures from other query groups like `locals.scm` 26 | ["as"] = { query = "@local.scope", query_group = "locals", desc = "Select language scope" }, 27 | }, 28 | -- You can choose the select mode (default is charwise 'v') 29 | -- 30 | -- Can also be a function which gets passed a table with the keys 31 | -- * query_string: eg '@function.inner' 32 | -- * method: eg 'v' or 'o' 33 | -- and should return the mode ('v', 'V', or '') or a table 34 | -- mapping query_strings to modes. 35 | selection_modes = { 36 | ['@parameter.outer'] = 'v', -- charwise 37 | ['@function.outer'] = 'V', -- linewise 38 | ['@class.outer'] = '', -- blockwise 39 | }, 40 | -- If you set this to `true` (default is `false`) then any textobject is 41 | -- extended to include preceding or succeeding whitespace. Succeeding 42 | -- whitespace has priority in order to act similarly to eg the built-in 43 | -- `ap`. 44 | -- 45 | -- Can also be a function which gets passed a table with the keys 46 | -- * query_string: eg '@function.inner' 47 | -- * selection_mode: eg 'v' 48 | -- and should return true or false 49 | include_surrounding_whitespace = true, 50 | }, 51 | swap = { 52 | enable = true, 53 | swap_next = { 54 | ["a"] = {query="@parameter.inner", desc="Swap with next parameter"}, 55 | }, 56 | swap_previous = { 57 | ["A"] = "@parameter.inner", 58 | }, 59 | }, 60 | }, 61 | }); 62 | end 63 | } 64 | -------------------------------------------------------------------------------- /lua/plugins/nvim-treesitter.lua: -------------------------------------------------------------------------------- 1 | return { 2 | "nvim-treesitter/nvim-treesitter", 3 | build = ":TSUpdate", 4 | config = function () 5 | local configs = require("nvim-treesitter.configs") 6 | 7 | configs.setup({ 8 | ensure_installed = { 9 | "c", "lua", "vim", "vimdoc", "query", "elixir", "heex", "javascript", "html", "markdown", "markdown_inline" 10 | }, 11 | auto_install = true, 12 | sync_install = false, 13 | highlight = { enable = true }, 14 | indent = { enable = true }, 15 | 16 | incremental_selection = { 17 | enable = true, 18 | keymaps = { 19 | init_selection = "", -- set to `false` to disable one of the mappings 20 | node_incremental = "", 21 | scope_incremental = false, 22 | node_decremental = "", 23 | }, 24 | }, 25 | }) 26 | end 27 | } 28 | -------------------------------------------------------------------------------- /lua/plugins/oil.lua: -------------------------------------------------------------------------------- 1 | return { 2 | "stevearc/oil.nvim", 3 | ---@module 'oil' 4 | ---@type oil.SetupOpts 5 | opts = { 6 | view_options = { 7 | show_hidden = true, 8 | }, 9 | }, 10 | -- Optional dependencies 11 | dependencies = { { "echasnovski/mini.icons", opts = {} } }, 12 | -- dependencies = { "nvim-tree/nvim-web-devicons" }, -- use if you prefer nvim-web-devicons 13 | -- Lazy loading is not recommended because it is very tricky to make it work correctly in all situations. 14 | lazy = false, 15 | } 16 | -------------------------------------------------------------------------------- /lua/plugins/project-fzf.lua: -------------------------------------------------------------------------------- 1 | return { 2 | "jakobwesthoff/project-fzf.nvim", 3 | dependencies = { 4 | "ahmedkhalf/project.nvim", -- Must be configured separately 5 | "ibhagwan/fzf-lua", 6 | }, 7 | opts = {}, -- Will call require('project-fzf').setup(opts) 8 | } 9 | -------------------------------------------------------------------------------- /lua/plugins/project.lua: -------------------------------------------------------------------------------- 1 | return { 2 | "ahmedkhalf/project.nvim", 3 | init = function() 4 | require("project_nvim").setup { 5 | -- your configuration comes her 6 | -- or leave it empty to use the default settings 7 | -- refer to the configuration section below 8 | } 9 | 10 | 11 | -- Absolutely minimal implementation of fzf-lua based project finder 12 | -- for fzf-lua, due to request from @KrisWilliams1 (Maybe extended to a 13 | -- full blown port from the original selector in the future) 14 | local history = require("project_nvim.utils.history") 15 | local project = require("project_nvim.project") 16 | 17 | vim.api.nvim_create_user_command("FzfProjects", function() 18 | local projects = history.get_recent_projects() 19 | 20 | require("fzf-lua").fzf_exec(projects, { 21 | prompt = "Projects> ", 22 | actions = { 23 | ["default"] = function(selected) 24 | if selected and #selected > 0 then 25 | local project_path = selected[1] 26 | if project.set_pwd(project_path, "fzf-lua") then 27 | require("fzf-lua").files() 28 | end 29 | end 30 | end 31 | } 32 | }) 33 | end, {}) 34 | end, 35 | keys = { 36 | { 37 | "fp", "FzfProjects", desc="Find Recent Projects" 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /lua/plugins/rustacean.lua: -------------------------------------------------------------------------------- 1 | return { 2 | 'mrcjkb/rustaceanvim', 3 | version = '^5', -- Recommended 4 | lazy = false, -- This plugin is already lazy 5 | } 6 | -------------------------------------------------------------------------------- /lua/plugins/showkeys.lua: -------------------------------------------------------------------------------- 1 | return { 2 | "nvzone/showkeys", 3 | cmd = "ShowkeysToggle", 4 | opts={ 5 | maxkeys=5 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /lua/plugins/sleuth-vim.lua: -------------------------------------------------------------------------------- 1 | return { 2 | "tpope/vim-sleuth", 3 | -- No further initialization needed, as this is a real "vim" not a lua 4 | -- plugin. 5 | } 6 | -------------------------------------------------------------------------------- /lua/plugins/statusline.lua: -------------------------------------------------------------------------------- 1 | return { 'echasnovski/mini.statusline', version = false, opts={} } 2 | -------------------------------------------------------------------------------- /lua/plugins/which-key.lua: -------------------------------------------------------------------------------- 1 | return { 2 | "folke/which-key.nvim", 3 | event = "VeryLazy", 4 | opts = { 5 | -- your configuration comes here 6 | -- or leave it empty to use the default settings 7 | -- refer to the configuration section below 8 | }, 9 | keys = { 10 | { 11 | "?", 12 | function() 13 | require("which-key").show({ global = false }) 14 | end, 15 | desc = "Buffer Local Keymaps (which-key)", 16 | }, 17 | }, 18 | } 19 | --------------------------------------------------------------------------------