diff --git a/lua/custom/plugins/beacon.lua b/lua/custom/plugins/beacon.lua new file mode 100644 index 00000000000..24b992b694d --- /dev/null +++ b/lua/custom/plugins/beacon.lua @@ -0,0 +1,9 @@ +return { + "danilamihailov/beacon.nvim", + version = "*", + config = function() + --require("beacon").setup({ + -- minimal_jump = 5, + --}) + end, +} diff --git a/lua/custom/plugins/cattpuccin.lua b/lua/custom/plugins/cattpuccin.lua new file mode 100644 index 00000000000..bba8440a1c9 --- /dev/null +++ b/lua/custom/plugins/cattpuccin.lua @@ -0,0 +1,12 @@ +return { + "catppuccin/nvim", + name = "catppuccin", + priority = 1001, + config = function() + require("catppuccin").setup({ + flavour = "mocha" + }) + vim.cmd.colorscheme "catppuccin" + end, +} + diff --git a/lua/custom/plugins/custom-init.lua b/lua/custom/plugins/custom-init.lua new file mode 100644 index 00000000000..4fb2e1725c0 --- /dev/null +++ b/lua/custom/plugins/custom-init.lua @@ -0,0 +1,52 @@ +-- You can add your own plugins here or in other files in this directory! +-- I promise not to create any merge conflicts in this directory :) +-- +-- See the kickstart.nvim README for more information + +package.path = package.path .. ";?.lua" + +-- Set the blinking cursor settings +vim.o.guicursor = 'n-v:block,i:ver25,r-cr-o:hor20,a:blinkwait700-blinkoff400-blinkon250' + +-- Adjust the split that it makes sense +vim.opt.splitbelow = true +vim.opt.splitright = true + +-- Make sure, that when we exit nvim the previous cursor settings get restored +vim.cmd([[ + augroup RestoreCursorShapeOnExit + autocmd! + autocmd VimLeave * set guicursor=a:block20 + augroup END +]]) + +-- Adding relative line numbers +vim.opt.relativenumber = true + +-- Fix the cursor in the middle of windows when scrolling +vim.opt.scrolloff = 6 + +-- Remap for dealing with word wrap in v mode (see init.lua:284) +vim.keymap.set('v', 'k', "v:count == 0 ? 'gk' : 'k'", { expr = true, silent = true}) +vim.keymap.set('v', 'j', "v:count == 0 ? 'gj' : 'j'", { expr = true, silent = true}) + +-- Provide function and keymap binding to show not saved changes of current buffer +function showBufferDiff() +vim.cmd([[w !diff % - ]]) +end +-- ":vim.cmd([[w !diff % - ]])" +vim.keymap.set('n', 'pd', showBufferDiff, { expr = true, silent = true, desc = "Print diff between buffer and file"}) + + +-- Mimic the tmux config here. S for vertical split, v for horizontal: +-- - Remap for easier window control access +-- - Remap general the window control access to . +-- - Remap (swapping) particular "s" to "v" when entering window control access. +-- (Bear in mind that you have to release keys, and then press "s" or "v". +-- Otherwise the swapping of "s" and "v" does not work. +local map = vim.api.nvim_set_keymap +map('n', '', '', {noremap = false}) +map('n', 's', 'v', {noremap = true}) +map('n', 'v', 's', {noremap = true}) +return { +} diff --git a/lua/custom/plugins/fterm.lua b/lua/custom/plugins/fterm.lua new file mode 100644 index 00000000000..b5fd4382335 --- /dev/null +++ b/lua/custom/plugins/fterm.lua @@ -0,0 +1,25 @@ +return { + 'numToStr/FTerm.nvim', + config = function() + require('FTerm').setup({ + -- just keep the standard settings for now + }) + + -- Toggle FTerm + vim.keymap.set('n', '', 'lua require("FTerm").toggle()', { desc = "Toggle FTerm"}) + vim.keymap.set('t', '', 'lua require("FTerm").toggle()', { desc = "Toggle FTerm"}) + + -- Run commands + vim.keymap.set('n', 'l', 'lua require("FTerm").run("lazygit")', { desc = "Run FTerm lazygit"}) + + -- Scratch commands + vim.keymap.set('n', 'bd', 'lua require("FTerm").scratch({ cmd = "sh scripts/build.sh" })', { desc = "Scratch build.sh with default options"}) + vim.keymap.set('n', 'bc', 'lua require("FTerm").scratch({ cmd = "sh scripts/build.sh -cb" })', { desc = "Scratch build.sh with clean build option"}) + vim.keymap.set('n', 'bf', 'lua require("FTerm").scratch({ cmd = "sh scripts/build.sh -fb" })', { desc = "Scratch build.sh with fresh option"}) + vim.keymap.set('n', 'bn', 'lua require("FTerm").scratch({ cmd = "sh scripts/build.sh -nb" })', { desc = "Scratch build.sh with no build option"}) + + vim.keymap.set('n', 'cf', 'lua require("FTerm").scratch({ cmd = "sh scripts/checkformat.sh" })', { desc = "Scratch checkformat readonly"}) + vim.keymap.set('n', 'ca', 'lua require("FTerm").scratch({ cmd = "sh scripts/checkanalyzer.sh" })', { desc = "Scratch checkanalyzer"}) + end, +} + diff --git a/lua/custom/plugins/harpoon.lua b/lua/custom/plugins/harpoon.lua new file mode 100644 index 00000000000..5d06373eeee --- /dev/null +++ b/lua/custom/plugins/harpoon.lua @@ -0,0 +1,81 @@ +return { + -- {{{ Define the Harpoon lazy.vim specificaiton. + + "ThePrimeagen/harpoon", + enabled = true, + branch = "harpoon2", + dependencies = { + "nvim-lua/plenary.nvim", + "nvim-telescope/telescope.nvim", + }, + + -- ----------------------------------------------------------------------- }}} + -- {{{ Define events to load Harpoon. + + keys = function() + local harpoon = require("harpoon") + local conf = require("telescope.config").values + + local function toggle_telescope(harpoon_files) + local file_paths = {} + for _, item in ipairs(harpoon_files.items) do + table.insert(file_paths, item.value) + end + require("telescope.pickers").new({}, { + prompt_title = "Harpoon", + finder = require("telescope.finders").new_table({ + results = file_paths, + }), + previewer = conf.file_previewer({}), + sorter = conf.generic_sorter({}), + }):find() + end + + + return { + -- Harpoon marked files 1 through 4 + {"", function() harpoon:list():select(1) end, desc ="Harpoon buffer 1"}, + {"", function() harpoon:list():select(2) end, desc ="Harpoon buffer 2"}, + {"", function() harpoon:list():select(3) end, desc ="Harpoon buffer 3"}, + {"", function() harpoon:list():select(4) end, desc ="Harpoon buffer 4"}, + + -- Harpoon next and previous. + {"", function() harpoon:list():next() end, desc ="Harpoon next buffer"}, + {"", function() harpoon:list():prev() end, desc ="Harpoon prev buffer"}, + + -- Harpoon user interface. + {"ht", function() harpoon.ui:toggle_quick_menu(harpoon:list()) end, desc ="Harpoon Toggle Menu"}, + {"ha", function() harpoon:list():append() end, desc ="Harpoon add file"}, + + -- Use Telescope as Harpoon user interface. + {"hs", function() toggle_telescope(harpoon:list() )end, desc ="Show Harpoon window"}, + } + end, + + -- ----------------------------------------------------------------------- }}} + -- {{{ Use Harpoon defaults or my customizations. + + opts = function(_, opts) + opts.settings = { + save_on_toggle = false, + sync_on_ui_close = false, + save_on_change = true, + enter_on_sendcmd = false, + tmux_autoclose_windows = false, + excluded_filetypes = { "harpoon", "alpha", "dashboard", "gitcommit" }, + mark_branch = false, + key = function() + return vim.loop.cwd() + end + } + end, + + -- ----------------------------------------------------------------------- }}} + -- {{{ Configure Harpoon. + + config = function(_, opts) + require("harpoon").setup(opts) + end, + + -- ----------------------------------------------------------------------- }}} +} diff --git a/lua/custom/plugins/init.lua b/lua/custom/plugins/init.lua index c05db465ea5..0a0248ef4fd 100644 --- a/lua/custom/plugins/init.lua +++ b/lua/custom/plugins/init.lua @@ -3,6 +3,51 @@ -- -- See the kickstart.nvim README for more information +-- Disabled netrw plugin, because we will use nvim-tree +vim.g.loaded_netrw = 1 +vim.g.loaded_netrwPlugin = 1 + +-- Make sure, that when we exit nvim the previous cursor settings get restored +vim.cmd [[ + augroup RestoreCursorShapeOnExit + autocmd! + autocmd VimLeave * set guicursor=a:block20 + augroup END +]] + +-- Set the blinking cursor settings +vim.opt.guicursor = 'n-v:block,i:ver25,r-cr-o:hor20,a:blinkwait700-blinkoff400-blinkon250' + +-- Remap for dealing with word wrap in v mode +vim.keymap.set('v', 'k', "v:count == 0 ? 'gk' : 'k'", { expr = true, silent = true }) +vim.keymap.set('v', 'j', "v:count == 0 ? 'gj' : 'j'", { expr = true, silent = true }) + +-- Provide function and keymap binding to show not saved changes of current buffer +function showBufferDiff() + vim.cmd [[w !diff % - ]] +end +-- ":vim.cmd([[w !diff % - ]])" +vim.keymap.set('n', 'pd', showBufferDiff, { expr = true, silent = true, desc = 'Print diff between buffer and file' }) + +-- Mimic the tmux config here. S for vertical split, v for horizontal: +-- - Remap for easier window control access +-- - Remap general the window control access to . +-- - Remap (swapping) particular "s" to "v" when entering window control access. +-- (Bear in mind that you have to release keys, and then press "s" or "v". +-- Otherwise the swapping of "s" and "v" does not work. +local map = vim.api.nvim_set_keymap +map('n', '', '', { noremap = false }) +map('n', 's', 'v', { noremap = true }) +map('n', 'v', 's', { noremap = true }) + +-- Mapping for delete into black hole register in normal mode +-- and replace visual selection with yanked text (unnamed register) without losing it. +-- Example: yiw or yi" to yank some text => xiwP or xiw"P to replace. +-- => visual select and x to replace. +vim.keymap.set('n', 'x', '"_d', { desc = 'Delete to black hole register' }) +vim.keymap.set('v', 'x', '"_dP', { desc = 'Replace selection with yanked text' }) + + -- Iterate over all Lua files in the plugins directory and load them local plugins_dir = vim.fs.joinpath(vim.fn.stdpath 'config', 'lua', 'custom', 'plugins') for file_name, type in vim.fs.dir(plugins_dir) do @@ -11,3 +56,5 @@ for file_name, type in vim.fs.dir(plugins_dir) do require('custom.plugins.' .. module) end end + +return {} diff --git a/lua/custom/plugins/local-highlight.lua b/lua/custom/plugins/local-highlight.lua new file mode 100644 index 00000000000..062f43beb2f --- /dev/null +++ b/lua/custom/plugins/local-highlight.lua @@ -0,0 +1,18 @@ +return { + 'tzachar/local-highlight.nvim', + + dependencies = { + 'folke/snacks.nvim', + }, + + config = function() + require('local-highlight').setup { + file_types = { 'xyz' }, + highlight_single_match = false, + cw_hlgroup = 'Search', + insert_mode = true, + } + + vim.keymap.set('n', 'ph', vim.cmd.LocalHighlightToggle, { expr = false, silent = true, desc = 'Toggle local-highlight.nvim' }) + end, +} diff --git a/lua/custom/plugins/nvim-tree.lua b/lua/custom/plugins/nvim-tree.lua new file mode 100644 index 00000000000..13cefc27b2e --- /dev/null +++ b/lua/custom/plugins/nvim-tree.lua @@ -0,0 +1,50 @@ +return { + 'nvim-tree/nvim-tree.lua', + version = '*', + lazy = false, + dependencies = { + 'nvim-tree/nvim-web-devicons', + }, + config = function() + require('nvim-tree').setup { + filters = { + dotfiles = true, + }, + } + -- Helper function to setup a custom keybindings when nvim-tree buffer is active + local function my_on_attach(bufnr) + local api = require 'nvim-tree.api' + + local function opts(desc) + return { desc = 'nvim-tree: ' .. desc, buffer = bufnr, noremap = true, silent = true, nowait = true } + end + + -- default mappings + api.config.mappings.default_on_attach(bufnr) + + -- add/overwrite custom mappings + vim.keymap.set('n', '?', api.tree.toggle_help, opts 'Help') + end + + -- pass to setup along with your other options + require('nvim-tree').setup { + --- + on_attach = my_on_attach, + --- + } + + -- fix the width of nvim tree if once adjusted. + require('nvim-tree').setup { + actions = { + open_file = { + quit_on_open = false, -- important: don't quit tree immediately + resize_window = false, -- prevent auto-resizing + }, + }, + } + + -- Keybinding in "normal" vi mode + local anotherApi = require 'nvim-tree.api' + vim.keymap.set('n', 't', anotherApi.tree.toggle, { desc = 'Toogle nvim-tree' }) + end, +} diff --git a/lua/custom/plugins/search-replace.lua b/lua/custom/plugins/search-replace.lua new file mode 100644 index 00000000000..55ac84782fc --- /dev/null +++ b/lua/custom/plugins/search-replace.lua @@ -0,0 +1,30 @@ +return { + 'roobert/search-replace.nvim', + config = function() + require('search-replace').setup { + -- optionally override defaults + default_replace_single_buffer_options = 'gcI', + default_replace_multi_buffer_options = 'egcI', + } + vim.keymap.set('v', '', 'SearchReplaceSingleBufferVisualSelection', opts) + vim.keymap.set('v', '', 'SearchReplaceWithinVisualSelection', opts) + vim.keymap.set('v', '', 'SearchReplaceWithinVisualSelectionCWord', opts) + + vim.keymap.set('n', 'rs', 'SearchReplaceSingleBufferSelections', { desc = '[s]elction list' }) + vim.keymap.set('n', 'ro', 'SearchReplaceSingleBufferOpen', { desc = '[o]pen' }) + vim.keymap.set('n', 'rw', 'SearchReplaceSingleBufferCWord', { desc = '[w]ord' }) + vim.keymap.set('n', 'rW', 'SearchReplaceSingleBufferCWORD', { desc = '[W]ORD' }) + vim.keymap.set('n', 're', 'SearchReplaceSingleBufferCExpr', { desc = '[e]xpr' }) + vim.keymap.set('n', 'rf', 'SearchReplaceSingleBufferCFile', { desc = '[f]ile' }) + + vim.keymap.set('n', 'rbs', 'SearchReplaceMultiBufferSelections', { desc = '[s]elction list' }) + vim.keymap.set('n', 'rbo', 'SearchReplaceMultiBufferOpen', { desc = '[o]pen' }) + vim.keymap.set('n', 'rbw', 'SearchReplaceMultiBufferCWord', { desc = '[w]ord' }) + vim.keymap.set('n', 'rbW', 'SearchReplaceMultiBufferCWORD', { desc = '[W]ORD' }) + vim.keymap.set('n', 'rbe', 'SearchReplaceMultiBufferCExpr', { desc = '[e]xpr' }) + vim.keymap.set('n', 'rbf', 'SearchReplaceMultiBufferCFile', { desc = '[f]ile' }) + + -- show the effects of a search / replace in a live preview window + vim.o.inccommand = 'split' + end, +} diff --git a/lua/custom/plugins/smart-split.lua b/lua/custom/plugins/smart-split.lua new file mode 100644 index 00000000000..00abbb3a1d8 --- /dev/null +++ b/lua/custom/plugins/smart-split.lua @@ -0,0 +1,132 @@ +return { + 'mrjones2014/smart-splits.nvim', + dependencies = { + 'pogyomo/submode.nvim', + }, + -- config = function() end, + config = function() + require('smart-splits').setup { + -- Ignored filetypes (only while resizing) + ignored_filetypes = { + 'nofile', + 'quickfix', + 'prompt', + }, + -- Ignored buffer types (only while resizing) + ignored_buftypes = { 'NvimTree' }, + -- the default number of lines/columns to resize by at a time + default_amount = 3, + -- Desired behavior when your cursor is at an edge and you + -- are moving towards that same edge: + -- 'wrap' => Wrap to opposite side + -- 'split' => Create a new split in the desired direction + -- 'stop' => Do nothing + -- function => You handle the behavior yourself + -- NOTE: If using a function, the function will be called with + -- a context object with the following fields: + -- { + -- mux = { + -- type:'tmux'|'wezterm'|'kitty' + -- current_pane_id():number, + -- is_in_session(): boolean + -- current_pane_is_zoomed():boolean, + -- -- following methods return a boolean to indicate success or failure + -- current_pane_at_edge(direction:'left'|'right'|'up'|'down'):boolean + -- next_pane(direction:'left'|'right'|'up'|'down'):boolean + -- resize_pane(direction:'left'|'right'|'up'|'down'):boolean + -- split_pane(direction:'left'|'right'|'up'|'down',size:number|nil):boolean + -- }, + -- direction = 'left'|'right'|'up'|'down', + -- split(), -- utility function to split current Neovim pane in the current direction + -- wrap(), -- utility function to wrap to opposite Neovim pane + -- } + -- NOTE: `at_edge = 'wrap'` is not supported on Kitty terminal + -- multiplexer, as there is no way to determine layout via the CLI + at_edge = 'wrap', + -- when moving cursor between splits left or right, + -- place the cursor on the same row of the *screen* + -- regardless of line numbers. False by default. + -- Can be overridden via function parameter, see Usage. + move_cursor_same_row = false, + -- whether the cursor should follow the buffer when swapping + -- buffers by default; it can also be controlled by passing + -- `{ move_cursor = true }` or `{ move_cursor = false }` + -- when calling the Lua function. + cursor_follows_swapped_bufs = false, + -- resize mode options + resize_mode = { + -- key to exit persistent resize mode + quit_key = '', + -- keys to use for moving in resize mode + -- in order of left, down, up' right + resize_keys = { 'h', 'j', 'k', 'l' }, + -- set to true to silence the notifications + -- when entering/exiting persistent resize mode + silent = false, + -- must be functions, they will be executed when + -- entering or exiting the resize mode + hooks = { + on_enter = nil, + on_leave = nil, + }, + }, + -- ignore these autocmd events (via :h eventignore) while processing + -- smart-splits.nvim computations, which involve visiting different + -- buffers and windows. These events will be ignored during processing, + -- and un-ignored on completed. This only applies to resize events, + -- not cursor movement events. + ignored_events = { + 'BufEnter', + 'WinEnter', + }, + -- enable or disable a multiplexer integration; + -- automatically determined, unless explicitly disabled or set, + -- by checking the $TERM_PROGRAM environment variable, + -- and the $KITTY_LISTEN_ON environment variable for Kitty + multiplexer_integration = nil, + -- disable multiplexer navigation if current multiplexer pane is zoomed + -- this functionality is only supported on tmux and Wezterm due to kitty + -- not having a way to check if a pane is zoomed + disable_multiplexer_nav_when_zoomed = true, + -- Supply a Kitty remote control password if needed, + -- or you can also set vim.g.smart_splits_kitty_password + -- see https://sw.kovidgoyal.net/kitty/conf/#opt-kitty.remote_control_password + kitty_password = nil, + -- default logging level, one of: 'trace'|'debug'|'info'|'warn'|'error'|'fatal' + log_level = 'info', + persistent_resize_mode = true, + } + + -- vim.keymap.set('n', 'r', require('smart-splits').start_resize_mode, { desc = 'Start resize mode' }) + vim.keymap.set('n', '', require('smart-splits').move_cursor_right, { desc = 'Move right' }) + vim.keymap.set('n', '', require('smart-splits').move_cursor_left, { desc = 'Move left' }) + vim.keymap.set('n', '', require('smart-splits').move_cursor_down, { desc = 'Move down' }) + vim.keymap.set('n', '', require('smart-splits').move_cursor_up, { desc = 'Move up' }) + + -- Resize + local submode = require 'submode' + submode.create('WinResize', { + mode = 'n', + enter = 'r', + leave = { '', 'q', '' }, + hook = { + on_enter = function() + vim.notify 'Use { h, j, k, l } or { , , , } to resize the window' + end, + on_leave = function() + vim.notify '' + end, + }, + default = function(register) + register('h', require('smart-splits').resize_left, { desc = 'Resize left' }) + register('j', require('smart-splits').resize_down, { desc = 'Resize down' }) + register('k', require('smart-splits').resize_up, { desc = 'Resize up' }) + register('l', require('smart-splits').resize_right, { desc = 'Resize right' }) + register('', require('smart-splits').resize_left, { desc = 'Resize left' }) + register('', require('smart-splits').resize_down, { desc = 'Resize down' }) + register('', require('smart-splits').resize_up, { desc = 'Resize up' }) + register('', require('smart-splits').resize_right, { desc = 'Resize right' }) + end, + }) + end, +}