8000 GitHub - atomdmac/nvim-spectre: Find the enemy and replace them with dark power.
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

atomdmac/nvim-spectre

 
 

Repository files navigation

nvim-spectre

A search panel for neovim.

Spectre find the enemy and replace them with dark power.

demo

Why Use Spectre?

  • Use regex in search
  • It can filter search by path glob (filetype)
  • It only searches when you leave Insert Mode
  • Use one buffer and you can edit or move
  • A tool to replace text on project

Installation

Plug 'nvim-lua/plenary.nvim'
Plug 'nvim-pack/nvim-spectre'

You may also need to install the following:

MacOs

You may need run brew install gnu-sed.

Usage

vim.keymap.set('n', '<leader>S', '<cmd>lua require("spectre").toggle()<CR>', {
    desc = "Toggle Spectre"
})
vim.keymap.set('n', '<leader>sw', '<cmd>lua require("spectre").open_visual({select_word=true})<CR>', {
    desc = "Search current word"
})
vim.keymap.set('v', '<leader>sw', '<esc><cmd>lua require("spectre").open_visual()<CR>', {
    desc = "Search current word"
})
vim.keymap.set('n', '<leader>sp', '<cmd>lua require("spectre").open_file_search({select_word=true})<CR>', {
    desc = "Search on current file"
})

Use command: :Spectre

Warnings

  • Always commit your files before you replace text. nvim-spectre does not support undo directly.
  • Don't use your crazy vim skills to edit result text or UI or you may encounter strange behaviour.
  • You can use dd to toggle result items.
  • You need to use <Esc> not <C-c> to leave insert mode.

Regex Issues

  • The default regex uses vim's magic mode \v and no-ignore-case.
  • It has different regex syntax compared to the rg command and replace command sed so be careful when replacing text.
  • It has a different highlighting result because I use vim regex to highlight text so be careful but you can try to replace.
  • If possible, we recommend building and using rust oxi engine to replace.

Replace

You can replace groups with \0-9 similar to vim and sed, if you run a replace command and don't see the change you may need to reload file with :e because sed is replace outside vim.

Customization

require('spectre').setup()
Config Change any settings if you don't like them. **Don't just copy all** as settings may change as the plugin is updated so it may be better use the default settings.
require('spectre').setup({

  color_devicons = true,
  open_cmd = 'vnew',
  live_update = false, -- auto execute search again when you write to any file in vim
  line_sep_start = '┌-----------------------------------------',
  result_padding = '¦  ',
  line_sep       = '└-----------------------------------------',
  highlight = {
      ui = "String",
      search = "DiffChange",
      replace = "DiffDelete"
  },
  mapping={
    ['toggle_line'] = {
        map = "dd",
        cmd = "<cmd>lua require('spectre').toggle_line()<CR>",
        desc = "toggle item"
    },
    ['enter_file'] = {
        map = "<cr>",
        cmd = "<cmd>lua require('spectre.actions').select_entry()<CR>",
        desc = "open file"
    },
    ['send_to_qf'] = {
        map = "<leader>q",
        cmd = "<cmd>lua require('spectre.actions').send_to_qf()<CR>",
        desc = "send all items to quickfix"
    },
    ['replace_cmd'] = {
        map = "<leader>c",
        cmd = "<cmd>lua require('spectre.actions').replace_cmd()<CR>",
        desc = "input replace command"
    },
    ['show_option_menu'] = {
        map = "<leader>o",
        cmd = "<cmd>lua require('spectre').show_options()<CR>",
        desc = "show options"
    },
    ['run_current_replace'] = {
      map = "<leader>rc",
      cmd = "<cmd>lua require('spectre.actions').run_current_replace()<CR>",
      desc = "replace current line"
    },
    ['run_replace'] = {
        map = "<leader>R",
        cmd = "<cmd>lua require('spectre.actions').run_replace()<CR>",
        desc = "replace all"
    },
    ['change_view_mode'] = {
        map = "<leader>v",
        cmd = "<cmd>lua require('spectre').change_view()<CR>",
        desc = "change result view mode"
    },
    ['change_replace_sed'] = {
      map = "trs",
      cmd = "<cmd>lua require('spectre').change_engine_replace('sed')<CR>",
      desc = "use sed to replace"
    },
    ['change_replace_oxi'] = {
      map = "tro",
      cmd = "<cmd>lua require('spectre').change_engine_replace('oxi')<CR>",
      desc = "use oxi to replace"
    },
    ['toggle_live_update']={
      map = "tu",
      cmd = "<cmd>lua require('spectre').toggle_live_update()<CR>",
      desc = "update when vim writes to file"
    },
    ['toggle_ignore_case'] = {
      map = "ti",
      cmd = "<cmd>lua require('spectre').change_options('ignore-case')<CR>",
      desc = "toggle ignore case"
    },
    ['toggle_ignore_hidden'] = {
      map = "th",
      cmd = "<cmd>lua require('spectre').change_options('hidden')<CR>",
      desc = "toggle search hidden"
    },
    ['resume_last_search'] = {
      map = "<leader>l",
      cmd = "<cmd>lua require('spectre').resume_last_search()<CR>",
      desc = "repeat last search"
    },
    -- you can put your mapping here it only use normal mode
  },
  find_engine = {
    -- rg is map with finder_cmd
    ['rg'] = {
      cmd = "rg",
      -- default args
      args = {
        '--color=never',
        '--no-heading',
        '--with-filename',
        '--line-number',
        '--column',
      } ,
      options = {
        ['ignore-case'] = {
          value= "--ignore-case",
          icon="[I]",
          desc="ignore case"
        },
        ['hidden'] = {
          value="--hidden",
          desc="hidden file",
          icon="[H]"
        },
        -- you can put any rg search option you want here it can toggle with
        -- show_option function
      }
    },
    ['ag'] = {
      cmd = "ag",
      args = {
        '--vimgrep',
        '-s'
      } ,
      options = {
        ['ignore-case'] = {
          value= "-i",
          icon="[I]",
          desc="ignore case"
        },
        ['hidden'] = {
          value="--hidden",
          desc="hidden file",
          icon="[H]"
        },
      },
    },
  },
  replace_engine={
      ['sed']={
          cmd = "sed",
          args = nil,
          options = {
            ['ignore-case'] = {
              value= "--ignore-case",
              icon="[I]",
              desc="ignore case"
            },
          }
      },
      -- call rust code by nvim-oxi to replace
      ['oxi'] = {
        cmd = 'oxi',
        args = {},
        options = {
          ['ignore-case'] = {
            value = "i",
            icon = "[I]",
            desc = "ignore case"
          },
        }
      }
  },
  default = {
      find = {
          --pick one of item in find_engine
          cmd = "rg",
          options = {"ignore-case"}
      },
      replace={
          --pick one of item in replace_engine
          cmd = "sed"
      }
  },
  replace_vim_cmd = "cdo",
  is_open_target_win = true, --open file on opener window
  is_insert_mode = false,  -- start open panel on is_insert_mode
  is_block_ui_break = false -- mapping backspace and enter key to avoid ui break
  open_template      = {
    -- an template to use on open function
    -- see the 'custom function' section below to learn how to configure the template
    -- { search_text = 'text1', replace_text = '', path = "" }
  }
})

Custom Functions

-- if you want to get items from spectre panel you can use some of the
-- following functions to get data from spectre.
require('spectre.actions').get_current_entry()
require('spectre.actions').get_all_entries()
require('spectre.actions').get_state()

-- write your custom open function
require('spectre').open({
  is_insert_mode = true,
  cwd = "~/.config/nvim",
  search_text="test",
  replace_text="test",
  path="lua/**/*.lua",
  is_close = false, -- close an exists instance of spectre and open new
})
-- you can use all variables above on command line
-- for example: Spectre % is_insert_mode=true cwd=~/.config/nvim
-- in this example `%` will expand to current file.

Replace Method

There are two replace methods sed and oxi.

Sed oxi
group number by '\0' group number by '${0}'
use vim to highlight on UI use rust to highlight on UI
use sed to replace use rust to replace
run sed command call rust code directly by nvim-oxi

Install oxi:

  • you will need to install cargo and run the command: build.sh nvim-oxi

  • set default replace command to "oxi" on setup()

require('spectre').setup({
    default = {
        replace = {
            cmd = "oxi"
       }
    }
  )

Sponsors

Thanks to everyone who sponsors my projects and makes continued development and maintenance possible!

FAQ

  • How can I add a custom status line? windline
    require('windline').add_status(
        require('spectre.state_utils').status_line()
    )
  • How to avoid ui break?
require('spectre').setup({ is_block_ui_break = true })

Spectre hardcodes some mappings in order to work correctly. You can remap them as described above. You are allowed to create as many mappings as you want. F 5678 or name and description choose any value. 'map' and 'cmd' are the only important fields.

  • Is spectre compatible with the plugin mini.animate?

Yes, but only if you set opts = { open = { enable = false } } on mini.animate, otherwise it will cause serious issues preventing spectre from opening/closing.

  • Why is it called Spectre?

I wanted to call it Search Panel but this name is not cool. I got the name of a hero on a game. Spectre has a skill to find enemy on global map so I use it:)

About

Find the enemy and replace them with dark power.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • Lua 92.3%
  • Rust 6.8%
  • Other 0.9%
0