Home

Awesome

<!-- LTeX: enabled=false -->

rip-substitute 🪦

<!-- LTeX: enabled=true --> <a href="https://dotfyle.com/plugins/chrisgrieser/nvim-rip-substitute"> <img alt="badge" src="https://dotfyle.com/plugins/chrisgrieser/nvim-rip-substitute/shield"/></a>

Perform search and replace operations in the current buffer using a modern user interface and contemporary regex syntax.

https://github.com/chrisgrieser/nvim-rip-substitute/assets/73286100/4afad8d8-c0d9-4ba6-910c-0510d4b9b669

Table of Contents

<!-- toc --> <!-- tocstop -->

Features

Installation

Requirements

-- lazy.nvim
{
	"chrisgrieser/nvim-rip-substitute",
	cmd = "RipSubstitute",
	keys = {
		{
			"<leader>fs",
			function() require("rip-substitute").sub() end,
			mode = { "n", "x" },
			desc = " rip substitute",
		},
	},
},

-- packer
use {
	"chrisgrieser/nvim-rip-substitute",
}

Configuration

-- default settings
require("rip-substitute").setup {
	popupWin = {
		title = " rip-substitute",
		border = "single",
		matchCountHlGroup = "Keyword",
		noMatchHlGroup = "ErrorMsg",
		hideSearchReplaceLabels = false,
		position = "bottom", -- "top"|"bottom"
	},
	prefill = {
		normal = "cursorWord", -- "cursorWord"|false
		visual = "selectionFirstLine", -- "selectionFirstLine"|false
		startInReplaceLineIfPrefill = false,
	},
	keymaps = {
		-- normal & visual mode
		confirm = "<CR>",
		abort = "q",
		prevSubst = "<Up>",
		nextSubst = "<Down>",
		openAtRegex101 = "R",
		insertModeConfirm = "<C-CR>", -- (except this one, obviously)
	},
	incrementalPreview = {
		matchHlGroup = "IncSearch",
		rangeBackdrop = {
			enabled = true,
			blend = 50, -- between 0 and 100
		},
	},
	regexOptions = {
		-- pcre2 enables lookarounds and backreferences, but performs slower
		pcre2 = true,
		---@type "case-sensitive"|"ignore-case"|"smart-case"
		casing = "case-sensitive",
		-- disable if you use named capture groups (see README for details)
		autoBraceSimpleCaptureGroups = true,
	},
	editingBehavior = {
		-- Experimental. When typing `()` in the `search` line, automatically
		-- adds `$n` to the `replace` line.
		autoCaptureGroups = false,
	},
	notificationOnSuccess = true,
}

[!NOTE] Any ripgrep config file set via RIPGREP_CONFIG_PATH is ignored by this plugin.

Usage

lua function

vim.keymap.set(
	{ "n", "x" },
	"<leader>fs",
	function() require("rip-substitute").sub() end,
	{ desc = " rip substitute" }
)

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.

" Substitute in entire file. Prefills the cursorword.
: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.

:RipSubstitute prefilled string

Advanced

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.

Filetype
The popup window uses the filetype rip-substitute. This can be useful, for instance, to disable auto-pairing plugins in the popup window.

Limitations

<!-- vale Google.FirstPerson = NO -->

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.

I also occasionally blog about vim: Nano Tips for Vim

<a href='https://ko-fi.com/Y8Y86SQ91' target='_blank'><img height='36' style='border:0px;height:36px;' src='https://cdn.ko-fi.com/cdn/kofi1.png?v=3' border='0' alt='Buy Me a Coffee at ko-fi.com' /></a>