All Projects → gbprod → substitute.nvim

gbprod / substitute.nvim

Licence: WTFPL License
Neovim plugin introducing a new operators motions to quickly replace and exchange text.

Programming Languages

lua
6591 projects
Vim Script
2826 projects
Makefile
30231 projects

Projects that are alternatives of or similar to substitute.nvim

nvim-ghost.nvim
👻 GhostText plugin for Neovim with zero dependencies 🎉 Supports neovim running inside WSL too! 🥳 Windows/Linux/macOS supported out-of-the-box! 😄 (Other OSes need python3.6+ installed)
Stars: ✭ 32 (-60.98%)
Mutual labels:  nvim, neovim-plugin, nvim-plugin
nvim-highlite
A colorscheme template that is "lite" on logic for the developer.
Stars: ✭ 163 (+98.78%)
Mutual labels:  nvim, neovim-plugin, nvim-plugin
aerial.nvim
Neovim plugin for a code outline window
Stars: ✭ 485 (+491.46%)
Mutual labels:  nvim, neovim-plugin, nvim-plugin
cutlass.nvim
Plugin that adds a 'cut' operation separate from 'delete'
Stars: ✭ 78 (-4.88%)
Mutual labels:  nvim, neovim-plugin, nvim-plugin
qf helper.nvim
A collection of improvements for the quickfix buffer
Stars: ✭ 70 (-14.63%)
Mutual labels:  nvim, neovim-plugin, nvim-plugin
code runner.nvim
Neovim plugin.The best code runner you could have, it is like the one in vscode but with super powers, it manages projects like in intellij but without being slow
Stars: ✭ 234 (+185.37%)
Mutual labels:  nvim, neovim-plugin, nvim-plugin
lspcontainers.nvim
Neovim plugin for lspcontainers.
Stars: ✭ 157 (+91.46%)
Mutual labels:  nvim, neovim-plugin, nvim-plugin
telescope-zoxide
An extension for telescope.nvim that allows you operate zoxide within Neovim.
Stars: ✭ 126 (+53.66%)
Mutual labels:  nvim, nvim-plugin
navigator.lua
Source code analysis & navigation plugin for Neovim. Navigate codes like a breeze🎐. Exploring LSP and 🌲Treesitter symbols a piece of 🍰. Take control like a boss 🦍.
Stars: ✭ 781 (+852.44%)
Mutual labels:  neovim-plugin, nvim-plugin
comment-box.nvim
✨ Clarify and beautify your comments using boxes and lines.
Stars: ✭ 91 (+10.98%)
Mutual labels:  nvim, neovim-plugin
bolt.nvim
⚡ Ultrafast multi-pane file manager for Neovim with fuzzy matching
Stars: ✭ 100 (+21.95%)
Mutual labels:  nvim, neovim-plugin
nvim-terminal
A Lua-Neovim plugin that toggles a terminal
Stars: ✭ 54 (-34.15%)
Mutual labels:  nvim, neovim-plugin
tabby.nvim
A declarative, highly configurable, and neovim style tabline plugin. Use your nvim tabs as a workspace multiplexer!
Stars: ✭ 232 (+182.93%)
Mutual labels:  nvim, neovim-plugin
vim-lamp
💡Language Server Protocol client for Vim.
Stars: ✭ 34 (-58.54%)
Mutual labels:  nvim, nvim-plugin
nvim
🍨 Soothing pastel theme for NeoVim
Stars: ✭ 659 (+703.66%)
Mutual labels:  nvim, neovim-plugin
feline.nvim
A minimal, stylish and customizable statusline for Neovim written in Lua
Stars: ✭ 867 (+957.32%)
Mutual labels:  nvim, neovim-plugin
firvish.nvim
WIP
Stars: ✭ 31 (-62.2%)
Mutual labels:  nvim, neovim-plugin
virtual-types.nvim
Neovim plugin that shows type annotations as virtual text
Stars: ✭ 171 (+108.54%)
Mutual labels:  nvim, nvim-plugin
stabilize.nvim
Neovim plugin to stabilize window open/close events.
Stars: ✭ 295 (+259.76%)
Mutual labels:  nvim, neovim-plugin
nvim-toggle-terminal
NeoVim plugin that toggles a terminal buffer in the current window maintaining the same shell instance
Stars: ✭ 54 (-34.15%)
Mutual labels:  nvim, nvim-plugin

🪓 substitute.nvim

Lua GitHub Workflow Status

substitute.nvim aim is to provide new operator motions to make it very easy to perform quick substitutions and exchange.

If you are familiar with svermeulen/vim-subversive and tommcdo/vim-exchange, this plugin does almost the same but rewritten in lua (and I hope this will be more maintainable, readable and efficient).

Features

See this plugin in action

⚡️ Requirements

  • Neovim >= 0.6.0

📦 Installation

Install the plugin with your preferred package manager:

packer

-- Lua
use({
  "gbprod/substitute.nvim",
  config = function()
    require("substitute").setup({
      -- your configuration comes here
      -- or leave it empty to use the default settings
      -- refer to the configuration section below
    })
  end
})

vim-plug

" Vim Script
Plug 'gbprod/substitute.nvim'
lua << EOF
  require("substitute").setup({
    -- your configuration comes here
    -- or leave it empty to use the default settings
    -- refer to the configuration section below
  })
EOF

⚙️ Configuration

Substitute comes with the following defaults:

{
  on_substitute = nil,
  yank_substitued_text = false,
  range = {
    prefix = "s",
    prompt_current_text = false,
    confirm = false,
    complete_word = false,
    motion1 = false,
    motion2 = false,
  },
  exchange = {
    motion = false,
  },
}

More details on these options is available in the sections below corresponding to the different features.

🔂 Substitute operator

It contains no default mappings and will have no effect until you add your own maps to it.

-- Lua
vim.api.nvim_set_keymap("n", "s", "<cmd>lua require('substitute').operator()<cr>", { noremap = true })
vim.api.nvim_set_keymap("n", "ss", "<cmd>lua require('substitute').line()<cr>", { noremap = true })
vim.api.nvim_set_keymap("n", "S", "<cmd>lua require('substitute').eol()<cr>", { noremap = true })
vim.api.nvim_set_keymap("x", "s", "<cmd>lua require('substitute').visual()<cr>", { noremap = true })

Or

" Vim Script
nnoremap s <cmd>lua require('substitute').operator()<cr>
nnoremap ss <cmd>lua require('substitute').line()<cr>
nnoremap S <cmd>lua require('substitute').eol()<cr>
xnoremap s <cmd>lua require('substitute').visual()<cr>

Then you can then execute s<motion> to substitute the text object provided by the motion with the contents of the default register (or an explicit register if provided). For example, you could execute siw to replace the current word under the cursor with the current yank, or sip to replace the paragraph, etc.

This action is dot-repeatable.

Note: in this case you will be shadowing the change character key s so you will have to use the longer form cl.

⚙️ Configuration

on_substitute

Default : nil

Function that will be called each times a substitution is made. This function takes a param argument that contains the register used for substitution.

yank_substitued_text

Default : false

If true, when performing a substitution, substitued text is pushed into the default register.

🤝 Integration

gbprod/yanky.nvim

To enable gbprod/yanky.nvim swap when performing a substitution, you can add this to your setup:

require("substitute").setup({
  on_substitute = function(event)
    require("yanky").init_ring("p", event.register, event.count, event.vmode:match("[vV�]"))
  end,
})
svermeulen/vim-yoink

To enable vim-yoink swap when performing a substitution, you can add this to your setup:

require("substitute").setup({
  on_substitute = function(_)
    vim.cmd("call yoink#startUndoRepeatSwap()")
  end,
})

vim-yoink does not support swapping when doing paste in visual mode. With this plugin, you can add thoss mappings to enable it :

vim.api.nvim_set_keymap("x", "p", "<cmd>lua require('substitute').visual()<cr>", {})
vim.api.nvim_set_keymap("x", "P", "<cmd>lua require('substitute').visual()<cr>", {})

or

xmap p <cmd>lua require('substitute').visual()<cr>
xmap P <cmd>lua require('substitute').visual()<cr>

🔁 Substitute over range motion

Another operator provided allows specifying both the text to replace and the line range over which to apply the change by using multiple consecutive motions.

vim.api.nvim_set_keymap("n", "<leader>s", "<cmd>lua require('substitute.range').operator()<cr>", { noremap = true })
vim.api.nvim_set_keymap("x", "<leader>s", "<cmd>lua require('substitute.range').visual()<cr>", {})
vim.api.nvim_set_keymap("n", "<leader>ss", "<cmd>lua require('substitute.range').word()<cr>", {})

or

nmap <leader>s <cmd>lua require('substitute.range').operator()<cr>
xmap <leader>s <cmd>lua require('substitute.range').visual()<cr>
nmap <leader>ss <cmd>lua require('substitute.range').word()<cr>

After adding this map, if you execute <leader>s<motion1><motion2> then the command line will be filled with a substitute command that allow to replace the text given by motion1 by the text will enter in the command line for each line provided by motion2.

Alternatively, we can also select motion1 in visual mode and then hit <leader>s<motion2> for the same effect.

For convenience, <leader>ss<motion2> can be used to select complete word under the cursor as motion1 (complete word means that complete_word options is override to true so is different from siwip which will not require that there be word boundaries on each match).

You can override any default configuration (described later) by passing this to the operator function. By example, this will use S as prefix of the substitution command (and use tpope/vim-abolish):

nmap <leader>S <cmd>lua require('substitute.range').operator({ prefix = 'S' })<cr>

⚙️ Configuration

range.prefix

Default : s

Substitution command that will be used (set it to S to use tpope/vim-abolish substitution by default).

range.prompt_current_text

Default : false

Substitution command replace part will be set to the current text. Eg. instead of s/pattern//g you will have s/pattern/pattern/g.

range.confirm

Default : false

Will ask for confirmation for each substitutions.

range.complete_word

Default : false

Will require that there be word boundaries on each match (eg: \<word\> instead of word).

range.motion1

Default : false

This will use this motion for the first motion of range substitution.

eg. lua require('substitute.range').operator({ motion1 = 'iW' }) will select inner WORD as subject of substitution.

range.motion2

Default : false

This will use this motion for the second motion of range substitution.

eg. lua require('substitute.range').operator({ motion2 = 'ap' }) will select around paragraph as range of substitution.

You can combine motion1 and motion2 : lua require('substitute.range').operator({ motion1='iw', motion2 = 'ap' }) will prepare substitution for inner word around paragraph.

🤝 Integration

tpope/vim-abolish

You can use tpope/vim-abolish substitution by default.

require("substitute").setup({
  range = {
    prefix = "S",
  }
})

🔀 Exchange operator

This operator allows to quickly exchange text inside a buffer.

Eg. To exchange two words, place your cursor on the first word and type sxiw. Then move to the second word and type sxiw again.

Note: the {motion} used in the first and second use of sx don't have to be the same. Note 2: this is dot-repeatable, so you can use . instead of sxiw for the second word.

You can select a whole line using the line function (sxx in the example below).

Because this operator has to be invoked twice to change the document, if you change your mind after invoking the operator once, you can cancel you selection using the cancel function (mapped to sxc in the example below).

vim.api.nvim_set_keymap("n", "sx", "<cmd>lua require('substitute.exchange').operator()<cr>", { noremap = true })
vim.api.nvim_set_keymap("n", "sxx", "<cmd>lua require('substitute.exchange').line()<cr>", { noremap = true })
vim.api.nvim_set_keymap("x", "X", "<cmd>lua require('substitute.exchange').visual()<cr>", { noremap = true })
vim.api.nvim_set_keymap("n", "sxc", "<cmd>lua require('substitute.exchange').cancel()<cr>", { noremap = true })

or

nmap sx <cmd>lua require('substitute.exchange').operator()<cr>
nmap sxx <cmd>lua require('substitute.exchange').line()<cr>
xmap X <cmd>lua require('substitute.exchange').visual()<cr>
nmap sxc <cmd>lua require('substitute.exchange').cancel()<cr>

⚙️ Configuration

exchange.motion

Default : nil

This will use this motion for exchange.

eg. lua require('substitute.exchange').operator({ motion = 'ap' }) will select around paragraph as range of exchange.

🎨 Colors

Description Group Default
Selected range for range substitution SubstituteRange link to Search
Selected text for exchange SubstituteExchange link to Search

🎉 Credits

This plugin is a lua version of svermeulen/vim-subversive and tommcdo/vim-exchange awesome plugins.

Thanks to m00qek lua plugin template.

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].