├── lua └── abstract-autocmds │ ├── utils.lua │ ├── init.lua │ ├── autocmds.lua │ └── mappings.lua ├── LICENSE └── README.md /lua/abstract-autocmds/utils.lua: -------------------------------------------------------------------------------- 1 | local M = {} 2 | 3 | local group = vim.api.nvim_create_augroup("AbstractAutoCmdsGroup", { clear = true }) 4 | 5 | function M.create_autocmd(events, opts) 6 | opts = vim.tbl_extend("force", opts, { group = group }) 7 | vim.api.nvim_create_autocmd(events, opts) 8 | end 9 | 10 | function M.opts_extend(default, opts) 11 | return vim.tbl_extend("force", default, opts ~= nil and opts or {}) 12 | end 13 | 14 | return M 15 | -------------------------------------------------------------------------------- /lua/abstract-autocmds/init.lua: -------------------------------------------------------------------------------- 1 | local autocmds = require("abstract-autocmds.autocmds") 2 | local mappings = require("abstract-autocmds.mappings") 3 | local M = {} 4 | 5 | function M.setup(opts) 6 | if opts == nil then 7 | return 8 | end 9 | 10 | local commands = vim.tbl_extend("force", autocmds, mappings) 11 | 12 | for key, value in pairs(opts) do 13 | if value then 14 | -- if no option is passed 15 | if value == true then 16 | commands[key]() 17 | goto continue 18 | end 19 | -- if option is passed 20 | if value.enable then 21 | commands[key](value.opts) 22 | end 23 | end 24 | ::continue:: 25 | end 26 | end 27 | 28 | return M 29 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2024 Abstract-IDE 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /lua/abstract-autocmds/autocmds.lua: -------------------------------------------------------------------------------- 1 | local M = {} 2 | local utils = require("abstract-autocmds.utils") 3 | local create_autocmd = utils.create_autocmd 4 | local opts_extend = require("abstract-autocmds.utils").opts_extend 5 | 6 | function M.highlight_on_yank(opts) 7 | opts = opts_extend({ timeout = 150 }, opts) 8 | create_autocmd("TextYankPost", { 9 | desc = "highlight text on yank", 10 | pattern = "*", 11 | callback = function() 12 | vim.hl.on_yank({ 13 | higroup = "Search", 14 | timeout = opts.timeout, 15 | on_visual = true, 16 | }) 17 | end, 18 | }) 19 | end 20 | 21 | function M.open_file_last_position() 22 | create_autocmd("BufWinEnter", { 23 | desc = "jump to the last position when reopening a file", 24 | pattern = "*", 25 | command = [[ if line("'\"") > 0 && line("'\"") <= line("$") | exe "normal! g`\"" | endif ]], 26 | }) 27 | end 28 | 29 | function M.remove_whitespace_on_save() 30 | create_autocmd("BufWritePre", { 31 | desc = "remove whitespaces on save", 32 | pattern = "*", 33 | command = "%s/\\s\\+$//e", 34 | }) 35 | end 36 | 37 | function M.no_autocomment_newline() 38 | create_autocmd({ "BufEnter", "FileType" }, { 39 | desc = "don't auto comment new line", 40 | pattern = "*", 41 | command = "setlocal formatoptions-=c formatoptions-=r formatoptions-=o", 42 | }) 43 | end 44 | 45 | function M.auto_resize_splited_window() 46 | create_autocmd("VimResized", { 47 | desc = "auto resize splited windows", 48 | pattern = "*", 49 | command = "tabdo wincmd =", 50 | }) 51 | end 52 | 53 | function M.clear_last_used_search() 54 | create_autocmd("BufWinEnter", { 55 | desc = "clear the last used search pattern", 56 | pattern = "*", 57 | command = "let @/ = ''", 58 | }) 59 | end 60 | 61 | function M.give_border(opts) 62 | create_autocmd("FileType", { 63 | desc = "Give border to required windows", 64 | pattern = opts.pattern ~= nil and opts.pattern or {}, 65 | callback = function() 66 | vim.api.nvim_win_set_config(0, { border = opts.border ~= nil and opts.border or "rounded" }) 67 | end, 68 | }) 69 | end 70 | 71 | function M.dont_suspend_with_cz() 72 | create_autocmd("BufEnter", { 73 | desc = "map ctl+z to nothing so that it don't suspend terminal", 74 | pattern = "*", 75 | command = "nnoremap ", 76 | }) 77 | end 78 | 79 | return M 80 | -------------------------------------------------------------------------------- /lua/abstract-autocmds/mappings.lua: -------------------------------------------------------------------------------- 1 | local opts_extend = require("abstract-autocmds.utils").opts_extend 2 | local M = {} 3 | 4 | -- smart deletion, dd 5 | -- It solves the issue, where you want to delete empty line, but dd will override your last yank. 6 | -- Code below will check if u are deleting empty line, if so - use black hole register. 7 | -- [src: https://www.reddit.com/r/neovim/comments/w0jzzv/comment/igfjx5y/?utm_source=share&utm_medium=web2x&context=3] 8 | function M.smart_dd() 9 | local dd = function() 10 | if vim.api.nvim_get_current_line():match("^%s*$") then 11 | return '"_dd' 12 | else 13 | return "dd" 14 | end 15 | end 16 | vim.keymap.set("n", "dd", dd, { noremap = true, expr = true }) 17 | end 18 | 19 | -- easier moving of code blocks 20 | -- Try to go into visual mode (v), thenselect several lines of code 21 | -- here and then press ``>`` several times. 22 | function M.visually_codeblock_shift() 23 | vim.api.nvim_set_keymap("v", "<", "", ">gv", { noremap = true, silent = true }) 25 | end 26 | 27 | -- move selected line(s) up or down 28 | function M.move_selected_upndown() 29 | vim.api.nvim_set_keymap("v", "J", ":m '>+1gv=gv", { noremap = true, silent = true }) 30 | vim.api.nvim_set_keymap("v", "K", ":m '<-2gv=gv", { noremap = true, silent = true }) 31 | end 32 | 33 | -- going back to normal mode which works even in vim's terminal 34 | -- eg: you may need this if you use floaterm to escape terminal 35 | function M.go_back_normal_in_terminal() 36 | vim.api.nvim_set_keymap("t", "", "", { noremap = true, silent = true }) 37 | end 38 | 39 | -- delete a word backward in insert mode with Ctrl+Backspace 40 | function M.ctrl_backspace_delete(opts) 41 | opts = opts_extend({ cmd_mode = true, insert_mode = true }, opts) 42 | if opts.insert_mode then 43 | vim.api.nvim_set_keymap("i", "", "", { noremap = true }) 44 | end 45 | if opts.cmd_mode then 46 | vim.api.nvim_set_keymap("c", "", "", { noremap = true }) 47 | end 48 | end 49 | 50 | -- Paste in visual mode without overwriting the yank register 51 | -- DEFAULT BEHAVIPR: in visual mode ('x'), pressing 'p' replaces the selected text with the content 52 | -- of the default register, effectively pasting the last deleted or yanked text. 53 | function M.smart_visual_paste() 54 | vim.api.nvim_set_keymap("x", "p", [[silent! normal! "_dP]], { noremap = true, silent = true }) 55 | end 56 | 57 | -- write/save when the buffer has been modified. 58 | function M.smart_save_in_insert_mode() 59 | vim.api.nvim_set_keymap("i", "", "ma:update `a", { noremap = true, silent = true }) 60 | vim.api.nvim_set_keymap("n", "", "ma:update `a", { noremap = true, silent = true }) 61 | end 62 | 63 | -- scroll up/down from center of screen 64 | function M.scroll_from_center() 65 | vim.api.nvim_set_keymap("n", "", "zz", { noremap = true, silent = true }) 66 | vim.api.nvim_set_keymap("n", "", "zz", { noremap = true, silent = true }) 67 | end 68 | 69 | -- search within visual selection 70 | function M.search_within_visual() 71 | vim.api.nvim_set_keymap("x", "/", "/\\%V", { noremap = true }) 72 | end 73 | 74 | return M 75 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Useful autocmds for Neovim. 2 | 3 | # Installation and Uses. 4 | 5 | ### using lazy.nvim 6 | 7 | All commands are disabled by default. 8 | 9 | ```lua 10 | 11 | { 12 | "Abstract-IDE/abstract-autocmds", 13 | lazy = false, 14 | config = function() 15 | require("abstract-autocmds").setup({ 16 | auto_resize_splited_window = true, 17 | remove_whitespace_on_save = true, 18 | no_autocomment_newline = true, 19 | clear_last_used_search = true, 20 | open_file_last_position = true, 21 | highlight_on_yank = { 22 | enable = true, 23 | opts = { 24 | timeout = 150, 25 | }, 26 | }, 27 | give_border = { 28 | enable = true, 29 | opts = { 30 | pattern = { "null-ls-info", "lspinfo" }, 31 | }, 32 | }, 33 | smart_dd = true, 34 | visually_codeblock_shift = true, 35 | move_selected_upndown = true, 36 | go_back_normal_in_terminal = true, 37 | ctrl_backspace_delete = { 38 | enable = true, 39 | opts = { 40 | insert_mode = true, 41 | cmd_mode = false, 42 | }, 43 | }, 44 | smart_visual_paste = true, 45 | dont_suspend_with_cz = true, 46 | smart_save_in_insert_mode = true, 47 | scroll_from_center = true, 48 | search_within_visual = true, 49 | }) 50 | end, 51 | } 52 | ``` 53 | 54 | # Available autocmds 55 | 56 | Automatically resizes split windows in tabs to maintain equal sizes when the Vim window is resized. 57 | 58 | ```lua 59 | auto_resize_splited_window = true 60 | ``` 61 | 62 | Removes trailing whitespace from each line when saving a buffer 63 | 64 | ```lua 65 | remove_whitespace_on_save = true 66 | ``` 67 | 68 | Prevents Neovim from automatically adding comments to new lines when entering a buffer or changing its file type. 69 | 70 | ```lua 71 | no_autocomment_newline = true 72 | ``` 73 | 74 | Clears the last used search pattern when entering a buffer window 75 | 76 | ```lua 77 | clear_last_used_search = true 78 | ``` 79 | 80 | Jumps to the last cursor position when reopening a file 81 | 82 | ```lua 83 | open_file_last_position = true 84 | ``` 85 | 86 | Highlights text when yanked in Neovim, using the specified timeout and applying the highlighting to the "Search" highlight group. 87 | 88 | ```lua 89 | highlight_on_yank = { 90 | enable = true, 91 | opts = { 92 | timeout = 150, 93 | }, 94 | } 95 | ``` 96 | 97 | Enables border decoration for specific patterns 98 | 99 | ```lua 100 | give_border = { 101 | enable = true, 102 | opts = { 103 | pattern = { "null-ls-info", "lspinfo" }, 104 | }, 105 | } 106 | ``` 107 | 108 | smart deletion functionality for the "dd" command. If the current line is empty, it deletes the line without affecting the yank register. Otherwise, it behaves like the standard "dd" command. 109 | 110 | ```lua 111 | smart_dd = true 112 | ``` 113 | 114 | Facilitates the movement of code blocks by allowing users to enter visual mode (v), select several lines of code, and then press ">" or "<" several times to shift the selected block of code. 115 | 116 | ```lua 117 | visually_codeblock_shift = true 118 | ``` 119 | 120 | Enables moving the selected line(s) up or down in visual mode. Pressing "J" moves the selected lines down, while "K" moves them up. 121 | 122 | ```lua 123 | move_selected_upndown = true 124 | ``` 125 | 126 | Provides a way to return to normal mode within Neovim's terminal, ensuring compatibility with plugins like floaterm. It maps the Escape key in terminal mode to the key sequence , which switches back to normal mode. 127 | 128 | ```lua 129 | go_back_normal_in_terminal = true 130 | ``` 131 | 132 | Enables deleting a word backward in insert or/and command mode using Ctrl+Backspace. 133 | 134 | ```lua 135 | ctrl_backspace_delete = { 136 | enable = true, 137 | opts = { 138 | insert_mode = true, 139 | cmd_mode = false, 140 | }, 141 | }, 142 | ``` 143 | 144 | Paste in visual mode without overwriting the yank register 145 | DEFAULT BEHAVIPR: in visual mode ('x'), pressing 'p' replaces the selected text with the content of the default register, effectively pasting the last deleted or yanked text. 146 | 147 | ```lua 148 | smart_visual_paste = true 149 | ``` 150 | 151 | Prevents Neovim from suspending with Ctrl+Z when entering a buffer, ensuring that it doesn't suspend the terminal. 152 | 153 | ```lua 154 | dont_suspend_with_cz = true 155 | ``` 156 | 157 | Enables saving the buffer when it has been modified, triggered by pressing Ctrl+S in insert mode or normal mode. 158 | 159 | ```lua 160 | smart_save_in_insert_mode = true 161 | ``` 162 | 163 | Enhances scrolling behavior in normal mode, allowing scrolling up/down from the center of the screen. 164 | 165 | ```lua 166 | scroll_from_center = true 167 | ``` 168 | --------------------------------------------------------------------------------