From d53a7d70064b7724da79996ec7fa0f0e4f0d22f4 Mon Sep 17 00:00:00 2001 From: RiverMatsumoto Date: Thu, 3 Oct 2024 18:53:41 -1000 Subject: [PATCH] init.lua update --- init.lua | 2355 +++++++++++++++++++++++++++++++++++------------------- 1 file changed, 1536 insertions(+), 819 deletions(-) diff --git a/init.lua b/init.lua index 8ecf9f94..eb8456a0 100644 --- a/init.lua +++ b/init.lua @@ -1,791 +1,104 @@ --[[ - ===================================================================== ==================== READ THIS BEFORE CONTINUING ==================== ===================================================================== -======== .-----. ======== -======== .----------------------. | === | ======== -======== |.-""""""""""""""""""-.| |-----| ======== -======== || || | === | ======== -======== || KICKSTART.NVIM || |-----| ======== -======== || || | === | ======== -======== || || |-----| ======== -======== ||:Tutor || |:::::| ======== -======== |'-..................-'| |____o| ======== -======== `"")----------------(""` ___________ ======== -======== /::::::::::| |::::::::::\ \ no mouse \ ======== -======== /:::========| |==hjkl==:::\ \ required \ ======== -======== '""""""""""""' '""""""""""""' '""""""""""' ======== -======== ======== -===================================================================== -===================================================================== + ros2-with-neovim is heavily inspired from Kickstart.nvim. -What is Kickstart? + I have basically taken the same approach of having a single file where all the + main configurations are done commenting clearly what all of them do. - 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 how 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 sure exactly 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 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 nvim 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! :) + You should consider this as a starting point into your Neovim journey. Then, you can + start to add as many plugins and configurations as you see fit :). --]] - -- Set as the leader key -- See `:help mapleader` --- NOTE: Must happen before plugins are loaded (otherwise wrong leader will be used) +-- NOTE: Must happen before plugins are required (otherwise wrong leader will be used) vim.g.mapleader = ' ' vim.g.maplocalleader = ' ' --- [[ Setting options ]] --- See `:help vim.opt` --- NOTE: You can change these options as you wish! --- For more options, you can see `:help option-list` - --- Make line numbers default -vim.opt.number = true --- You can also add relative line numbers, for help with jumping. --- Experiment for yourself to see if you like it! --- vim.opt.relativenumber = true - --- Enable mouse mode, can be useful for resizing splits for example! -vim.opt.mouse = 'a' - --- Don't show the mode, since it's already in status line -vim.opt.showmode = false - --- Sync clipboard between OS and Neovim. --- Remove this option if you want your OS clipboard to remain independent. --- See `:help 'clipboard'` -vim.opt.clipboard = 'unnamedplus' - --- Enable break indent -vim.opt.breakindent = true - --- indentation --- vim.opt.autoindent = true --- vim.opt.smartindent = true - --- Save undo history -vim.opt.undofile = true - --- Case-insensitive searching UNLESS \C or capital in search -vim.opt.ignorecase = true -vim.opt.smartcase = true - --- Keep signcolumn on by default -vim.opt.signcolumn = 'yes' - --- spaces instead of tab -vim.opt.expandtab = true - --- tab width 4 --- vim.opt.shiftwidth = 4 --- vim.opt.tabstop = 4 --- vim.opt.softtabstop = 4 - --- Decrease update time -vim.opt.updatetime = 250 -vim.opt.timeoutlen = 300 - --- Configure how new splits should be opened -vim.opt.splitright = true -vim.opt.splitbelow = true - --- Sets how neovim will display certain whitespace in the editor. --- See `:help 'list'` --- and `:help 'listchars'` -vim.opt.list = true -vim.opt.listchars = { tab = '» ', trail = '·', nbsp = '␣' } - --- Preview substitutions live, as you type! -vim.opt.inccommand = 'split' - --- Show which line your cursor is on -vim.opt.cursorline = true - --- Minimal number of screen lines to keep above and below the cursor. -vim.opt.scrolloff = 10 - --- [[ Basic Keymaps ]] --- See `:help vim.keymap.set()` - --- Set highlight on search, but clear on pressing in normal mode -vim.opt.hlsearch = true -vim.keymap.set('n', '', 'nohlsearch') - --- Diagnostic keymaps -vim.keymap.set('n', '[d', vim.diagnostic.goto_prev, { desc = 'Go to previous [D]iagnostic message' }) -vim.keymap.set('n', ']d', vim.diagnostic.goto_next, { desc = 'Go to next [D]iagnostic message' }) -vim.keymap.set('n', 'e', vim.diagnostic.open_float, { desc = 'Show diagnostic [E]rror messages' }) -vim.keymap.set('n', 'q', vim.diagnostic.setloclist, { desc = 'Open diagnostic [Q]uickfix list' }) -vim.api.nvim_set_keymap('n', '\\', ':Neotree toggle current reveal_force_cwd', { noremap = true }) -vim.api.nvim_set_keymap('n', '|', ':Neotree toggle reveal', { noremap = true }) -vim.api.nvim_set_keymap('n', 'gd', ':Neotree float reveal_file= reveal_force_cwd', { noremap = true }) -vim.api.nvim_set_keymap('n', '', ':w', { noremap = true }) -vim.api.nvim_set_keymap('i', '', ':w', { noremap = true }) -vim.api.nvim_set_keymap('n', 'Y', 'yy', { noremap = true }) -vim.api.nvim_set_keymap('v', '', '"+y', { noremap = true }) --- vim.api.nvim_set_keymap('i', '', '', { noremap = true }) - --- 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' }) - --- [[ Basic Autocommands ]] --- See `:help lua-guide-autocommands` - --- Highlight when yanking (copying) text --- Try it with `yap` in normal mode --- See `:help vim.highlight.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.highlight.on_yank() - end, -}) - --- [[ Install `lazy.nvim` plugin manager ]] --- See `:help lazy.nvim.txt` or https://github.com/folke/lazy.nvim for more info +-- Install package manager +-- https://github.com/folke/lazy.nvim +-- `:help lazy.nvim.txt` for more info +-- INFO: There are different plugins manager for neovim. I prefer Lazy local lazypath = vim.fn.stdpath 'data' .. '/lazy/lazy.nvim' if not vim.loop.fs_stat(lazypath) then - local lazyrepo = 'https://github.com/folke/lazy.nvim.git' - vim.fn.system { 'git', 'clone', '--filter=blob:none', '--branch=stable', lazyrepo, lazypath } -end ---@diagnostic disable-next-line: undefined-field + vim.fn.system { + 'git', + 'clone', + '--filter=blob:none', + 'https://github.com/folke/lazy.nvim.git', + '--branch=stable', -- latest stable release + lazypath, + } +end + vim.opt.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 { - -- NOTE: Plugins can be added with a link (or for a github repo: 'owner/repo' link). - 'tpope/vim-sleuth', -- Detect tabstop and shiftwidth automatically +-- You can configure plugins using the `config` key. +-- You can also configure plugins after the setup call, +-- as they will be available in your neovim runtime. +require('lazy').setup({ + -- INFO: Git related plugins 'voldikss/vim-floaterm', - - -- 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 force a plugin to be loaded. - -- - -- This is equivalent to: - -- require('Comment').setup({}) - - -- "gc" to comment visual regions/lines + 'tpope/vim-fugitive', -- Git wrapper for vim + 'rhysd/conflict-marker.vim', -- weapon to fight against merge conflicts { 'numToStr/Comment.nvim', opts = {} }, - -- 'sainnhe/gruvbox-material', - 'nvim-lualine/lualine.nvim', + 'rhysd/git-messenger.vim', -- Shows commit message under cursor { - 'f4z3r/gruvbox-material.nvim', - name = 'gruvbox-material', - lazy = false, - priority = 1000, - opts = {}, - }, - -- Here is a more advanced example where we pass configuration - -- options to `gitsigns.nvim`. This is equivalent to the following lua: - -- require('gitsigns').setup({ ... }) - -- - -- 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 = '~' }, - }, - }, - }, - - -- NOTE: Plugins can also be configured to run lua code when they are loaded. - -- - -- This is often very useful to both group configuration, as well as handle - -- lazy loading plugins that don't need to be loaded immediately at startup. - -- - -- For example, in the following configuration, we use: - -- event = 'VimEnter' - -- - -- which loads which-key before all the UI elements are loaded. Events can be - -- normal autocommands events (`:help autocmd-events`). - -- - -- Then, because we use the `config` key, the configuration only runs - -- after the plugin has been loaded: - -- config = function() ... end - - { -- Useful plugin to show you pending keybinds. - 'folke/which-key.nvim', - event = 'VimEnter', -- Sets the loading event to 'VimEnter' - config = function() -- This is the function that runs, AFTER loading - require('which-key').setup() - - -- Document existing key chains - require('which-key').register { - ['c'] = { name = '[C]ode', _ = 'which_key_ignore' }, - ['d'] = { name = '[D]ocument', _ = 'which_key_ignore' }, - ['r'] = { name = '[R]ename', _ = 'which_key_ignore' }, - ['s'] = { name = '[S]earch', _ = 'which_key_ignore' }, - ['w'] = { name = '[W]orkspace', _ = 'which_key_ignore' }, - } - end, - }, - - -- NOTE: Plugins can specify dependencies. - -- - -- The dependencies are proper plugin specifications as well - anything - -- you do for a plugin at the top level, you can do for a dependency. - -- - -- Use the `dependencies` key to specify the dependencies of a particular plugin - - { -- Fuzzy Finder (files, lsp, etc) - 'nvim-telescope/telescope.nvim', - event = 'VimEnter', - branch = '0.1.x', - dependencies = { - 'nvim-lua/plenary.nvim', - { -- If encountering errors, see telescope-fzf-native README for install instructions - 'nvim-telescope/telescope-fzf-native.nvim', - - -- `build` is used to run some command when the plugin is installed/updated. - -- This is only run then, not every time Neovim starts up. - build = 'make', - - -- `cond` is a condition used to determine whether this plugin should be - -- installed and loaded. - cond = function() - return vim.fn.executable 'make' == 1 - end, - }, - { 'nvim-telescope/telescope-ui-select.nvim' }, - - -- Useful for getting pretty icons, but requires special font. - -- If you already have a Nerd Font, or terminal set up with fallback fonts - -- you can enable this - { 'nvim-tree/nvim-web-devicons' }, - }, + 'lewis6991/gitsigns.nvim', -- Similar to fugitive, but adds additiona functionality + event = 'VeryLazy', 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 { - -- You can put your default mappings / updates / etc. in here - -- All the info you're looking for is in `:help telescope.setup()` - -- - defaults = { - -- mappings = { - -- i = { [''] = 'to_fuzzy_refine' }, - -- }, - file_ignore_patterns = { - 'node_modules', - 'build', - '%.git$', - '%.cache$', - '%.o$', - '%.a$', - '%.out$', - '%.class$', - '%.pdf$', - '%.mkv$', - '%.mp4$', - '%.zip$', - '%.make$', - }, - }, - pickers = { - find_files = { - hidden = true, - }, - }, - extensions = { - ['ui-select'] = { - require('telescope.themes').get_dropdown(), - }, - 'projects', + require('gitsigns').setup { + signs = { + add = { text = '│' }, + change = { text = '│' }, + delete = { text = '_' }, + topdelete = { text = '‾' }, + changedelete = { text = '~' }, + untracked = { text = '┆' }, }, } - - -- Enable telescope extensions, if they are installed - pcall(require('telescope').load_extension, 'fzf') - pcall(require('telescope').load_extension, 'ui-select') - - -- See `:help telescope.builtin` - local builtin = require 'telescope.builtin' - vim.keymap.set('n', 'sh', builtin.help_tags, { desc = '[S]earch [H]elp' }) - vim.keymap.set('n', 'sk', builtin.keymaps, { desc = '[S]earch [K]eymaps' }) - vim.keymap.set('n', 'sf', builtin.find_files, { desc = '[S]earch [F]iles' }) - vim.keymap.set('n', 'ss', builtin.builtin, { desc = '[S]earch [S]elect Telescope' }) - vim.keymap.set('n', 'sw', builtin.grep_string, { desc = '[S]earch current [W]ord' }) - vim.keymap.set('n', 'sg', builtin.live_grep, { desc = '[S]earch by [G]rep' }) - vim.keymap.set('n', 'sd', builtin.diagnostics, { desc = '[S]earch [D]iagnostics' }) - vim.keymap.set('n', 'sr', builtin.resume, { desc = '[S]earch [R]esume' }) - vim.keymap.set('n', 's.', builtin.oldfiles, { desc = '[S]earch Recent Files ("." for repeat)' }) - vim.keymap.set('n', '', builtin.buffers, { desc = '[ ] Find existing buffers' }) - - -- Slightly advanced example of overriding default behavior and theme - vim.keymap.set('n', '/', function() - -- You can pass additional configuration to telescope to change theme, layout, etc. - builtin.current_buffer_fuzzy_find(require('telescope.themes').get_dropdown { - winblend = 10, - previewer = false, - }) - end, { desc = '[/] Fuzzily search in current buffer' }) - - -- Also possible to pass additional configuration options. - -- See `:help telescope.builtin.live_grep()` for information about particular keys - vim.keymap.set('n', 's/', function() - builtin.live_grep { - grep_open_files = true, - prompt_title = 'Live Grep in Open Files', - } - end, { desc = '[S]earch [/] in Open Files' }) - - -- Shortcut for searching your neovim configuration files - vim.keymap.set('n', 'sn', function() - builtin.find_files { cwd = vim.fn.stdpath 'config' } - end, { desc = '[S]earch [N]eovim files' }) end, }, - { - 'ErickKramer/nvim-ros2', + 'sindrets/diffview.nvim', -- Single tabpage interface for easily cycling through diffs + event = 'VeryLazy', dependencies = { 'nvim-lua/plenary.nvim', + }, + }, + { -- Quick selection of co-authors + 'ErickKramer/git-coauthors.nvim', + dependencies = { 'nvim-telescope/telescope.nvim', - 'nvim-treesitter/nvim-treesitter', - }, - opts = { - -- Add any custom options here - autocmds = true, - telescope = true, - treesitter = true, }, }, - { -- LSP Configuration & Plugins - 'neovim/nvim-lspconfig', - dependencies = { - -- Automatically install LSPs and related tools to stdpath for neovim - 'williamboman/mason.nvim', - 'williamboman/mason-lspconfig.nvim', - 'WhoIsSethDaniel/mason-tool-installer.nvim', - - -- Useful status updates for LSP. - -- NOTE: `opts = {}` is the same as calling `require('fidget').setup({})` - { 'j-hui/fidget.nvim', opts = {} }, - }, + -- INFO: Enhance Editor Experience + { + 'iamcco/markdown-preview.nvim', -- Markdown previewer + -- event = "VeryLazy", + build = function() + vim.fn['mkdp#util#install']() + end, config = function() - -- Brief Aside: **What is LSP?** - -- - -- LSP is an acronym 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` + -- Refresh markdown when saving the buffer or leaving insert mode + vim.g.mkdp_refresh_slow = 1 - -- 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 - -- many times. - -- - -- 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) - vim.keymap.set('n', keys, func, { buffer = event.buf, desc = 'LSP: ' .. desc }) - end + -- Fancy title + vim.g.mkdp_page_title = '「${name}」' - -- 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('gd', require('telescope.builtin').lsp_definitions, '[G]oto [D]efinition') + -- Dark mode (of course) + vim.g.mkdp_theme = 'dark' - -- Find references for the word under your cursor. - map('gr', require('telescope.builtin').lsp_references, '[G]oto [R]eferences') + -- Avoid auto close + vim.g.mkdp_auto_close = 0 - -- Jump to the implementation of the word under your cursor. - -- Useful when your language has ways of declaring types without an actual implementation. - map('gI', require('telescope.builtin').lsp_implementations, '[G]oto [I]mplementation') - - -- 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('D', require('telescope.builtin').lsp_type_definitions, 'Type [D]efinition') - - -- Fuzzy find all the symbols in your current document. - -- Symbols are things like variables, functions, types, etc. - map('ds', require('telescope.builtin').lsp_document_symbols, '[D]ocument [S]ymbols') - - -- Fuzzy find all the symbols in your current workspace - -- Similar to document symbols, except searches over your whole project. - map('ws', require('telescope.builtin').lsp_dynamic_workspace_symbols, '[W]orkspace [S]ymbols') - - -- Rename the variable under your cursor - -- Most Language Servers support renaming across files, etc. - map('rn', 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('ca', vim.lsp.buf.code_action, '[C]ode [A]ction') - - -- Opens a popup that displays documentation about the word under your cursor - -- See `:help K` for why this keymap - map('K', vim.lsp.buf.hover, 'Hover Documentation') - - -- WARN: This is not Goto Definition, this is Goto Declaration. - -- For example, in C this would take you to the header - map('gD', vim.lsp.buf.declaration, '[G]oto [D]eclaration') - - -- The following two autocommands are used to highlight references of the - -- word under your cursor when your cursor rests there for a little while. - -- See `:help CursorHold` for information about when this is executed - -- - -- When you move your cursor, the highlights will be cleared (the second autocommand). - local client = vim.lsp.get_client_by_id(event.data.client_id) - if client and client.server_capabilities.documentHighlightProvider then - vim.api.nvim_create_autocmd({ 'CursorHold', 'CursorHoldI' }, { - buffer = event.buf, - callback = vim.lsp.buf.document_highlight, - }) - - vim.api.nvim_create_autocmd({ 'CursorMoved', 'CursorMovedI' }, { - buffer = event.buf, - callback = vim.lsp.buf.clear_references, - }) - end - end, - }) - - -- LSP servers and clients are able to communicate to each other what features they support. - -- By default, Neovim doesn't support everything that is in the LSP Specification. - -- When you add nvim-cmp, luasnip, etc. Neovim now has *more* capabilities. - -- So, we create new capabilities with nvim cmp, and then broadcast that to the servers. - local capabilities = vim.lsp.protocol.make_client_capabilities() - capabilities = vim.tbl_deep_extend('force', capabilities, require('cmp_nvim_lsp').default_capabilities()) - - -- Enable the following language servers - -- Feel free to add/remove any LSPs that you want here. They will automatically be installed. - -- - -- Add any additional override configuration in the following tables. Available keys are: - -- - cmd (table): Override the default command used to start the server - -- - filetypes (table): Override the default list of associated filetypes for the server - -- - capabilities (table): Override fields in capabilities. Can be used to disable certain LSP features. - -- - settings (table): Override the default settings passed when initializing the server. - -- For example, to see the options for `lua_ls`, you could go to: https://luals.github.io/wiki/settings/ - local servers = { - clangd = { - cmd = { - 'clangd', - '--compile-commands-dir=build', - }, - }, - -- gopls = {}, - pyright = {}, - -- rust_analyzer = {}, - -- ... etc. See `:help lspconfig-all` for a list of all the pre-configured LSPs - -- - -- Some languages (like typescript) have entire language plugins that can be useful: - -- https://github.com/pmizio/typescript-tools.nvim - -- - -- But for many setups, the LSP (`tsserver`) will work just fine - -- tsserver = {}, - -- - - lua_ls = { - -- cmd = {...}, - -- filetypes { ...}, - -- capabilities = {}, - settings = { - Lua = { - runtime = { version = 'LuaJIT' }, - workspace = { - checkThirdParty = false, - -- Tells lua_ls where to find all the Lua files that you have loaded - -- for your neovim configuration. - library = { - '${3rd}/luv/library', - unpack(vim.api.nvim_get_runtime_file('', true)), - }, - -- If lua_ls is really slow on your computer, you can try this instead: - -- library = { vim.env.VIMRUNTIME }, - }, - completion = { - callSnippet = 'Replace', - }, - -- You can toggle below to ignore Lua_LS's noisy `missing-fields` warnings - -- diagnostics = { disable = { 'missing-fields' } }, - }, - }, - }, - } - - -- Ensure the servers and tools above are installed - -- To check the current status of installed tools and/or manually install - -- other tools, you can run - -- :Mason - -- - -- You can press `g?` for help in this menu - require('mason').setup() - - -- You can add other tools here that you want Mason to install - -- for you, so that they are available from within Neovim. - local ensure_installed = vim.tbl_keys(servers or {}) - vim.list_extend(ensure_installed, { - 'stylua', -- Used to format lua code - }) - require('mason-tool-installer').setup { ensure_installed = ensure_installed } - - require('mason-lspconfig').setup { - handlers = { - function(server_name) - local server = servers[server_name] or {} - -- This handles overriding only values explicitly passed - -- by the server configuration above. Useful when disabling - -- certain features of an LSP (for example, turning off formatting for tsserver) - server.capabilities = vim.tbl_deep_extend('force', {}, capabilities, server.capabilities or {}) - require('lspconfig')[server_name].setup(server) - end, - }, - } + vim.g.mkdp_combine_preview = 1 + vim.g.mkdp_combine_preview_auto_refresh = 1 end, }, - - { -- Autoformat - 'stevearc/conform.nvim', - opts = { - notify_on_error = false, - format_on_save = { - timeout_ms = 500, - lsp_fallback = true, - }, - formatters_by_ft = { - lua = { 'stylua' }, - -- Conform can also run multiple formatters sequentially - -- python = { "isort", "black" }, - c = { 'clangd' }, - -- - -- You can use a sub-list to tell conform to run *until* a formatter - -- is found. - -- javascript = { { "prettierd", "prettier" } }, - }, - }, - }, - - { -- Autocompletion - 'hrsh7th/nvim-cmp', - event = 'InsertEnter', - dependencies = { - -- Snippet Engine & its associated nvim-cmp source - { - 'L3MON4D3/LuaSnip', - 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)(), - }, - 'saadparwaiz1/cmp_luasnip', - - -- Adds other completion capabilities. - -- nvim-cmp does not ship with all sources by default. They are split - -- into multiple repos for maintenance purposes. - 'hrsh7th/cmp-nvim-lsp', - 'hrsh7th/cmp-path', - - -- If you want to add a bunch of pre-configured snippets, - -- you can use this plugin to help you. It even has snippets - -- for various frameworks/libraries/etc. but you will have to - -- set up the ones that are useful for you. - -- 'rafamadriz/friendly-snippets', - }, - config = function() - -- See `:help cmp` - local cmp = require 'cmp' - local luasnip = require 'luasnip' - luasnip.config.setup {} - - cmp.setup { - snippet = { - expand = function(args) - luasnip.lsp_expand(args.body) - end, - }, - completion = { completeopt = 'menu,menuone,noinsert' }, - - -- For an understanding of why these mappings were - -- chosen, you will need to read `:help ins-completion` - -- - -- No, but seriously. Please read `:help ins-completion`, it is really good! - mapping = cmp.mapping.preset.insert { - -- Select the [n]ext item - [''] = cmp.mapping.select_next_item(), - -- Select the [p]revious item - [''] = cmp.mapping.select_prev_item(), - - -- Accept ([y]es) the completion. - -- This will auto-import if your LSP supports it. - -- This will expand snippets if the LSP sent a snippet. - [''] = cmp.mapping.confirm { select = true }, - - -- Manually trigger a completion from nvim-cmp. - -- Generally you don't need this, because nvim-cmp will display - -- completions whenever it has completion options available. - [''] = cmp.mapping.complete {}, - - -- Think of as moving to the right of your snippet expansion. - -- So if you have a snippet that's like: - -- function $name($args) - -- $body - -- end - -- - -- will move you to the right of each of the expansion locations. - -- is similar, except moving you backwards. - [''] = cmp.mapping(function() - if luasnip.expand_or_locally_jumpable() then - luasnip.expand_or_jump() - end - end, { 'i', 's' }), - [''] = cmp.mapping(function() - if luasnip.locally_jumpable(-1) then - luasnip.jump(-1) - end - end, { 'i', 's' }), - }, - sources = { - { name = 'nvim_lsp' }, - { name = 'luasnip' }, - { name = 'path' }, - }, - } - end, - }, - { -- 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 @@ -802,90 +115,1488 @@ require('lazy').setup { vim.cmd.hi 'Comment gui=none' end, }, - - -- Highlight todo, notes, etc in comments - { 'folke/todo-comments.nvim', event = 'VimEnter', dependencies = { 'nvim-lua/plenary.nvim' }, opts = { signs = false } }, - - { -- Collection of various small independent plugins/modules - 'echasnovski/mini.nvim', + { + 'f4z3r/gruvbox-material.nvim', + name = 'gruvbox-material', + lazy = false, + priority = 1000, + opts = {}, + }, + 'mg979/vim-visual-multi', -- Enable multicursor + { + "nvim-neo-tree/neo-tree.nvim", + branch = "v3.x", + dependencies = { + "nvim-lua/plenary.nvim", + "nvim-tree/nvim-web-devicons", -- not strictly required, but recommended + "MunifTanjim/nui.nvim", + -- "3rd/image.nvim", -- Optional image support in preview window: See `# Preview Mode` for more information + } + }, + 'nvim-tree/nvim-web-devicons', -- Add fancy icons + -- { + -- 'nvim-tree/nvim-tree.lua', -- File tree + -- config = function() + -- -- Config needed for nvim-tree + -- vim.g.loaded_netrw = 1 + -- vim.g.loaded_netrwPlugin = 1 + -- require('nvim-tree').setup { + -- sort_by = 'case_sensitive', + -- view = { + -- adaptive_size = false, + -- relativenumber = true, + -- width = 40, + -- }, + -- renderer = { + -- group_empty = true, + -- }, + -- filters = { + -- dotfiles = true, + -- }, + -- } + -- end, + -- }, + { + 'folke/todo-comments.nvim', -- Fancy TODOs/FIXMEs + dependencies = 'nvim-lua/plenary.nvim', + opts = {}, + }, + { -- Improve file navigation with search labels + 'folke/flash.nvim', + event = 'VeryLazy', + ---@type Flash.Config + opts = {}, + keys = { + { + 's', + mode = { 'n', 'x', 'o' }, + function() + require('flash').jump() + end, + desc = 'Flash', + }, + { + 'S', + mode = { 'n', 'x', 'o' }, + function() + require('flash').treesitter() + end, + desc = 'Flash Treesitter', + }, + { + 'r', + mode = 'o', + function() + require('flash').remote() + end, + desc = 'Remote Flash', + }, + { + 'R', + mode = { 'o', 'x' }, + function() + require('flash').treesitter_search() + end, + desc = 'Treesitter Search', + }, + -- { "", mode = { "c" }, function() require("flash").toggle() end, desc = "Toggle Flash Search" }, + }, + }, + { + 'folke/trouble.nvim', -- Quickfix list for LSP errors + dependencies = 'nvim-tree/nvim-web-devicons', config = function() - -- Better Around/Inside textobjects - -- - -- Examples: - -- - va) - [V]isually select [A]round [)]paren - -- - yinq - [Y]ank [I]nside [N]ext [']quote - -- - ci' - [C]hange [I]nside [']quote - require('mini.ai').setup { n_lines = 500 } - - -- Add/delete/replace surroundings (brackets, quotes, etc.) - -- - -- - saiw) - [S]urround [A]dd [I]nner [W]ord [)]Paren - -- - sd' - [S]urround [D]elete [']quotes - -- - sr)' - [S]urround [R]eplace [)] ['] - require('mini.surround').setup() - - -- Simple and easy statusline. - -- You could remove this setup call if you don't like it, - -- and try some other statusline plugin - local statusline = require 'mini.statusline' - statusline.setup() - - -- You can configure sections in the statusline by overriding their - -- default behavior. For example, here we disable the section for - -- cursor information because line numbers are already enabled - ---@diagnostic disable-next-line: duplicate-set-field - statusline.section_location = function() - return '' + require('trouble').setup { + signs = { + -- icons / text used for a diagnostic + error = '', + warning = '', + hint = '', + information = '', + other = '﫠', + }, + } + end, + }, + { + 'folke/which-key.nvim', -- Popup with possible keybindings of the command you started to type + opts = {}, + }, + { + 'nvim-lualine/lualine.nvim', -- Fancier statusline + config = function() + local function get_venv() + local venv = vim.env.VIRTUAL_ENV + if venv then + local env = string.match(venv, '[^/]+$') + return ' ' .. env + else + return '' + end end - -- ... and there is more! - -- Check out: https://github.com/echasnovski/mini.nvim + local ros_distro = vim.fn.expand '$ROS_DISTRO' + + local function get_ros_distro() + if ros_distro and ros_distro ~= '$ROS_DISTRO' then + return '󰭆 ' .. ros_distro + else + return '' + end + end + require('lualine').setup { + options = { + icons_enabled = true, + theme = 'onedark', + component_separators = '|', + section_separators = '', + ignore_focus = { + 'dapui_watches', + 'dapui_breakpoints', + 'dapui_scopes', + 'dapui_console', + 'dapui_stacks', + 'dap-repl', + }, + disabled_filetypes = { 'NvimTree' }, + }, + sections = { + lualine_a = { 'mode' }, + lualine_b = { 'branch', 'diff', 'diagnostics' }, + lualine_c = { 'filename' }, + lualine_x = { { get_venv }, { get_ros_distro }, 'fileformat', 'filetype' }, + lualine_y = { 'progress' }, + lualine_z = { 'location' }, + }, + } end, }, - - { -- Highlight, edit, and navigate code - 'nvim-treesitter/nvim-treesitter', - build = ':TSUpdate', + { + 'nvim-pack/nvim-spectre', -- Advance Search and Replace + opts = {}, + }, + { + 'goolord/alpha-nvim', -- Greeter dashboard + dependencies = { 'nvim-tree/nvim-web-devicons' }, config = function() - -- [[ Configure Treesitter ]] See `:help nvim-treesitter` + local alpha = require 'alpha' + local dashboard = require 'alpha.themes.dashboard' + dashboard.section.header.val = { + [[██████╗ ██████╗ ███████╗]], + [[██╔══██╗██╔═══██╗██╔════╝]], + [[██████╔╝██║ ██║███████╗]], + [[██╔══██╗██║ ██║╚════██║]], + [[██║ ██║╚██████╔╝███████║]], + [[╚═╝ ╚═╝ ╚═════╝ ╚══════╝]], + } + dashboard.section.buttons.val = { + dashboard.button('f', ' Find file', ':Telescope find_files '), + dashboard.button('t', ' Find text', ':Telescope live_grep '), + dashboard.button('n', ' New file', ':ene startinsert '), + dashboard.button('c', ' Configuration', ':e ~/.config/nvim/init.lua '), + dashboard.button('u', ' Update plugins', ':Lazy sync'), + dashboard.button('q', ' Quit', ':qa'), + } + local handle = io.popen 'fortune' + local fortune = handle:read '*a' + handle:close() + dashboard.section.footer.val = fortune - ---@diagnostic disable-next-line: missing-fields - require('nvim-treesitter.configs').setup { - ensure_installed = { 'bash', 'c', 'html', 'lua', 'markdown', 'vim', 'vimdoc' }, - -- Autoinstall languages that are not installed - auto_install = true, - highlight = { enable = true }, - indent = { enable = true }, + dashboard.config.opts.noautocmd = true + + vim.cmd [[autocmd User AlphaReady echo 'ready']] + + alpha.setup(dashboard.config) + end, + }, + { + 'romgrk/barbar.nvim', -- Tabline plugin that improves buffers and tabs + event = 'BufEnter', + dependencies = 'nvim-tree/nvim-web-devicons', + init = function() + vim.g.barbar_auto_setup = false + end, + lazy = true, + }, + { + -- Add indentation guides even on blank lines + 'lukas-reineke/indent-blankline.nvim', + -- Enable `lukas-reineke/indent-blankline.nvim` + -- See `:help indent_blankline.txt` + main = 'ibl', + opts = {}, + config = function() + local highlight = { + 'RainbowRed', + 'RainbowYellow', + 'RainbowBlue', + 'RainbowOrange', + 'RainbowGreen', + 'RainbowViolet', + 'RainbowCyan', } - -- There are additional nvim-treesitter modules that you can use to interact - -- with nvim-treesitter. You should go explore a few and see what interests you: - -- - -- - Incremental selection: Included, see `:help nvim-treesitter-incremental-selection-mod` - -- - Show your current context: https://github.com/nvim-treesitter/nvim-treesitter-context - -- - Treesitter + textobjects: https://github.com/nvim-treesitter/nvim-treesitter-textobjects + local hooks = require 'ibl.hooks' + -- create the highlight groups in the highlight setup hook, so they are reset + -- every time the colorscheme changes + hooks.register(hooks.type.HIGHLIGHT_SETUP, function() + vim.api.nvim_set_hl(0, 'RainbowRed', { fg = '#E06C75' }) + vim.api.nvim_set_hl(0, 'RainbowYellow', { fg = '#E5C07B' }) + vim.api.nvim_set_hl(0, 'RainbowBlue', { fg = '#61AFEF' }) + vim.api.nvim_set_hl(0, 'RainbowOrange', { fg = '#D19A66' }) + vim.api.nvim_set_hl(0, 'RainbowGreen', { fg = '#98C379' }) + vim.api.nvim_set_hl(0, 'RainbowViolet', { fg = '#C678DD' }) + vim.api.nvim_set_hl(0, 'RainbowCyan', { fg = '#56B6C2' }) + end) + require('ibl').setup { + indent = { highlight = highlight, char = '┊' }, + scope = { enabled = false }, + } + end, + }, + { + 'akinsho/toggleterm.nvim', -- Improve handling neovim terminals + opts = {}, + config = function() + require('toggleterm').setup { + size = 20, + open_mapping = [[]], + hide_numbers = true, + shade_filetypes = {}, + shade_terminals = true, + shading_factor = 2, + start_in_insert = true, + insert_mappings = true, + persist_size = true, + direction = 'float', + close_on_exit = true, + shell = vim.o.shell, + float_opts = { + border = 'curved', + winblend = 0, + highlights = { + border = 'Normal', + background = 'Normal', + }, + }, + } + function _G.set_terminal_keymaps() + local opts = { noremap = true } + vim.diagnostic.disable(0) + vim.api.nvim_buf_set_keymap(0, 't', '', [[]], opts) + end + + -- ==================================================== + -- Custom terminals + -- ==================================================== + vim.cmd 'autocmd! TermOpen term://* lua set_terminal_keymaps()' + + local Terminal = require('toggleterm.terminal').Terminal + + local lazygit = Terminal:new { + cmd = 'lazygit', + hidden = true, + direction = 'float', + float_opts = { -- Get floating window in full screen + width = vim.o.columns, + height = vim.o.lines, + }, + on_open = function(term) + vim.cmd 'startinsert!' + vim.diagnostic.disable(0) + vim.api.nvim_buf_set_keymap(0, 't', '', 'close', { silent = false, noremap = true }) + if vim.fn.mapcheck('', 't') ~= '' then + vim.api.nvim_buf_del_keymap(term.bufnr, 't', '') + end + end, + } + + function _lazygit_toggle() + -- lazygit.dir = vim.fn.getcwd() -- Open lazygit in the current working directory + lazygit.dir = vim.fn.expand '%:p:h' -- Open lazygit in the repository from the file + lazygit:toggle() + end + + local python = Terminal:new { + cmd = 'ipython3', + direction = 'horizontal', + hidden = true, + hidden_numbers = true, + } + + function _python_toggle() + python:toggle() + end + + -- Fancy terminals + vim.api.nvim_set_keymap('n', 'lg', 'lua _lazygit_toggle()', { noremap = true, silent = true }) + vim.api.nvim_set_keymap('n', 'ip', 'lua _python_toggle()', { noremap = true, silent = true }) + end, + }, + { + 'stevearc/dressing.nvim', + opts = {}, + config = function() + require('dressing').setup { + input = { + get_config = function() + return { + title_pos = 'center', + win_options = { + sidescrolloff = 10, + }, + insert_only = false, + } + end, + }, + } + end, + }, + { -- Color theme + 'navarasu/onedark.nvim', + priority = 1000, + -- config = function() + -- vim.cmd.colorscheme 'onedark' + -- end, + }, + -- Fuzzy Finder (files, lsp, etc) + { + 'nvim-telescope/telescope.nvim', + branch = '0.1.x', + dependencies = { + 'nvim-lua/plenary.nvim', + -- Fuzzy Finder Algorithm which requires local dependencies to be built. + -- Only load if `make` is available. Make sure you have the system + -- requirements installed. + { + 'nvim-telescope/telescope-fzf-native.nvim', + -- NOTE: If you are having trouble with this installation, + -- refer to the README for telescope-fzf-native for more instructions. + build = 'make', + cond = function() + return vim.fn.executable 'make' == 1 + end, + }, + 'benfowler/telescope-luasnip.nvim', -- Allows to search the available snippet + 'nvim-telescope/telescope-live-grep-args.nvim', -- Enable passing arguments to ripgrep + }, + config = function() + require('telescope').setup { + defaults = { + prompt_prefix = '🔍 ', + vimgrep_arguments = { + 'rg', + '--color=never', + '--no-heading', + '--with-filename', + '--line-number', + '--column', + '--smart-case', + '--follow', + }, + path_display = { + truncate = 3, + }, + }, + pickers = { + find_files = { + find_command = { + 'rg', + '--files', + '--hidden', + '-g', + '!.git', + }, + follow = true, + }, + lsp_document_symbols = { + show_line = true, + }, + }, + extensions = { + fzf = { + fuzzy = true, -- false will only do exact matching + override_generic_sorter = true, -- override the generic sorter + override_file_sorter = true, -- override the file sorter + case_mode = 'smart_case', -- or "ignore_case" or "respect_case" + }, + }, + } + require('telescope').load_extension 'fzf' + require('telescope').load_extension 'luasnip' + require('telescope').load_extension 'live_grep_args' + require('telescope').load_extension 'coauthors' end, }, - -- The following two 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 - -- put them in the right spots if you want. + -- + -- NOTE: This is where your plugins related to LSP can be installed. + -- The configuration is done below. Search for lspconfig to find it below. + { + -- LSP Configuration & Plugins + 'neovim/nvim-lspconfig', + dependencies = { + -- Automatically install LSPs to stdpath for neovim + { 'williamboman/mason.nvim', config = true }, + 'williamboman/mason-lspconfig.nvim', + 'WhoIsSethDaniel/mason-tool-installer.nvim', - -- NOTE: Next step on your Neovim journey: Add/Configure additional plugins for kickstart - -- - -- Here are some example plugins that I've included in the kickstart repository. - -- Uncomment any of the lines below to enable them (you will need to restart nvim). - -- - -- require 'kickstart.plugins.debug', - require 'kickstart.plugins.indent_line', + -- Useful status updates for LSP + { + 'j-hui/fidget.nvim', + config = function() + require('fidget').setup { + -- Options related to notification subsystem + notification = { + -- Options related to the notification window and buffer + window = { + normal_hl = 'Comment', -- Base highlight group in the notification window + border = 'rounded', -- Border around the notification window + zindex = 45, -- Stacking priority of the notification window + max_width = 0, -- Maximum width of the notification window + max_height = 0, -- Maximum height of the notification window + x_padding = 1, -- Padding from right edge of window boundary + y_padding = 0, -- Padding from bottom edge of window boundary + align = 'bottom', -- How to align the notification window + relative = 'editor', -- What the notification window position is relative to + }, + }, + } + end, + }, + }, + config = function() + -- INFO: LSP Settings + -- This contains the configuration of several components related to LSPs + -- - luasnip + -- - mason + -- - mason-lspconfig + -- - nvim-cmp + -- - nvim-lspconfig - -- 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. - -- For additional information, see `:help lazy.nvim-lazy.nvim-structuring-your-plugins` - { import = 'custom.plugins' }, -} + -- PERF: + -- ==================================================== + -- LSP Keymaps + -- ==================================================== + + -- This function gets run when an LSP connects to a particular buffer. + vim.api.nvim_create_autocmd('LspAttach', { + group = vim.api.nvim_create_augroup('personal-lsp-attach', { clear = true }), + callback = function(event) + -- Create a wrapper function to simplify keymaps creation + local map = function(keys, func, desc) + vim.keymap.set('n', keys, func, { buffer = event.buf, desc = 'LSP: ' .. desc }) + end + + -- 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('gd', require('telescope.builtin').lsp_definitions, '[G]oto [D]efinition') + -- Find references for the word under your cursor. + map('gr', 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('gI', require('telescope.builtin').lsp_implementations, '[G]oto [I]mplementation') + -- 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('D', require('telescope.builtin').lsp_type_definitions, 'Type [D]efinition') + -- Fuzzy find all the symbols in your current document. + -- Symbols are things like variables, functions, types, etc. + map('ds', require('telescope.builtin').lsp_document_symbols, '[D]ocument [S]ymbols') + -- Fuzzy find all the symbols in your current workspace + -- Similar to document symbols, except searches over your whole project. + map('ws', require('telescope.builtin').lsp_dynamic_workspace_symbols, '[W]orkspace [S]ymbols') + + -- Rename the variable under your cursor + -- Most Language Servers support renaming across files, etc. + map('rn', 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('ca', vim.lsp.buf.code_action, '[C]ode [A]ction') + + -- Opens a popup that displays documentation about the word under your cursor + -- See `:help K` for why this keymap + map('K', vim.lsp.buf.hover, 'Hover Documentation') + map('', vim.lsp.buf.signature_help, 'Signature Documentation') + -- NOTE: This is not Goto Definition, this is Goto Declaration. + -- For example, in C this would take you to the header + + -- 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.server_capabilities.documentHighlightProvider then + vim.api.nvim_create_autocmd({ 'CursorHold', 'CursorHoldI' }, { + buffer = event.buf, + callback = vim.lsp.buf.document_highlight, + }) + + vim.api.nvim_create_autocmd({ 'CursorMoved', 'CursorMovedI' }, { + buffer = event.buf, + callback = vim.lsp.buf.clear_references, + }) + end + end, + }) + + -- PERF: + -- ==================================================== + -- LSP Servers + -- ==================================================== + local servers = { + clangd = { + cmd = { + -- see clangd --help-hidden + 'clangd', + '--background-index', + -- by default, clang-tidy use -checks=clang-diagnostic-*,clang-analyzer-* + -- to add more checks, create .clang-tidy file in the root directory + -- and add Checks key, see https://clang.llvm.org/extra/clang-tidy/ + '--clang-tidy', + '--completion-style=bundled', + '--cross-file-rename', + '--header-insertion=iwyu', + }, + }, + pyright = { + python = { + analysis = { + autoSearchPaths = true, + diagnosticMode = 'openFilesOnly', + useLibraryCodeForTypes = true, + reportDuplicateImport = true, + }, + }, + }, + lua_ls = { + settings = { + Lua = { + runtime = { version = 'LuaJIT' }, + workspace = { + checkThirdParty = false, + library = { + '${3rd}/luv/library', + unpack(vim.api.nvim_get_runtime_file('', true)), + }, + }, + completion = { + callSnippet = 'Replace', + }, + }, + }, + }, + } + + -- PERF: + -- ==================================================== + -- capabilities Configuratioon + -- ==================================================== + + -- nvim-cmp supports additional completion capabilities, so broadcast that to servers + local capabilities = vim.lsp.protocol.make_client_capabilities() + -- capabilities.workspace.didChangeWatchedFiles.dynamicRegistration = false + capabilities = require('cmp_nvim_lsp').default_capabilities(capabilities) + capabilities.offsetEncoding = { 'utf-16' } + capabilities.textDocument.completion.completionItem.snippetSupport = true + + -- Enable folding (for nvim-ufo) + capabilities.textDocument.foldingRange = { + dynamicRegistration = false, + lineFoldingOnly = true, + } + + -- PERF: + -- ==================================================== + -- Mason Configuratioon + -- ==================================================== + + -- Setup mason so it can manage external tooling + require('mason').setup { + ui = { + border = 'rounded', + }, + } + + -- mason-lspconfig configurations + require('mason-lspconfig').setup { + handlers = { + function(server_name) + local server = servers[server_name] or {} + -- This handles overriding only values explicitly passed + -- by the server configuration above. Useful when disabling + -- certain features of an LSP (for example, turning off formatting for tsserver) + server.capabilities = vim.tbl_deep_extend('force', {}, capabilities, server.capabilities or {}) + require('lspconfig')[server_name].setup(server) + end, + }, + } + require('mason-tool-installer').setup { + + -- List of all DAP, Linter and Formatters to install + ensure_installed = { + -- LSPs + 'clangd', + 'lua_ls', + 'pyright', + 'ruff', + + -- DAP + 'codelldb', + 'cpptools', + + -- Linter + 'cpplint', + + -- Formatters + 'stylua', + 'prettier', + }, + + -- if set to true this will check each tool for updates. If updates + -- are available the tool will be updated. This setting does not + -- affect :MasonToolsUpdate or :MasonToolsInstall. + -- Default: false + auto_update = false, + + -- automatically install / update on startup. If set to false nothing + -- will happen on startup. You can use :MasonToolsInstall or + -- :MasonToolsUpdate to install tools and check for updates. + -- Default: true + run_on_start = true, + + -- set a delay (in ms) before the installation starts. This is only + -- effective if run_on_start is set to true. + -- e.g.: 5000 = 5 second delay, 10000 = 10 second delay, etc... + -- Default: 0 + start_delay = 3000, -- 3 second delay + + -- Only attempt to install if 'debounce_hours' number of hours has + -- elapsed since the last time Neovim was started. This stores a + -- timestamp in a file named stdpath('data')/mason-tool-installer-debounce. + -- This is only relevant when you are using 'run_on_start'. It has no + -- effect when running manually via ':MasonToolsInstall' etc.... + -- Default: nil + debounce_hours = 5, -- at least 5 hours between attempts to install/update + } + + -- PERF: + -- ==================================================== + -- nvim-cmp configuration + -- ==================================================== + + local cmp = require 'cmp' + local luasnip = require 'luasnip' + + cmp.setup { + snippet = { + expand = function(args) + luasnip.lsp_expand(args.body) + end, + }, + -- performance = { + -- max_view_entries = 20, + -- }, + mapping = cmp.mapping.preset.insert { + [''] = cmp.mapping.select_next_item(), + [''] = cmp.mapping.select_prev_item(), + [''] = cmp.mapping.scroll_docs(-4), + [''] = cmp.mapping.scroll_docs(4), + [''] = cmp.mapping.complete(), + [''] = cmp.mapping.abort(), + [''] = cmp.mapping.confirm { + behavior = cmp.ConfirmBehavior.Replace, + select = true, + }, + [''] = cmp.mapping(function(fallback) + if cmp.visible() then + cmp.select_next_item() + elseif luasnip.expand_or_jumpable() then + luasnip.expand_or_jump() + else + fallback() + end + end, { 'i', 's' }), + [''] = cmp.mapping(function(fallback) + if cmp.visible() then + cmp.select_prev_item() + elseif luasnip.jumpable(-1) then + luasnip.jump(-1) + else + fallback() + end + end, { 'i', 's' }), + }, + sources = { + { name = 'nvim_lsp', max_item_count = 10 }, + { name = 'luasnip' }, + { name = 'path', max_item_count = 5 }, + { name = 'buffer', max_item_count = 5 }, + }, + window = { + completion = cmp.config.window.bordered(), + documentation = cmp.config.window.bordered(), + }, + } + + -- Suggested approach to cancel snippet session after going back to normal mode + -- Taken from https://github.com/L3MON4D3/LuaSnip/issues/258#issuecomment-1011938524 + function leave_snippet() + if + ((vim.v.event.old_mode == 's' and vim.v.event.new_mode == 'n') or vim.v.event.old_mode == 'i') + and require('luasnip').session.current_nodes[vim.api.nvim_get_current_buf()] + and not require('luasnip').session.jump_active + then + require('luasnip').unlink_current() + end + end + + -- stop snippets when you leave to normal mode + vim.api.nvim_command [[ autocmd ModeChanged * lua leave_snippet() ]] + + -- Custom command to disable completion + local cmp_enabled = true + vim.api.nvim_create_user_command('ToggleAutoComplete', function() + if cmp_enabled then + require('cmp').setup.buffer { enabled = false } + cmp_enabled = false + else + require('cmp').setup.buffer { enabled = true } + cmp_enabled = true + end + end, {}) + + -- Configure cmp-cmdline + cmp.setup.cmdline('/', { + mapping = cmp.mapping.preset.cmdline(), + sources = { + { name = 'buffer' }, + }, + }) + -- `:` cmdline setup. + cmp.setup.cmdline(':', { + mapping = cmp.mapping.preset.cmdline(), + sources = cmp.config.sources({ + { name = 'path' }, + }, { + { + name = 'cmdline', + option = { + ignore_cmds = { 'Man', '!' }, + }, + }, + }), + }) + + -- PERF: + -- ==================================================== + -- LSP related UI Configurations + -- ==================================================== + + -- Add bordered to LSP info + require('lspconfig.ui.windows').default_options.border = 'rounded' + + -- INFO: Configure LSP textDocuments + vim.lsp.handlers['textDocument/hover'] = vim.lsp.with(vim.lsp.handlers.hover, { border = 'rounded' }) + + vim.lsp.handlers['textDocument/signatureHelp'] = vim.lsp.with(vim.lsp.handlers.signature_help, { border = 'rounded' }) + + -- Diagnostic signs + local diagnostic_signs = { + { name = 'DiagnosticSignError', text = ' ' }, + { name = 'DiagnosticSignWarn', text = ' ' }, + { name = 'DiagnosticSignHint', text = ' ' }, + { name = 'DiagnosticSignInfo', text = ' ' }, + } + for _, sign in ipairs(diagnostic_signs) do + vim.fn.sign_define(sign.name, { texthl = sign.name, text = sign.text, numhl = sign.name }) + end + + vim.diagnostic.config { + virtual_text = { + prefix = '●', -- Could be '■', '▎', 'x' + }, + severity_sort = true, + float = { + source = 'always', -- Or "if_many" + }, + signs = true, + } + end, + }, + { -- Formatter + 'stevearc/conform.nvim', + config = function() + require('conform').setup { + formatters_by_ft = { + json = { { 'prettierd', 'prettier' } }, + lua = { 'stylua' }, + markdown = { 'prettier' }, + -- Conform will run multiple formatters sequentially + python = function(bufnr) + if require('conform').get_formatter_info('ruff_format', bufnr).available then + return { 'ruff_format' } + else + return { 'isort', 'black' } + end + end, + yaml = { 'prettier' }, + ['*'] = { 'injected' }, + }, + ignore_errors = true, + -- Map of treesitter language to file extension + -- A temporary file name with this extension will be generated during formatting + -- because some formatters care about the filename. + lang_to_ext = { + bash = 'sh', + latex = 'tex', + markdown = 'md', + python = 'py', + }, + } + -- + -- set up Format and f commands which should behave equivalently + vim.api.nvim_create_user_command('Format', function(args) + local range = nil + if args.count ~= -1 then + local end_line = vim.api.nvim_buf_get_lines(0, args.line2 - 1, args.line2, true)[1] + range = { + start = { args.line1, 0 }, + ['end'] = { args.line2, end_line:len() }, + } + end + require('conform').format { async = true, lsp_fallback = true, range = range } + end, { range = true }) + vim.keymap.set('', 'f', function() + require('conform').format { async = true, lsp_fallback = true } + end) + end, + }, + { + -- Autocompletion + 'hrsh7th/nvim-cmp', + dependencies = { + -- Snippet Engine & its associated nvim-cmp source + 'L3MON4D3/LuaSnip', + 'saadparwaiz1/cmp_luasnip', + 'hrsh7th/cmp-nvim-lsp', -- Adds LSP completion capabilities + 'hrsh7th/cmp-buffer', -- Source for buffer words + 'hrsh7th/cmp-path', -- Add source filesystem path + 'hrsh7th/cmp-cmdline', -- Source for vim's cmdline + }, + }, + { + 'rafamadriz/friendly-snippets', -- Snippets collection + config = function() + require('luasnip.loaders.from_vscode').lazy_load() + + require('luasnip/loaders/from_vscode').lazy_load { + paths = { + vim.fn.stdpath 'config' .. '/snippets', + }, + } + end, + }, + { + -- Highlight, edit, and navigate code + 'nvim-treesitter/nvim-treesitter', + dependencies = { + 'nvim-treesitter/nvim-treesitter-textobjects', + }, + build = ':TSUpdate', + config = function() + -- [[ Configure Treesitter ]] + -- See `:help nvim-treesitter` + vim.defer_fn(function() + require('nvim-treesitter.configs').setup { + -- Add languages to be installed here that you want installed for treesitter + ensure_installed = { + 'bash', + 'c', + 'cpp', + 'csv', + 'dockerfile', + 'gitcommit', + 'gitignore', + 'go', + 'html', + 'json', + 'lua', + 'markdown', + 'markdown_inline', + 'python', + 'vim', + 'vimdoc', + 'xml', + 'yaml', + }, + + -- Autoinstall languages that are not installed. Defaults to false (but you can change for yourself!) + auto_install = false, + highlight = { + enable = true, + disable = function(lang, bufnr) -- Disable in large files + return vim.api.nvim_buf_line_count(bufnr) > 50000 + end, + additional_vim_regex_highlighting = false, + }, + indent = { enable = true, disable = { 'python', 'cpp' } }, + incremental_selection = { + enable = true, + keymaps = { + init_selection = '', + node_incremental = '', + scope_incremental = '', + node_decremental = '', + }, + }, + textobjects = { + select = { + enable = true, + lookahead = true, -- Automatically jump forward to textobj, similar to targets.vim + keymaps = { + -- You can use the capture groups defined in textobjects.scm + ['aa'] = '@parameter.outer', + ['ia'] = '@parameter.inner', + ['af'] = '@function.outer', + ['if'] = '@function.inner', + ['ac'] = '@class.outer', + ['ic'] = '@class.inner', + }, + }, + move = { + enable = true, + set_jumps = true, -- whether to set jumps in the jumplist + goto_next_start = { + [']m'] = '@function.outer', + [']]'] = '@class.outer', + }, + goto_next_end = { + [']M'] = '@function.outer', + [']['] = '@class.outer', + }, + goto_previous_start = { + ['[m'] = '@function.outer', + ['[['] = '@class.outer', + }, + goto_previous_end = { + ['[M'] = '@function.outer', + ['[]'] = '@class.outer', + }, + }, + swap = { + enable = true, + swap_next = { + ['a'] = '@parameter.inner', + }, + swap_previous = { + ['A'] = '@parameter.inner', + }, + }, + }, + } + end, 0) + + -- Configure highlight group for treesittercontext + vim.cmd [[ hi TreesitterContextBottom gui=underline guisp=#a6e3a1 ]] + end, + }, + -- INFO: Debug adapters + { + 'mfussenegger/nvim-dap', -- Enable debug adapters + dependencies = { + 'mfussenegger/nvim-dap-python', -- Python debug adapter + 'rcarriga/nvim-dap-ui', -- UI-like for debugging + 'theHamsta/nvim-dap-virtual-text', -- Inline text during debugging + 'nvim-neotest/nvim-nio', -- Needed by nvim-dap-ui + 'folke/neodev.nvim', -- Recommended by nvim-dap-ui + }, + config = function() + require('neodev').setup { + library = { plugins = { 'nvim-dap-ui' }, types = true }, + } + -- PERF: + -- =================================================== + -- UI related configurations + -- ==================================================== + local dap = require 'dap' + local sign = vim.fn.sign_define + + sign('DapBreakpoint', { text = ' ', texthl = 'DapBreakpoint', linehl = '', numhl = '' }) + sign('DapBreakpointCondition', { text = ' ', texthl = 'DapBreakpointCondition', linehl = '', numhl = '' }) + sign('DapLogPoint', { text = '◆ ', texthl = 'DapLogPoint', linehl = '', numhl = '' }) + sign('DapStoppedLine', { text = '󰁕 ', texthl = 'DapLogPoint', linehl = '', numhl = '' }) + sign('DapBreakpointRejected', { text = ' ', texthl = 'DapBreakpointRejected', linehl = '', numhl = '' }) + + -- PERF: + -- =================================================== + -- Adapters + -- ==================================================== + dap.adapters.codelldb = { + type = 'server', + port = '${port}', + executable = { + command = vim.fn.expand '$HOME/.local/share/nvim/mason/bin/codelldb', + args = { '--port', '${port}' }, + }, + } + -- PERF: + -- =================================================== + -- Configurations + -- ==================================================== + dap.configurations.cpp = { + { + name = 'C++: Run file', + type = 'codelldb', + request = 'launch', + program = function() + return vim.fn.input('Path to executable: ', vim.fn.getcwd() .. '/', 'file') + end, + cwd = '${workspaceFolder}', + stopOnEntry = false, + }, + { + -- If you get an "Operation not permitted" error using this, try disabling YAMA: + -- echo 0 | sudo tee /proc/sys/kernel/yama/ptrace_scope + name = 'C++: Attach to process', + type = 'codelldb', -- Adjust this to match your adapter name (`dap.adapters.`) + request = 'attach', + pid = require('dap.utils').pick_process, + args = {}, + }, + { + name = 'C++: ROS Node', + type = 'codelldb', + request = 'launch', + -- Might need to consider using vim.ui.input + program = function() + local pkgName = vim.fn.input('ROS Package: ', '') + return vim.fn.input('Path to executable: ', vim.fn.getcwd() .. '/install/' .. pkgName .. '/lib/' .. pkgName .. '/', 'file') + end, + cwd = '${workspaceFolder}', + stopOnEntry = false, + }, + } + -- PERF: + -- ==================================================== + -- Extensions configurations + -- ==================================================== + require('dapui').setup { + controls = { + icons = { + pause = '⏸ ', + play = '▶ ', + terminate = '⏹ ', + }, + }, + floating = { + border = 'rounded', + }, + layouts = { + { + elements = { + { id = 'stacks', size = 0.30 }, + { id = 'breakpoints', size = 0.20 }, + { id = 'scopes', size = 0.50 }, + }, + position = 'left', + size = 40, + }, + { + elements = { + { id = 'console', size = 0.50 }, + { id = 'repl', size = 0.50 }, + }, + position = 'bottom', + size = 10, + }, + }, + } + require('nvim-dap-virtual-text').setup() + require('dap-python').setup() + table.insert(require('dap').configurations.python, { + type = 'python', + request = 'launch', + name = 'Python: ROS2 lauch test', + program = '/opt/ros/humble/bin/launch_test', + args = { '${file}' }, + }) + + require('dap-python').test_runner = 'pytest' + + -- PERF: + -- ==================================================== + -- Custom User Commands for Dap + -- ==================================================== + vim.api.nvim_create_user_command('DapUIToggle', ":lua require('dapui').toggle()", {}) + vim.api.nvim_create_user_command('DapPytestMethod', ":lua require('dap-python').test_method()", {}) + + vim.api.nvim_create_user_command('DapResetUI', ":lua require('dapui').open({reset = true})", { desc = 'Reset DAP UI Layout' }) + + vim.api.nvim_create_user_command( + 'DapLogBreakpoint', + ":lua require('dap').set_breakpoint(nil, nil, vim.fn.input('Log Message: '))", + { desc = 'Set log message breakpoint' } + ) + vim.api.nvim_create_user_command( + 'DapConditionBreakpoint', + ":lua require('dap').set_breakpoint(vim.fn.input('Breakpoint Condition: '))", + { desc = 'Set conditional breakpoint' } + ) + vim.api.nvim_create_user_command( + 'DapConditionHitBreakpoint', + ":lua require('dap').set_breakpoint(vim.fn.input('Breapoint Condition: '), vim.fn.input('Hit Condition: '))", + { desc = 'Set condition and hit breakpoint' } + ) + vim.api.nvim_create_user_command( + 'DapHitBreakpoint', + ":lua require('dap').set_breakpoint(nil, vim.fn.input('Hit Condition: '))", + { desc = 'Set hit breakpoint' } + ) + + -- PERF: + -- ==================================================== + -- Configure DAP UI Listeners + -- ==================================================== + local dapui = require 'dapui' + dap.listeners.before.attach.dapui_config = function() + dapui.open() + end + dap.listeners.before.launch.dapui_config = function() + dapui.open() + end + dap.listeners.before.event_terminated.dapui_config = function() + dapui.close() + end + dap.listeners.before.exited.dapui_config = function() + dapui.close() + end + end, + }, + + -- NOTE: Here you can add additional plugins that can enhance your Neovim Journey + { -- ROS2 related plugin + 'ErickKramer/nvim-ros2', + dependencies = { + 'nvim-lua/plenary.nvim', + 'nvim-telescope/telescope.nvim', + 'nvim-treesitter/nvim-treesitter', + }, + opts = { + autocmds = true, + telescope = true, + treesitter = true, + }, + }, +}, {}) + +--[[INFO: Editor Settingss + -- Take the time to check the settings underneath and configure them base on your needs and preferences + --]] +-- Set highlight on search +vim.o.hlsearch = false + +-- Make line numbers default +vim.opt.nu = true +vim.opt.relativenumber = true + +-- Enable mouse mode +vim.o.mouse = 'a' + +-- Enable break indent +vim.o.breakindent = true + +-- Save undo history +vim.o.undofile = true + +-- Case insensitive searching UNLESS /C or capital in search +vim.o.ignorecase = true +vim.o.smartcase = true + +-- Decrease update time +vim.o.updatetime = 250 +vim.o.timeoutlen = 300 + +-- Configure how new splits should be opened +vim.opt.splitright = true +vim.opt.splitbelow = true + +-- Preview substitutions live, as you type! +vim.opt.inccommand = 'split' + +-- Keep signcolumn on +vim.wo.signcolumn = 'yes' +vim.opt.signcolumn = 'yes:1' -- Enable expanding signcolumn + +-- Highlight current line +vim.opt.cursorline = true + +-- Render the column delimiter +vim.opt.colorcolumn = '100' + +-- Prefer spaces of 2 over tabs +vim.opt.tabstop = 2 +vim.opt.shiftwidth = 2 +vim.opt.expandtab = true + +-- Render trailing spaces +vim.opt.listchars = { trail = '⇲', tab = '◦ ' } +vim.opt.list = true + +-- Share system clipboard +vim.opt.clipboard = 'unnamedplus' + +-- Set completeopt to have a better completion experience +vim.o.completeopt = 'menuone,noselect' + +-- Remap for dealing with word wrap +vim.keymap.set('n', 'k', "v:count == 0 ? 'gk' : 'k'", { expr = true, silent = true }) +vim.keymap.set('n', 'j', "v:count == 0 ? 'gj' : 'j'", { expr = true, silent = true }) + +-- set termguicolors to enable highlight groups +vim.opt.termguicolors = true + +-- Highlight on yank +local highlight_group = vim.api.nvim_create_augroup('YankHighlight', { clear = true }) +vim.api.nvim_create_autocmd('TextYankPost', { + callback = function() + vim.highlight.on_yank() + end, + group = highlight_group, + pattern = '*', +}) + +-- Relative line numbers +local numtogGrp = vim.api.nvim_create_augroup('NumberToggle', { clear = true }) +vim.api.nvim_create_autocmd({ 'BufEnter', 'InsertLeave', 'FocusGained' }, { + pattern = '*', + callback = function() + vim.opt.relativenumber = true + end, + group = numtogGrp, + desc = 'Turn on relative line numbering when the buffer is entered.', +}) +vim.api.nvim_create_autocmd({ 'BufLeave', 'InsertEnter', 'FocusLost' }, { + pattern = '*', + callback = function() + vim.opt.relativenumber = false + end, + group = numtogGrp, + desc = 'Turn off relative line numbering when the buffer is exited.', +}) + +--[[ INFO: Keymaps configurations +-- Make sure to change these keymaps so that they make the most sense to you +--]] + +-- Improve motions +vim.keymap.set('n', '', 'zz') +vim.keymap.set('n', '', 'zz') +vim.keymap.set('n', 'n', 'nzzzv') +vim.keymap.set('n', 'N', 'Nzzzv') +vim.keymap.set('v', 'J', ":m '>+1gv=gv", { desc = 'Move selected lines down' }) +vim.keymap.set('v', 'K', ":m '<-2gv=gv", { desc = 'Move selected lines down' }) + +-- Improve splits navigation +vim.keymap.set('n', '', 'h') +vim.keymap.set('n', '', 'j') +vim.keymap.set('n', '', 'k') +vim.keymap.set('n', '', 'l') + +-- Improve pasting +vim.keymap.set('x', 'p', [["_dP]], { desc = 'Preserve previous word when pasting' }) + +vim.keymap.set('n', 'ya', ':%y+', { desc = 'Yank all content in file' }) + +-- Diagnostic keymaps +vim.keymap.set('n', '[d', vim.diagnostic.goto_prev) +vim.keymap.set('n', ']d', vim.diagnostic.goto_next) +vim.keymap.set('n', 'e', vim.diagnostic.open_float, { desc = 'Open diagnostic in floating window' }) +vim.keymap.set('n', 'q', vim.diagnostic.setloclist, { desc = 'Send diagnostic to loclist' }) +vim.keymap.set('n', 'dd', vim.diagnostic.disable, { desc = '[D]iagnostics [D]disable' }) +vim.keymap.set('n', 'de', vim.diagnostic.enable, { desc = '[D]iagnostics [E]nable' }) + +-- Change workingdir +vim.keymap.set('n', 'cw', ':cd %:p:h:pwd', { desc = 'Change current workding dir' }) +-- Fix forward jump after setting +-- https://github.com/neovim/neovim/issues/20126 +vim.keymap.set('n', '', '', { noremap = true }) + +-- Editor experience +vim.keymap.set('n', '', ':write', { desc = 'Save file' }) +vim.keymap.set('n', 'cd', ':ToggleAutoComplete', { desc = '[C]ompletion [D]isable' }) +vim.keymap.set('n', 'ce', ':ToggleAutoComplete', { desc = '[C]ompletion [E]nable' }) + +-- ==================================================== +-- Telescope +-- ==================================================== +vim.keymap.set('n', '?', require('telescope.builtin').oldfiles, { desc = '[?] Find recently opened files' }) +vim.keymap.set('n', '', require('telescope.builtin').buffers, { desc = '[ ] Find existing buffers' }) +vim.keymap.set('n', '/', function() + -- You can pass additional configuration to telescope to change theme, layout, etc. + require('telescope.builtin').current_buffer_fuzzy_find(require('telescope.themes').get_dropdown { + previewer = false, + sorting_strategy = 'ascending', + }) +end, { desc = '[/] Fuzzily search in current buffer]' }) + +vim.keymap.set('n', 'sf', require('telescope.builtin').find_files, { desc = '[S]earch [F]iles' }) +vim.keymap.set('n', 'sh', require('telescope.builtin').help_tags, { desc = '[S]earch [H]elp' }) +vim.keymap.set('n', 'sw', require('telescope.builtin').grep_string, { desc = '[S]earch current [W]ord' }) +vim.keymap.set('n', 'sg', require('telescope.builtin').live_grep, { desc = '[S]earch by [G]rep' }) +vim.keymap.set('n', 'sd', require('telescope.builtin').diagnostics, { desc = '[S]earch [D]iagnostics' }) +vim.keymap.set('n', 'sp', require('telescope.builtin').spell_suggest, { desc = '[S][P]ell suggestion' }) +vim.keymap.set('n', 'sk', require('telescope.builtin').keymaps, { desc = '[S]earch [K]eymaps' }) +vim.keymap.set('n', 'gf', require('telescope.builtin').git_files, { desc = 'Search [G]it [F]iles' }) +vim.keymap.set('n', 'sc', require('telescope.builtin').git_commits, { desc = '[S]earch git [C]ommits' }) +vim.keymap.set('n', 'sr', require('telescope.builtin').resume, { desc = 'Telescope [S]earch [R]esume' }) +-- Also possible to pass additional configuration options. +-- See `:help telescope.builtin.live_grep()` for information about particular keys +vim.keymap.set('n', 's/', function() + require('telescope.builtin').live_grep { + grep_open_files = true, + prompt_title = 'Live Grep in Open Files', + } +end, { desc = '[S]earch [/] in Open Files' }) +-- Shortcut for searching your neovim configuration files +vim.keymap.set('n', 'sn', function() + require('telescope.builtin').find_files { cwd = vim.fn.stdpath 'config' } +end, { desc = '[S]earch [N]eovim files' }) + +-- ==================================================== +-- Nvim Tree +-- ==================================================== +vim.keymap.set('n', 'ff', ':NvimTreeFindFile', { desc = 'NvimTree [F]ind [F]ile' }) +vim.keymap.set('n', 'tt', ':NvimTreeToggle', { desc = 'NvimTree [T]ree [T]oggle' }) + +-- ==================================================== +-- Execute over files +-- ==================================================== +vim.keymap.set('n', 'ru', ':w:!%:p', { desc = '[R][U]n current file' }) +vim.keymap.set('n', 'me', ':!chmod +x %:p', { desc = '[M]ake current file [E]xecutable' }) + +-- ==================================================== +-- Spectre +-- ==================================================== +vim.keymap.set('n', 'P', require('spectre').open, { desc = 'Open Search and Replace' }) + +-- ==================================================== +-- Trouble +-- ==================================================== +vim.keymap.set('n', 'xx', 'TroubleToggle', { silent = true, noremap = true, desc = 'Toggle trouble window' }) +vim.keymap.set( + 'n', + 'xw', + 'TroubleToggle workspace_diagnostics', + { silent = true, noremap = true, desc = 'Trouble diagnostics for the whole workspace' } +) +vim.keymap.set( + 'n', + 'xd', + 'TroubleToggle document_diagnostics', + { silent = true, noremap = true, desc = 'Trouble diagnostics for current document' } +) + +-- ==================================================== +-- Uncrustify +-- ==================================================== +vim.api.nvim_create_user_command( + 'Uncrustify', + -- ":!uncrustify -c /home/ekramer/evobot_ecosystem/humble_ws/ament_code_style.cfg --replace %:p -q --no-backup", {} + ':!ament_uncrustify --reformat %:p', + {} +) + +-- ==================================================== +-- Debugging -> dap +-- ==================================================== +vim.keymap.set('n', '', ":lua require('dapui').toggle()") +vim.keymap.set('n', 'dc', ":lua require('dap').continue()") +vim.keymap.set('n', 'do', ":lua require('dap').step_over()") +vim.keymap.set('n', 'di', ":lua require('dap').step_into()") +vim.keymap.set('n', 'dk', function() + require('dap.ui.widgets').hover() +end) +vim.keymap.set('n', 'd?', function() + local widgets = require 'dap.ui.widgets' + widgets.centered_float(widgets.scopes) +end) +vim.keymap.set('n', 'du', ":lua require('dap').step_out()") +vim.keymap.set('n', 'dl', ":lua require('dapui').float_element()", { silent = true, noremap = true, desc = 'Open floating window in Dap UI' }) +vim.keymap.set('n', 'dt', ":lua require('dap').toggle_breakpoint()", { silent = true, noremap = true, desc = 'Toggle breakpoint' }) +vim.keymap.set('n', 'dm', ":lua require('dap-python').test_method()", { silent = true, noremap = true, desc = 'DapPytest : Debug method' }) +vim.keymap.set('n', 'df', ":lua require('dap-python').test_class()", { silent = true, noremap = true, desc = 'DapPytest : Debug class' }) + +-- ==================================================== +-- barbar --> Tabs management +-- ==================================================== +vim.keymap.set('n', '', 'BufferPrevious', { silent = true, noremap = true, desc = 'Go to previous tab' }) +vim.keymap.set('n', '', 'BufferNext', { silent = true, noremap = true, desc = 'Go to next tab' }) +vim.keymap.set('n', '', 'BufferClose', { silent = true, noremap = true, desc = 'Close current buffer' }) +local opts = { noremap = true, silent = true } +-- Goto buffer in position... +vim.keymap.set('n', '', 'BufferGoto 1', opts) +vim.keymap.set('n', '', 'BufferGoto 2', opts) +vim.keymap.set('n', '', 'BufferGoto 3', opts) +vim.keymap.set('n', '', 'BufferGoto 4', opts) +vim.keymap.set('n', '', 'BufferGoto 5', opts) +vim.keymap.set('n', '', 'BufferGoto 6', opts) +vim.keymap.set('n', '', 'BufferGoto 7', opts) +vim.keymap.set('n', '', 'BufferGoto 8', opts) +vim.keymap.set('n', '', 'BufferGoto 9', opts) +vim.keymap.set('n', '', 'BufferLast', opts) + +-- ==================================================== +-- Quickfix +-- ==================================================== +vim.keymap.set('n', 'cn', ':cnext', { desc = 'Next quickfix list' }) +vim.keymap.set('n', 'cp', ':cprevious', { desc = 'Previous quickfix list' }) + +-- ==================================================== +-- Markdown +-- ==================================================== +vim.keymap.set('n', 'mp', ':MarkdownPreview', { desc = '[M]arkdown [P]review' }) + +-- ==================================================== +-- nvim-ros2 +-- ==================================================== +vim.keymap.set('n', 'li', ':Telescope ros2 interfaces', { desc = '[ROS 2]: List interfaces' }) +vim.keymap.set('n', 'ln', ':Telescope ros2 nodes', { desc = '[ROS 2]: List nodes' }) +vim.keymap.set('n', 'la', ':Telescope ros2 actions', { desc = '[ROS 2]: List actions' }) +vim.keymap.set('n', 'lt', ':Telescope ros2 topics', { desc = '[ROS 2]: List topics' }) +vim.keymap.set('n', 'ls', ':Telescope ros2 services', { desc = '[ROS 2]: List services' }) + +-- ==================================================== +-- git_coauthors +-- ==================================================== +vim.keymap.set('n', 'ga', ':Telescope coauthors', { desc = '[G]it co-[A]uthors' }) + +-- NOTE: Custon User Commads + +-- ==================================================== +-- ROS 2 related commands +-- ==================================================== +vim.api.nvim_command [[ + command! ColconBuild :! CC=clang CXX=clang++ colcon build --symlink-install --cmake-args -DCMAKE_EXPORT_COMPILE_COMMANDS=ON +]] +vim.api.nvim_command [[ + command! -nargs=1 ColconBuildSingle :! CC=clang CXX=clang++ colcon build --symlink-install --cmake-args -DCMAKE_EXPORT_COMPILE_COMMANDS=ON --packages-up-to +]] +vim.api.nvim_command [[ + command! ColconBuildDebug :! CC=clang CXX=clang++ colcon build --symlink-install --cmake-args -DCMAKE_EXPORT_COMPILE_COMMANDS=ON -DCMAKE_BUILD_TYPE=Debug +]] +vim.api.nvim_command [[ + command! -nargs=1 ColconBuildDebugSingle :! CC=clang CXX=clang++ colcon build --symlink-install --cmake-args -DCMAKE_EXPORT_COMPILE_COMMANDS=ON -DCMAKE_BUILD_TYPE=Debug --packages-up-to +]] + +-- Test +vim.api.nvim_command [[ + command! ColconTest :! colcon test +]] +vim.api.nvim_command [[ + command! -nargs=1 ColconTestSingle :! colcon test --packages-select +]] +vim.api.nvim_command [[ + command! ColconTestResult :! colcon test-result --all +]] -- The line beneath this is called `modeline`. See `:help modeline` -- vim: ts=2 sts=2 sw=2 et @@ -948,3 +1659,9 @@ vim.api.nvim_create_autocmd('FileType', { vim.opt_local.expandtab = true end, }) + +-- Remap copy line +vim.api.nvim_set_keymap('n', 'Y', 'yy', { noremap = true, silent = true }) +-- Open Neo-tree automatically on startup +vim.cmd('Neotree show') +vim.api.nvim_set_keymap('i', '{', '{}', { noremap = true, silent = true })