grug-far.nvim

repository·main·Indexed 24 days ago

https://github.com/magicduck/grug-far.nvim

A Find and Replace plugin for Neovim that leverages ripgrep (rg) and ast-grep. It provides an interactive UI for searching and replacing text, supporting features like debounced searching, diff previews, interpreted script replacements via Lua or Vimscript, and search history management. It includes support for multiple search engines (ripgrep, astgrep, astgrep-rules) and provides a Lua API for programmatic control.

Tokens
1.9K
Snippets
4
Records
11
Agent score
34%

What's inside grug-far.nvim

  1. Replace matches using an interpreted script

    main

    For complex replacements, you can use the Swap Replacement Interpreter action to switch to a script engine like lua or vimscript. This allows you to write logic that executes for every match.

    Lua Interpreter:

    • Write the body of a Lua function in the Replace: input.
    • Use the match variable to refer to the current match.
    • You must return the value intended as the replacement.
    • astgrep engine users: You can access meta variables via the vars table (e.g., $A is vars.A, $$$ARGS is vars.ARGS).
  2. Manage search history

    main

    grug-far tracks search history. You can manually add entries via History Add or automatically via successful Replace or Sync All actions.

    To reuse a search, use the History Open action to open the history as a buffer, then select an entry.

    History Entry Format:

    <optional comment>
    Engine: <astgrep|astgrep-rules|ripgrep>(|lua)?
    Search: <text>
    Replace: <text>
    Files Filter: <text>
    Flags: <text>

    Entries can span multiple lines using the | continuation prefix.

  3. Sync result lines back to originating files

    main

    You can sync text from the grug-far results buffer back to the source files. This is useful for free-form editing of results before applying them.

    Note: Syncing is only supported by the ripgrep engine and is disabled when using the --multiline flag.

    Available Actions:

    1. Sync Line: Syncs the current line.
    2. Sync All: Syncs all lines that have changed compared to the source.
    3. Apply Next/Apply Prev: Syncs the current line/diff and removes it from the results buffer.

    Behavioral Notes:

    • A sync only occurs if the line has changed (via replacement or manual edit).
    • Deleting a result line excludes it from Sync All.
    • To enable sync for empty string replacements, add the --replace= flag.
  4. Open and edit grug-far.nvim buffers

    main

    Use the :GrugFar command to open a new vertical split buffer for searching and replacing.

    • Visual Mode: If you run the command while in visual mode, the search string will be pre-filled with your selection.
    • Search within selection: To restrict the search and replace operation to the current visual selection range, use the :GrugFarWithin command instead.
    • Editing: The search interface is a standard buffer. You can edit it freely, and the UI is designed to recover gracefully from common buffer operations like ggVGd (delete all lines).
    :GrugFar
  5. Install grug-far.nvim using lazy.nvim

    main

    You can install grug-far.nvim using the lazy.nvim package manager. The plugin is lazy-loaded by default because it defers its requirements. You can optionally call .setup() to override default options or set them via the vim.g.grug_far global variable.

    Important: Ensure you have your <localleader> configured, as grug-far.nvim uses it for buffer-local keymaps.

      {
        'MagicDuck/grug-far.nvim',
        -- Note (lazy loading): grug-far.lua defers all it's requires so it's lazy by default
        -- additional lazy config to defer loading is not really needed...
        config = function()
          -- optional setup call to override plugin options
          -- alternatively you can set options with vim.g.grug_far = { ... }
          require('grug-far').setup({
            -- options, see Configuration section below
            -- there are no required options atm
          });
        end
      },
  6. Check requirements for grug-far.nvim

    main

    Before using grug-far.nvim, ensure your environment meets the following requirements:

    • Neovim: >= 0.11.0 (Note: Use tag 1.6.3 if you are on Neovim 0.10)
    • ripgrep: >= 14 (version 15 or higher is recommended)
    • ast-grep (Optional): Required if you want to use the ast-grep search engine. Version >= 0.36 is recommended.
    • Nerd Font (Optional): Recommended for icon support.
    • Icon Support (Optional): Either nvim-web-devicons or mini.icons for file icons.

    If you encounter issues, run :checkhealth grug-far to diagnose.

  7. Search and replace with grug-far.nvim

    main

    Searching is debounced and happens as you type.

    • Previewing: If you provide a replacement string, a diff will be shown in the results.
    • Executing Replacement: To apply the changes, invoke the Replace action (default keybind: <localleader>r).
    • Empty String Replacement: When replacing matches with an empty string, you will be prompted for confirmation. To see the replacement in the results area, add the --replace= flag.
    • Filtering: Use the Paths input to target specific files or directories. Supported path formats include relative/absolute paths, ~, environment variables, and path providers.

    Path Providers:

    • <buflist>: Files in currently opened buffers.
    • <buflist-cwd>: Files in opened buffers that are also in the current working directory.
    • <qflist>: Files in the quickfix list.
  8. Navigate and preview search results

    main

    Navigate through search results using the following actions:

    • Goto: Press <enter> on a file path to open the file, or on a match line to jump to the specific file/line/column. (Default keybind: Goto).
    • Open: Similar to Goto, but keeps your cursor in the grug-far buffer.
    • Open Next/Prev: Use <down> and <up> to open result locations in sequence.
    • Preview: Opens the result location in a floating window to keep your current buffer layout.

    Pro-tip: You can provide a <count> before these commands to jump to a specific result line number. Enable resultLocation.showNumberLabel = true to see these numbers in the UI.

  9. Fix RPC[Error] with copilot.nvim

    main

    If you encounter RPC[Error] ... Document for URI could not be found errors involving grug-far URIs, it is likely caused by a conflict with copilot.nvim. To resolve this, exclude the grug-far related filetypes in your copilot.nvim configuration.

    filetypes = {
      ["grug-far"] = false,
      ["grug-far-history"] = false,
      ["grug-far-help"] = false,
    }
  10. Configure grug-far via Lua API

    main

    You can programmatically control grug-far using the require('grug-far') API. Common patterns include:

    Launch with specific pre-fills:

    require('grug-far').open({ prefills = { search = 'my_query' } })

    Launch with ast-grep engine:

    require('grug-far').open({ engine = 'astgrep' })

    Launch as a transient buffer (unlisted, auto-deletes on close):

    require('grug-far').open({ transient = true })

    Run a command before editing files (Hooks):

    require('grug-far').open({ hooks = {
      on_before_edit_file = function(on_finish, file) 
        return require('grug-far').spawn_cmd_async({
          cmd_path = 'p4',
          args = { 'edit', file.path },
          on_finish = on_finish,
        })
      end,
    }})
    require('grug-far').open({ prefills = { search = vim.fn.expand("<cword>") } })