init.lua 36 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866
  1. --[[
  2. =====================================================================
  3. ==================== READ THIS BEFORE CONTINUING ====================
  4. =====================================================================
  5. ======== .-----. ========
  6. ======== .----------------------. | === | ========
  7. ======== |.-""""""""""""""""""-.| |-----| ========
  8. ======== || || | === | ========
  9. ======== || KICKSTART.NVIM || |-----| ========
  10. ======== || || | === | ========
  11. ======== || || |-----| ========
  12. ======== ||:Tutor || |:::::| ========
  13. ======== |'-..................-'| |____o| ========
  14. ======== `"")----------------(""` ___________ ========
  15. ======== /::::::::::| |::::::::::\ \ no mouse \ ========
  16. ======== /:::========| |==hjkl==:::\ \ required \ ========
  17. ======== '""""""""""""' '""""""""""""' '""""""""""' ========
  18. ======== ========
  19. =====================================================================
  20. =====================================================================
  21. What is Kickstart?
  22. Kickstart.nvim is *not* a distribution.
  23. Kickstart.nvim is a starting point for your own configuration.
  24. The goal is that you can read every line of code, top-to-bottom, understand
  25. what your configuration is doing, and modify it to suit your needs.
  26. Once you've done that, you can start exploring, configuring and tinkering to
  27. make Neovim your own! That might mean leaving Kickstart just the way it is for a while
  28. or immediately breaking it into modular pieces. It's up to you!
  29. If you don't know anything about Lua, I recommend taking some time to read through
  30. a guide. One possible example which will only take 10-15 minutes:
  31. - https://learnxinyminutes.com/docs/lua/
  32. After understanding a bit more about Lua, you can use `:help lua-guide` as a
  33. reference for how Neovim integrates Lua.
  34. - :help lua-guide
  35. - (or HTML version): https://neovim.io/doc/user/lua-guide.html
  36. Kickstart Guide:
  37. TODO: The very first thing you should do is to run the command `:Tutor` in Neovim.
  38. If you don't know what this means, type the following:
  39. - <escape key>
  40. - :
  41. - Tutor
  42. - <enter key>
  43. (If you already know the Neovim basics, you can skip this step.)
  44. Once you've completed that, you can continue working through **AND READING** the rest
  45. of the kickstart init.lua.
  46. Next, run AND READ `:help`.
  47. This will open up a help window with some basic information
  48. about reading, navigating and searching the builtin help documentation.
  49. This should be the first place you go to look when you're stuck or confused
  50. with something. It's one of my favorite Neovim features.
  51. MOST IMPORTANTLY, we provide a keymap "<space>sh" to [s]earch the [h]elp documentation,
  52. which is very useful when you're not exactly sure of what you're looking for.
  53. I have left several `:help X` comments throughout the init.lua
  54. These are hints about where to find more information about the relevant settings,
  55. plugins or Neovim features used in Kickstart.
  56. NOTE: Look for lines like this
  57. Throughout the file. These are for you, the reader, to help you understand what is happening.
  58. Feel free to delete them once you know what you're doing, but they should serve as a guide
  59. for when you are first encountering a few different constructs in your Neovim config.
  60. If you experience any errors while trying to install kickstart, run `:checkhealth` for more info.
  61. I hope you enjoy your Neovim journey,
  62. - TJ
  63. P.S. You can delete this when you're done too. It's your config now! :)
  64. --]]
  65. -- Set <space> as the leader key
  66. -- See `:help mapleader`
  67. -- NOTE: Must happen before plugins are loaded (otherwise wrong leader will be used)
  68. vim.g.mapleader = ' '
  69. vim.g.maplocalleader = ' '
  70. -- Set to true if you have a Nerd Font installed
  71. vim.g.have_nerd_font = false
  72. -- [[ Setting options ]]
  73. -- See `:help vim.opt`
  74. -- NOTE: You can change these options as you wish!
  75. -- For more options, you can see `:help option-list`
  76. -- Make line numbers default
  77. vim.opt.number = true
  78. -- You can also add relative line numbers, to help with jumping.
  79. -- Experiment for yourself to see if you like it!
  80. -- vim.opt.relativenumber = true
  81. -- Enable mouse mode, can be useful for resizing splits for example!
  82. vim.opt.mouse = 'a'
  83. -- Don't show the mode, since it's already in the status line
  84. vim.opt.showmode = false
  85. -- Sync clipboard between OS and Neovim.
  86. -- Remove this option if you want your OS clipboard to remain independent.
  87. -- See `:help 'clipboard'`
  88. vim.opt.clipboard = 'unnamedplus'
  89. -- Enable break indent
  90. vim.opt.breakindent = true
  91. -- Save undo history
  92. vim.opt.undofile = true
  93. -- Case-insensitive searching UNLESS \C or one or more capital letters in the search term
  94. vim.opt.ignorecase = true
  95. vim.opt.smartcase = true
  96. -- Keep signcolumn on by default
  97. vim.opt.signcolumn = 'yes'
  98. -- Decrease update time
  99. vim.opt.updatetime = 250
  100. -- Decrease mapped sequence wait time
  101. -- Displays which-key popup sooner
  102. vim.opt.timeoutlen = 300
  103. -- Configure how new splits should be opened
  104. vim.opt.splitright = true
  105. vim.opt.splitbelow = true
  106. -- Sets how neovim will display certain whitespace characters in the editor.
  107. -- See `:help 'list'`
  108. -- and `:help 'listchars'`
  109. vim.opt.list = true
  110. vim.opt.listchars = { tab = '» ', trail = '·', nbsp = '␣' }
  111. -- Preview substitutions live, as you type!
  112. vim.opt.inccommand = 'split'
  113. -- Show which line your cursor is on
  114. vim.opt.cursorline = true
  115. -- Minimal number of screen lines to keep above and below the cursor.
  116. vim.opt.scrolloff = 10
  117. -- [[ Basic Keymaps ]]
  118. -- See `:help vim.keymap.set()`
  119. -- Set highlight on search, but clear on pressing <Esc> in normal mode
  120. vim.opt.hlsearch = true
  121. vim.keymap.set('n', '<Esc>', '<cmd>nohlsearch<CR>')
  122. -- Diagnostic keymaps
  123. vim.keymap.set('n', '[d', vim.diagnostic.goto_prev, { desc = 'Go to previous [D]iagnostic message' })
  124. vim.keymap.set('n', ']d', vim.diagnostic.goto_next, { desc = 'Go to next [D]iagnostic message' })
  125. vim.keymap.set('n', '<leader>e', vim.diagnostic.open_float, { desc = 'Show diagnostic [E]rror messages' })
  126. vim.keymap.set('n', '<leader>q', vim.diagnostic.setloclist, { desc = 'Open diagnostic [Q]uickfix list' })
  127. -- Exit terminal mode in the builtin terminal with a shortcut that is a bit easier
  128. -- for people to discover. Otherwise, you normally need to press <C-\><C-n>, which
  129. -- is not what someone will guess without a bit more experience.
  130. --
  131. -- NOTE: This won't work in all terminal emulators/tmux/etc. Try your own mapping
  132. -- or just use <C-\><C-n> to exit terminal mode
  133. vim.keymap.set('t', '<Esc><Esc>', '<C-\\><C-n>', { desc = 'Exit terminal mode' })
  134. -- TIP: Disable arrow keys in normal mode
  135. -- vim.keymap.set('n', '<left>', '<cmd>echo "Use h to move!!"<CR>')
  136. -- vim.keymap.set('n', '<right>', '<cmd>echo "Use l to move!!"<CR>')
  137. -- vim.keymap.set('n', '<up>', '<cmd>echo "Use k to move!!"<CR>')
  138. -- vim.keymap.set('n', '<down>', '<cmd>echo "Use j to move!!"<CR>')
  139. -- Keybinds to make split navigation easier.
  140. -- Use CTRL+<hjkl> to switch between windows
  141. --
  142. -- See `:help wincmd` for a list of all window commands
  143. vim.keymap.set('n', '<C-h>', '<C-w><C-h>', { desc = 'Move focus to the left window' })
  144. vim.keymap.set('n', '<C-l>', '<C-w><C-l>', { desc = 'Move focus to the right window' })
  145. vim.keymap.set('n', '<C-j>', '<C-w><C-j>', { desc = 'Move focus to the lower window' })
  146. vim.keymap.set('n', '<C-k>', '<C-w><C-k>', { desc = 'Move focus to the upper window' })
  147. -- [[ Basic Autocommands ]]
  148. -- See `:help lua-guide-autocommands`
  149. -- Highlight when yanking (copying) text
  150. -- Try it with `yap` in normal mode
  151. -- See `:help vim.highlight.on_yank()`
  152. vim.api.nvim_create_autocmd('TextYankPost', {
  153. desc = 'Highlight when yanking (copying) text',
  154. group = vim.api.nvim_create_augroup('kickstart-highlight-yank', { clear = true }),
  155. callback = function()
  156. vim.highlight.on_yank()
  157. end,
  158. })
  159. -- [[ Install `lazy.nvim` plugin manager ]]
  160. -- See `:help lazy.nvim.txt` or https://github.com/folke/lazy.nvim for more info
  161. local lazypath = vim.fn.stdpath 'data' .. '/lazy/lazy.nvim'
  162. if not vim.loop.fs_stat(lazypath) then
  163. local lazyrepo = 'https://github.com/folke/lazy.nvim.git'
  164. vim.fn.system { 'git', 'clone', '--filter=blob:none', '--branch=stable', lazyrepo, lazypath }
  165. end ---@diagnostic disable-next-line: undefined-field
  166. vim.opt.rtp:prepend(lazypath)
  167. -- [[ Configure and install plugins ]]
  168. --
  169. -- To check the current status of your plugins, run
  170. -- :Lazy
  171. --
  172. -- You can press `?` in this menu for help. Use `:q` to close the window
  173. --
  174. -- To update plugins you can run
  175. -- :Lazy update
  176. --
  177. -- NOTE: Here is where you install your plugins.
  178. require('lazy').setup({
  179. -- NOTE: Plugins can be added with a link (or for a github repo: 'owner/repo' link).
  180. 'tpope/vim-sleuth', -- Detect tabstop and shiftwidth automatically
  181. -- NOTE: Plugins can also be added by using a table,
  182. -- with the first argument being the link and the following
  183. -- keys can be used to configure plugin behavior/loading/etc.
  184. --
  185. -- Use `opts = {}` to force a plugin to be loaded.
  186. --
  187. -- This is equivalent to:
  188. -- require('Comment').setup({})
  189. -- "gc" to comment visual regions/lines
  190. { 'numToStr/Comment.nvim', opts = {} },
  191. -- Here is a more advanced example where we pass configuration
  192. -- options to `gitsigns.nvim`. This is equivalent to the following Lua:
  193. -- require('gitsigns').setup({ ... })
  194. --
  195. -- See `:help gitsigns` to understand what the configuration keys do
  196. { -- Adds git related signs to the gutter, as well as utilities for managing changes
  197. 'lewis6991/gitsigns.nvim',
  198. opts = {
  199. signs = {
  200. add = { text = '+' },
  201. change = { text = '~' },
  202. delete = { text = '_' },
  203. topdelete = { text = '‾' },
  204. changedelete = { text = '~' },
  205. },
  206. },
  207. },
  208. -- NOTE: Plugins can also be configured to run Lua code when they are loaded.
  209. --
  210. -- This is often very useful to both group configuration, as well as handle
  211. -- lazy loading plugins that don't need to be loaded immediately at startup.
  212. --
  213. -- For example, in the following configuration, we use:
  214. -- event = 'VimEnter'
  215. --
  216. -- which loads which-key before all the UI elements are loaded. Events can be
  217. -- normal autocommands events (`:help autocmd-events`).
  218. --
  219. -- Then, because we use the `config` key, the configuration only runs
  220. -- after the plugin has been loaded:
  221. -- config = function() ... end
  222. { -- Useful plugin to show you pending keybinds.
  223. 'folke/which-key.nvim',
  224. event = 'VimEnter', -- Sets the loading event to 'VimEnter'
  225. config = function() -- This is the function that runs, AFTER loading
  226. require('which-key').setup()
  227. -- Document existing key chains
  228. require('which-key').register {
  229. ['<leader>c'] = { name = '[C]ode', _ = 'which_key_ignore' },
  230. ['<leader>d'] = { name = '[D]ocument', _ = 'which_key_ignore' },
  231. ['<leader>r'] = { name = '[R]ename', _ = 'which_key_ignore' },
  232. ['<leader>s'] = { name = '[S]earch', _ = 'which_key_ignore' },
  233. ['<leader>w'] = { name = '[W]orkspace', _ = 'which_key_ignore' },
  234. }
  235. end,
  236. },
  237. -- NOTE: Plugins can specify dependencies.
  238. --
  239. -- The dependencies are proper plugin specifications as well - anything
  240. -- you do for a plugin at the top level, you can do for a dependency.
  241. --
  242. -- Use the `dependencies` key to specify the dependencies of a particular plugin
  243. { -- Fuzzy Finder (files, lsp, etc)
  244. 'nvim-telescope/telescope.nvim',
  245. event = 'VimEnter',
  246. branch = '0.1.x',
  247. dependencies = {
  248. 'nvim-lua/plenary.nvim',
  249. { -- If encountering errors, see telescope-fzf-native README for installation instructions
  250. 'nvim-telescope/telescope-fzf-native.nvim',
  251. -- `build` is used to run some command when the plugin is installed/updated.
  252. -- This is only run then, not every time Neovim starts up.
  253. build = 'make',
  254. -- `cond` is a condition used to determine whether this plugin should be
  255. -- installed and loaded.
  256. cond = function()
  257. return vim.fn.executable 'make' == 1
  258. end,
  259. },
  260. { 'nvim-telescope/telescope-ui-select.nvim' },
  261. -- Useful for getting pretty icons, but requires a Nerd Font.
  262. { 'nvim-tree/nvim-web-devicons', enabled = vim.g.have_nerd_font },
  263. },
  264. config = function()
  265. -- Telescope is a fuzzy finder that comes with a lot of different things that
  266. -- it can fuzzy find! It's more than just a "file finder", it can search
  267. -- many different aspects of Neovim, your workspace, LSP, and more!
  268. --
  269. -- The easiest way to use Telescope, is to start by doing something like:
  270. -- :Telescope help_tags
  271. --
  272. -- After running this command, a window will open up and you're able to
  273. -- type in the prompt window. You'll see a list of `help_tags` options and
  274. -- a corresponding preview of the help.
  275. --
  276. -- Two important keymaps to use while in Telescope are:
  277. -- - Insert mode: <c-/>
  278. -- - Normal mode: ?
  279. --
  280. -- This opens a window that shows you all of the keymaps for the current
  281. -- Telescope picker. This is really useful to discover what Telescope can
  282. -- do as well as how to actually do it!
  283. -- [[ Configure Telescope ]]
  284. -- See `:help telescope` and `:help telescope.setup()`
  285. require('telescope').setup {
  286. -- You can put your default mappings / updates / etc. in here
  287. -- All the info you're looking for is in `:help telescope.setup()`
  288. --
  289. -- defaults = {
  290. -- mappings = {
  291. -- i = { ['<c-enter>'] = 'to_fuzzy_refine' },
  292. -- },
  293. -- },
  294. -- pickers = {}
  295. extensions = {
  296. ['ui-select'] = {
  297. require('telescope.themes').get_dropdown(),
  298. },
  299. },
  300. }
  301. -- Enable Telescope extensions if they are installed
  302. pcall(require('telescope').load_extension, 'fzf')
  303. pcall(require('telescope').load_extension, 'ui-select')
  304. -- See `:help telescope.builtin`
  305. local builtin = require 'telescope.builtin'
  306. vim.keymap.set('n', '<leader>sh', builtin.help_tags, { desc = '[S]earch [H]elp' })
  307. vim.keymap.set('n', '<leader>sk', builtin.keymaps, { desc = '[S]earch [K]eymaps' })
  308. vim.keymap.set('n', '<leader>sf', builtin.find_files, { desc = '[S]earch [F]iles' })
  309. vim.keymap.set('n', '<leader>ss', builtin.builtin, { desc = '[S]earch [S]elect Telescope' })
  310. vim.keymap.set('n', '<leader>sw', builtin.grep_string, { desc = '[S]earch current [W]ord' })
  311. vim.keymap.set('n', '<leader>sg', builtin.live_grep, { desc = '[S]earch by [G]rep' })
  312. vim.keymap.set('n', '<leader>sd', builtin.diagnostics, { desc = '[S]earch [D]iagnostics' })
  313. vim.keymap.set('n', '<leader>sr', builtin.resume, { desc = '[S]earch [R]esume' })
  314. vim.keymap.set('n', '<leader>s.', builtin.oldfiles, { desc = '[S]earch Recent Files ("." for repeat)' })
  315. vim.keymap.set('n', '<leader><leader>', builtin.buffers, { desc = '[ ] Find existing buffers' })
  316. -- Slightly advanced example of overriding default behavior and theme
  317. vim.keymap.set('n', '<leader>/', function()
  318. -- You can pass additional configuration to Telescope to change the theme, layout, etc.
  319. builtin.current_buffer_fuzzy_find(require('telescope.themes').get_dropdown {
  320. winblend = 10,
  321. previewer = false,
  322. })
  323. end, { desc = '[/] Fuzzily search in current buffer' })
  324. -- It's also possible to pass additional configuration options.
  325. -- See `:help telescope.builtin.live_grep()` for information about particular keys
  326. vim.keymap.set('n', '<leader>s/', function()
  327. builtin.live_grep {
  328. grep_open_files = true,
  329. prompt_title = 'Live Grep in Open Files',
  330. }
  331. end, { desc = '[S]earch [/] in Open Files' })
  332. -- Shortcut for searching your Neovim configuration files
  333. vim.keymap.set('n', '<leader>sn', function()
  334. builtin.find_files { cwd = vim.fn.stdpath 'config' }
  335. end, { desc = '[S]earch [N]eovim files' })
  336. end,
  337. },
  338. { -- LSP Configuration & Plugins
  339. 'neovim/nvim-lspconfig',
  340. dependencies = {
  341. -- Automatically install LSPs and related tools to stdpath for Neovim
  342. 'williamboman/mason.nvim',
  343. 'williamboman/mason-lspconfig.nvim',
  344. 'WhoIsSethDaniel/mason-tool-installer.nvim',
  345. -- Useful status updates for LSP.
  346. -- NOTE: `opts = {}` is the same as calling `require('fidget').setup({})`
  347. { 'j-hui/fidget.nvim', opts = {} },
  348. -- `neodev` configures Lua LSP for your Neovim config, runtime and plugins
  349. -- used for completion, annotations and signatures of Neovim apis
  350. { 'folke/neodev.nvim', opts = {} },
  351. },
  352. config = function()
  353. -- Brief aside: **What is LSP?**
  354. --
  355. -- LSP is an initialism you've probably heard, but might not understand what it is.
  356. --
  357. -- LSP stands for Language Server Protocol. It's a protocol that helps editors
  358. -- and language tooling communicate in a standardized fashion.
  359. --
  360. -- In general, you have a "server" which is some tool built to understand a particular
  361. -- language (such as `gopls`, `lua_ls`, `rust_analyzer`, etc.). These Language Servers
  362. -- (sometimes called LSP servers, but that's kind of like ATM Machine) are standalone
  363. -- processes that communicate with some "client" - in this case, Neovim!
  364. --
  365. -- LSP provides Neovim with features like:
  366. -- - Go to definition
  367. -- - Find references
  368. -- - Autocompletion
  369. -- - Symbol Search
  370. -- - and more!
  371. --
  372. -- Thus, Language Servers are external tools that must be installed separately from
  373. -- Neovim. This is where `mason` and related plugins come into play.
  374. --
  375. -- If you're wondering about lsp vs treesitter, you can check out the wonderfully
  376. -- and elegantly composed help section, `:help lsp-vs-treesitter`
  377. -- This function gets run when an LSP attaches to a particular buffer.
  378. -- That is to say, every time a new file is opened that is associated with
  379. -- an lsp (for example, opening `main.rs` is associated with `rust_analyzer`) this
  380. -- function will be executed to configure the current buffer
  381. vim.api.nvim_create_autocmd('LspAttach', {
  382. group = vim.api.nvim_create_augroup('kickstart-lsp-attach', { clear = true }),
  383. callback = function(event)
  384. -- NOTE: Remember that Lua is a real programming language, and as such it is possible
  385. -- to define small helper and utility functions so you don't have to repeat yourself.
  386. --
  387. -- In this case, we create a function that lets us more easily define mappings specific
  388. -- for LSP related items. It sets the mode, buffer and description for us each time.
  389. local map = function(keys, func, desc)
  390. vim.keymap.set('n', keys, func, { buffer = event.buf, desc = 'LSP: ' .. desc })
  391. end
  392. -- Jump to the definition of the word under your cursor.
  393. -- This is where a variable was first declared, or where a function is defined, etc.
  394. -- To jump back, press <C-t>.
  395. map('gd', require('telescope.builtin').lsp_definitions, '[G]oto [D]efinition')
  396. -- Find references for the word under your cursor.
  397. map('gr', require('telescope.builtin').lsp_references, '[G]oto [R]eferences')
  398. -- Jump to the implementation of the word under your cursor.
  399. -- Useful when your language has ways of declaring types without an actual implementation.
  400. map('gI', require('telescope.builtin').lsp_implementations, '[G]oto [I]mplementation')
  401. -- Jump to the type of the word under your cursor.
  402. -- Useful when you're not sure what type a variable is and you want to see
  403. -- the definition of its *type*, not where it was *defined*.
  404. map('<leader>D', require('telescope.builtin').lsp_type_definitions, 'Type [D]efinition')
  405. -- Fuzzy find all the symbols in your current document.
  406. -- Symbols are things like variables, functions, types, etc.
  407. map('<leader>ds', require('telescope.builtin').lsp_document_symbols, '[D]ocument [S]ymbols')
  408. -- Fuzzy find all the symbols in your current workspace.
  409. -- Similar to document symbols, except searches over your entire project.
  410. map('<leader>ws', require('telescope.builtin').lsp_dynamic_workspace_symbols, '[W]orkspace [S]ymbols')
  411. -- Rename the variable under your cursor.
  412. -- Most Language Servers support renaming across files, etc.
  413. map('<leader>rn', vim.lsp.buf.rename, '[R]e[n]ame')
  414. -- Execute a code action, usually your cursor needs to be on top of an error
  415. -- or a suggestion from your LSP for this to activate.
  416. map('<leader>ca', vim.lsp.buf.code_action, '[C]ode [A]ction')
  417. -- Opens a popup that displays documentation about the word under your cursor
  418. -- See `:help K` for why this keymap.
  419. map('K', vim.lsp.buf.hover, 'Hover Documentation')
  420. -- WARN: This is not Goto Definition, this is Goto Declaration.
  421. -- For example, in C this would take you to the header.
  422. map('gD', vim.lsp.buf.declaration, '[G]oto [D]eclaration')
  423. -- The following two autocommands are used to highlight references of the
  424. -- word under your cursor when your cursor rests there for a little while.
  425. -- See `:help CursorHold` for information about when this is executed
  426. --
  427. -- When you move your cursor, the highlights will be cleared (the second autocommand).
  428. local client = vim.lsp.get_client_by_id(event.data.client_id)
  429. if client and client.server_capabilities.documentHighlightProvider then
  430. vim.api.nvim_create_autocmd({ 'CursorHold', 'CursorHoldI' }, {
  431. buffer = event.buf,
  432. callback = vim.lsp.buf.document_highlight,
  433. })
  434. vim.api.nvim_create_autocmd({ 'CursorMoved', 'CursorMovedI' }, {
  435. buffer = event.buf,
  436. callback = vim.lsp.buf.clear_references,
  437. })
  438. end
  439. end,
  440. })
  441. -- LSP servers and clients are able to communicate to each other what features they support.
  442. -- By default, Neovim doesn't support everything that is in the LSP specification.
  443. -- When you add nvim-cmp, luasnip, etc. Neovim now has *more* capabilities.
  444. -- So, we create new capabilities with nvim cmp, and then broadcast that to the servers.
  445. local capabilities = vim.lsp.protocol.make_client_capabilities()
  446. capabilities = vim.tbl_deep_extend('force', capabilities, require('cmp_nvim_lsp').default_capabilities())
  447. -- Enable the following language servers
  448. -- Feel free to add/remove any LSPs that you want here. They will automatically be installed.
  449. --
  450. -- Add any additional override configuration in the following tables. Available keys are:
  451. -- - cmd (table): Override the default command used to start the server
  452. -- - filetypes (table): Override the default list of associated filetypes for the server
  453. -- - capabilities (table): Override fields in capabilities. Can be used to disable certain LSP features.
  454. -- - settings (table): Override the default settings passed when initializing the server.
  455. -- For example, to see the options for `lua_ls`, you could go to: https://luals.github.io/wiki/settings/
  456. local servers = {
  457. clangd = {},
  458. -- gopls = {},
  459. pyright = {},
  460. -- rust_analyzer = {},
  461. -- ... etc. See `:help lspconfig-all` for a list of all the pre-configured LSPs
  462. --
  463. -- Some languages (like typescript) have entire language plugins that can be useful:
  464. -- https://github.com/pmizio/typescript-tools.nvim
  465. --
  466. -- But for many setups, the LSP (`tsserver`) will work just fine
  467. -- tsserver = {},
  468. --
  469. lua_ls = {
  470. -- cmd = {...},
  471. -- filetypes = { ...},
  472. -- capabilities = {},
  473. settings = {
  474. Lua = {
  475. completion = {
  476. callSnippet = 'Replace',
  477. },
  478. -- You can toggle below to ignore Lua_LS's noisy `missing-fields` warnings
  479. -- diagnostics = { disable = { 'missing-fields' } },
  480. },
  481. },
  482. },
  483. }
  484. -- Ensure the servers and tools above are installed
  485. -- To check the current status of installed tools and/or manually install
  486. -- other tools, you can run
  487. -- :Mason
  488. --
  489. -- You can press `g?` for help in this menu.
  490. require('mason').setup()
  491. -- You can add other tools here that you want Mason to install
  492. -- for you, so that they are available from within Neovim.
  493. local ensure_installed = vim.tbl_keys(servers or {})
  494. vim.list_extend(ensure_installed, {
  495. 'stylua', -- Used to format Lua code
  496. })
  497. require('mason-tool-installer').setup { ensure_installed = ensure_installed }
  498. require('mason-lspconfig').setup {
  499. handlers = {
  500. function(server_name)
  501. local server = servers[server_name] or {}
  502. -- This handles overriding only values explicitly passed
  503. -- by the server configuration above. Useful when disabling
  504. -- certain features of an LSP (for example, turning off formatting for tsserver)
  505. server.capabilities = vim.tbl_deep_extend('force', {}, capabilities, server.capabilities or {})
  506. require('lspconfig')[server_name].setup(server)
  507. end,
  508. },
  509. }
  510. end,
  511. },
  512. { -- Autoformat
  513. 'stevearc/conform.nvim',
  514. opts = {
  515. notify_on_error = false,
  516. format_on_save = function(bufnr)
  517. -- Disable "format_on_save lsp_fallback" for languages that don't
  518. -- have a well standardized coding style. You can add additional
  519. -- languages here or re-enable it for the disabled ones.
  520. local disable_filetypes = { c = true, cpp = true }
  521. return {
  522. timeout_ms = 500,
  523. lsp_fallback = not disable_filetypes[vim.bo[bufnr].filetype],
  524. }
  525. end,
  526. formatters_by_ft = {
  527. lua = { 'stylua' },
  528. -- Conform can also run multiple formatters sequentially
  529. -- python = { "isort", "black" },
  530. --
  531. -- You can use a sub-list to tell conform to run *until* a formatter
  532. -- is found.
  533. -- javascript = { { "prettierd", "prettier" } },
  534. },
  535. },
  536. },
  537. { -- Autocompletion
  538. 'hrsh7th/nvim-cmp',
  539. event = 'InsertEnter',
  540. dependencies = {
  541. -- Snippet Engine & its associated nvim-cmp source
  542. {
  543. 'L3MON4D3/LuaSnip',
  544. build = (function()
  545. -- Build Step is needed for regex support in snippets.
  546. -- This step is not supported in many windows environments.
  547. -- Remove the below condition to re-enable on windows.
  548. if vim.fn.has 'win32' == 1 or vim.fn.executable 'make' == 0 then
  549. return
  550. end
  551. return 'make install_jsregexp'
  552. end)(),
  553. dependencies = {
  554. -- `friendly-snippets` contains a variety of premade snippets.
  555. -- See the README about individual language/framework/plugin snippets:
  556. -- https://github.com/rafamadriz/friendly-snippets
  557. -- {
  558. -- 'rafamadriz/friendly-snippets',
  559. -- config = function()
  560. -- require('luasnip.loaders.from_vscode').lazy_load()
  561. -- end,
  562. -- },
  563. },
  564. },
  565. 'saadparwaiz1/cmp_luasnip',
  566. -- Adds other completion capabilities.
  567. -- nvim-cmp does not ship with all sources by default. They are split
  568. -- into multiple repos for maintenance purposes.
  569. 'hrsh7th/cmp-nvim-lsp',
  570. 'hrsh7th/cmp-path',
  571. },
  572. config = function()
  573. -- See `:help cmp`
  574. local cmp = require 'cmp'
  575. local luasnip = require 'luasnip'
  576. luasnip.config.setup {}
  577. cmp.setup {
  578. snippet = {
  579. expand = function(args)
  580. luasnip.lsp_expand(args.body)
  581. end,
  582. },
  583. completion = { completeopt = 'menu,menuone,noinsert' },
  584. -- For an understanding of why these mappings were
  585. -- chosen, you will need to read `:help ins-completion`
  586. --
  587. -- No, but seriously. Please read `:help ins-completion`, it is really good!
  588. mapping = cmp.mapping.preset.insert {
  589. -- Select the [n]ext item
  590. ['<C-n>'] = cmp.mapping.select_next_item(),
  591. -- Select the [p]revious item
  592. ['<C-p>'] = cmp.mapping.select_prev_item(),
  593. -- Scroll the documentation window [b]ack / [f]orward
  594. ['<C-b>'] = cmp.mapping.scroll_docs(-4),
  595. ['<C-f>'] = cmp.mapping.scroll_docs(4),
  596. -- Accept ([y]es) the completion.
  597. -- This will auto-import if your LSP supports it.
  598. -- This will expand snippets if the LSP sent a snippet.
  599. ['<C-y>'] = cmp.mapping.confirm { select = true },
  600. -- Manually trigger a completion from nvim-cmp.
  601. -- Generally you don't need this, because nvim-cmp will display
  602. -- completions whenever it has completion options available.
  603. ['<C-Space>'] = cmp.mapping.complete {},
  604. -- Think of <c-l> as moving to the right of your snippet expansion.
  605. -- So if you have a snippet that's like:
  606. -- function $name($args)
  607. -- $body
  608. -- end
  609. --
  610. -- <c-l> will move you to the right of each of the expansion locations.
  611. -- <c-h> is similar, except moving you backwards.
  612. ['<C-l>'] = cmp.mapping(function()
  613. if luasnip.expand_or_locally_jumpable() then
  614. luasnip.expand_or_jump()
  615. end
  616. end, { 'i', 's' }),
  617. ['<C-h>'] = cmp.mapping(function()
  618. if luasnip.locally_jumpable(-1) then
  619. luasnip.jump(-1)
  620. end
  621. end, { 'i', 's' }),
  622. -- For more advanced Luasnip keymaps (e.g. selecting choice nodes, expansion) see:
  623. -- https://github.com/L3MON4D3/LuaSnip?tab=readme-ov-file#keymaps
  624. },
  625. sources = {
  626. { name = 'nvim_lsp' },
  627. { name = 'luasnip' },
  628. { name = 'path' },
  629. },
  630. }
  631. end,
  632. },
  633. { -- You can easily change to a different colorscheme.
  634. -- Change the name of the colorscheme plugin below, and then
  635. -- change the command in the config to whatever the name of that colorscheme is.
  636. --
  637. -- If you want to see what colorschemes are already installed, you can use `:Telescope colorscheme`.
  638. 'folke/tokyonight.nvim',
  639. priority = 1000, -- Make sure to load this before all the other start plugins.
  640. init = function()
  641. -- Load the colorscheme here.
  642. -- Like many other themes, this one has different styles, and you could load
  643. -- any other, such as 'tokyonight-storm', 'tokyonight-moon', or 'tokyonight-day'.
  644. vim.cmd.colorscheme 'tokyonight-night'
  645. -- You can configure highlights by doing something like:
  646. vim.cmd.hi 'Comment gui=none'
  647. end,
  648. },
  649. -- Highlight todo, notes, etc in comments
  650. { 'folke/todo-comments.nvim', event = 'VimEnter', dependencies = { 'nvim-lua/plenary.nvim' }, opts = { signs = false } },
  651. { -- Collection of various small independent plugins/modules
  652. 'echasnovski/mini.nvim',
  653. config = function()
  654. -- Better Around/Inside textobjects
  655. --
  656. -- Examples:
  657. -- - va) - [V]isually select [A]round [)]paren
  658. -- - yinq - [Y]ank [I]nside [N]ext [']quote
  659. -- - ci' - [C]hange [I]nside [']quote
  660. require('mini.ai').setup { n_lines = 500 }
  661. -- Add/delete/replace surroundings (brackets, quotes, etc.)
  662. --
  663. -- - saiw) - [S]urround [A]dd [I]nner [W]ord [)]Paren
  664. -- - sd' - [S]urround [D]elete [']quotes
  665. -- - sr)' - [S]urround [R]eplace [)] [']
  666. require('mini.surround').setup()
  667. -- Simple and easy statusline.
  668. -- You could remove this setup call if you don't like it,
  669. -- and try some other statusline plugin
  670. local statusline = require 'mini.statusline'
  671. -- set use_icons to true if you have a Nerd Font
  672. statusline.setup { use_icons = vim.g.have_nerd_font }
  673. -- You can configure sections in the statusline by overriding their
  674. -- default behavior. For example, here we set the section for
  675. -- cursor location to LINE:COLUMN
  676. ---@diagnostic disable-next-line: duplicate-set-field
  677. statusline.section_location = function()
  678. return '%2l:%-2v'
  679. end
  680. -- ... and there is more!
  681. -- Check out: https://github.com/echasnovski/mini.nvim
  682. end,
  683. },
  684. { -- Highlight, edit, and navigate code
  685. 'nvim-treesitter/nvim-treesitter',
  686. build = ':TSUpdate',
  687. opts = {
  688. ensure_installed = { 'bash', 'c', 'html', 'lua', 'markdown', 'vim', 'vimdoc', 'python' },
  689. -- Autoinstall languages that are not installed
  690. auto_install = true,
  691. highlight = {
  692. enable = true,
  693. -- Some languages depend on vim's regex highlighting system (such as Ruby) for indent rules.
  694. -- If you are experiencing weird indenting issues, add the language to
  695. -- the list of additional_vim_regex_highlighting and disabled languages for indent.
  696. additional_vim_regex_highlighting = { 'ruby' },
  697. },
  698. indent = { enable = true, disable = { 'ruby' } },
  699. },
  700. config = function(_, opts)
  701. -- [[ Configure Treesitter ]] See `:help nvim-treesitter`
  702. ---@diagnostic disable-next-line: missing-fields
  703. require('nvim-treesitter.configs').setup(opts)
  704. -- There are additional nvim-treesitter modules that you can use to interact
  705. -- with nvim-treesitter. You should go explore a few and see what interests you:
  706. --
  707. -- - Incremental selection: Included, see `:help nvim-treesitter-incremental-selection-mod`
  708. -- - Show your current context: https://github.com/nvim-treesitter/nvim-treesitter-context
  709. -- - Treesitter + textobjects: https://github.com/nvim-treesitter/nvim-treesitter-textobjects
  710. end,
  711. },
  712. -- The following two comments only work if you have downloaded the kickstart repo, not just copy pasted the
  713. -- init.lua. If you want these files, they are in the repository, so you can just download them and
  714. -- place them in the correct locations.
  715. -- NOTE: Next step on your Neovim journey: Add/Configure additional plugins for Kickstart
  716. --
  717. -- Here are some example plugins that I've included in the Kickstart repository.
  718. -- Uncomment any of the lines below to enable them (you will need to restart nvim).
  719. --
  720. -- require 'kickstart.plugins.debug',
  721. -- require 'kickstart.plugins.indent_line',
  722. -- require 'kickstart.plugins.lint',
  723. -- NOTE: The import below can automatically add your own plugins, configuration, etc from `lua/custom/plugins/*.lua`
  724. -- This is the easiest way to modularize your config.
  725. --
  726. -- Uncomment the following line and add your plugins to `lua/custom/plugins/*.lua` to get going.
  727. -- For additional information, see `:help lazy.nvim-lazy.nvim-structuring-your-plugins`
  728. -- { import = 'custom.plugins' },
  729. }, {
  730. ui = {
  731. -- If you are using a Nerd Font: set icons to an empty table which will use the
  732. -- default lazy.nvim defined Nerd Font icons, otherwise define a unicode icons table
  733. icons = vim.g.have_nerd_font and {} or {
  734. cmd = '⌘',
  735. config = '🛠',
  736. event = '📅',
  737. ft = '📂',
  738. init = '⚙',
  739. keys = '🗝',
  740. plugin = '🔌',
  741. runtime = '💻',
  742. require = '🌙',
  743. source = '📄',
  744. start = '🚀',
  745. task = '📌',
  746. lazy = '💤 ',
  747. },
  748. },
  749. })
  750. require 'custom/options'
  751. require 'custom/keymap'
  752. --
  753. -- The line beneath this is called `modeline`. See `:help modeline`
  754. -- vim: ts=2 sts=2 sw=2 et