(Range) preserve visual selection orientation in from_motion
Some checks failed
ci / ci (push) Failing after 1m7s
Some checks failed
ci / ci (push) Failing after 1m7s
This commit is contained in:
4
.gitmodules
vendored
4
.gitmodules
vendored
@@ -2,7 +2,3 @@
|
||||
path = library/busted
|
||||
url = https://github.com/LuaCATS/busted
|
||||
branch = main
|
||||
[submodule "library/luv"]
|
||||
path = library/luv
|
||||
url = https://github.com/LuaCATS/luv
|
||||
branch = main
|
||||
|
||||
Submodule library/luv deleted from 3615eb12c9
26
lua/u.lua
26
lua/u.lua
@@ -542,6 +542,7 @@ function Range.from_motion(motion, opts)
|
||||
local is_bracket_txtobj = is_txtobj and BRACKET_MAP[motion_rest] ~= nil
|
||||
|
||||
-- SECTION: Capture original state for restoration
|
||||
local vinf, vinf_inverted = Range.from_vtext()
|
||||
local original_state = {
|
||||
winview = vim.fn.winsaveview(),
|
||||
unnamed_register = vim.fn.getreg '"',
|
||||
@@ -551,7 +552,8 @@ function Range.from_motion(motion, opts)
|
||||
opfunc = vim.go.operatorfunc,
|
||||
prev_captured_range = _G.Range__from_motion_opfunc_captured_range,
|
||||
prev_mode = vim.fn.mode(),
|
||||
vinf = Range.from_vtext(),
|
||||
vinf = vinf,
|
||||
vinf_inverted = vinf_inverted,
|
||||
}
|
||||
--- @type u.Range|nil
|
||||
_G.Range__from_motion_opfunc_captured_range = nil
|
||||
@@ -603,7 +605,9 @@ function Range.from_motion(motion, opts)
|
||||
vim.fn.setpos('.', original_state.cursor)
|
||||
vim.fn.setpos("'[", original_state.mark_lbracket)
|
||||
vim.fn.setpos("']", original_state.mark_rbracket)
|
||||
if original_state.prev_mode ~= 'n' then original_state.vinf:set_visual_selection() end
|
||||
if original_state.prev_mode ~= 'n' then
|
||||
original_state.vinf:set_visual_selection(original_state.vinf_inverted)
|
||||
end
|
||||
vim.go.operatorfunc = original_state.opfunc
|
||||
_G.Range__from_motion_opfunc_captured_range = original_state.prev_captured_range
|
||||
|
||||
@@ -663,7 +667,8 @@ end
|
||||
function Range.from_vtext()
|
||||
local r = Range.from_marks('v', '.')
|
||||
if vim.fn.mode() == 'V' then r = r:to_linewise() end
|
||||
return r
|
||||
local inverted = Pos.from_pos '.' ~= r.stop
|
||||
return r, inverted
|
||||
end
|
||||
|
||||
--- Get range information from the current text range being operated on
|
||||
@@ -806,18 +811,23 @@ end
|
||||
|
||||
function Range:save_to_extmark() return Extmark.from_range(self, NS) end
|
||||
|
||||
function Range:set_visual_selection()
|
||||
--- @param inverted boolean?
|
||||
function Range:set_visual_selection(inverted)
|
||||
if self:is_empty() then return end
|
||||
if vim.api.nvim_get_current_buf() ~= self.start.bufnr then
|
||||
error 'Range:set_visual_selection() called on a buffer other than the current buffer'
|
||||
end
|
||||
|
||||
local curr_mode = vim.fn.mode()
|
||||
if curr_mode ~= self.mode then vim.cmd.normal { args = { self.mode }, bang = true } end
|
||||
local curr_mode = vim.fn.mode():sub(1, 1)
|
||||
if curr_mode ~= self.mode then vim.cmd.normal { args = { ESC .. self.mode }, bang = true } end
|
||||
|
||||
self.start:save_to_pos '.'
|
||||
local start, stop = self.start, self.stop
|
||||
if inverted then
|
||||
start, stop = stop, start
|
||||
end
|
||||
start:save_to_pos '.'
|
||||
vim.cmd.normal { args = { 'o' }, bang = true }
|
||||
self.stop:save_to_pos '.'
|
||||
stop:save_to_pos '.'
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
@@ -468,6 +468,42 @@ describe('Range', function()
|
||||
end)
|
||||
end)
|
||||
|
||||
it('from_motion preserves visual selection orientation (cursor at start)', function()
|
||||
withbuf({ 'the quick brown fox' }, function()
|
||||
vim.fn.setpos('.', { 0, 1, 5, 0 })
|
||||
vim.cmd.normal 'v'
|
||||
vim.cmd.normal { args = { 'o' }, bang = true }
|
||||
vim.fn.setpos('.', { 0, 1, 3, 0 })
|
||||
vim.cmd.normal { args = { 'o' }, bang = true }
|
||||
|
||||
vim.cmd.normal { args = { 'o' }, bang = true }
|
||||
local cursor_before = vim.fn.getpos('.')[3]
|
||||
|
||||
Range.from_motion 'aw'
|
||||
|
||||
vim.cmd.normal { args = { 'o' }, bang = true }
|
||||
local cursor_after = vim.fn.getpos('.')[3]
|
||||
|
||||
assert.are_not_same(cursor_before, cursor_after)
|
||||
end)
|
||||
end)
|
||||
|
||||
it('from_motion preserves visual selection orientation (cursor at stop)', function()
|
||||
withbuf({ 'the quick brown fox' }, function()
|
||||
vim.fn.setpos('.', { 0, 1, 3, 0 })
|
||||
vim.cmd.normal 'vll'
|
||||
|
||||
local cursor_before = vim.fn.getpos('.')[3]
|
||||
|
||||
Range.from_motion 'aw'
|
||||
|
||||
vim.cmd.normal { args = { 'o' }, bang = true }
|
||||
local cursor_after = vim.fn.getpos('.')[3]
|
||||
|
||||
assert.are_not_same(cursor_before, cursor_after)
|
||||
end)
|
||||
end)
|
||||
|
||||
describe('from_motion with max_lines', function()
|
||||
it('returns nil when bracket chars are beyond max_lines', function()
|
||||
-- A large block where { and } are far from cursor
|
||||
|
||||
Reference in New Issue
Block a user