Skip to content

Commit

Permalink
feat(jump): added options for remote operator pending mode
Browse files Browse the repository at this point in the history
  • Loading branch information
folke committed Jun 26, 2023
1 parent 6f6af15 commit 436d1f4
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 37 deletions.
16 changes: 14 additions & 2 deletions lua/flash/config.lua
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,9 @@ local defaults = {
},
},
-- options used for remote flash
remote = {},
remote = {
remote_op = { restore = true, motion = true },
},
},
-- options for the floating window that shows the prompt,
-- for regular jumps
Expand All @@ -164,7 +166,17 @@ local defaults = {
zindex = 1000,
},
},
remote = {},
-- options for remote operator pending mode
remote_op = {
-- restore window views and cursor position
-- after doing a remote operation
restore = false,
-- always enter a new motion when doing a remote operation,
-- and jump.pos is `start` or `end`.
-- When `false`, the remote window's cursor position and jump
-- target will be used instead.
motion = false,
},
}

---@type Flash.Config
Expand Down
91 changes: 57 additions & 34 deletions lua/flash/jump.lua
Original file line number Diff line number Diff line change
Expand Up @@ -48,59 +48,82 @@ end
---@return Flash.Match?
function M.remote_op(match, state)
vim.api.nvim_feedkeys(Util.t("<Esc>"), "t", false)
local win = vim.api.nvim_get_current_win()

-- schedul e 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)
-- use a new motion to select the text-object to act on,
-- unless we're jumping to a range
if state.opts.remote_op.motion then
if vim.fn.mode() == "v" then
vim.cmd("normal! v")
end

-- 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
if state.opts.jump.pos == "range" then
vim.api.nvim_win_set_cursor(match.win, match.pos)
vim.cmd("normal! v")
vim.api.nvim_win_set_cursor(match.win, match.end_pos)
else
vim.api.nvim_win_set_cursor(
match.win,
state.opts.jump.pos == "start" and match.pos or match.end_pos
)
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)
-- otherwise, use the remote window's cursor position
else
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)
end

-- re-trigger the operator
vim.api.nvim_input('"' .. vim.v.register .. vim.v.operator)
vim.schedule(function()
M.restore_remote(state)
end)
if state.opts.remote_op.restore then
vim.schedule(function()
M.restore_remote(state)
end)
end
end)
end

-- Restore window views after the remote operation ends
---@param state Flash.State
function M.restore_remote(state)
-- wait till getting user input clears
if Hacks.mappings_disabled() then
local check = assert(vim.loop.new_check())
check:start(function()
if not Hacks.mappings_disabled() then
check:stop()
check:close()
vim.schedule(function()
M.restore_remote(state)
end)
end
end)
return
end

local restore = vim.schedule_wrap(function()
state:restore()
end)

-- wait till getting user input clears
if not Hacks.mappings_enabled() then
return Util.on_done(function()
return Hacks.mappings_enabled()
end, function()
M.restore_remote(state)
end)

-- wait till operator pending mode ends
elseif vim.fn.mode(true):sub(1, 2) == "no" then
return Util.on_done(function()
return vim.fn.mode(true):sub(1, 2) ~= "no"
end, function()
M.restore_remote(state)
end)

-- restore after making edits
if vim.v.operator == "c" then
elseif vim.fn.mode() == "i" and vim.v.operator == "c" then
vim.api.nvim_create_autocmd("InsertLeave", {
once = true,
callback = restore,
Expand Down
1 change: 0 additions & 1 deletion lua/flash/state.lua
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ local Prompt = require("flash.prompt")
---@field matcher? fun(win: window, state:Flash.State, pos: {from:Pos, to:Pos}): Flash.Match[]
---@field pattern? string
---@field labeler? fun(matches:Flash.Match[], state:Flash.State)
---@field remote? {on_restore?: fun()}

---@class Flash.State
---@field win window
Expand Down

0 comments on commit 436d1f4

Please sign in to comment.