Skip to content

Commit

Permalink
Merge pull request #47 from AgatZan/issue-wrong_select
Browse files Browse the repository at this point in the history
Unexpected result of `getSelectText()`
  • Loading branch information
LintaoAmons authored Nov 13, 2024
2 parents ec91580 + 71c2aca commit 0e3ee1f
Show file tree
Hide file tree
Showing 6 changed files with 333 additions and 30 deletions.
1 change: 1 addition & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,5 @@ jobs:
neovim: true
version: ${{ matrix.neovim_version }}
- name: Run tests
timeout-minutes: 3
run: make test
32 changes: 22 additions & 10 deletions lua/scratch/utils.lua
Original file line number Diff line number Diff line change
Expand Up @@ -77,17 +77,29 @@ local table_length = function(T)
end

---@return string[]
local function getSelectedText()
local _, csrow, cscol, _ = unpack(vim.fn.getpos("'<"))
local _, cerow, cecol, _ = unpack(vim.fn.getpos("'>"))

local lines = vim.fn.getline(csrow, cerow)
local n = table_length(lines)
if n <= 0 then
return {}
local function getSelectedText(mark, selection_mode)
local pos1 = vim.fn.getpos("v")
local pos2 = vim.fn.getpos(mark)
local lines = {}
local start_row, start_col, end_row, end_col = pos1[2], pos1[3], pos2[2], pos2[3]
local text = vim.api.nvim_buf_get_lines(0, start_row - 1, end_row, true)
end_row = end_row - start_row + 1
start_row = 1
if selection_mode == "v" then
table.insert(lines, text[1]:sub(start_col))
for i = start_row + 1, end_row do
table.insert(lines, text[i])
end
lines[end_row] = lines[end_row]:sub(1, end_col)
elseif selection_mode == "V" then
for i = start_row, end_row do
table.insert(lines, text[i])
end
elseif selection_mode == vim.api.nvim_replace_termcodes("<C-V>", true, true, true) then
for i = start_row, end_row do
table.insert(lines, text[i]:sub(start_col, end_col))
end
end
lines[n] = string.sub(lines[n], 1, cecol)
lines[1] = string.sub(lines[1], cscol)
return lines
end

Expand Down
11 changes: 7 additions & 4 deletions plugin/scratch_plugin.lua
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,14 @@ local scratch_main = require("scratch")
scratch_main.setup()

vim.api.nvim_create_user_command("Scratch", function(args)
if args.range > 0 then
scratch_api.scratch({ content = utils.getSelectedText() })
else
scratch_api.scratch()
local mode = vim.api.nvim_get_mode().mode
local opts
if mode ~= "n" then
opts = { content = utils.getSelectedText(".", mode) }
elseif args.range > 0 then
opts = { content = vim.api.nvim_buf_get_lines(0, args.line1 - 1, args.line2, true) }
end
scratch_api.scratch(opts)
end, { range = true })

vim.api.nvim_create_user_command("ScratchOpen", scratch_api.openScratch, {})
Expand Down
16 changes: 0 additions & 16 deletions tests/test_first.lua

This file was deleted.

135 changes: 135 additions & 0 deletions tests/test_plugin.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
local child = MiniTest.new_child_neovim()
local new_set = MiniTest.new_set

local function mock()
local mock_api = {}
mock_api.scratch = function(opts)
_G.scratch_opts = opts
end
mock_api.openScratch = function()
print("TODO")
end
mock_api.fzfScratch = mock_api.openScratch
mock_api.scratchWithName = mock_api.openScratch

package.loaded["scratch.api"] = mock_api
vim.g.loaded_scratch = 0
dofile("plugin/scratch_plugin.lua")
end
local select_wise = function(coord, selection_mode)
local vim = child
local start_row, start_col, end_row, end_col = coord[1], coord[2], coord[3], coord[4]
local mode = vim.api.nvim_get_mode()
if mode.mode ~= "n" then
local esc = vim.api.nvim_replace_termcodes("<ESC>", true, true, true)
vim.api.nvim_cmd({ cmd = "normal", bang = true, args = { esc } }, {})
vim.api.nvim_cmd({ cmd = "normal", bang = true, args = { esc } }, {})
end
selection_mode = vim.api.nvim_replace_termcodes(selection_mode, true, true, true)
vim.api.nvim_cmd({ cmd = "normal", bang = true, args = { selection_mode } }, {})

vim.api.nvim_win_set_cursor(0, { start_row, start_col - 1 })
vim.cmd("normal! o")
vim.api.nvim_win_set_cursor(0, { end_row, end_col - 1 })
end

local function table_select(text, coord, selection_mode)
local lines = {}
local start_row, start_col, end_row, end_col = coord[1], coord[2], coord[3], coord[4]
if selection_mode == "v" then
table.insert(lines, text[start_row]:sub(start_col))
for i = start_row + 1, end_row do
table.insert(lines, text[i])
end
local ind = end_row - start_row + 1
lines[ind] = lines[ind]:sub(1, end_col)
elseif selection_mode == "V" then
for i = start_row, end_row do
table.insert(lines, text[i])
end
elseif selection_mode == vim.api.nvim_replace_termcodes("<C-V>", true, true, true) then
for i = start_row, end_row do
table.insert(lines, text[i]:sub(start_col, end_col))
end
end
return lines
end
local T = new_set()
T["Scratch"] = new_set({
hooks = {
pre_once = function()
child.restart({ "-u", "scripts/minimal_init.lua" })
child.lua_func(mock)
end,
post_once = child.stop,
},
})
local BUFFER_TEXT = {
"some",
"text here will be",
"inserted",
"now",
}
T["Scratch"]["select_branch"] = new_set({
parametrize = { { "v" }, { "V" }, { vim.api.nvim_replace_termcodes("<C-V>", true, true, true) } },
})
T["Scratch"]["select_branch"]["parameter"] = new_set({
parametrize = {
{
{ 1, 1, 1, 4 },
},
{
{ 1, 2, 1, 4 },
},
{
{ 2, 1, 3, 4 },
},
{
{ 1, 1, 2, 2 },
},
{
{ 1, 1, 1, 1 },
},
{
{ 1, 1, 4, 4 },
},
},
})
T["Scratch"]["select_branch"]["parameter"]["some_text"] = function(selection_mode, coord)
child.api.nvim_buf_set_lines(0, 0, -1, false, BUFFER_TEXT)
child.api.nvim_set_keymap("v", " ", ":Scratch<CR>", {})
select_wise(coord, selection_mode)
MiniTest.add_note("|1>" .. vim.inspect(child.api.nvim_get_mode()))
MiniTest.add_note(
"|2>"
.. vim.inspect(
child.lua_get(
[[require("scratch.utils").getSelectedText(".", vim.api.nvim_get_mode().mode)]]
)
)
)
child.type_keys(" ")
MiniTest.expect.equality(
table_select(BUFFER_TEXT, coord, selection_mode),
child.lua_get("_G.scratch_opts").content
)
end
T["Scratch"]["range_branch"] = new_set()
T["Scratch"]["range_branch"]["lines"] = function()
child.api.nvim_buf_set_lines(0, 0, -1, false, BUFFER_TEXT)
child.type_keys(":1,2Scratch<CR>")
MiniTest.expect.equality(
table_select(BUFFER_TEXT, { 1, 1, 2, 2 }, "V"),
child.lua_get("_G.scratch_opts").content
)
end
T["Scratch"]["range_branch"]["selection"] = function()
child.api.nvim_buf_set_lines(0, 0, -1, false, BUFFER_TEXT)
select_wise({ 1, 1, 3, 3 }, "V")
child.type_keys(":", "Scratch<CR>")
MiniTest.expect.equality(
table_select(BUFFER_TEXT, { 1, 1, 3, 2 }, "V"),
child.lua_get("_G.scratch_opts").content
)
end
return T
168 changes: 168 additions & 0 deletions tests/test_select.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
local child = MiniTest.new_child_neovim()
local getSelectedText
local function table_select(text, coord, selection_mode)
local lines = {}
local start_row, start_col, end_row, end_col = coord[1], coord[2], coord[3], coord[4]
if selection_mode == "v" then
table.insert(lines, text[start_row]:sub(start_col))
for i = start_row + 1, end_row do
table.insert(lines, text[i])
end
local ind = end_row - start_row + 1
lines[ind] = lines[ind]:sub(1, end_col)
elseif selection_mode == "V" then
for i = start_row, end_row do
table.insert(lines, text[i])
end
elseif selection_mode == vim.api.nvim_replace_termcodes("<C-V>", true, true, true) then
for i = start_row, end_row do
table.insert(lines, text[i]:sub(start_col, end_col))
end
end
return lines
end
local select_wise = function(coord, selection_mode)
local vim = child
local start_row, start_col, end_row, end_col = coord[1], coord[2], coord[3], coord[4]
local mode = vim.api.nvim_get_mode()
if mode.mode ~= "n" then
local esc = vim.api.nvim_replace_termcodes("<ESC>", true, true, true)
vim.api.nvim_cmd({ cmd = "normal", bang = true, args = { esc } }, {})
vim.api.nvim_cmd({ cmd = "normal", bang = true, args = { esc } }, {})
end
selection_mode = vim.api.nvim_replace_termcodes(selection_mode, true, true, true)
vim.api.nvim_cmd({ cmd = "normal", bang = true, args = { selection_mode } }, {})

vim.api.nvim_win_set_cursor(0, { start_row, start_col - 1 })
vim.cmd("normal! o")
vim.api.nvim_win_set_cursor(0, { end_row, end_col - 1 })
end

-- local function old_real(mark, mode)
-- local _, csrow, cscol, _ = unpack(vim.fn.getpos("'<"))
-- local _, cerow, cecol, _ = unpack(vim.fn.getpos("'>"))
--
-- local lines = vim.fn.getline(csrow, cerow)
-- local n = #lines
-- if n <= 0 then
-- return {}
-- end
-- lines[n] = string.sub(lines[n], 1, cecol)
-- lines[1] = string.sub(lines[1], cscol)
-- return lines
-- end

local new_set = MiniTest.new_set
local T = new_set({
parametrize = { { "v" }, { "V" }, { vim.api.nvim_replace_termcodes("<C-V>", true, true, true) } },
})
T["param"] = new_set({
parametrize = {
{
{ 1, 1, 1, 4 },
},
{
{ 1, 2, 1, 4 },
},
{
{ 2, 1, 3, 4 },
},
{
{ 1, 1, 2, 2 },
},
{
{ 1, 1, 1, 1 },
},
{
{ 1, 1, 4, 4 },
},
},
})
local BUFFER_TEXT = {
"some",
"text here will be",
"inserted",
"now",
}
-- T["param"]["old"] = new_set({
-- hooks = {
-- pre_case = function()
-- child.restart({ "-u", "scripts/minimal_init.lua" })
-- child.api.nvim_buf_set_lines(0, 0, -1, false, BUFFER_TEXT)
-- end,
-- post_case = function()
-- child.stop()
-- end,
-- },
-- })
T["param"]["new"] = new_set({
hooks = {
pre_case = function()
child.restart({ "-u", "scripts/minimal_init.lua" })
child.api.nvim_buf_set_lines(0, 0, -1, false, BUFFER_TEXT)
getSelectedText = require("scratch.utils").getSelectedText
end,
post_case = function()
child.stop()
end,
},
n_retry = 2,
})
-- T["param"]["old"]["not_workd"] = function(selection_mode, coord)
-- select_wise(coord, selection_mode)
-- MiniTest.expect.no_equality(
-- table_select(BUFFER_TEXT, coord, selection_mode),
-- child.lua_func(old_real)
-- )
-- end
T["param"]["new"]["workd"] = function(selection_mode, coord)
select_wise(coord, selection_mode)
MiniTest.expect.equality(
table_select(BUFFER_TEXT, coord, selection_mode),
child.lua_func(getSelectedText, ".", selection_mode)
)
end
-- T["param"]["old"]["at_command"] = function(selection_mode, coord)
-- select_wise(coord, selection_mode)
-- child.type_keys(":")
-- MiniTest.expect.equality(
-- table_select(BUFFER_TEXT, coord, selection_mode),
-- child.lua_func(old_real)
-- )
-- end
T["param"]["new"]["at_command"] = function(selection_mode, coord)
select_wise(coord, selection_mode)
child.type_keys(":")
MiniTest.add_note("|1>--- " .. vim.inspect(child.fn.getpos("'>")))
MiniTest.add_note("|2>--- " .. vim.inspect(child.fn.getpos(".")))
MiniTest.expect.equality(
table_select(BUFFER_TEXT, coord, selection_mode),
child.lua_func(getSelectedText, "'>", selection_mode)
)
end
T["new"] = new_set({
hooks = {
pre_case = function()
child.restart({ "-u", "scripts/minimal_init.lua" })
child.api.nvim_buf_set_lines(0, 0, -1, false, {})
getSelectedText = require("scratch.utils").getSelectedText
end,
post_case = function()
child.stop()
end,
},
parametrize = { { { 1, 1, 1, 1 } } },
})
T["new"]["empty_file"] = function(selection_mode, coord)
select_wise(coord, selection_mode)
local pos1 = child.fn.getpos("v")
local pos2 = child.fn.getpos(".")
MiniTest.add_note("|1>--- " .. vim.inspect(pos1))
MiniTest.add_note("|2>--- " .. vim.inspect(pos2))
MiniTest.expect.equality(
table_select({ "" }, coord, selection_mode),
child.lua_func(getSelectedText, ".", selection_mode)
)
end

return T

0 comments on commit 0e3ee1f

Please sign in to comment.