|
| 1 | +<!-- markdownlint-disable MD013 --> |
| 2 | + |
| 3 | +# CLAUDE.md |
| 4 | + |
| 5 | +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. |
| 6 | + |
| 7 | +## Project Overview |
| 8 | + |
| 9 | +search-replace.nvim is a Neovim plugin for enhanced search and replace with a floating dashboard. It provides quick keymaps to populate substitute commands, toggle flags (g/c/i), cycle through ranges/separators/magic modes, and shows a live dashboard during command-line editing. |
| 10 | + |
| 11 | +## Commands |
| 12 | + |
| 13 | +### Linting |
| 14 | + |
| 15 | +```bash |
| 16 | +luacheck lua/ --globals vim |
| 17 | +stylua --check lua/ |
| 18 | +``` |
| 19 | + |
| 20 | +### Formatting |
| 21 | + |
| 22 | +```bash |
| 23 | +stylua lua/ |
| 24 | +``` |
| 25 | + |
| 26 | +### Testing |
| 27 | + |
| 28 | +```bash |
| 29 | +# Run all tests (requires busted test framework) |
| 30 | +busted tests/ |
| 31 | + |
| 32 | +# Run a specific test file |
| 33 | +busted tests/search-replace_spec.lua |
| 34 | +``` |
| 35 | + |
| 36 | +## Architecture |
| 37 | + |
| 38 | +The plugin follows a modular architecture with four main components: |
| 39 | + |
| 40 | +### init.lua (Entry Point) |
| 41 | + |
| 42 | +- Handles `setup()` configuration merging |
| 43 | +- Sets up keymaps for normal/visual/command-line modes |
| 44 | +- Re-exports public API from core module |
| 45 | + |
| 46 | +### core.lua (Business Logic) |
| 47 | + |
| 48 | +- Manages search-replace state (`sar_state`) tracking active session, current word, separator, magic mode |
| 49 | +- Implements toggle functions that return keystroke sequences using `<C-\>e` expression pattern |
| 50 | +- All toggle functions use `set_cmd_and_pos()` helper to update both command text and cursor position atomically |
| 51 | +- Uses `should_sar()` to detect if current cmdline is a substitute command (either in active mode or auto-detected) |
| 52 | + |
| 53 | +### dashboard.lua (UI) |
| 54 | + |
| 55 | +- Parses substitute commands and displays current state in a floating window |
| 56 | +- Uses `CmdlineChanged` autocmd to auto-detect and display dashboard for any substitute command |
| 57 | +- Maintains a `hidden` state to respect user's manual toggle |
| 58 | +- Applies syntax highlighting using extmarks in a namespace |
| 59 | + |
| 60 | +### float.lua (Window Management) |
| 61 | + |
| 62 | +- Reusable floating window implementation inspired by mini.notify architecture |
| 63 | +- Handles buffer/window caching, creation, and cleanup |
| 64 | +- Uses `vim.cmd('redraw')` after updates for immediate display |
| 65 | +- Reschedules operations via `vim.schedule()` when in fast event context |
| 66 | + |
| 67 | +### utils.lua (Shared Utilities) |
| 68 | + |
| 69 | +- Pattern constants for substitute command detection |
| 70 | +- `parse_substitute_cmd()` - parses `:s` commands into range/separator/magic/search/replace/flags |
| 71 | +- `split_by_separator()` - splits strings while respecting escaped separators |
| 72 | +- `trigger_cmdline_refresh()` - uses fake keystroke (space + backspace) to force cmdline refresh |
| 73 | + |
| 74 | +## Key Implementation Details |
| 75 | + |
| 76 | +- Toggle functions return expression strings that Neovim evaluates (using `{ expr = true }` in keymap) |
| 77 | +- The `<C-\>e` pattern allows replacing the entire command line via expression evaluation |
| 78 | +- Dashboard refresh uses a fake keystroke technique because direct redraws don't work in cmdline mode |
| 79 | +- The plugin auto-detects any substitute command (not just those started via `<leader>r`) to show the dashboard |
| 80 | + |
| 81 | +## Code Style |
| 82 | + |
| 83 | +- Uses 2-space indentation |
| 84 | +- Single quotes preferred |
| 85 | +- Max line length: 120 characters |
| 86 | +- LuaDoc annotations for type hints (`---@class`, `---@param`, `---@return`) |
0 commit comments