https://github.com/chrisgrieser/nvim-rip-substitute
Search and replace in the current buffer with incremental preview, a convenient UI, and modern regex syntax.
Science Score: 36.0%
This score indicates how likely this project is to be science-related based on various indicators:
-
○CITATION.cff file
-
✓codemeta.json file
Found codemeta.json file -
✓.zenodo.json file
Found .zenodo.json file -
○DOI references
-
✓Academic publication links
Links to: researchgate.net -
○Committers with academic emails
-
○Institutional organization owner
-
○JOSS paper metadata
-
○Scientific vocabulary similarity
Low similarity (10.0%) to scientific vocabulary
Keywords
Keywords from Contributors
Repository
Search and replace in the current buffer with incremental preview, a convenient UI, and modern regex syntax.
Basic Info
Statistics
- Stars: 274
- Watchers: 2
- Forks: 13
- Open Issues: 2
- Releases: 0
Topics
Metadata Files
README.md
rip-substitute 🪦
Search and replace in the current buffer with incremental preview, a convenient UI, and modern regex syntax.
Table of Contents
Features
- Search and replace in the current buffer using ripgrep.
- Uses common regex syntax — no more dealing with arcane vim regex.
- Incremental preview of matched strings and replacements & live count of matches.
- Popup window instead of command line. This entails:
- Syntax highlighting of the regex.
- Editing with vim motions.
- No more dealing with delimiters.
- Sensible defaults: entire buffer (
%), all matches in a line (/g), case-sensitive (/I). - Can substitute only in a range, with visual emphasis of the range
- History of previous substitutions.
- Performant: In a file with 5000 lines and thousands of matches, still performs blazingly fast.™
- Regex101 integration: Open the planned substitution in a pre-configured regex101 browser tab for debugging.
- Quality-of-Life features: automatic prefill of the escaped cursorword,
adaptive popup window width, toggle
ripgrepflags, … - Syntax comparison:
```txt
all three are equivalent
vim's :substitute
:% s/(foo)bar(.)\@!/\1baz/gI
vim's :substitute (very magic mode)
:% s/\v(foo)bar(.)@!/\1baz/gI
rip-substitute
(foo)bar(?!.) $1baz ```
Installation
Requirements
- nvim 0.10+
- ripgrep with pcre2 support
+ brew install ripgrep (already includes pcre2 by default)
+ cargo install ripgrep --features pcre2
- Alternatively, you can also use this plugin without pcre2 by setting
regexOptions.pcre2 = false in the config. However, some features like
lookaheads are not supported then.
- Optional: :TSInstall regex to add syntax highlighting in the popup window
```lua
-- lazy.nvim
{
"chrisgrieser/nvim-rip-substitute",
cmd = "RipSubstitute",
opts = {},
keys = {
{
"
-- packer use { "chrisgrieser/nvim-rip-substitute", config = function() require("rip-substitute").setup() end, } ```
Configuration
lua
-- default settings
require("rip-substitute").setup {
popupWin = {
title = " rip-substitute",
border = getBorder(), -- `vim.o.winborder` on nvim 0.11, otherwise "rounded"
matchCountHlGroup = "Keyword",
noMatchHlGroup = "ErrorMsg",
position = "bottom", ---@type "top"|"bottom"
hideSearchReplaceLabels = false,
hideKeymapHints = false,
disableCompletions = true, -- disables all blink.cmp completions
},
prefill = {
normal = "cursorWord", ---@type "cursorWord"|false
visual = "selection", ---@type "selection"|false (does not work with ex-command – see README)
startInReplaceLineIfPrefill = false,
alsoPrefillReplaceLine = false,
},
keymaps = { -- normal mode (if not stated otherwise)
abort = "q",
confirm = "<CR>",
insertModeConfirm = "<C-CR>",
prevSubstitutionInHistory = "<Up>",
nextSubstitutionInHistory = "<Down>",
toggleFixedStrings = "<C-f>", -- ripgrep's `--fixed-strings`
toggleIgnoreCase = "<C-c>", -- ripgrep's `--ignore-case`
openAtRegex101 = "R",
showHelp = "?",
},
incrementalPreview = {
matchHlGroup = "IncSearch",
rangeBackdrop = {
enabled = true,
blend = 50, -- between 0 and 100
},
},
regexOptions = {
startWithFixedStringsOn = false,
startWithIgnoreCase = false,
pcre2 = true, -- enables lookarounds and backreferences, but slightly slower
autoBraceSimpleCaptureGroups = true, -- disable if using named capture groups (see README for details)
},
editingBehavior = {
-- Typing `()` in the `search` line, automatically adds `$n` to the `replace` line.
autoCaptureGroups = false,
},
notification = {
onSuccess = true,
icon = "",
},
debug = false, -- extra notifications for debugging
}
[!NOTE] A
ripgrepconfig file set viaRIPGREP_CONFIG_PATHis ignored by this plugin.
Usage
lua function
lua
vim.keymap.set(
{ "n", "x" },
"<leader>fs",
function() require("rip-substitute").sub() end,
{ desc = " rip substitute" }
)
- Normal mode: prefills the word under the cursor (escaped)
- Visual mode: prefills the selection (escaped)
- Visual line mode: replacements are only applied to the selected lines (= the selection is used as range)
[!TIP] Use
showHelp(default keymap:?) to show a notification containing all keymaps available in the popup window.
Ex-command
Alternatively, you can use the ex command :RipSubstitute, which also
accepts a range
argument.
Note that when using the ex-command, visual mode and visual line mode both pass a range. To prefill the current selection, you therefore need to use the lua function.
```vim " Substitute in entire file. Prefills the escaped word under the cursor. :RipSubstitute
" Substitute in line range of the visual selection. :'<,'>RipSubstitute
" Substitute in given range (in this case: current line to end of file). :.,$ RipSubstitute ```
You can also pass a prefill for the search value, in which case the prefill is not escaped.
vim
:RipSubstitute prefilled_unescaped_string
Advanced
Remember prefill
The function require("rip-substitute").rememberCursorWord() can be used to
save the word under the cursor for the next time rip-substitute is called.
(This overrides any other prefill for that run.)
One use case for this is to set a prefill for when you intend to run substitute
with a range, since calling rip-substitute in visual line is not able to pick
up a prefill.
Filetype
The popup window uses the filetype rip-substitute. This can be useful, for
instance, to disable auto-pairing plugins in the popup window.
autoBraceSimpleCaptureGroups
A gotcha of ripgrep's regex syntax is that it treats $1a as the named
capture group "1a" and not as the first capture group followed by the
letter "a" (see ripgrep's man page on --replace for details).
If regexOptions.autoBraceSimpleCaptureGroups = true (the default),
rip-substitute automatically changes $1a to ${1}a, to make writing the
regex more intuitive. However, if you regularly use named capture groups, you
may want to disable this setting.
Escape character
If your substitution text contains a dollar sign, for example, if you want
/home/user to be replaced with $HOME, remember that ripgrep requires $
as an escape sequence. In short, you'll need to set $$HOME as substitution text.
Limitations
- Searching/replacing for line breaks (
\nor\r) is not supported. See issue #28. - This plugin only searches the current buffer. To search and replace in
multiple files via
ripgrep, use a plugin like grug-far.nvim.
About the developer
In my day job, I am a sociologist studying the social mechanisms underlying the digital economy. For my PhD project, I investigate the governance of the app economy and how software ecosystems manage the tension between innovation and compatibility. If you are interested in this subject, feel free to get in touch.
Owner
- Name: Chris Grieser
- Login: chrisgrieser
- Kind: user
- Location: Berlin, Germany
- Company: Technical University of Berlin
- Website: https://chris-grieser.de/
- Repositories: 189
- Profile: https://github.com/chrisgrieser
Researcher in sociology & software developer
GitHub Events
Total
- Issues event: 23
- Watch event: 87
- Delete event: 4
- Issue comment event: 24
- Push event: 83
- Pull request event: 13
- Fork event: 8
- Create event: 6
Last Year
- Issues event: 23
- Watch event: 87
- Delete event: 4
- Issue comment event: 24
- Push event: 83
- Pull request event: 13
- Fork event: 8
- Create event: 6
Committers
Last synced: 9 months ago
Top Committers
| Name | Commits | |
|---|---|---|
| Chris Grieser | 7****r | 311 |
| sid-6581 | s****1@g****m | 2 |
| Ajay Mamtora | 4****a | 2 |
| qw457812 | 3****2 | 1 |
| dependabot[bot] | 4****] | 1 |
| Lvim Tech | 8****h | 1 |
| Artur Taranchiev | g****b@i****l | 1 |
| Ajay Mamtora | A****a@m****k | 1 |
| Stephane Pluchart | s****t@q****o | 1 |
Committer Domains (Top 20 + Academic)
Issues and Pull Requests
Last synced: 6 months ago
All Time
- Total issues: 30
- Total pull requests: 19
- Average time to close issues: 4 days
- Average time to close pull requests: about 1 month
- Total issue authors: 22
- Total pull request authors: 10
- Average comments per issue: 2.57
- Average comments per pull request: 2.0
- Merged pull requests: 13
- Bot issues: 0
- Bot pull requests: 4
Past Year
- Issues: 18
- Pull requests: 11
- Average time to close issues: 6 days
- Average time to close pull requests: 9 days
- Issue authors: 15
- Pull request authors: 5
- Average comments per issue: 1.72
- Average comments per pull request: 0.55
- Merged pull requests: 8
- Bot issues: 0
- Bot pull requests: 4
Top Authors
Issue Authors
- Ajaymamtora (4)
- wvffle (2)
- sharpchen (2)
- mriva (2)
- YousufSSyed (2)
- mikavilpas (2)
- Muizzyranking (1)
- farzadmf (1)
- tim-hilde (1)
- c30ra (1)
- Oneechan69 (1)
- niuiic (1)
- kevintraver (1)
- stefanwatt (1)
- niba (1)
Pull Request Authors
- dependabot[bot] (5)
- Ajaymamtora (5)
- stefanwatt (2)
- sid-6581 (2)
- UN-9BOT (2)
- JarKz (2)
- n3wborn (2)
- lvim-tech (2)
- qw457812 (2)
- ewok (1)
- kevintraver (1)
Top Labels
Issue Labels
Pull Request Labels
Dependencies
- actions/checkout v4 composite
- stevearc/nvim-typecheck-action v2 composite
- actions/checkout v4 composite
- kdheepak/panvimdoc main composite
- stefanzweifel/git-auto-commit-action v4 composite
- amannn/action-semantic-pull-request v5 composite
- actions/stale v8 composite
- JohnnyMorganz/stylua-action v4 composite
- actions/checkout v4 composite
- stefanzweifel/git-auto-commit-action v4 composite