diff --git a/KEYMAPS.md b/KEYMAPS.md index 2c4e1ae..e4f1622 100644 --- a/KEYMAPS.md +++ b/KEYMAPS.md @@ -49,14 +49,6 @@ ## Text Editing -### Undo Break-points (Insert Mode) - -| Keymap | Mode | Action | -| ------ | ------ | ---------------------------- | -| `,` | Insert | Comma + undo break-point | -| `.` | Insert | Period + undo break-point | -| `;` | Insert | Semicolon + undo break-point | - ### Smart Closing Punctuation Skip (Insert Mode) | Keymap | Mode | Action | @@ -115,9 +107,9 @@ ## Flash (Smart Navigation) -| Keymap | Mode | Action | -| ------ | ------------------------ | ------------------------------- | -| `s` | Normal, Visual, Operator | Flash search (jump to location) | +| Keymap | Mode | Action | +| ----------- | ------------------------ | ------------------------------- | +| `/` | Normal, Visual, Operator | Flash search (jump to location) | ## Grug-far (Search & Replace) @@ -147,12 +139,11 @@ ### LSP Code Actions & Formatting -| Keymap | Mode | Action | -| ------------ | ---------------------- | ------------------ | -| `cr` | Normal | Rename symbol | -| `ca` | Normal, Visual | Code action | -| `cf` | Normal, Visual, Select | Format buffer | -| `\H` | Normal | Toggle inlay hints | +| Keymap | Mode | Action | +| ------------ | ---------------------- | ------------------------------- | +| `cr` | Normal | Rename symbol | +| `ca` | Normal, Visual | Code action | +| `cf` | Normal, Visual, Select | Format buffer | | `uv` | Normal | Toggle virtual text diagnostics | ## Treesitter @@ -166,12 +157,6 @@ | `gvs` | Normal | Expand to scope | | `gvp` | Normal | Shrink to previous node | -### Treesitter Context - -| Keymap | Mode | Action | -| ------ | ------ | ------------------------------- | -| `\t` | Normal | Toggle treesitter context panel | - ## Mini.nvim ### Mini.files (File Navigator) @@ -251,7 +236,6 @@ | Keymap | Mode | Action | | ----------------- | ------ | -------------------------------- | | `` | Normal | Smart find (auto-detect context) | -| `/` | Normal | Grep search | | `:` | Normal | Command history | | `.` | Normal | Scratch buffer selector | @@ -311,6 +295,7 @@ | `sc` | Normal | Commands | | `sd` | Normal | Diagnostics | | `sD` | Normal | Buffer diagnostics | +| `sg` | Normal | Grep | | `sh` | Normal | Search history | | `sH` | Normal | Highlights | | `si` | Normal | Icons | diff --git a/init.lua b/init.lua index 4ca0273..a8cc8fc 100644 --- a/init.lua +++ b/init.lua @@ -8,31 +8,20 @@ █ █ █ █ ██████ ▀██▀ ██▄▄█▀ ██▄▄ ██▄▄██▄ ██▄▄ ██ ▀█▄█▀ █ ▄▄▄▄▄ █ █ ▄▄▄▄▄ █ ██ ██ ██ ██ ██▄▄▄▄ ██ ██ ██ ██ ██ ██ ========================================================================== --]] - -- WHAT: HYPERfix.nvim entry point - loads configuration in order -- WHY: Ensures predictable startup: options, plugins, keymaps -- HOW: Requires Lua modules in dependency order -- NOTE: Colorscheme set before lazy.nvim to avoid initial flash -- REFERENCE: See README.md for quick start and philosophy -- See KEYMAPS.md for complete keymap reference - --- ============================================================================ --- Load core editor options and settings -- ---------------------------------------------------------------------------- +-- Load core editor options and settings require("config.options") --- ============================================================================ --- Colorschemes --- ---------------------------------------------------------------------------- --- local colorschemes = require("colorschemes") --- colorschemes.kakariko.setup() - -- Alternative colorscheme generated with mini.hues and mini.colors vim.cmd.colorscheme("kokiri") --- ============================================================================ -- Load plugin manager and remaining configurations --- ---------------------------------------------------------------------------- require("config.lazy") require("config.keymaps") require("config.autocmds") diff --git a/lazy-lock.json b/lazy-lock.json index b9831e3..8f9eabb 100644 --- a/lazy-lock.json +++ b/lazy-lock.json @@ -14,13 +14,13 @@ "mason-nvim-dap.nvim": { "branch": "main", "commit": "9a10e096703966335bd5c46c8c875d5b0690dade" }, "mason-tool-installer.nvim": { "branch": "main", "commit": "517ef5994ef9d6b738322664d5fdd948f0fdeb46" }, "mason.nvim": { "branch": "main", "commit": "57e5a8addb8c71fb063ee4acda466c7cf6ad2800" }, - "mini.nvim": { "branch": "main", "commit": "e7a8e5a0920df1435172d42fb32e474bbb30d021" }, + "mini.nvim": { "branch": "main", "commit": "43ec25063430196d36f5fff5758c9101775f3d57" }, "nvim-dap": { "branch": "master", "commit": "818cd8787a77a97703eb1d9090543a374f79a9ac" }, "nvim-dap-ui": { "branch": "master", "commit": "cf91d5e2d07c72903d052f5207511bf7ecdb7122" }, "nvim-lint": { "branch": "master", "commit": "1f19dacd945a7b1a57f29f32b2d7168384df3d36" }, "nvim-lspconfig": { "branch": "master", "commit": "d696e36d5792daf828f8c8e8d4b9aa90c1a10c2a" }, "nvim-nio": { "branch": "master", "commit": "21f5324bfac14e22ba26553caf69ec76ae8a7662" }, - "nvim-treesitter": { "branch": "main", "commit": "36fcb4a4238928f0b627e1ab84ade0acc1facc2c" }, + "nvim-treesitter": { "branch": "main", "commit": "7efc1b58a8061d29786860006c7257c90a5196dc" }, "nvim-treesitter-context": { "branch": "master", "commit": "64dd4cf3f6fd0ab17622c5ce15c91fc539c3f24a" }, "nvim-treesitter-textobjects": { "branch": "main", "commit": "ecd03f5811eb5c66d2fa420b79121b866feecd82" }, "plenary.nvim": { "branch": "master", "commit": "b9fd5226c2f76c951fc8ed5923d85e4de065e509" }, diff --git a/lua/config/autocmds.lua b/lua/config/autocmds.lua index af5cee7..3f50150 100644 --- a/lua/config/autocmds.lua +++ b/lua/config/autocmds.lua @@ -1,6 +1,6 @@ -- ============================================================================= -- AUTOCOMMANDS --- ============================================================================= +-- ----------------------------------------------------------------------------- -- WHAT: Autocommands automatically trigger actions in response to events -- (e.g., when you open a file, save it, switch focus, resize window) -- @@ -17,7 +17,7 @@ -- - callback: function to execute when event fires -- -- REFERENCE: https://neovim.io/doc/user/autocmd.html --- ============================================================================= +-- ----------------------------------------------------------------------------- local function augroup(name) return vim.api.nvim_create_augroup("hyperfix_" .. name, { clear = true }) @@ -25,14 +25,19 @@ end -- ============================================================================= -- Checktime: Reload File on External Changes --- ============================================================================= +-- ----------------------------------------------------------------------------- -- WHAT: Detects when a file changes on disk and reloads it in your buffer -- WHY: Keeps your buffer in sync if another process modifies the file -- (prevents "file changed" conflicts) -- HOW: Triggers on FocusGained (window refocuses), TermClose, TermLeave -- and runs :checktime to reload if needed --- ============================================================================= -vim.api.nvim_create_autocmd({ "FocusGained", "TermClose", "TermLeave" }, { +-- ----------------------------------------------------------------------------- + +vim.api.nvim_create_autocmd({ + "FocusGained", + "TermClose", + "TermLeave", +}, { group = augroup("checktime"), callback = function() if vim.o.buftype ~= "nofile" then vim.cmd("checktime") end @@ -41,11 +46,12 @@ vim.api.nvim_create_autocmd({ "FocusGained", "TermClose", "TermLeave" }, { -- ============================================================================= -- Highlight on Yank: Visual Feedback When Copying --- ============================================================================= +-- ----------------------------------------------------------------------------- -- WHAT: Briefly highlights text you just yanked (copied) -- WHY: Provides visual feedback so you know the selection worked -- HOW: Triggers on TextYankPost and calls vim's built-in highlight.on_yank() --- ============================================================================= +-- ----------------------------------------------------------------------------- + vim.api.nvim_create_autocmd("TextYankPost", { group = augroup("highlight_yank"), callback = function() (vim.hl or vim.highlight).on_yank() end, @@ -53,11 +59,12 @@ vim.api.nvim_create_autocmd("TextYankPost", { -- ============================================================================= -- Resize Splits: Auto-Balance Window Layout --- ============================================================================= +-- ----------------------------------------------------------------------------- -- WHAT: Automatically resizes splits when the Neovim window is resized -- WHY: Keeps your window layout proportional and balanced after resizing -- HOW: Triggers on VimResized and runs wincmd = (equal width/height) --- ============================================================================= +-- ----------------------------------------------------------------------------- + vim.api.nvim_create_autocmd({ "VimResized" }, { group = augroup("resize_splits"), callback = function() @@ -69,13 +76,14 @@ vim.api.nvim_create_autocmd({ "VimResized" }, { -- ============================================================================= -- Last Location: Jump to Where You Left Off --- ============================================================================= +-- ----------------------------------------------------------------------------- -- WHAT: Reopens a file at the cursor position where you last closed it -- WHY: Speeds up workflow by skipping manual navigation back to where -- you were working -- HOW: Triggers on BufReadPost, restores the " mark (last position) -- if it's valid (excluding git commits and other special files) --- ============================================================================= +-- ----------------------------------------------------------------------------- + vim.api.nvim_create_autocmd("BufReadPost", { group = augroup("last_loc"), callback = function(event) @@ -98,14 +106,15 @@ vim.api.nvim_create_autocmd("BufReadPost", { -- ============================================================================= -- Close With 'q': Quick Exit for Help/Info/Output Buffers --- ============================================================================= +-- ----------------------------------------------------------------------------- -- WHAT: Maps 'q' key to close help, info panels, and output windows -- WHY: Provides a consistent, intuitive way to exit read-only buffers -- (easier than remembering :close or :quit) -- HOW: Triggers on FileType for specific filetypes (help, lspinfo, etc.) -- and maps 'q' to close + delete the buffer -- NOTE: Marks these buffers as unlisted so they don't clutter buffer list --- ============================================================================= +-- ----------------------------------------------------------------------------- + vim.api.nvim_create_autocmd("FileType", { group = augroup("close_with_q"), pattern = { @@ -142,11 +151,12 @@ vim.api.nvim_create_autocmd("FileType", { -- ============================================================================= -- Man Unlisted: Hide Man Pages from Buffer List --- ============================================================================= +-- ----------------------------------------------------------------------------- -- WHAT: Hides man page buffers from the buffer list -- WHY: Keeps your buffer list clean when viewing man pages inline -- HOW: Triggers on FileType "man" and sets buflisted = false --- ============================================================================= +-- ----------------------------------------------------------------------------- + vim.api.nvim_create_autocmd("FileType", { group = augroup("man_unlisted"), pattern = { "man" }, @@ -156,6 +166,7 @@ vim.api.nvim_create_autocmd("FileType", { -- ============================================================================= -- Disable colorcolumn when wrap is on -- ---------------------------------------------------------------------------- + vim.api.nvim_create_autocmd("OptionSet", { group = augroup("wrap_colorcolumn"), pattern = "wrap", @@ -170,12 +181,13 @@ vim.api.nvim_create_autocmd("OptionSet", { -- ============================================================================= -- JSON Conceal: Show All JSON Content --- ============================================================================= +-- ----------------------------------------------------------------------------- -- WHAT: Disables concealing for JSON files so nothing is hidden -- WHY: JSON files should always show all content (no hidden characters) -- Default conceallevel would hide quotes/brackets -- HOW: Triggers on FileType for json/jsonc/json5 and sets conceallevel = 0 --- ============================================================================= +-- ----------------------------------------------------------------------------- + vim.api.nvim_create_autocmd({ "FileType" }, { group = augroup("json_conceal"), pattern = { "json", "jsonc", "json5" }, @@ -184,13 +196,14 @@ vim.api.nvim_create_autocmd({ "FileType" }, { -- ============================================================================= -- Auto Create Directory: Create Parent Dirs on Save --- ============================================================================= +-- ----------------------------------------------------------------------------- -- WHAT: Automatically creates parent directories when saving a file -- WHY: Prevents "parent directory doesn't exist" errors when saving -- to a path with missing intermediate directories -- HOW: Triggers on BufWritePre and creates directory structure with mkdir -- NOTE: Skips remote files (ssh://, http://, etc.) --- ============================================================================= +-- ----------------------------------------------------------------------------- + vim.api.nvim_create_autocmd({ "BufWritePre" }, { group = augroup("auto_create_dir"), callback = function(event) diff --git a/lua/config/keymaps.lua b/lua/config/keymaps.lua index 88ac7aa..d5e8798 100644 --- a/lua/config/keymaps.lua +++ b/lua/config/keymaps.lua @@ -1,18 +1,19 @@ -- ============================================================================= -- KEYMAPS: Custom Vim key bindings and remaps --- ============================================================================= +-- ----------------------------------------------------------------------------- -- WHAT: Define custom keyboard shortcuts for common editor actions -- WHY: Faster workflow with mnemonic patterns (f = find, g = git) -- HOW: Use vim.keymap.set() with mode, key, action, and description -- NOTE: Full reference in KEYMAPS.md; most keymaps come from plugins -- REFERENCE: KEYMAPS.md for complete keymap documentation --- ============================================================================= +-- ----------------------------------------------------------------------------- local map = vim.keymap.set -- ============================================================================= -- Window navigation -- ----------------------------------------------------------------------------- -- stylua: ignore start + map("n", "", "h", { desc = "Window Left" }) map("n", "", "j", { desc = "Window Down" }) map("n", "", "k", { desc = "Window Up" }) @@ -21,19 +22,19 @@ map("n", "", "l", { desc = "Window Right" } -- ============================================================================= -- BUFFER MANAGEMENT -- ----------------------------------------------------------------------------- + map("n", "bn", "bnext", { desc = "[N]ext Buffer" }) map("n", "bp", "bprevious", { desc = "[P]rev Buffer" }) -- ============================================================================= -- TAB MANAGEMENT -- ----------------------------------------------------------------------------- -map("n", "", "tabnew", { desc = "New [T]ab" }) -map("n", "n", "tabnext", { desc = "[N]ext" }) + +map("n", "", "tabnext", { desc = "[TAB] over" }) +map("n", "n", "tabnew", { desc = "[N]ew" }) map("n", "p", "tabprevious", { desc = "[P]rev" }) -map("n", "f", "tabfirst", { desc = "[F]irst" }) -map("n", "l", "tablast", { desc = "[L]ast" }) map("n", "q", "tabclose", { desc = "[Q]uit" }) -map("n", "o", "tabonly", { desc = "Close [O]thers" }) +map("n", "o", "tabonly", { desc = "[O]nly" }) -- stylua: ignore end -- ============================================================================= @@ -43,6 +44,7 @@ map("n", "o", "tabonly", { desc = "Close [O]thers" -- WHY: Lines that wrap shouldn't count as multiple "down" presses (gj/gk) -- HOW: Uses expression mapping to choose between j/gj based on count -- ----------------------------------------------------------------------------- + map( { "n", "x" }, "j", @@ -77,6 +79,7 @@ map( -- REFERENCE: https://github.com/mhinz/vim-galore#saner-behavior-of-n-and-n -- NOTE: 'zv' in normal mode opens folds to show matched line -- ----------------------------------------------------------------------------- + map( "n", "n", @@ -121,23 +124,25 @@ map( -- WHY: Allows undoing text after specific punctuation without losing everything -- HOW: u creates an undo point without moving cursor -- ----------------------------------------------------------------------------- + map("i", ",", ",u") map("i", ".", ".u") map("i", ";", ";u") -- ============================================================================= -- SMART CLOSING PUNCTUATION SKIP --- ============================================================================= +-- ----------------------------------------------------------------------------- -- WHAT: Skip past closing punctuation in insert mode -- WHY: Streamlines workflow—jump over ) } ] ' " without arrow keys -- HOW: Checks if next character is closing punctuation, moves cursor forward --- ============================================================================= +-- ----------------------------------------------------------------------------- + map("i", "", function() local line = vim.api.nvim_get_current_line() local row, col = unpack(vim.api.nvim_win_get_cursor(0)) local next_char = line:sub(col + 1, col + 1) - if next_char:match("[)%]}'\" ]") then + if next_char:match("[%)%]%}%\"%']") then vim.api.nvim_win_set_cursor(0, { row, col + 1 }) end end, { noremap = true, silent = true, desc = "Skip past closing punctuation" }) @@ -145,8 +150,10 @@ end, { noremap = true, silent = true, desc = "Skip past closing punctuation" }) -- ============================================================================= -- FILE MANAGEMENT -- ----------------------------------------------------------------------------- + map({ "i", "x", "n", "s" }, "", "w", { desc = "Save File" }) map("n", "fn", "enew", { desc = "[N]ew File" }) +map("n", "fs", "w", { desc = "[S]ave File" }) -- ============================================================================= -- INDENTATION @@ -154,24 +161,28 @@ map("n", "fn", "enew", { desc = "[N]ew File" }) -- WHAT: Re-indent selection when using < or > in visual mode -- HOW: gv reselects previous visual selection after the indent -- ----------------------------------------------------------------------------- + map("x", "<", "", ">gv") -- ============================================================================= -- PLUGIN MANAGEMENT -- ----------------------------------------------------------------------------- + map("n", "nl", "Lazy", { desc = "[L]azy" }) -- ============================================================================= -- DIAGNOSTICS TOGGLE --- ============================================================================= +-- ----------------------------------------------------------------------------- -- WHAT: Toggle virtual text diagnostics on/off -- WHY: Reduces visual clutter when you need focus or enables diagnostics when needed -- HOW: Uses vim.diagnostic.config to toggle virtual_text on current buffer --- ============================================================================= +-- ----------------------------------------------------------------------------- + map("n", "uv", function() local config = vim.diagnostic.config() - local vtext = config.virtual_text + local vtext + if config then vtext = config.virtual_text end -- Toggle: if enabled, disable; if disabled, enable with default settings vim.diagnostic.config({ virtual_text = not vtext }) local status = not vtext and "enabled" or "disabled" @@ -180,15 +191,16 @@ end, { desc = "Toggle [V]irtual Text Diagnostics" }) -- ============================================================================= -- APPLICATION MANAGEMENT --- ============================================================================= +-- ----------------------------------------------------------------------------- -- WHAT: Quit group keymaps with session support -- WHY: Save sessions and prompt for unsaved changes before quitting -- HOW: qq = quit all, qw = save all & quit, qQ = force quit -- qs = save session, qr = restore session (picker) --- ============================================================================= -map("n", "qq", "qa", { desc = "[Q]uit All" }) +-- ----------------------------------------------------------------------------- +map("n", "qq", "qa", { desc = "[Q]uit All" }) map("n", "qw", "wqa", { desc = "[W]rite & Quit" }) +map("n", "qQ", "q!", { desc = "Force [Q]uit" }) map("n", "qW", function() local sessions = require("mini.sessions") @@ -213,8 +225,6 @@ map("n", "qW", function() end end, { desc = "[W]rite to Session & Quit" }) -map("n", "qQ", "q!", { desc = "Force [Q]uit" }) - map("n", "qs", function() local sessions = require("mini.sessions") local active_session = vim.v.this_session ~= "" and vim.v.this_session or nil @@ -260,6 +270,7 @@ map( -- ============================================================================= -- COMMENTING -- ----------------------------------------------------------------------------- + map( "n", "gco", diff --git a/lua/config/options.lua b/lua/config/options.lua index 59bda7d..4aa3a7e 100644 --- a/lua/config/options.lua +++ b/lua/config/options.lua @@ -1,26 +1,25 @@ -- ============================================================================= -- Globals --- ============================================================================= +-- ----------------------------------------------------------------------------- -- WHAT: Global variables for Neovim behavior -- WHY: Configure behavior that affects the entire editor -- HOW: Set vim.g values for mapleader, LSP root detection, etc. -- NOTE: These must be set before loading plugins that depend on them --- ============================================================================= +-- ----------------------------------------------------------------------------- -- stylua: ignore start vim.g.mapleader = " " vim.g.maplocalleader = "\\" - vim.g.ai_cmp = true vim.g.root_spec = { "lsp", { ".git", "lua" }, "cwd" } vim.g.markdown_recommended_style = 0 -- ============================================================================= -- Options (Undo & History) --- ============================================================================= +-- ----------------------------------------------------------------------------- -- WHAT: Configure long-term undo history and backup behavior -- HOW: Disable swapfiles, enable undofile with high undo levels --- ============================================================================= +-- ----------------------------------------------------------------------------- local opt = vim.opt @@ -34,11 +33,11 @@ opt.writebackup = false -- Don't use backup files -- ============================================================================= -- Options (Display & Visual) --- ============================================================================= +-- ----------------------------------------------------------------------------- -- WHAT: Configure visual display, colors, and rendering -- WHY: Improves readability and accessibility (WCAG AAA compliant) -- HOW: Set line spacing, colors, cursor visibility, highlight columns --- ============================================================================= +-- ----------------------------------------------------------------------------- opt.background = "dark" opt.termguicolors = true -- True color support @@ -55,11 +54,11 @@ opt.guicursor = "" -- ============================================================================= -- Options (Indentation & Tabs) --- ============================================================================= +-- ----------------------------------------------------------------------------- -- WHAT: Configure tab behavior and indentation -- WHY: Ensures consistent formatting across files -- HOW: Use spaces, set width to 2, enable smart indent --- ============================================================================= +-- ----------------------------------------------------------------------------- opt.expandtab = true -- Use spaces instead of tabs opt.tabstop = 2 -- Number of spaces tabs count for @@ -70,11 +69,11 @@ opt.smartindent = true -- Insert indents automatically -- ============================================================================= -- Options (Search & Replace) --- ============================================================================= +-- ----------------------------------------------------------------------------- -- WHAT: Configure search behavior and substitution preview -- WHY: Improves search experience with better feedback -- HOW: Enable case-sensitive search with smart case, preview substitutions --- ============================================================================= +-- ----------------------------------------------------------------------------- opt.hlsearch = false -- Highlight all matches on previous search pattern opt.incsearch = true -- Incremental search @@ -86,9 +85,9 @@ opt.grepprg = "rg --vimgrep" -- ============================================================================= -- Options (Window & Split Behavior) --- ============================================================================= +-- ----------------------------------------------------------------------------- -- WHAT: Configure window splitting and navigation --- ============================================================================= +-- ----------------------------------------------------------------------------- opt.splitbelow = true -- Put new windows below current opt.splitright = true -- Put new windows right of current @@ -103,57 +102,55 @@ opt.linebreak = true -- Wrap lines at convenient points -- ============================================================================= -- Options (Completion & Menu) --- ============================================================================= +-- ----------------------------------------------------------------------------- -- WHAT: Configure completion menu appearance and behavior -- WHY: Better control over autocompletion UX -- HOW: Set popup size, blend, and completion options --- ============================================================================= +-- ----------------------------------------------------------------------------- opt.completeopt = "menu,menuone,noselect" opt.pumheight = 10 -- Maximum number of entries in a popup opt.pumblend = 10 -- Popup blend --- stylua: ignore end -- ============================================================================= -- Options (Folding) --- ============================================================================= +-- ----------------------------------------------------------------------------- -- WHAT: Configure code folding display and behavior -- WHY: Improves navigation in large files -- HOW: Use indent-based folding with custom fold characters --- ============================================================================= +-- ----------------------------------------------------------------------------- opt.foldmethod = "indent" -opt.foldlevel = 99 -opt.foldtext = "" -opt.fillchars = { - foldopen = "󱄰", - foldclose = "󱄱", +opt.foldlevel = 99 +opt.foldtext = "" +opt.fillchars = { + foldopen = "󱄰", + foldclose = "󱄱", } -- ============================================================================= -- Options (Whitespace & Special Characters) --- ============================================================================= +-- ----------------------------------------------------------------------------- -- WHAT: Configure display of invisible characters -- WHY: Makes whitespace visible to catch formatting issues -- HOW: Show tabs, trailing spaces, and line extends/precedes --- ============================================================================= +-- ----------------------------------------------------------------------------- -opt.list = true -- Show some invisible characters (tabs...) +opt.list = true -- Show some invisible characters (tabs...) opt.listchars = { - tab = "▸ ", - trail = "·", - extends = "❯", - precedes = "❮", + tab = "▸ ", + trail = "·", + extends = "❯", + precedes = "❮", } -- ============================================================================= -- Options (Formatting & Input) --- ============================================================================= +-- ----------------------------------------------------------------------------- -- WHAT: Configure text formatting and user input handling -- WHY: Improves editing experience and text quality -- HOW: Set format options, confirm on exit, virtualedit for block mode --- ============================================================================= --- stylua: ignore start +-- ----------------------------------------------------------------------------- opt.formatoptions = "jcroqlnt" opt.confirm = true -- Confirm to save changes before exiting modified buffer @@ -163,34 +160,33 @@ opt.clipboard = "unnamedplus" -- Sync with system clipboard -- ============================================================================= -- Options (Modes & Status) --- ============================================================================= +-- ----------------------------------------------------------------------------- -- WHAT: Configure mode display and status information -- WHY: Status info is shown via statusline plugin, not native display -- HOW: Hide native mode indicator, use global statusline --- ============================================================================= +-- ----------------------------------------------------------------------------- opt.showmode = false -- Dont show mode since we have a statusline opt.laststatus = 3 -- global statusline -- ============================================================================= -- Options (Timing & Key Sequences) --- ============================================================================= +-- ----------------------------------------------------------------------------- -- WHAT: Configure timing for key sequences and updates -- WHY: Provides time to think before triggering commands -- HOW: Set longer timeoutlen for which-key, updatetime for CursorHold --- ============================================================================= +-- ----------------------------------------------------------------------------- opt.timeoutlen = 1250 opt.jumpoptions = "view" --- stylua: ignore end -- ============================================================================= -- Options (Messages & Feedback) --- ============================================================================= +-- ----------------------------------------------------------------------------- -- WHAT: Configure which messages and warnings are shown -- WHY: Reduces visual clutter while keeping necessary feedback -- HOW: Use shortmess to suppress certain notifications --- ============================================================================= +-- ----------------------------------------------------------------------------- opt.shortmess:append({ W = true, -- Don't print "written" message @@ -201,9 +197,9 @@ opt.shortmess:append({ -- ============================================================================= -- Options (Session Management) --- ============================================================================= +-- ----------------------------------------------------------------------------- -- WHAT: Configure what information is saved in sessions --- ============================================================================= +-- ----------------------------------------------------------------------------- opt.sessionoptions = { "buffers", @@ -218,17 +214,17 @@ opt.sessionoptions = { -- ============================================================================= -- Options (Command-Line) --- ============================================================================= +-- ----------------------------------------------------------------------------- -- WHAT: Configure command-line completion behavior -- HOW: Use longest match first, then full completion --- ============================================================================= +-- ----------------------------------------------------------------------------- opt.wildmode = "longest:full,full" -- Command-line completion mode -- ============================================================================= -- Options (Spelling) --- ============================================================================= +-- ----------------------------------------------------------------------------- -- WHAT: Configure spell checking language --- ============================================================================= +-- ----------------------------------------------------------------------------- opt.spelllang = { "en" } diff --git a/lua/plugins/flash.lua b/lua/plugins/flash.lua index 4b6ab88..9fc6fd6 100644 --- a/lua/plugins/flash.lua +++ b/lua/plugins/flash.lua @@ -1,60 +1,57 @@ -- ============================================================================= -- FLASH.NVIM: Lightning-Fast Motion Navigation --- ============================================================================= +-- ----------------------------------------------------------------------------- -- WHAT: Jump anywhere visible using intuitive two-keystroke motions with labels -- WHY: Standard Vim motions (w, f, b) require multiple keypresses for distant targets. -- Flash labels all matches so you jump in one or two keystrokes (neurodivergent-friendly!) -- HOW: Activate with 's' and type the target character; Flash labels each match -- NOTE: Works in normal, visual, and operator modes. Integrates with d/c/y operators. -- REFERENCE: https://github.com/folke/flash.nvim --- =============================================================================------------------------------------------------------------------- -- -- KEYMAPS AND USAGE --- ================== --- • s : Search and jump to any visible character (normal/visual/op-pending) --- • S : Search within syntax tree (jump to language constructs) --- • r : Remote motion (use with operators: 'd', 'c', 'y', etc.) --- • R : Search syntax tree for operators --- • C-s : Toggle Flash search (e.g., disable if activated on accident) +-- ----------------- +-- • / : Search and jump to any visible character (normal/visual/op-pending) +-- • S : Search within syntax tree (jump to language constructs) +-- • r : Remote motion (use with operators: 'd', 'c', 'y', etc.) +-- • R : Search syntax tree for operators +-- • C-s : Toggle Flash search (e.g., disable if activated on accident) -- --- EXAMPLES: 's' + 'f' = jump to next f, 'ds' + label = delete to target, 'c2s' = change --- ============================================================================= +-- EXAMPLES: '/' + 'f' = jump to next f, 'd/' + label = delete to target +-- ----------------------------------------------------------------------------- return { - { - "folke/flash.nvim", - lazy = true, - opts = {}, - keys = { - { - "s", - mode = { "n", "x", "o" }, - function() require("flash").jump() end, - desc = "Flash [S]earch", - }, - { - "S", - mode = { "n", "x", "o" }, - function() require("flash").treesitter() end, - desc = "Flash Tree[s]itter", - }, - { - "r", - mode = "o", - function() require("flash").remote() end, - desc = "[R]emote Flash", - }, - { - "R", - mode = { "o", "x" }, - function() require("flash").treesitter_search() end, - desc = "T[r]eesitter Search", - }, - { - "", - mode = { "c" }, - function() require("flash").toggle() end, - desc = "Toggle Flash [S]earch", - }, + "folke/flash.nvim", + lazy = true, + opts = {}, + keys = { + { + "/", + mode = { "n", "x", "o" }, + function() require("flash").jump() end, + desc = "Flash Search", + }, + { + "S", + mode = { "n", "x", "o" }, + function() require("flash").treesitter() end, + desc = "Flash Tree[s]itter", + }, + { + "r", + mode = "o", + function() require("flash").remote() end, + desc = "[R]emote Flash", + }, + { + "R", + mode = { "o", "x" }, + function() require("flash").treesitter_search() end, + desc = "T[r]eesitter Search", + }, + { + "", + mode = { "c" }, + function() require("flash").toggle() end, + desc = "Toggle Flash [S]earch", }, }, } diff --git a/lua/plugins/lint.lua b/lua/plugins/lint.lua index 9c43680..d4415e5 100644 --- a/lua/plugins/lint.lua +++ b/lua/plugins/lint.lua @@ -13,13 +13,6 @@ return { "mfussenegger/nvim-lint", lazy = true, event = { "BufReadPost", "BufWritePost" }, - keys = { - { - "cL", - function() require("lint").try_lint() end, - desc = "[L]int", - }, - }, config = function() local lint = require("lint") @@ -38,21 +31,5 @@ return { zsh = { "shellcheck" }, markdown = { "markdownlint" }, } - - -- ========================================================================= - -- htmlhint: Disable self-closing slash warning (HTML5 standard) - -- ------------------------------------------------------------------------- - lint.linters.htmlhint = lint.linters.htmlhint or {} - lint.linters.htmlhint.args = { - "--rules", - "void-elements:false", -- Don't warn about void elements without slashes - } - - -- ========================================================================= - -- Auto-lint on save - -- ------------------------------------------------------------------------- - vim.api.nvim_create_autocmd({ "BufWritePost" }, { - callback = function() require("lint").try_lint() end, - }) end, } diff --git a/lua/plugins/lsp.lua b/lua/plugins/lsp.lua index 83207d9..e0dbd0a 100644 --- a/lua/plugins/lsp.lua +++ b/lua/plugins/lsp.lua @@ -19,6 +19,10 @@ return { "saghen/blink.cmp", "onsails/lspkind.nvim", }, + + -- --------------------------------------------------------------------------- + -- config + -- --------------------------------------------------------------------------- config = function() vim.api.nvim_create_autocmd("LspAttach", { group = vim.api.nvim_create_augroup( @@ -35,7 +39,9 @@ return { end end + -- --------------------------------------------------------------------- -- Highlight references under cursor (hover highlighting) + -- --------------------------------------------------------------------- local client = vim.lsp.get_client_by_id(event.data.client_id) if client @@ -49,6 +55,7 @@ return { "hyperfix-lsp-highlight", { clear = false } ) + vim.api.nvim_create_autocmd({ "CursorHold", "CursorHoldI" }, { buffer = event.buf, group = highlight_augroup, @@ -75,24 +82,13 @@ return { end, }) end - - -- Enable inlay hints (function parameters, types) - if - client_supports_method( - client, - vim.lsp.protocol.Methods.textDocument_inlayHint, - event.buf - ) - then - vim.lsp.inlay_hint.enable(true, { bufnr = event.buf }) - end end, }) - -- ======================================================================= + -- ========================================================================= -- Diagnostic Config: error display, signs, and inline messages -- NOTE: See :help vim.diagnostic.Opts - -- ----------------------------------------------------------------------- + -- ------------------------------------------------------------------------- vim.diagnostic.config({ severity_sort = true, -- Sort by error > warn > info > hint float = { border = "rounded", source = "if_many" }, -- Hover window styling @@ -106,6 +102,7 @@ return { [vim.diagnostic.severity.HINT] = "󱁞 ", }, } or {}, + -- Inline error messages at end of line virtual_text = { source = "if_many", -- Show source only if multiple diagnostics on line @@ -125,7 +122,9 @@ return { -- Merge blink.cmp's LSP capabilities with server config local capabilities = require("blink.cmp").get_lsp_capabilities() + -- ------------------------------------------------------------------------- -- Language server-specific settings + -- ------------------------------------------------------------------------- local servers = { lua_ls = { settings = { @@ -147,7 +146,9 @@ return { }, } - -- Extract server names and add formatters (tools, not LSPs) + -- ------------------------------------------------------------------------- + -- Extract server names and add formatters + -- ------------------------------------------------------------------------- local ensure_installed = vim.tbl_keys(servers or {}) vim.list_extend(ensure_installed, { "stylua", -- Lua formatter @@ -162,7 +163,9 @@ return { ensure_installed = ensure_installed, -- Auto-install tools }) + -- ------------------------------------------------------------------------- -- Auto-install LSPs and setup with lspconfig + -- ------------------------------------------------------------------------- require("mason-lspconfig").setup({ ensure_installed = {}, -- Empty: install all, not just listed servers automatic_installation = true, -- Auto-install on server attach @@ -182,19 +185,11 @@ return { }, }) - -- ========================================================================= + -- ------------------------------------------------------------------------- -- lspkind.nvim setup -- ------------------------------------------------------------------------- require("lspkind").init({ - - -- defines how annotations are shown - -- default: symbol - -- options: 'text', 'text_symbol', 'symbol_text', 'symbol' mode = "symbol_text", - - -- default symbol map - -- can be either 'default' (requires nerd-fonts font) or - -- 'codicons' for codicon preset (requires vscode-codicons font) preset = "default", }) end, diff --git a/lua/plugins/mini.lua b/lua/plugins/mini.lua index e6ac41a..3a26e8d 100644 --- a/lua/plugins/mini.lua +++ b/lua/plugins/mini.lua @@ -121,12 +121,12 @@ return { require("mini.bracketed").setup() require("mini.colors").setup() require("mini.icons").setup() - require("mini.surround").setup() - require("mini.operators").setup() require("mini.move").setup() + require("mini.operators").setup() require("mini.pairs").setup() require("mini.splitjoin").setup() require("mini.statusline").setup() + require("mini.surround").setup() require("mini.tabline").setup() require("mini.visits").setup() end, diff --git a/lua/plugins/snacks.lua b/lua/plugins/snacks.lua index f34bed1..99f32c0 100644 --- a/lua/plugins/snacks.lua +++ b/lua/plugins/snacks.lua @@ -20,9 +20,7 @@ return { -- OPTIONS CONFIGURATION -- --------------------------------------------------------------------------- opts = { - -- ========================================================================= -- Dashboard: Home screen on startup - -- ------------------------------------------------------------------------- dashboard = { enabled = true, preset = { header = dashboard.header }, @@ -30,17 +28,13 @@ return { formats = dashboard.formats, }, - -- ========================================================================= -- Picker: Fuzzy finder / file/buffer/grep picker - -- ------------------------------------------------------------------------- picker = { enabled = true, sources = { explorer = { enabled = false } }, }, - -- ========================================================================= -- Styles: Notification and UI styling - -- ------------------------------------------------------------------------- styles = { enabled = true, notification = { wo = { wrap = true } }, @@ -82,19 +76,14 @@ return { -- KEYMAPS -- --------------------------------------------------------------------------- keys = { - -- ========================================================================= - -- Top Level: Global navigation & utilities + -- ------------------------------------------------------------------------- + -- GLOBAL: Top-level navigation & utilities -- ------------------------------------------------------------------------- { "", function() Snacks.picker.smart() end, desc = "Smart Search", }, - { - "/", - function() Snacks.picker.grep() end, - desc = "Grep", - }, { ":", function() Snacks.picker.command_history() end, @@ -111,13 +100,13 @@ return { desc = "[T]erminal", }, - -- ========================================================================= - -- Buffer: Buffer operations + -- ------------------------------------------------------------------------- + -- BUFFER: Buffer operations -- ------------------------------------------------------------------------- { "bb", function() Snacks.picker.buffers() end, - desc = "Select [B]uffer", + desc = "[B]uffer", }, { "bg", @@ -127,7 +116,7 @@ return { { "bq", function() Snacks.bufdelete() end, - desc = "[Q]uit Buffer ", + desc = "[Q]uit Buffer", }, { "bS", @@ -135,8 +124,8 @@ return { desc = "[S]elect Scratch Buffer", }, - -- ========================================================================= - -- Find/File: File & project navigation + -- ------------------------------------------------------------------------- + -- FILE: File & project navigation -- ------------------------------------------------------------------------- { "ff", @@ -165,8 +154,8 @@ return { mode = { "n", "x" }, }, - -- ========================================================================= - -- Git: Git operations & GitHub integration + -- ------------------------------------------------------------------------- + -- GIT: Git operations & GitHub integration -- ------------------------------------------------------------------------- { "gb", @@ -176,7 +165,7 @@ return { { "gB", function() Snacks.gitbrowse() end, - desc = "Open [B]rowser", + desc = "[B]rowser", mode = { "n", "v" }, }, { @@ -187,12 +176,12 @@ return { { "gf", function() Snacks.picker.git_files() end, - desc = "Git [F]iles", + desc = "[F]iles", }, { "gF", function() Snacks.picker.git_log_file() end, - desc = "Git Log [F]ile", + desc = "Log [F]ile", }, { "gg", @@ -202,32 +191,32 @@ return { { "gi", function() Snacks.picker.gh_issue() end, - desc = "GitHub [I]ssues (open)", + desc = "[I]ssues (open)", }, { "gI", function() Snacks.picker.gh_issue({ state = "all" }) end, - desc = "GitHub [I]ssues (all)", + desc = "[I]ssues (all)", }, { "gl", function() Snacks.picker.git_log() end, - desc = "Git [L]og", + desc = "[L]og", }, { "gL", function() Snacks.picker.git_log_line() end, - desc = "Git Log [L]ine", + desc = "Log [L]ine", }, { "gp", function() Snacks.picker.gh_pr() end, - desc = "GitHub [P]ull Requests (open)", + desc = "[P]ull Requests (open)", }, { "gP", function() Snacks.picker.gh_pr({ state = "all" }) end, - desc = "GitHub [P]ull Requests (all)", + desc = "[P]ull Requests (all)", }, { "gs", @@ -240,8 +229,8 @@ return { desc = "[S]tash", }, - -- ========================================================================= - -- Help: Documentation & configuration + -- ------------------------------------------------------------------------- + -- HELP: Documentation & configuration -- ------------------------------------------------------------------------- { "ha", @@ -291,8 +280,8 @@ return { end, }, - -- ========================================================================= - -- Search: Search & inspection utilities + -- ------------------------------------------------------------------------- + -- SEARCH: Search & inspection utilities -- ------------------------------------------------------------------------- { "sc", @@ -309,6 +298,11 @@ return { function() Snacks.picker.diagnostics_buffer() end, desc = "Buffer [D]iagnostics", }, + { + "sg", + function() Snacks.picker.grep() end, + desc = "[G]rep", + }, { "sh", function() Snacks.picker.search_history() end, @@ -375,7 +369,7 @@ return { desc = "LSP Workspace [S]ymbols", }, - -- ========================================================================= + -- ------------------------------------------------------------------------- -- UI: Interface toggles & settings -- ------------------------------------------------------------------------- { @@ -394,8 +388,8 @@ return { desc = "[Z]oom", }, - -- ========================================================================= - -- Other: Navigation & reference jumping + -- ------------------------------------------------------------------------- + -- NAVIGATION: Navigation & reference jumping -- ------------------------------------------------------------------------- { "]]", @@ -415,8 +409,8 @@ return { desc = "[D]ashboard", }, - -- ========================================================================= - -- LSP: Language server operations + -- ------------------------------------------------------------------------- + -- LSP: Language server picker operations (definitions, references, etc.) -- ------------------------------------------------------------------------- { "gd", @@ -429,10 +423,9 @@ return { desc = "[D]eclaration", }, { - "gr", - function() Snacks.picker.lsp_references() end, - nowait = true, - desc = "[R]eferences", + "gi", + function() Snacks.picker.lsp_incoming_calls() end, + desc = "Calls [I]ncoming", }, { "gI", @@ -440,41 +433,46 @@ return { desc = "[I]mplementation", }, { - "gy", - function() Snacks.picker.lsp_type_definitions() end, - desc = "T[y]pe Definition", + "go", + function() Snacks.picker.lsp_outgoing_calls() end, + desc = "Calls [O]utgoing", }, { - "gi", - function() Snacks.picker.lsp_incoming_calls() end, - desc = "Calls [I]ncoming", + "gR", + function() Snacks.picker.lsp_references() end, + nowait = true, + desc = "[R]eferences", }, { - "go", - function() Snacks.picker.lsp_outgoing_calls() end, - desc = "Calls [O]utgoing", + "gy", + function() Snacks.picker.lsp_type_definitions() end, + desc = "T[y]pe Definition", }, { "cl", function() Snacks.picker.lsp_config() end, desc = "[L]sp Info", }, + + -- ------------------------------------------------------------------------- + -- LSP ACTIONS: LSP buffer operations + -- ------------------------------------------------------------------------- { "ca", vim.lsp.buf.code_action, - desc = "Code [A]ction", + desc = "[A]ction", mode = { "n", "x" }, }, { "cc", vim.lsp.codelens.run, - desc = "Run [C]odelens", + desc = "[C]odelens", mode = { "n", "x" }, }, { "cC", vim.lsp.codelens.refresh, - desc = "Refresh & Display [C]odelens", + desc = "Refresh [C]odelens", mode = { "n" }, }, { @@ -484,16 +482,14 @@ return { }, }, - -- =========================================================================== + -- --------------------------------------------------------------------------- -- INIT: Setup & configuration (runs at VeryLazy) -- --------------------------------------------------------------------------- init = function() vim.api.nvim_create_autocmd("User", { pattern = "VeryLazy", callback = function() - -- ===================================================================== -- Debug Utilities: Global functions for pretty debugging - -- --------------------------------------------------------------------- _G.dd = function(...) Snacks.debug.inspect(...) end _G.bt = function() Snacks.debug.backtrace() end @@ -504,10 +500,18 @@ return { vim.print = _G.dd end - -- ===================================================================== + -- --------------------------------------------------------------------- -- Toggle Mappings: Create toggles for UI features (with u) -- --------------------------------------------------------------------- Snacks.toggle.animate():map("ua") + Snacks.toggle.diagnostics({ name = "[D]iagnostics" }):map("ud") + Snacks.toggle.dim():map("uD", { desc = "Dim" }) + Snacks.toggle.indent():map("ug", { desc = "Indent Guides" }) + Snacks.toggle.line_number({ name = "[L]ine number" }):map("ul") + Snacks.toggle.inlay_hints({ name = "Inlay [H]ints" }):map("uh") + Snacks.toggle.option("spell", { name = "[S]pelling" }):map("us") + Snacks.toggle.scroll():map("uS") + Snacks.toggle.option("wrap", { name = "[W]rap" }):map("uw") Snacks.toggle .option("conceallevel", { @@ -517,27 +521,13 @@ return { }) :map("uc") - Snacks.toggle.diagnostics({ name = "[D]iagnostics" }):map("ud") - - Snacks.toggle.dim():map("uD", { desc = "Dim" }) - Snacks.toggle.indent():map("ug", { desc = "Indent Guides" }) - Snacks.toggle .option("relativenumber", { name = "Re[l]ative Number" }) :map("uL") - Snacks.toggle.line_number({ name = "[L]ine number" }):map("ul") - Snacks.toggle .treesitter({ name = "[T]reesitter Highlights" }) :map("uT") - - Snacks.toggle.inlay_hints({ name = "Inlay [H]ints" }):map("uh") - - Snacks.toggle.option("spell", { name = "[S]pelling" }):map("us") - - Snacks.toggle.scroll():map("uS") - Snacks.toggle.option("wrap", { name = "[W]rap" }):map("uw") end, }) end, diff --git a/lua/plugins/which-key.lua b/lua/plugins/which-key.lua index 9c210d5..e937683 100644 --- a/lua/plugins/which-key.lua +++ b/lua/plugins/which-key.lua @@ -9,7 +9,6 @@ -- KEYMAPS: ? to show all keymaps -- RELATED: lua/config/keymaps.lua, lua/config/options.lua (timeoutlen setting) -- ----------------------------------------------------------------------------- - return { "folke/which-key.nvim", event = "VeryLazy", @@ -18,7 +17,6 @@ return { preset = "helix", -- Use helix-style keybinding help UI delay = 0, defaults = {}, - -- Nerd Font icons for visual clarity icons = { breadcrumb = "󰯙 ", -- Active key combo breadcrumb separator = "", -- Key/label separator @@ -34,7 +32,9 @@ return { -- --------------------------------------------------------------------- { "?", - icon = "󱕴", -- Show keymaps + function() require("which-key").show({ global = true }) end, + desc = "Keymaps", + icon = "󱕴", }, { "e", @@ -47,7 +47,7 @@ return { }, { "/", - desc = "Grep", + desc = "Flash Search", icon = "󰍈", }, { @@ -74,6 +74,14 @@ return { group = "[TAB]", icon = "", }, + { + "q", + icon = "", + }, + { + "", + icon = "", + }, { "c", group = "[C]ode", @@ -135,11 +143,6 @@ return { group = "[G]oto", icon = "󱡮", }, - { - "gs", - group = "[S]urround", - icon = "󰟫", - }, { "z", group = "Fold", @@ -165,13 +168,6 @@ return { }, }, }, - keys = { - { - "?", - function() require("which-key").show({ global = false }) end, - desc = "Keymaps", - }, - }, config = function(_, opts) local wk = require("which-key") wk.setup(opts)