diff --git a/.github/workflows/panvimdoc.yml b/.github/workflows/panvimdoc.yml
new file mode 100644
index 0000000..0945f4d
--- /dev/null
+++ b/.github/workflows/panvimdoc.yml
@@ -0,0 +1,20 @@
+name: panvimdoc
+
+on: [push]
+
+jobs:
+ docs:
+ runs-on: ubuntu-latest
+ name: pandoc to vimdoc
+ steps:
+ - uses: actions/checkout@v2
+ - name: panvimdoc
+ uses: kdheepak/panvimdoc@main
+ with:
+ vimdoc: substitute-nvim
+ description: Neovim plugin introducing a new operator motions to quickly replace text.
+ version: 'NVIM v0.6.0'
+ - uses: stefanzweifel/git-auto-commit-action@v4
+ with:
+ commit_message: 'chore: auto generate docs'
+ branch: ${{ github.head_ref }}
diff --git a/doc/substitute-nvim.txt b/doc/substitute-nvim.txt
new file mode 100644
index 0000000..a580be9
--- /dev/null
+++ b/doc/substitute-nvim.txt
@@ -0,0 +1,245 @@
+*substitute-nvim.txt*Neovim plugin introducing a new operator motions to quickly replace text.
+
+==============================================================================
+Table of Contents *substitute-nvim-table-of-contents*
+
+1. substitute.nvim |substitute-nvim-substitute.nvim|
+ - Usage |substitute-nvim-usage|
+ - Substitute operator |substitute-nvim-substitute-operator|
+ - Substitute over range motion|substitute-nvim-substitute-over-range-motion|
+ - Credits |substitute-nvim-credits|
+
+==============================================================================
+1. substitute.nvim *substitute-nvim-substitute.nvim*
+
+
+
+
+`substitute.nvim` aim is to provide new operator motions to make it very easy
+to perform quick substitutions.
+
+If you are familiar with svermeulen/vim-subversive
+, this plugin does almost the
+same but rewritten in `lua` (and I hope this will be more maintainable,
+readable and efficient).
+
+This is a beta version, expect bugs ;) (but I use it daily).
+
+USAGE *substitute-nvim-usage*
+
+Requires neovim > 0.6.0.
+
+Using https://github.com/wbthomason/packer.nvim:
+
+>
+ use({
+ "gbprod/substitute.nvim",
+ config = function()
+ require("substitute").setup()
+ end
+ })
+<
+
+
+SUBSTITUTE OPERATOR *substitute-nvim-substitute-operator*
+
+It contains no default mappings and will have no effect until you add your own
+maps to it.
+
+>
+ vim.api.nvim_set_keymap("n", "s", "lua require('substitute').operator()", { noremap = true })
+ vim.api.nvim_set_keymap("n", "ss", "lua require('substitute').line()", { noremap = true })
+ vim.api.nvim_set_keymap("n", "S", "lua require('substitute').eol()", { noremap = true })
+ vim.api.nvim_set_keymap("x", "s", "lua require('substitute').visual()", { noremap = true })
+<
+
+
+Or
+
+>
+ nnoremap s lua require('substitute').operator()
+ nnoremap ss lua require('substitute').line()
+ nnoremap S lua require('substitute').eol()
+ xnoremap s lua require('substitute').visual()
+<
+
+
+Then you can then execute `s` 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 ~
+
+ *substitute-nvim-`on_substitute`*
+
+`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.
+
+ *substitute-nvim-`yank_substitued_text`*
+
+`yank_substitued_text` Default : `false`
+
+
+If `true`, when performing a substitution, substitued text is pushed into the
+default register.
+
+INTEGRATION ~
+
+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", "lua require('substitute').visual()", {})
+ vim.api.nvim_set_keymap("x", "P", "lua require('substitute').visual()", {})
+<
+
+
+or
+
+>
+ xmap p lua require('substitute').visual()
+ xmap P lua require('substitute').visual()
+<
+
+
+SUBSTITUTE OVER RANGE MOTION *substitute-nvim-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", "s", "lua require('substitute.range').operator()", { noremap = true })
+ vim.api.nvim_set_keymap("x", "s", "lua require('substitute.range').visual()")
+ vim.api.nvim_set_keymap("n", "ss", "lua require('substitute.range').word()")
+<
+
+
+or
+
+>
+ nmap s lua require('substitute.range').operator()
+ xmap s lua require('substitute.range').visual()
+ nmap ss lua require('substitute.range').word()
+<
+
+
+After adding this map, if you execute `s` 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
+`s` for the same effect.
+
+For convenience, `ss` 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 S lua require('substitute.range').operator({ prefix = 'S' })
+<
+
+
+CONFIGURATION ~
+
+ *substitute-nvim-`range.prefix`*
+
+`range.prefix` Default : `s`
+
+
+Substitution command that will be used (set it to `S` to use tpope/vim-abolish
+ substitution by default).
+
+ *substitute-nvim-`range.prompt_current_text`*
+
+`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`.
+
+ *substitute-nvim-`range.confirm`*
+
+`range.confirm` Default : `false`
+
+
+Will ask for confirmation for each substitutions.
+
+ *substitute-nvim-`range.complete_word`*
+
+`range.complete_word` Default : `false`
+
+
+Will require that there be word boundaries on each match (eg: `\`
+instead of `word`).
+
+INTEGRATION ~
+
+tpope/vim-abolish ~
+
+You can use tpope/vim-abolish
+substitution by default.
+
+>
+ require("substitute").setup({
+ range = {
+ prefix = "S",
+ }
+ })
+<
+
+
+CONFIGURATION ~
+
+ *substitute-nvim-`range.prefix`*
+
+`range.prefix` Default : `s`
+
+
+Function that will be called each times a substitution is made. This function
+takes a `param` argument that contains the `register` used for substitution.
+
+CREDITS *substitute-nvim-credits*
+
+This plugin is a lua version of svermeulen/vim-subversive
+ awesome plugin.
+
+Thanks to m00qek lua plugin template
+.
+
+Generated by panvimdoc
+
+vim:tw=78:ts=8:noet:ft=help:norl:
diff --git a/doc/substitute.nvim.txt b/doc/substitute.nvim.txt
new file mode 100644
index 0000000..e69de29
diff --git a/lua/substitute.lua b/lua/substitute.lua
index ac94377..dac62fa 100644
--- a/lua/substitute.lua
+++ b/lua/substitute.lua
@@ -17,17 +17,21 @@ function substitute.operator()
vim.api.nvim_feedkeys("g@", "i", false)
end
-local function do_substitution(start_row, start_col, end_row, end_col, register)
+local function do_substitution(regions, register, vmode)
local replacement = vim.fn.getreg(register)
if config.options.yank_substitued_text then
vim.fn.setreg(
utils.get_default_register(),
- table.concat(utils.nvim_buf_get_text(start_row, start_col, end_row, end_col), "\n")
+ table.concat(utils.get_text(regions), "\n"),
+ utils.get_register_type(vmode)
)
end
- vim.api.nvim_buf_set_text(0, start_row, start_col, end_row, end_col, vim.split(replacement:gsub("\n$", ""), "\n"))
+ local text = vim.split(replacement:gsub("\n$", ""), "\n")
+ for _, region in ipairs(regions) do
+ vim.api.nvim_buf_set_text(0, region.start_row - 1, region.start_col, region.end_row - 1, region.end_col + 1, text)
+ end
if config.options.on_substitute ~= nil then
config.options.on_substitute({
@@ -37,14 +41,8 @@ local function do_substitution(start_row, start_col, end_row, end_col, register)
end
function substitute.operator_callback(vmode)
- local region = utils.get_region(vmode)
- do_substitution(
- region.start_row - 1,
- region.start_col,
- region.end_row - 1,
- region.end_col + 1,
- substitute.state.register
- )
+ local regions = utils.get_regions(vmode)
+ do_substitution(regions, substitute.state.register, vmode)
end
function substitute.line()
@@ -67,8 +65,8 @@ end
function substitute.visual()
substitute.state.register = vim.v.register
- vim.o.operatorfunc = "v:lua.require'substitute'.operator_callback"
- vim.api.nvim_feedkeys("g@`>", "i", false)
+ vim.cmd([[execute "normal! \"]])
+ substitute.operator_callback(vim.fn.visualmode())
end
return substitute
diff --git a/lua/substitute/range.lua b/lua/substitute/range.lua
index 323f94b..64664e1 100644
--- a/lua/substitute/range.lua
+++ b/lua/substitute/range.lua
@@ -53,14 +53,14 @@ function range.clear_match()
end
function range.operator_callback(vmode)
- local region = utils.get_region(vmode)
- if region.start_row ~= region.end_row then
+ local regions = utils.get_regions(vmode)
+ if vim.tbl_count(regions) ~= 1 or regions[1].start_row ~= regions[1].end_row then
vim.notify("Multiline is not supported by SubstituteRange", vim.log.levels.INFO)
return
end
- local line = vim.api.nvim_buf_get_lines(0, region.start_row - 1, region.end_row, true)
- range.state.subject = string.sub(line[1], region.start_col + 1, region.end_col + 1)
+ local line = vim.api.nvim_buf_get_lines(0, regions[1].start_row - 1, regions[1].end_row, true)
+ range.state.subject = string.sub(line[1], regions[1].start_col + 1, regions[1].end_col + 1)
create_match()
diff --git a/lua/substitute/utils.lua b/lua/substitute/utils.lua
index b270c68..7919c92 100644
--- a/lua/substitute/utils.lua
+++ b/lua/substitute/utils.lua
@@ -1,30 +1,58 @@
local utils = {}
-function utils.get_region(vmode)
- local sln, eln
- if vmode:match("[vV]") then
- sln = vim.api.nvim_buf_get_mark(0, "<")
- eln = vim.api.nvim_buf_get_mark(0, ">")
- else
- sln = vim.api.nvim_buf_get_mark(0, "[")
- eln = vim.api.nvim_buf_get_mark(0, "]")
+function utils.get_regions(vmode)
+ if vmode == vim.api.nvim_replace_termcodes("", true, false, true) then
+ local start = vim.api.nvim_buf_get_mark(0, "<")
+ local finish = vim.api.nvim_buf_get_mark(0, ">")
+
+ local regions = {}
+
+ for row = start[1], finish[1], 1 do
+ local current_row_len = vim.fn.getline(row):len() - 1
+
+ table.insert(regions, {
+ start_row = row,
+ start_col = start[2],
+ end_row = row,
+ end_col = current_row_len >= finish[2] and finish[2] or current_row_len,
+ })
+ end
+
+ return regions
end
+ local start_mark, end_mark = "[", "]"
+ if vmode:match("[vV]") then
+ start_mark, end_mark = "<", ">"
+ end
+
+ local start = vim.api.nvim_buf_get_mark(0, start_mark)
+ local finish = vim.api.nvim_buf_get_mark(0, end_mark)
+ local end_row_len = vim.fn.getline(finish[1]):len() - 1
+
return {
- start_row = sln[1],
- start_col = sln[2],
- end_row = eln[1],
- end_col = math.min(eln[2], vim.fn.getline(eln[1]):len() - 1),
+ {
+ start_row = start[1],
+ start_col = start[2],
+ end_row = finish[1],
+ end_col = end_row_len >= finish[2] and finish[2] or end_row_len,
+ },
}
end
-function utils.nvim_buf_get_text(start_row, start_col, end_row, end_col)
- local lines = vim.api.nvim_buf_get_lines(0, start_row, end_row + 1, true)
+function utils.get_text(regions)
+ local all_lines = {}
+ for _, region in ipairs(regions) do
+ local lines = vim.api.nvim_buf_get_lines(0, region.start_row - 1, region.end_row, true)
+ lines[vim.tbl_count(lines)] = string.sub(lines[vim.tbl_count(lines)], 0, region.end_col + 1)
+ lines[1] = string.sub(lines[1], region.start_col + 1)
- lines[vim.tbl_count(lines)] = string.sub(lines[vim.tbl_count(lines)], 0, end_col)
- lines[1] = string.sub(lines[1], start_col + 1)
+ for _, line in ipairs(lines) do
+ table.insert(all_lines, line)
+ end
+ end
- return lines
+ return all_lines
end
function utils.get_default_register()
@@ -41,4 +69,16 @@ function utils.get_default_register()
return '"'
end
+function utils.get_register_type(vmode)
+ if vmode == vim.api.nvim_replace_termcodes("", true, false, true) then
+ return "b"
+ end
+
+ if vmode == "V" then
+ return "l"
+ end
+
+ return "c"
+end
+
return utils
diff --git a/spec/spec.vim b/spec/spec.vim
index 3ae3339..a2a0691 100644
--- a/spec/spec.vim
+++ b/spec/spec.vim
@@ -5,3 +5,12 @@ runtime plugin/plenary.vim
runtime ../plugin/substitute.vim
lua require('plenary.busted')
+
+lua vim.api.nvim_set_keymap("n", "ss", "lua require('substitute').line()", { noremap = true })
+lua vim.api.nvim_set_keymap("n", "S", "lua require('substitute').eol()", { noremap = true })
+lua vim.api.nvim_set_keymap("x", "s", "lua require('substitute').visual()", { noremap = true })
+lua vim.api.nvim_set_keymap("n", "s", "lua require('substitute').operator()", { noremap = true })
+
+lua vim.api.nvim_set_keymap("n", "s", "lua require('substitute.range').operator()", { noremap = true, })
+
+
diff --git a/spec/substitute/range_spec.lua b/spec/substitute/range_spec.lua
index 484af39..dca864b 100644
--- a/spec/substitute/range_spec.lua
+++ b/spec/substitute/range_spec.lua
@@ -11,10 +11,6 @@ describe("Substitute range", function()
local buf = vim.api.nvim_create_buf(false, true)
vim.api.nvim_command("buffer " .. buf)
- vim.api.nvim_set_keymap("n", "s", "lua require('substitute.range').operator()", {
- noremap = true,
- })
-
vim.api.nvim_buf_set_lines(0, 0, -1, true, {
"Lorem",
"ipsum",
diff --git a/spec/substitute/utils_spec.lua b/spec/substitute/utils_spec.lua
index 20af1c0..26ca7d5 100644
--- a/spec/substitute/utils_spec.lua
+++ b/spec/substitute/utils_spec.lua
@@ -1,37 +1,207 @@
local utils = require("substitute.utils")
-describe("Test get region", function()
- it("should find region", function()
- local buf = vim.api.nvim_create_buf(false, true)
- vim.api.nvim_command("buffer " .. buf)
- vim.api.nvim_buf_set_lines(0, 0, -1, true, {
- "Lorem",
- "Ipsum",
- })
+local function execute_keys(feedkeys)
+ local keys = vim.api.nvim_replace_termcodes(feedkeys, true, false, true)
+ vim.api.nvim_feedkeys(keys, "x", false)
+end
+
+local function create_test_buffer()
+ local buf = vim.api.nvim_create_buf(false, true)
+ vim.api.nvim_command("buffer " .. buf)
+
+ vim.api.nvim_buf_set_lines(0, 0, -1, true, {
+ "Lorem ipsum dolor sit amet,",
+ "consectetur adipiscing elit.",
+ "Nulla malesuada lacus at ornare accumsan.",
+ })
+end
- vim.api.nvim_buf_set_mark(buf, "[", 1, 1, {})
- vim.api.nvim_buf_set_mark(buf, "]", 2, 2, {})
+describe("Get regions in operatorfunc", function()
+ before_each(create_test_buffer)
- local region = utils.get_region("char")
+ it("should select word", function()
+ local region
+ _G.callback = function()
+ region = utils.get_regions(vim.fn.visualmode())
+ end
- assert(region.start_col == 1)
- assert(region.start_row == 1)
- assert(region.end_col == 2)
- assert(region.end_row == 2)
+ vim.o.operatorfunc = "v:lua.callback"
+ execute_keys("g@iw")
+
+ assert.are.same({ { start_row = 1, start_col = 0, end_row = 1, end_col = 4 } }, region)
end)
- it("should get text", function()
- local buf = vim.api.nvim_create_buf(false, true)
- vim.api.nvim_command("buffer " .. buf)
- vim.api.nvim_buf_set_lines(0, 0, -1, true, {
- "Lorem",
- "Ipsum",
- })
+ it("should select to end of the line", function()
+ local region
+ _G.callback = function()
+ region = utils.get_regions(vim.fn.visualmode())
+ end
+
+ execute_keys("2w")
+ vim.o.operatorfunc = "v:lua.callback"
+ execute_keys("g@$")
+
+ assert.are.same({ { start_row = 1, start_col = 12, end_row = 1, end_col = 26 } }, region)
+ end)
+
+ it("should select many lines", function()
+ local region
+ _G.callback = function()
+ region = utils.get_regions(vim.fn.visualmode())
+ end
+
+ execute_keys("2w")
+ vim.o.operatorfunc = "v:lua.callback"
+ execute_keys("g@5w")
+
+ assert.are.same({ { start_row = 1, start_col = 12, end_row = 2, end_col = 11 } }, region)
+ end)
+
+ it("should select to end of file", function()
+ local region
+ _G.callback = function()
+ region = utils.get_regions(vim.fn.visualmode())
+ end
+
+ execute_keys("w")
+ vim.o.operatorfunc = "v:lua.callback"
+ execute_keys("g@G")
+
+ assert.are.same({ { start_row = 1, start_col = 6, end_row = 3, end_col = 6 } }, region)
+ end)
+end)
- local text = utils.nvim_buf_get_text(0, 1, 1, 4)
- assert.are.same({ "orem", "Ipsu" }, text)
+describe("Get regions in visual mode", function()
+ before_each(create_test_buffer)
+
+ it("should select word", function()
+ execute_keys("ve")
+ local region = utils.get_regions(vim.fn.visualmode())
+
+ assert.are.same({ { start_row = 1, start_col = 0, end_row = 1, end_col = 4 } }, region)
+ end)
+
+ it("should select to end of the line", function()
+ execute_keys("2w")
+ execute_keys("v$")
+ local region = utils.get_regions(vim.fn.visualmode())
+
+ assert.are.same({ { start_row = 1, start_col = 12, end_row = 1, end_col = 26 } }, region)
+ end)
+
+ it("should select many lines", function()
+ execute_keys("2w")
+ execute_keys("v5w")
+ local region = utils.get_regions(vim.fn.visualmode())
+
+ assert.are.same({ { start_row = 1, start_col = 12, end_row = 2, end_col = 12 } }, region)
+ end)
+
+ it("should select to end of file", function()
+ execute_keys("w")
+ execute_keys("vG")
+ local region = utils.get_regions(vim.fn.visualmode())
+
+ assert.are.same({ { start_row = 1, start_col = 6, end_row = 3, end_col = 6 } }, region)
+ end)
+end)
+
+describe("Get regions in VISUAL mode", function()
+ before_each(create_test_buffer)
+
+ it("should select line", function()
+ execute_keys("w")
+ execute_keys("V")
+ local region = utils.get_regions(vim.fn.visualmode())
+
+ assert.are.same({ { start_row = 1, start_col = 0, end_row = 1, end_col = 26 } }, region)
+ end)
+
+ it("should select multiple lines", function()
+ execute_keys("wj")
+ execute_keys("Vj")
+ local region = utils.get_regions(vim.fn.visualmode())
+
+ assert.are.same({ { start_row = 2, start_col = 0, end_row = 3, end_col = 40 } }, region)
+ end)
+end)
+
+describe("Get regions in CTRL-V mode", function()
+ before_each(create_test_buffer)
+
+ it("should select word", function()
+ execute_keys("w")
+ local region = utils.get_regions(vim.fn.visualmode())
+
+ assert.are.same({ { start_row = 1, start_col = 0, end_row = 1, end_col = 6 } }, region)
+ end)
+
+ it("should select on 2 lines", function()
+ execute_keys("wj")
+ local region = utils.get_regions(vim.fn.visualmode())
+
+ assert.are.same({
+ { start_row = 1, start_col = 0, end_row = 1, end_col = 6 },
+ { start_row = 2, start_col = 0, end_row = 2, end_col = 6 },
+ }, region)
+ end)
+
+ it("should select to the end of lines", function()
+ execute_keys("wj")
+ execute_keys("j$")
+ local region = utils.get_regions(vim.fn.visualmode())
+
+ assert.are.same({
+ { start_row = 2, start_col = 6, end_row = 2, end_col = 27 },
+ { start_row = 3, start_col = 6, end_row = 3, end_col = 40 },
+ }, region)
+ end)
+
+ it("should select from the beginning of lines", function()
+ execute_keys("jjl")
+ local region = utils.get_regions(vim.fn.visualmode())
+
+ assert.are.same({
+ { start_row = 1, start_col = 0, end_row = 1, end_col = 1 },
+ { start_row = 2, start_col = 0, end_row = 2, end_col = 1 },
+ { start_row = 3, start_col = 0, end_row = 3, end_col = 1 },
+ }, region)
+ end)
+end)
+
+describe("Get text", function()
+ before_each(create_test_buffer)
+
+ it("should get one word at the beginning", function()
+ local text = utils.get_text({ { start_row = 1, start_col = 0, end_row = 1, end_col = 4 } })
+
+ assert.are.same({ "Lorem" }, text)
+ end)
+
+ it("should get one word", function()
+ local text = utils.get_text({ { start_row = 1, start_col = 6, end_row = 1, end_col = 10 } })
+
+ assert.are.same({ "ipsum" }, text)
+ end)
+
+ it("should get one word at the end", function()
+ local text = utils.get_text({ { start_row = 2, start_col = 23, end_row = 2, end_col = 27 } })
+
+ assert.are.same({ "elit." }, text)
+ end)
+
+ it("should get text on 2 lines", function()
+ local text = utils.get_text({ { start_row = 1, start_col = 6, end_row = 2, end_col = 21 } })
+
+ assert.are.same({ "ipsum dolor sit amet,", "consectetur adipiscing" }, text)
+ end)
+
+ it("should get text on 2 regions", function()
+ local text = utils.get_text({
+ { start_row = 1, start_col = 6, end_row = 1, end_col = 10 },
+ { start_row = 2, start_col = 23, end_row = 2, end_col = 27 },
+ })
- text = utils.nvim_buf_get_text(0, 1, 0, 4)
- assert.are.same({ "ore" }, text)
+ assert.are.same({ "ipsum", "elit." }, text)
end)
end)
diff --git a/spec/substitute_spec.lua b/spec/substitute_spec.lua
index b597df6..9633717 100644
--- a/spec/substitute_spec.lua
+++ b/spec/substitute_spec.lua
@@ -17,17 +17,7 @@ describe("Substitute", function()
local buf = vim.api.nvim_create_buf(false, true)
vim.api.nvim_command("buffer " .. buf)
- vim.api.nvim_set_keymap("n", "ss", "lua require('substitute').line()", { noremap = true })
- vim.api.nvim_set_keymap("n", "S", "lua require('substitute').eol()", { noremap = true })
- vim.api.nvim_set_keymap("n", "s", "lua require('substitute').operator()", { noremap = true })
-
- vim.api.nvim_buf_set_lines(0, 0, -1, true, {
- "Lorem",
- "ipsum",
- "dolor",
- "sit",
- "amet",
- })
+ vim.api.nvim_buf_set_lines(0, 0, -1, true, { "Lorem", "ipsum", "dolor", "sit", "amet" })
end)
it("should substitute line", function()
@@ -112,6 +102,14 @@ describe("Substitute", function()
assert.are.same({ "Lorem", "Lorem", "amet" }, get_buf_lines())
end)
+
+ it("should substitute in visual mode", function()
+ execute_keys("yw")
+ execute_keys("jv$")
+ execute_keys("s")
+
+ assert.are.same({ "Lorem", "Lorem", "dolor", "sit", "amet" }, get_buf_lines())
+ end)
end)
describe("On substitute option", function()
@@ -129,3 +127,47 @@ describe("On substitute option", function()
assert(called)
end)
end)
+
+describe("When yank_substitued_text is set", function()
+ before_each(function()
+ substitute.setup()
+
+ local buf = vim.api.nvim_create_buf(false, true)
+ vim.api.nvim_command("buffer " .. buf)
+
+ vim.api.nvim_buf_set_lines(0, 0, -1, true, { "Lorem", "ipsum", "dolor", "sit", "amet" })
+ end)
+
+ it("should yank in default register", function()
+ substitute.setup({ yank_substitued_text = true })
+
+ execute_keys("yw")
+ execute_keys("j")
+ execute_keys("sw")
+
+ assert.are.same("ipsum", vim.fn.getreg())
+ assert.are.same("v", vim.fn.getregtype())
+ end)
+
+ it("should yank in default register in visual mode", function()
+ substitute.setup({ yank_substitued_text = true })
+
+ execute_keys("ywj")
+ execute_keys("vjj")
+ execute_keys("s")
+
+ assert.are.same("ipsum\ndolor\ns", vim.fn.getreg())
+ assert.are.same("v", vim.fn.getregtype())
+ end)
+
+ it("should yank in default register in ctrl-v mode", function()
+ substitute.setup({ yank_substitued_text = true })
+
+ execute_keys("ywj")
+ execute_keys("jjl")
+ execute_keys("s")
+
+ assert.are.same("ip\ndo\nsi", vim.fn.getreg())
+ assert.are.same(vim.api.nvim_replace_termcodes("2", true, false, true), vim.fn.getregtype())
+ end)
+end)