Skip to content

Commit

Permalink
fix(jump): operator pending mode for remote jumps now behaves correctly
Browse files Browse the repository at this point in the history
  • Loading branch information
folke committed Jun 25, 2023
1 parent 1fa0018 commit cb24e66
Showing 1 changed file with 67 additions and 3 deletions.
70 changes: 67 additions & 3 deletions lua/flash/jump.lua
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
local Pos = require("flash.search.pos")
local Util = require("flash.util")
local M = {}

---@param match Flash.Match
Expand All @@ -10,11 +11,76 @@ function M.jump(match, state)
vim.cmd("normal! m'")
end

local mode = vim.fn.mode(true)
local is_op = mode:sub(1, 2) == "no"
local is_visual = mode:sub(1, 1) == "v"

-- change window if needed
if match.win ~= vim.api.nvim_get_current_win() then
if is_op then
-- use our special logic for remote operator pending mode
return M.remote_op(match, state)
end

if is_visual then
-- cancel visual mode in the current window,
-- to avoid issues with the remote window
vim.cmd("normal! v")
end

vim.api.nvim_set_current_win(match.win)

if is_visual then
-- enable visual mode in the remote window,
-- from its current cursor position
vim.cmd("normal! v")
end
end

M._jump(match, state, { op = is_op })
end

-- Remote operator pending mode.Cancel the operator and
-- re-trigger the operator in the remote window.
---@param match Flash.Match
---@param state Flash.State
---@return Flash.Match?
function M.remote_op(match, state)
vim.api.nvim_feedkeys(Util.t("<Esc>"), "t", false)

-- schedule this so that the active operator is properly cancelled
vim.schedule(function()
vim.api.nvim_set_current_win(match.win)

local from = vim.api.nvim_win_get_cursor(match.win)
M._jump(match, state, { op = true })
local to = vim.api.nvim_win_get_cursor(match.win)

-- if a range was selected, use that instead
if vim.fn.mode() == "v" then
vim.cmd("normal! v") -- end the selection
from = vim.api.nvim_buf_get_mark(0, "<")
to = vim.api.nvim_buf_get_mark(0, ">")
end

-- select the range for the operator
vim.api.nvim_win_set_cursor(0, from)
vim.cmd("normal! v")
vim.api.nvim_win_set_cursor(0, to)

-- re-trigger the operator
vim.api.nvim_input('"' .. vim.v.register .. vim.v.operator)
end)
end

-- Performs the actual jump in the current window,
-- taking operator-pending mode into account.
---@param match Flash.Match
---@param state Flash.State
---@param opts? {op:boolean}
---@return Flash.Match?
function M._jump(match, state, opts)
opts = opts or {}
-- select range
if state.opts.jump.pos == "range" then
if vim.fn.mode() == "v" then
Expand All @@ -24,11 +90,9 @@ function M.jump(match, state)
vim.cmd("normal! v")
vim.api.nvim_win_set_cursor(match.win, match.end_pos)
else
local mode = vim.fn.mode(true)

local pos = state.opts.jump.pos == "start" and match.pos or match.end_pos

if mode:sub(1, 2) == "no" then
if opts.op then
-- fix inclusive/exclusive
-- default is exclusive
if state.opts.jump.inclusive ~= false then
Expand Down

0 comments on commit cb24e66

Please sign in to comment.