diff --git a/init.lua b/init.lua index aff5250e921..8b3375b3044 100644 --- a/init.lua +++ b/init.lua @@ -1,211 +1,390 @@ ---[[ - -===================================================================== -==================== READ THIS BEFORE CONTINUING ==================== -===================================================================== -======== .-----. ======== -======== .----------------------. | === | ======== -======== |.-""""""""""""""""""-.| |-----| ======== -======== || || | === | ======== -======== || KICKSTART.NVIM || |-----| ======== -======== || || | === | ======== -======== || || |-----| ======== -======== ||:Tutor || |:::::| ======== -======== |'-..................-'| |____o| ======== -======== `"")----------------(""` ___________ ======== -======== /::::::::::| |::::::::::\ \ no mouse \ ======== -======== /:::========| |==hjkl==:::\ \ required \ ======== -======== '""""""""""""' '""""""""""""' '""""""""""' ======== -======== ======== -===================================================================== -===================================================================== - -What is Kickstart? - - Kickstart.nvim is *not* a distribution. - - Kickstart.nvim is a starting point for your own configuration. - The goal is that you can read every line of code, top-to-bottom, understand - what your configuration is doing, and modify it to suit your needs. - - Once you've done that, you can start exploring, configuring and tinkering to - make Neovim your own! That might mean leaving Kickstart just the way it is for a while - or immediately breaking it into modular pieces. It's up to you! - - If you don't know anything about Lua, I recommend taking some time to read through - a guide. One possible example which will only take 10-15 minutes: - - https://learnxinyminutes.com/docs/lua/ - - After understanding a bit more about Lua, you can use `:help lua-guide` as a - reference for how Neovim integrates Lua. - - :help lua-guide - - (or HTML version): https://neovim.io/doc/user/lua-guide.html - -Kickstart Guide: - - TODO: The very first thing you should do is to run the command `:Tutor` in Neovim. - - If you don't know what this means, type the following: - - - - : - - Tutor - - - - (If you already know the Neovim basics, you can skip this step.) - - Once you've completed that, you can continue working through **AND READING** the rest - of the kickstart init.lua. - - Next, run AND READ `:help`. - This will open up a help window with some basic information - about reading, navigating and searching the builtin help documentation. - - This should be the first place you go to look when you're stuck or confused - with something. It's one of my favorite Neovim features. - - MOST IMPORTANTLY, we provide a keymap "sh" to [s]earch the [h]elp documentation, - which is very useful when you're not exactly sure of what you're looking for. - - I have left several `:help X` comments throughout the init.lua - These are hints about where to find more information about the relevant settings, - plugins or Neovim features used in Kickstart. - - NOTE: Look for lines like this - - Throughout the file. These are for you, the reader, to help you understand what is happening. - Feel free to delete them once you know what you're doing, but they should serve as a guide - for when you are first encountering a few different constructs in your Neovim config. - -If you experience any errors while trying to install kickstart, run `:checkhealth` for more info. - -I hope you enjoy your Neovim journey, -- TJ - -P.S. You can delete this when you're done too. It's your config now! :) ---]] - --- ============================================================ --- SECTION 1: OPTIONS --- Core Neovim settings, leaders, options, basic keymaps, basic autocmds --- ============================================================ -do - -- Enable faster startup by caching compiled Lua modules - vim.loader.enable() - - -- Set as the leader key - -- See `:help mapleader` - -- NOTE: Must happen before plugins are loaded (otherwise wrong leader will be used) - vim.g.mapleader = ' ' - vim.g.maplocalleader = ' ' - - -- Set to true if you have a Nerd Font installed and selected in the terminal - vim.g.have_nerd_font = false - - -- [[ Setting options ]] - -- See `:help vim.o` - -- NOTE: You can change these options as you wish! - -- For more options, you can see `:help option-list` +vim.g.loaded_netrw = 1 +vim.g.loaded_netrwPlugin = 1 + +-- optionally enable 24-bit colour +vim.opt.termguicolors = true + +-- NOTE: Must happen before plugins are loaded (otherwise wrong leader will be used) +-- vim.g.mapleader = ' ' +-- vim.g.maplocalleader = ' ' + +-- Set to true if you have a Nerd Font installed and selected in the terminal +vim.g.have_nerd_font = true + +-- [[ Setting options ]] +-- See `:help vim.o` +-- NOTE: You can change these options as you wish! +-- For more options, you can see `:help option-list` + +-- Make line numbers default +vim.o.number = true +-- You can also add relative line numbers, to help with jumping. +-- Experiment for yourself to see if you like it! +-- vim.o.relativenumber = true + +-- Enable mouse mode, can be useful for resizing splits for example! +vim.o.mouse = 'a' + +-- Don't show the mode, since it's already in the status line +vim.o.showmode = false + +-- Sync clipboard between OS and Neovim. +-- Schedule the setting after `UiEnter` because it can increase startup-time. +-- Remove this option if you want your OS clipboard to remain independent. +-- See `:help 'clipboard'` +vim.schedule(function() + vim.o.clipboard = 'unnamedplus' +end) + +-- Enable break indent +vim.o.breakindent = true + +-- Save undo history +vim.o.undofile = true + +-- Case-insensitive searching UNLESS \C or one or more capital letters in the search term +vim.o.ignorecase = true +vim.o.smartcase = true + +-- Keep signcolumn on by default +vim.o.signcolumn = 'yes' + +-- Decrease update time +vim.o.updatetime = 250 + +-- Decrease mapped sequence wait time +vim.o.timeoutlen = 300 + +-- Configure how new splits should be opened +vim.o.splitright = true +vim.o.splitbelow = true + +-- Sets how neovim will display certain whitespace characters in the editor. +-- See `:help 'list'` +-- and `:help 'listchars'` +-- +-- Notice listchars is set using `vim.opt` instead of `vim.o`. +-- It is very similar to `vim.o` but offers an interface for conveniently interacting with tables. +-- See `:help lua-options` +-- and `:help lua-options-guide` +vim.o.list = true +vim.opt.listchars = { tab = '» ', trail = '·', nbsp = '␣' } + +-- Preview substitutions live, as you type! +vim.o.inccommand = 'split' + +-- Show which line your cursor is on +vim.o.cursorline = true + +-- Minimal number of screen lines to keep above and below the cursor. +vim.o.scrolloff = 10 + +-- if performing an operation that would fail due to unsaved changes in the buffer (like `:q`), +-- instead raise a dialog asking if you wish to save the current file(s) +-- See `:help 'confirm'` +vim.o.confirm = true + +-- [[ Basic Keymaps ]] +-- See `:help vim.keymap.set()` + +-- Clear highlights on search when pressing in normal mode +-- See `:help hlsearch` +vim.keymap.set('n', '', 'nohlsearch') + +-- Diagnostic keymaps +vim.keymap.set('n', 'q', vim.diagnostic.setloclist, { desc = 'Open diagnostic [Q]uickfix list' }) + +-- Exit terminal mode in the builtin terminal with a shortcut that is a bit easier +-- for people to discover. Otherwise, you normally need to press , which +-- is not what someone will guess without a bit more experience. +-- +-- NOTE: This won't work in all terminal emulators/tmux/etc. Try your own mapping +-- or just use to exit terminal mode +vim.keymap.set('t', '', '', { desc = 'Exit terminal mode' }) + +-- TIP: Disable arrow keys in normal mode +-- vim.keymap.set('n', '', 'echo "Use h to move!!"') +-- vim.keymap.set('n', '', 'echo "Use l to move!!"') +-- vim.keymap.set('n', '', 'echo "Use k to move!!"') +-- vim.keymap.set('n', '', 'echo "Use j to move!!"') + +-- Keybinds to make split navigation easier. +-- Use CTRL+ to switch between windows +-- +-- See `:help wincmd` for a list of all window commands +vim.keymap.set('n', '', '', { desc = 'Move focus to the left window' }) +vim.keymap.set('n', '', '', { desc = 'Move focus to the right window' }) +vim.keymap.set('n', '', '', { desc = 'Move focus to the lower window' }) +vim.keymap.set('n', '', '', { desc = 'Move focus to the upper window' }) + +-- Make Ctrl-c behave exactly like Esc to trigger InsertLeave +vim.keymap.set('i', '', '') + +-- NOTE: Some terminals have colliding keymaps or are not able to send distinct keycodes +-- vim.keymap.set("n", "", "H", { desc = "Move window to the left" }) +-- vim.keymap.set("n", "", "L", { desc = "Move window to the right" }) +-- vim.keymap.set("n", "", "J", { desc = "Move window to the lower" }) +-- vim.keymap.set("n", "", "K", { desc = "Move window to the upper" }) + +-- [[ Basic Autocommands ]] +-- See `:help lua-guide-autocommands` + +-- Highlight when yanking (copying) text +-- Try it with `yap` in normal mode +-- See `:help vim.hl.on_yank()` +vim.api.nvim_create_autocmd('TextYankPost', { + desc = 'Highlight when yanking (copying) text', + group = vim.api.nvim_create_augroup('kickstart-highlight-yank', { clear = true }), + callback = function() + vim.hl.on_yank() + end, +}) + +-- [[ Install `lazy.nvim` plugin manager ]] +-- See `:help lazy.nvim.txt` or https://github.com/folke/lazy.nvim for more info +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 + error('Error cloning lazy.nvim:\n' .. out) + end +end - -- Make line numbers default - vim.o.number = true - -- You can also add relative line numbers, to help with jumping. - -- Experiment for yourself to see if you like it! - -- vim.o.relativenumber = true +---@type vim.Option +local rtp = vim.opt.rtp +rtp:prepend(lazypath) + +-- [[ Configure and install plugins ]] +-- +-- To check the current status of your plugins, run +-- :Lazy +-- +-- You can press `?` in this menu for help. Use `:q` to close the window +-- +-- To update plugins you can run +-- :Lazy update +-- +-- NOTE: Here is where you install your plugins. +require('lazy').setup({ + { + 'habamax/vim-godot', + event = 'VimEnter', + }, + { + 'nvim-tree/nvim-tree.lua', + version = '*', + lazy = false, + dependencies = { + 'nvim-tree/nvim-web-devicons', + }, + config = function() + require('nvim-tree').setup { + view = { + side = 'right', -- Put tree on the right + width = 30, -- Width of the window + }, + actions = { + open_file = { + quit_on_open = true, -- Optional: close tree when you open a file + }, + }, + filters = { + dotfiles = false, + }, + git = { + enable = true, + ignore = false, + timeout = 500, + }, + } - -- Enable mouse mode, can be useful for resizing splits for example! - vim.o.mouse = 'a' + -- Map Ctrl-g to Toggle the tree + vim.keymap.set('n', '', 'NvimTreeToggle', { desc = 'Toggle file explorer' }) + end, + }, + { + 'akinsho/bufferline.nvim', + version = '*', + dependencies = 'nvim-tree/nvim-web-devicons', + config = function() + require('bufferline').setup { + options = { + -- Enable mouse support + mouse = { + middle_mouse_command = 'bdelete! %d', -- Middle click to close + }, - -- Don't show the mode, since it's already in the status line - vim.o.showmode = false + -- Show LSP errors in the tabline + diagnostics = 'nvim_lsp', - -- Sync clipboard between OS and Neovim. - -- Schedule the setting after `UiEnter` because it can increase startup-time. - -- Remove this option if you want your OS clipboard to remain independent. - -- See `:help 'clipboard'` - vim.schedule(function() vim.o.clipboard = 'unnamedplus' end) + -- Optional: Add an offset if you decide to move NvimTree back to the left + -- offsets = { { filetype = "NvimTree", text = "File Explorer", text_align = "left" } }, + }, + } - -- Enable break indent - vim.o.breakindent = true + -- [[ Keymaps ]] + local map = vim.keymap.set + local opts = { noremap = true, silent = true, desc = 'Bufferline' } - -- Enable undo/redo changes even after closing and reopening a file - vim.o.undofile = true + -- 1. Switch to specific buffer (Alt+1 through Alt+9) + for i = 1, 9 do + map('n', '', 'BufferLineGoToBuffer ' .. i .. '', { desc = 'Go to buffer ' .. i }) + end - -- Case-insensitive searching UNLESS \C or one or more capital letters in the search term - vim.o.ignorecase = true - vim.o.smartcase = true + -- 2. Switch Focus (Left/Right) + -- Note: is Alt + Comma (which has the < symbol) + -- is Alt + Period (which has the > symbol) + map('n', '', 'BufferLineCyclePrev', { desc = 'Previous Buffer' }) + map('n', '', 'BufferLineCycleNext', { desc = 'Next Buffer' }) - -- Keep signcolumn on by default - vim.o.signcolumn = 'yes' + -- 3. Move (Re-order) Buffer + -- Note: is effectively Alt + Shift + Comma + -- > is effectively Alt + Shift + Period + map('n', '', 'BufferLineMovePrev', { desc = 'Move buffer left' }) + map('n', '>', 'BufferLineMoveNext', { desc = 'Move buffer right' }) - -- Decrease update time - vim.o.updatetime = 250 + map('n', '', 'bdelete!', { desc = 'Close Buffer (Tab)' }) + end, + }, + { + 'nvimdev/lspsaga.nvim', + event = 'LspAttach', -- Important: Load only when LSP connects + dependencies = { + 'nvim-treesitter/nvim-treesitter', + 'nvim-tree/nvim-web-devicons', + }, + config = function() + -- Modern setup call + require('lspsaga').setup { + ui = { + border = 'rounded', + }, + } - -- Decrease mapped sequence wait time - vim.o.timeoutlen = 300 + local opts = { noremap = true, silent = true } - -- Configure how new splits should be opened - vim.o.splitright = true - vim.o.splitbelow = true + vim.keymap.set('n', 'K', 'Lspsaga hover_doc', opts) + vim.keymap.set('n', 'gd', 'Lspsaga finder', opts) -- Changed from lsp_finder to finder + vim.keymap.set('i', '', 'Lspsaga signature_help', opts) + vim.keymap.set('n', 'gp', 'Lspsaga peek_definition', opts) -- Changed from preview_definition to peek_definition + vim.keymap.set('n', 'gr', 'Lspsaga rename', opts) + end, + }, + { + 'MunifTanjim/prettier.nvim', + dependencies = { + 'neovim/nvim-lspconfig', + 'nvimtools/none-ls.nvim', -- Community fork of null-ls + }, + config = function() + local prettier = require 'prettier' + + prettier.setup { + bin = 'prettier', -- or 'prettierd' (if installed) + filetypes = { + 'css', + 'graphql', + 'html', + 'javascript', + 'javascriptreact', + 'json', + 'less', + 'markdown', + 'scss', + 'typescript', + 'typescriptreact', + 'yaml', + }, + ['null-ls'] = { + condition = function() + return prettier.config_exists { + check_package_json = true, + } + end, + runtime_condition = function(params) + -- return false to skip running prettier + return true + end, + timeout = 5000, + }, + } + end, + }, + { + 'windwp/nvim-ts-autotag', + config = function() + require('nvim-ts-autotag').setup() + end, + }, + { + 'windwp/nvim-autopairs', + event = 'InsertEnter', + config = true, + -- use opts = {} for passing setup options + -- this is equivalent to setup({}) function + }, + { + 'stevearc/oil.nvim', + ---@module 'oil' + ---@type oil.SetupOpts + opts = {}, + -- Optional dependencies + dependencies = { 'nvim-tree/nvim-web-devicons' }, -- use if you prefer nvim-web-devicons + lazy = false, + }, + { + 'christoomey/vim-tmux-navigator', + cmd = { + 'TmuxNavigateLeft', + 'TmuxNavigateDown', + 'TmuxNavigateUp', + 'TmuxNavigateRight', + 'TmuxNavigatePrevious', + 'TmuxNavigatorProcessList', + }, + keys = { + { '', 'TmuxNavigateLeft' }, + { '', 'TmuxNavigateDown' }, + { '', 'TmuxNavigateUp' }, + { '', 'TmuxNavigateRight' }, + { '', 'TmuxNavigatePrevious' }, + }, + }, + 'NMAC427/guess-indent.nvim', -- Detect tabstop and shiftwidth automatically - -- Sets how neovim will display certain whitespace characters in the editor. - -- See `:help 'list'` - -- and `:help 'listchars'` + -- NOTE: Plugins can also be added by using a table, + -- with the first argument being the link and the following + -- keys can be used to configure plugin behavior/loading/etc. + -- + -- Use `opts = {}` to automatically pass options to a plugin's `setup()` function, forcing the plugin to be loaded. -- - -- Notice listchars is set using `vim.opt` instead of `vim.o`. - -- It is very similar to `vim.o` but offers an interface for conveniently interacting with tables. - -- See `:help lua-options` - -- and `:help lua-guide-options` - vim.o.list = true - vim.opt.listchars = { tab = '» ', trail = '·', nbsp = '␣' } - - -- Preview substitutions live, as you type! - vim.o.inccommand = 'split' - - -- Show which line your cursor is on - vim.o.cursorline = true - - -- Minimal number of screen lines to keep above and below the cursor. - vim.o.scrolloff = 10 - - -- if performing an operation that would fail due to unsaved changes in the buffer (like `:q`), - -- instead raise a dialog asking if you wish to save the current file(s) - -- See `:help 'confirm'` - vim.o.confirm = true -end --- ============================================================ --- SECTION 2: KEYMAPS --- basic keymaps --- ============================================================ -do - -- [[ Basic Keymaps ]] - -- See `:help vim.keymap.set()` - - -- Clear highlights on search when pressing in normal mode - -- See `:help hlsearch` - vim.keymap.set('n', '', 'nohlsearch') - - -- Diagnostic Config & Keymaps - -- See `:help vim.diagnostic.Opts` - vim.diagnostic.config { - update_in_insert = false, - severity_sort = true, - float = { border = 'rounded', source = 'if_many' }, - underline = { severity = { min = vim.diagnostic.severity.WARN } }, - - -- Can switch between these as you prefer - virtual_text = true, -- Text shows up at the end of the line - virtual_lines = false, -- Text shows up underneath the line, with virtual lines - - -- Auto open the float, so you can easily read the errors when jumping with `[d` and `]d` - jump = { - on_jump = function(_, bufnr) - vim.diagnostic.open_float { - bufnr = bufnr, - scope = 'cursor', - focus = false, - } - end, + -- Alternatively, use `config = function() ... end` for full control over the configuration. + -- If you prefer to call `setup` explicitly, use: + -- { + -- 'lewis6991/gitsigns.nvim', + -- config = function() + -- require('gitsigns').setup({ + -- -- Your gitsigns configuration here + -- }) + -- end, + -- } + -- + -- Here is a more advanced example where we pass configuration + -- options to `gitsigns.nvim`. + -- + -- See `:help gitsigns` to understand what the configuration keys do + { -- Adds git related signs to the gutter, as well as utilities for managing changes + 'lewis6991/gitsigns.nvim', + opts = { + signs = { + add = { text = '+' }, + change = { text = '~' }, + delete = { text = '_' }, + topdelete = { text = '‾' }, + changedelete = { text = '~' }, + }, }, } @@ -359,6 +538,45 @@ do topdelete = { text = '‾' }, ---@diagnostic disable-line: missing-fields changedelete = { text = '~' }, ---@diagnostic disable-line: missing-fields }, + config = function() + -- 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! + -- + -- 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! + + -- [[ Configure Telescope ]] + -- See `:help telescope` and `:help telescope.setup()` + require('telescope').setup { + defaults = { + -- prevent telescope from searching inside the .git/ folder itself + file_ignore_patterns = { '.git/', '.venv/', 'node_modules/', 'dist/', 'generated/', 'migrations/' }, + }, + pickers = { + find_files = { + hidden = true, -- Show dotfiles (e.g. .env, .config) + no_ignore = true, -- Show files ignored by .gitignore + }, + }, + extensions = { + ['ui-select'] = { + require('telescope.themes').get_dropdown(), + }, + }, + } } -- Useful plugin to show you pending keybinds. @@ -503,6 +721,167 @@ do extensions = { ['ui-select'] = { require('telescope.themes').get_dropdown() }, }, + config = function() + -- 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` + + -- 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' }) + + -- Find references for the word under your cursor. + map('grr', require('telescope.builtin').lsp_references, '[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. + map('gri', require('telescope.builtin').lsp_implementations, '[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 . + map('grd', require('telescope.builtin').lsp_definitions, '[G]oto [D]efinition') + + -- 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') + + -- Fuzzy find all the symbols in your current document. + -- Symbols are things like variables, functions, types, etc. + map('gO', require('telescope.builtin').lsp_document_symbols, 'Open Document Symbols') + + -- Fuzzy find all the symbols in your current workspace. + -- Similar to document symbols, except searches over your entire project. + map('gW', require('telescope.builtin').lsp_dynamic_workspace_symbols, '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*. + map('grt', require('telescope.builtin').lsp_type_definitions, '[G]oto [T]ype Definition') + + -- This function resolves a difference between neovim nightly (version 0.11) and stable (version 0.10) + ---@param client vim.lsp.Client + ---@param method vim.lsp.protocol.Method + ---@param bufnr? integer some lsp support methods only in specific files + ---@return boolean + local function client_supports_method(client, method, bufnr) + if vim.fn.has 'nvim-0.11' == 1 then + return client:supports_method(method, bufnr) + else + return client:supports_method(method, { bufnr = bufnr }) + end + end + + -- 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(client, vim.lsp.protocol.Methods.textDocument_documentHighlight, event.buf) then + local highlight_augroup = vim.api.nvim_create_augroup('kickstart-lsp-highlight', { clear = false }) + vim.api.nvim_create_autocmd({ 'CursorHold', 'CursorHoldI' }, { + buffer = event.buf, + group = highlight_augroup, + callback = vim.lsp.buf.document_highlight, + }) + + vim.api.nvim_create_autocmd({ 'CursorMoved', 'CursorMovedI' }, { + buffer = event.buf, + group = highlight_augroup, + callback = vim.lsp.buf.clear_references, + }) + + vim.api.nvim_create_autocmd('LspDetach', { + group = vim.api.nvim_create_augroup('kickstart-lsp-detach', { clear = true }), + callback = function(event2) + vim.lsp.buf.clear_references() + vim.api.nvim_clear_autocmds { group = 'kickstart-lsp-highlight', buffer = event2.buf } + end, + }) + end + + -- The following code creates a keymap to toggle inlay hints in your + -- code, if the language server you are using supports them + -- + -- This may be unwanted, since they displace some of your code + if client and client_supports_method(client, vim.lsp.protocol.Methods.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, + }) + + -- Diagnostic Config + -- See :help vim.diagnostic.Opts + vim.diagnostic.config { + severity_sort = true, + float = { border = 'rounded', source = 'if_many' }, + underline = { severity = vim.diagnostic.severity.ERROR }, + signs = vim.g.have_nerd_font and { + text = { + [vim.diagnostic.severity.ERROR] = '󰅚 ', + [vim.diagnostic.severity.WARN] = '󰀪 ', + [vim.diagnostic.severity.INFO] = '󰋽 ', + [vim.diagnostic.severity.HINT] = '󰌶 ', + }, + } or {}, + virtual_text = { + source = 'if_many', + spacing = 2, + format = function(diagnostic) + local diagnostic_message = { + [vim.diagnostic.severity.ERROR] = diagnostic.message, + [vim.diagnostic.severity.WARN] = diagnostic.message, + [vim.diagnostic.severity.INFO] = diagnostic.message, + [vim.diagnostic.severity.HINT] = diagnostic.message, + } + return diagnostic_message[diagnostic.severity] + end, + }, } -- Enable Telescope extensions if they are installed @@ -731,14 +1110,88 @@ do }, }) end, - ---@type lspconfig.settings.lua_ls - settings = { - Lua = { - format = { enable = false }, -- Disable formatting (formatting is done by stylua) + formatters_by_ft = { + lua = { 'stylua' }, + javascript = { 'prettierd', 'prettier', stop_after_first = true }, + typescript = { 'prettierd', 'prettier', stop_after_first = true }, + javascriptreact = { 'prettierd', 'prettier', stop_after_first = true }, + typescriptreact = { 'prettierd', 'prettier', stop_after_first = true }, + json = { 'prettierd', 'prettier', stop_after_first = true }, + css = { 'prettierd', 'prettier', stop_after_first = true }, + html = { 'prettierd', 'prettier', stop_after_first = true }, + markdown = { 'prettierd', 'prettier', stop_after_first = true }, + }, + }, + }, + + { -- Autocompletion + 'saghen/blink.cmp', + event = 'VimEnter', + version = '1.*', + dependencies = { + -- Snippet Engine + { + 'L3MON4D3/LuaSnip', + version = '2.*', + build = (function() + -- Build Step is needed for regex support in snippets. + -- This step is not supported in many windows environments. + -- Remove the below condition to re-enable on windows. + if vim.fn.has 'win32' == 1 or vim.fn.executable 'make' == 0 then + return + end + return 'make install_jsregexp' + end)(), + dependencies = { + -- `friendly-snippets` contains a variety of premade snippets. + -- See the README about individual language/framework/plugin snippets: + -- https://github.com/rafamadriz/friendly-snippets + -- { + -- 'rafamadriz/friendly-snippets', + -- config = function() + -- require('luasnip.loaders.from_vscode').lazy_load() + -- end, + -- }, }, }, }, - } + config = function(_, opts) + -- Define the orange color (matches TokyoNight orange) + vim.api.nvim_set_hl(0, 'KindOrange', { fg = '#ff9e64', bold = true }) + + -- Initialize blink with your options + require('blink.cmp').setup(opts) + end, + --- @module 'blink.cmp' + --- @type blink.cmp.Config + opts = { + 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 :h 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 + }, vim.pack.add { gh 'neovim/nvim-lspconfig', @@ -747,8 +1200,25 @@ do gh 'WhoIsSethDaniel/mason-tool-installer.nvim', } - -- Automatically install LSPs and related tools to stdpath for Neovim - require('mason').setup {} + 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 = true, auto_show_delay_ms = 200 }, + menu = { + draw = { + columns = { + { 'label' }, + { 'kind', 'label_description', gap = 1 }, + }, + components = { + kind = { + -- 2. Force the highlight to always use our Orange group + highlight = 'KindOrange', + }, + }, + }, + }, + }, -- Ensure the servers and tools above are installed -- @@ -858,6 +1328,69 @@ do -- https://github.com/L3MON4D3/LuaSnip?tab=readme-ov-file#keymaps }, + { -- You can easily change to a different colorscheme. + -- Change the name of the colorscheme plugin below, and then + -- change the command in the config to whatever the name of that colorscheme is. + -- + -- If you want to see what colorschemes are already installed, you can use `:Telescope colorscheme`. + 'folke/tokyonight.nvim', + priority = 998, -- Make sure to load this before all the other start plugins. + config = function() + ---@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' + end, + }, + { + 'ellisonleao/gruvbox.nvim', + name = 'gruvbox', + lazy = false, + priority = 997, + config = function() + -- Optional: Set configuration before applying + vim.g.gruvbox_contrast_dark = 'dark' -- 'soft', 'medium', 'hard' + + -- Apply the colorscheme + vim.cmd 'colorscheme gruvbox' + end, + }, + + -- Highlight todo, notes, etc in comments + { + 'folke/todo-comments.nvim', + event = 'VimEnter', + dependencies = { 'nvim-lua/plenary.nvim' }, + opts = { + signs = false, + keywords = { + FIX = { + icon = ' ', -- icon used for the sign, and in search results + color = 'error', -- can be a hex color, or a named color (see below) + alt = { 'FIXME', 'BUG', 'FIXIT', 'ISSUE' }, -- a set of other keywords that all map to this FIX keywords + -- signs = false, -- configure signs for some keywords individually + }, + TODO = { icon = ' ', color = 'todo' }, + HACK = { icon = ' ', color = 'warning' }, + WARN = { icon = ' ', color = 'warning', alt = { 'WARNING', 'XXX' } }, + PERF = { icon = ' ', alt = { 'OPTIM', 'PERFORMANCE', 'OPTIMIZE' } }, + NOTE = { icon = ' ', color = 'hint', alt = { 'INFO' } }, + TEST = { icon = '⏲ ', color = 'test', alt = { 'TESTING', 'PASSED', 'FAILED' } }, + DONE = { color = 'done', alt = { 'FINISHED', 'COMPLETE' } }, + }, + colors = { + done = { 'Done', '#A89984' }, + todo = { 'Todo', '#98971A' }, + }, + }, + }, appearance = { -- 'mono' (default) for 'Nerd Font Mono' or 'normal' for 'Nerd Font' -- Adjusts spacing to ensure icons are aligned @@ -949,14 +1482,41 @@ do treesitter_try_attach(buf, language) end end, - }) -end - --- ============================================================ --- SECTION 10: OPTIONAL EXAMPLES / NEXT STEPS --- kickstart.plugins.* examples --- ============================================================ -do + }, + { -- Highlight, edit, and navigate code + 'nvim-treesitter/nvim-treesitter', + build = ':TSUpdate', + main = 'nvim-treesitter.config', -- Sets main module to use for opts + -- [[ Configure Treesitter ]] See `:help nvim-treesitter` + opts = { + ensure_installed = { + 'bash', + 'c', + 'diff', + 'html', + 'lua', + 'luadoc', + 'markdown', + 'markdown_inline', + 'query', + 'vim', + 'vimdoc', + 'javascript', + 'typescript', + 'tsx', + 'xml', + 'gdscript', + 'godot_resource', + 'gdshader', + }, + auto_install = true, + highlight = { + enable = true, + additional_vim_regex_highlighting = { 'ruby' }, + }, + indent = { enable = true, disable = { 'ruby', 'gdscript', 'godot_resource', 'gdshader' } }, + }, + }, -- 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. @@ -966,18 +1526,85 @@ do -- 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` + 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 recommend keymaps + + -- NOTE: The import below can automatically add your own plugins, configuration, etc from `lua/custom/plugins/*.lua` + -- This is the easiest way to modularize your config. -- -- Uncomment the following line and add your plugins to `lua/custom/plugins/*.lua` to get going. -- require 'custom.plugins' end --- The line beneath this is called `modeline`. See `:help modeline` --- vim: ts=2 sts=2 sw=2 et +-- tab setup +vim.opt.tabstop = 2 -- How wide a tab character looks +vim.opt.shiftwidth = 2 -- How much indentation changes when you hit >> or << +vim.opt.softtabstop = 2 -- How many spaces inserted when you hit +vim.opt.expandtab = true -- Convert tabs to spaces + +-- oil setup +require('oil').setup { + keymaps = { + [''] = 'actions.refresh', + [''] = { 'actions.select', opts = { horizontal = true } }, + [''] = false, + [''] = false, + [''] = false, + }, + view_options = { + show_hidden = true, + }, +} +vim.keymap.set('n', '-', 'Oil', { desc = 'Open parent directory' }) + +-- relative/absolute line numbers setup +vim.opt.number = true +vim.opt.relativenumber = true + +local number_toggle_group = vim.api.nvim_create_augroup('NumberToggle', { clear = true }) + +vim.api.nvim_create_autocmd({ 'InsertEnter' }, { + group = number_toggle_group, + pattern = '*', + callback = function() + vim.opt.relativenumber = false + end, +}) + +vim.api.nvim_create_autocmd({ 'InsertLeave' }, { + group = number_toggle_group, + pattern = '*', + callback = function() + vim.opt.relativenumber = true + end, +}) + +vim.lsp.config('gdscript', { + capabilities = capabilities, +}) + +vim.lsp.enable 'gdscript' + +local paths_to_check = { '/', '/../' } +local is_godot_project = false +local godot_project_path = '' +local cwd = vim.fn.getcwd() + +-- iterate over paths and check +for key, value in pairs(paths_to_check) do + if vim.uv.fs_stat(cwd .. value .. 'project.godot') then + is_godot_project = true + godot_project_path = cwd .. value + break + end +end + +local is_server_running = vim.uv.fs_stat(godot_project_path .. '/server.pipe') +-- start server, if not already running +if is_godot_project and not is_server_running then + vim.fn.serverstart(godot_project_path .. '/server.pipe') +end diff --git a/lua/kickstart/plugins/debug.lua b/lua/kickstart/plugins/debug.lua index db5448c2cfc..725130a263c 100644 --- a/lua/kickstart/plugins/debug.lua +++ b/lua/kickstart/plugins/debug.lua @@ -28,10 +28,86 @@ vim.keymap.set('n', '', function() require('dapui').toggle() end, { desc = ' local dap = require 'dap' local dapui = require 'dapui' -require('mason-nvim-dap').setup { - -- Makes a best effort to setup the various debuggers with - -- reasonable debug configurations - automatic_installation = true, + -- Add your own debuggers here + 'leoluz/nvim-dap-go', + }, + keys = { + -- Basic debugging keymaps, feel free to change to your liking! + { + '', + function() + require('dap').continue() + end, + desc = 'Debug: Start/Continue', + }, + { + '', + function() + require('dap').step_into() + end, + desc = 'Debug: Step Into', + }, + { + '', + function() + require('dap').step_over() + end, + desc = 'Debug: Step Over', + }, + { + '', + function() + require('dap').step_out() + end, + desc = 'Debug: Step Out', + }, + { + 'b', + function() + require('dap').toggle_breakpoint() + end, + desc = 'Debug: Toggle Breakpoint', + }, + { + 'B', + function() + require('dap').set_breakpoint(vim.fn.input 'Breakpoint condition: ') + end, + desc = 'Debug: Set Breakpoint', + }, + -- Toggle to see last session result. Without this, you can't see session output in case of unhandled exception. + { + '', + function() + require('dapui').toggle() + end, + desc = 'Debug: See last session result.', + }, + }, + config = function() + local dap = require 'dap' + local dapui = require 'dapui' + + dap.adapters.godot = { + type = 'server', + host = '127.0.0.1', + port = 6006, + } + + dap.configurations.gdscript = { + { + type = 'godot', + request = 'launch', + name = 'Launch scene', + project = '${workspaceFolder}', + launch_scene = true, + }, + } + + require('mason-nvim-dap').setup { + -- Makes a best effort to setup the various debuggers with + -- reasonable debug configurations + automatic_installation = true, -- You can provide additional configuration to the handlers, -- see mason-nvim-dap README for more information