{"id":13411065,"url":"https://github.com/nvim-pack/nvim-spectre","last_synced_at":"2025-05-14T04:07:48.164Z","repository":{"id":37359781,"uuid":"352367984","full_name":"nvim-pack/nvim-spectre","owner":"nvim-pack","description":"Find the enemy and replace them with dark power.","archived":false,"fork":false,"pushed_at":"2025-05-13T02:51:44.000Z","size":7429,"stargazers_count":2216,"open_issues_count":12,"forks_count":76,"subscribers_count":6,"default_branch":"master","last_synced_at":"2025-05-13T03:32:39.790Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Lua","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/nvim-pack.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null},"funding":{"patreon":"windwp","custom":"https://www.buymeacoffee.com/wind.wp"}},"created_at":"2021-03-28T15:37:56.000Z","updated_at":"2025-05-13T02:51:48.000Z","dependencies_parsed_at":"2023-11-15T10:43:51.967Z","dependency_job_id":"2352c290-64ff-46be-9892-16f53060cca1","html_url":"https://github.com/nvim-pack/nvim-spectre","commit_stats":null,"previous_names":["windwp/nvim-spectre"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nvim-pack%2Fnvim-spectre","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nvim-pack%2Fnvim-spectre/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nvim-pack%2Fnvim-spectre/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nvim-pack%2Fnvim-spectre/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/nvim-pack","download_url":"https://codeload.github.com/nvim-pack/nvim-spectre/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254069446,"owners_count":22009556,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-07-30T20:01:11.176Z","updated_at":"2025-05-14T04:07:48.142Z","avatar_url":"https://github.com/nvim-pack.png","language":"Lua","readme":"# nvim-spectre\n\nA search panel for neovim.\n\n**Spectre** **find the enemy and replace them with dark power.**\n\n![demo](https://github.com/windwp/nvim-spectre/wiki/assets/demospectre.gif)\n\n## Why Use Spectre?\n\n- Use regex in search\n- It can filter search by path glob (filetype)\n- It only searches when you leave **Insert Mode**\n- Use one buffer and you can edit or move\n- A tool to replace text on project\n\n## Installation\n\n```lua\nPlug 'nvim-lua/plenary.nvim'\nPlug 'nvim-pack/nvim-spectre'\n```\n\nYou may also need to install the following:\n\n- [BurntSushi/ripgrep](https://github.com/BurntSushi/ripgrep) (finder)\n- [devicons](https://github.com/kyazdani42/nvim-web-devicons) or [mini.icons](https://github.com/echasnovski/mini.nvim/blob/main/readmes/mini-icons.md) (icons)\n- [sed](https://www.gnu.org/software/sed/) (replace tool)\n- [trouble.nvim](https://github.com/folke/trouble.nvim) (improved quickfix list)\n\n### MacOs\n\nYou may need run `brew install gnu-sed`.\n\n## Usage\n\n```lua\nvim.keymap.set('n', '\u003cleader\u003eS', '\u003ccmd\u003elua require(\"spectre\").toggle()\u003cCR\u003e', {\n    desc = \"Toggle Spectre\"\n})\nvim.keymap.set('n', '\u003cleader\u003esw', '\u003ccmd\u003elua require(\"spectre\").open_visual({select_word=true})\u003cCR\u003e', {\n    desc = \"Search current word\"\n})\nvim.keymap.set('v', '\u003cleader\u003esw', '\u003cesc\u003e\u003ccmd\u003elua require(\"spectre\").open_visual()\u003cCR\u003e', {\n    desc = \"Search current word\"\n})\nvim.keymap.set('n', '\u003cleader\u003esp', '\u003ccmd\u003elua require(\"spectre\").open_file_search({select_word=true})\u003cCR\u003e', {\n    desc = \"Search on current file\"\n})\n```\n\nUse command: `:Spectre`\n\n## Warnings\n\n- Always commit your files before you replace text. `nvim-spectre`\n  does not support undo directly.\n- Don't use your crazy vim skills to edit result text or UI or you may\n  encounter strange behaviour.\n- You can use `dd` to toggle result items.\n- You need to use `\u003cEsc\u003e` not `\u003cC-c\u003e` to leave insert mode.\n\n## Regex Issues\n\n- The default regex uses vim's **magic mode** `\\v` and **no-ignore-case**.\n- It has different regex syntax compared to the `rg` command and\n  replace command `sed` so be careful when replacing text.\n- It has a different highlighting result because I use vim regex to\n  highlight text so be careful but you can try to replace.\n- If possible, we recommend building and using rust oxi engine to replace.\n\n## Replace\n\nYou can replace groups with `\\0-9` similar to vim and sed, if you run\na replace command and don't see the change you may need to reload file\nwith `:e` because `sed` is replace outside vim.\n\n## Customization\n\n```lua\nrequire('spectre').setup()\n```\n\n\u003cdetails\u003e\n  \u003csummary\u003eConfig\u003c/summary\u003e\n Change any settings if you don't like them. **Don't just copy all** as\nsettings may change as the plugin is updated so it may be better use\nthe default settings.\n\n```lua\nrequire('spectre').setup({\n\n  color_devicons = true,\n  open_cmd = 'vnew', -- can also be a lua function\n  live_update = false, -- auto execute search again when you write to any file in vim\n  lnum_for_results = true, -- show line number for search/replace results\n  line_sep_start = '┌-----------------------------------------',\n  result_padding = '¦  ',\n  line_sep       = '└-----------------------------------------',\n  highlight = {\n      ui = \"String\",\n      search = \"DiffChange\",\n      replace = \"DiffDelete\"\n  },\n  mapping={\n    ['tab'] = {\n        map = '\u003cTab\u003e',\n        cmd = \"\u003ccmd\u003elua require('spectre').tab()\u003ccr\u003e\",\n        desc = 'next query'\n    },\n    ['shift-tab'] = {\n        map = '\u003cS-Tab\u003e',\n        cmd = \"\u003ccmd\u003elua require('spectre').tab_shift()\u003ccr\u003e\",\n        desc = 'previous query'\n    },\n    ['toggle_line'] = {\n        map = \"dd\",\n        cmd = \"\u003ccmd\u003elua require('spectre').toggle_line()\u003cCR\u003e\",\n        desc = \"toggle item\"\n    },\n    ['enter_file'] = {\n        map = \"\u003ccr\u003e\",\n        cmd = \"\u003ccmd\u003elua require('spectre.actions').select_entry()\u003cCR\u003e\",\n        desc = \"open file\"\n    },\n    ['send_to_qf'] = {\n        map = \"\u003cleader\u003eq\",\n        cmd = \"\u003ccmd\u003elua require('spectre.actions').send_to_qf()\u003cCR\u003e\",\n        desc = \"send all items to quickfix\"\n    },\n    ['replace_cmd'] = {\n        map = \"\u003cleader\u003ec\",\n        cmd = \"\u003ccmd\u003elua require('spectre.actions').replace_cmd()\u003cCR\u003e\",\n        desc = \"input replace command\"\n    },\n    ['show_option_menu'] = {\n        map = \"\u003cleader\u003eo\",\n        cmd = \"\u003ccmd\u003elua require('spectre').show_options()\u003cCR\u003e\",\n        desc = \"show options\"\n    },\n    ['run_current_replace'] = {\n      map = \"\u003cleader\u003erc\",\n      cmd = \"\u003ccmd\u003elua require('spectre.actions').run_current_replace()\u003cCR\u003e\",\n      desc = \"replace current line\"\n    },\n    ['run_replace'] = {\n        map = \"\u003cleader\u003eR\",\n        cmd = \"\u003ccmd\u003elua require('spectre.actions').run_replace()\u003cCR\u003e\",\n        desc = \"replace all\"\n    },\n    ['change_view_mode'] = {\n        map = \"\u003cleader\u003ev\",\n        cmd = \"\u003ccmd\u003elua require('spectre').change_view()\u003cCR\u003e\",\n        desc = \"change result view mode\"\n    },\n    ['change_replace_sed'] = {\n      map = \"trs\",\n      cmd = \"\u003ccmd\u003elua require('spectre').change_engine_replace('sed')\u003cCR\u003e\",\n      desc = \"use sed to replace\"\n    },\n    ['change_replace_oxi'] = {\n      map = \"tro\",\n      cmd = \"\u003ccmd\u003elua require('spectre').change_engine_replace('oxi')\u003cCR\u003e\",\n      desc = \"use oxi to replace\"\n    },\n    ['toggle_live_update']={\n      map = \"tu\",\n      cmd = \"\u003ccmd\u003elua require('spectre').toggle_live_update()\u003cCR\u003e\",\n      desc = \"update when vim writes to file\"\n    },\n    ['toggle_ignore_case'] = {\n      map = \"ti\",\n      cmd = \"\u003ccmd\u003elua require('spectre').change_options('ignore-case')\u003cCR\u003e\",\n      desc = \"toggle ignore case\"\n    },\n    ['toggle_ignore_hidden'] = {\n      map = \"th\",\n      cmd = \"\u003ccmd\u003elua require('spectre').change_options('hidden')\u003cCR\u003e\",\n      desc = \"toggle search hidden\"\n    },\n    ['resume_last_search'] = {\n      map = \"\u003cleader\u003el\",\n      cmd = \"\u003ccmd\u003elua require('spectre').resume_last_search()\u003cCR\u003e\",\n      desc = \"repeat last search\"\n    },\n    ['select_template'] = {\n        map = '\u003cleader\u003erp',\n        cmd = \"\u003ccmd\u003elua require('spectre.actions').select_template()\u003cCR\u003e\",\n        desc = 'pick template',\n    },\n    ['delete_line'] = {\n        map = '\u003cleader\u003erd',\n        cmd = \"\u003ccmd\u003elua require('spectre.actions').run_delete_line()\u003cCR\u003e\",\n        desc = 'delete line',\n    }\n    -- you can put your mapping here it only use normal mode\n  },\n  find_engine = {\n    -- rg is map with finder_cmd\n    ['rg'] = {\n      cmd = \"rg\",\n      -- default args\n      args = {\n        '--color=never',\n        '--no-heading',\n        '--with-filename',\n        '--line-number',\n        '--column',\n      },\n      options = {\n        ['ignore-case'] = {\n          value= \"--ignore-case\",\n          icon=\"[I]\",\n          desc=\"ignore case\"\n        },\n        ['hidden'] = {\n          value=\"--hidden\",\n          desc=\"hidden file\",\n          icon=\"[H]\"\n        },\n        -- you can put any rg search option you want here it can toggle with\n        -- show_option function\n      }\n    },\n    ['ag'] = {\n      cmd = \"ag\",\n      args = {\n        '--vimgrep',\n        '-s'\n      } ,\n      options = {\n        ['ignore-case'] = {\n          value= \"-i\",\n          icon=\"[I]\",\n          desc=\"ignore case\"\n        },\n        ['hidden'] = {\n          value=\"--hidden\",\n          desc=\"hidden file\",\n          icon=\"[H]\"\n        },\n      },\n    },\n  },\n  replace_engine={\n      ['sed']={\n          cmd = \"sed\",\n          args = nil,\n          options = {\n            ['ignore-case'] = {\n              value= \"--ignore-case\",\n              icon=\"[I]\",\n              desc=\"ignore case\"\n            },\n          }\n      },\n      -- call rust code by nvim-oxi to replace\n      ['oxi'] = {\n        cmd = 'oxi',\n        args = {},\n        options = {\n          ['ignore-case'] = {\n            value = \"i\",\n            icon = \"[I]\",\n            desc = \"ignore case\"\n          },\n        }\n      },\n      ['sd'] = {\n        cmd = \"sd\",\n        options = { },\n      },\n  },\n  default = {\n      find = {\n          --pick one of item in find_engine\n          cmd = \"rg\",\n          options = {\"ignore-case\"}\n      },\n      replace={\n          --pick one of item in replace_engine\n          cmd = \"sed\"\n      }\n  },\n  replace_vim_cmd = \"cdo\",\n  use_trouble_qf = false, -- use trouble.nvim as quickfix list\n  is_open_target_win = true, --open file on opener window\n  is_insert_mode = false,  -- start open panel on is_insert_mode\n  is_block_ui_break = false -- mapping backspace and enter key to avoid ui break\n  open_template      = {\n    -- an template to use on open function\n    -- see the 'custom function' section below to learn how to configure the template\n    -- { search_text = 'text1', replace_text = '', path = \"\" }\n  }\n})\n\n```\n\n\u003c/details\u003e\n\n### Custom Functions\n\n```lua\n-- if you want to get items from spectre panel you can use some of the\n-- following functions to get data from spectre.\nrequire('spectre.actions').get_current_entry()\nrequire('spectre.actions').get_all_entries()\nrequire('spectre.actions').get_state()\n\n-- write your custom open function\nrequire('spectre').open({\n  is_insert_mode = true,\n  -- the directory where the search tool will be started in\n  cwd = \"~/.config/nvim\",\n  search_text=\"test\",\n  replace_text=\"test\",\n  -- the pattern of files to consider for searching\n  path=\"lua/**/*.lua\",\n  -- the directories or files to search in\n  search_paths = {\"lua/\", \"plugin/\"},\n  is_close = false, -- close an exists instance of spectre and open new\n})\n-- you can use all variables above on command line\n-- for example: Spectre % is_insert_mode=true cwd=~/.config/nvim\n-- in this example `%` will expand to current file.\n```\n\n### Search paths\n\nBy default, searching is performed in the current working directory, which can\nalso be customized using the `cwd` option in the example above.\n\nThe `path` option limits the search only to the files matching the provided\npattern. Note, however, that even if you provide the `path`, all files in the\n`cwd` still need to be listed, and this could be quite slow if `cwd` is a large\ndirectory.\n\nTo limit the search paths further, you can also provide the `search_paths`\noption. This is the list of directories or files to search in, regardless of the\n`cwd`.\n\n## Replace Method\n\nThere are three replace methods `sed`, `oxi` and `sd`.\n\n| Sed                        | oxi                                 |\n| -------------------------- | ----------------------------------- |\n| group number by '\\0'       | group number by '${0}'              |\n| use vim to highlight on UI | use rust to highlight on UI         |\n| use sed to replace         | use rust to replace                 |\n| run sed command            | call rust code directly by nvim-oxi |\n\nInstall `oxi`:\n\n- you will need to install `cargo` and run the command:\n  [build.sh](./build.sh)\n  [nvim-oxi](https://github.com/noib3/nvim-oxi)\n\n- set default replace command to `\"oxi\"` on `setup()`\n\n```lua\nrequire('spectre').setup({\n    default = {\n        replace = {\n            cmd = \"oxi\"\n       }\n    }\n})\n```\n\n## Sponsors\n\nThanks to everyone who sponsors my projects and makes continued development and maintenance possible!\n\n\u003c!-- patreon --\u003e\u003ca href=\"https://github.com/t4t5\"\u003e\u003cimg src=\"https://github.com/t4t5.png\" width=\"60px\" alt=\"\" /\u003e\u003c/a\u003e\u003c!-- patreon--\u003e\n\n## FAQ\n\n- How can I add a custom status line? [windline](https://github.com/windwp/windline.nvim)\n\n```lua\n    require('windline').add_status(\n        require('spectre.state_utils').status_line()\n    )\n```\n\n- How to avoid ui break?\n\n```lua\nrequire('spectre').setup({ is_block_ui_break = true })\n```\n\n\u003e [Spectre hardcodes some mappings in order to work correctly](https://github.com/nvim-pack/nvim-spectre/blob/1abe23ec9b7bc3082164f4cb842d521ef70e080e/lua/spectre/init.lua#L175). You can remap them as described above. You are allowed to create as many mappings as you want. For name and description choose any value. 'map' and 'cmd' are the only important fields.\n\n- Is spectre compatible with the plugin mini.animate?\n\n\u003e Yes, but only if you set `opts = { open = { enable = false } }` on `mini.animate`, otherwise it will cause serious issues preventing spectre from opening/closing.\n\n- Why is it called Spectre?\n\nI wanted to call it `Search Panel` but this name is not cool.\nI got the name of a hero on a game.\nSpectre has a skill to find enemy on global map so I use it:)\n","funding_links":["https://patreon.com/windwp","https://www.buymeacoffee.com/wind.wp"],"categories":["Search","Lua"],"sub_categories":["Markdown and LaTeX","Assembly"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnvim-pack%2Fnvim-spectre","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnvim-pack%2Fnvim-spectre","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnvim-pack%2Fnvim-spectre/lists"}