Skip to content

fix: builtin find not working with dot repeat #622

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Jun 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -174,10 +174,10 @@ vim.keymap.set({ "n", "x", "o" }, ",", ts_repeat_move.repeat_last_move_previous)
-- vim.keymap.set({ "n", "x", "o" }, ",", ts_repeat_move.repeat_last_move_opposite)

-- Optionally, make builtin f, F, t, T also repeatable with ; and ,
vim.keymap.set({ "n", "x", "o" }, "f", ts_repeat_move.builtin_f)
vim.keymap.set({ "n", "x", "o" }, "F", ts_repeat_move.builtin_F)
vim.keymap.set({ "n", "x", "o" }, "t", ts_repeat_move.builtin_t)
vim.keymap.set({ "n", "x", "o" }, "T", ts_repeat_move.builtin_T)
vim.keymap.set({ "n", "x", "o" }, "f", ts_repeat_move.builtin_f_expr, { expr = true })
vim.keymap.set({ "n", "x", "o" }, "F", ts_repeat_move.builtin_F_expr, { expr = true })
vim.keymap.set({ "n", "x", "o" }, "t", ts_repeat_move.builtin_t_expr, { expr = true })
vim.keymap.set({ "n", "x", "o" }, "T", ts_repeat_move.builtin_T_expr, { expr = true })
```

You can even make a custom repeat behaviour.
Expand Down
68 changes: 66 additions & 2 deletions lua/nvim-treesitter/textobjects/repeatable_move.lua
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ local M = {}

M.last_move = nil
-- { func = move, opts = { ... }, additional_args = {} }
-- { func = builtin_find, opts = { ... }, additional_args = {} }
-- { func = "f", opts = { ... }, additional_args = {} }
-- register any other function, but make sure the the first args is an opts table with a `forward` boolean.
-- prefer to set using M.set_last_move

Expand Down Expand Up @@ -104,7 +104,21 @@ M.repeat_last_move = function(opts_extend)
opts = M.last_move.opts
end

M.last_move.func(opts, unpack(M.last_move.additional_args))
if M.last_move.func == "f" or M.last_move.func == "t" then
if opts.forward then
vim.cmd([[normal! ]] .. vim.v.count1 .. ";")
else
vim.cmd([[normal! ]] .. vim.v.count1 .. ",")
end
elseif M.last_move.func == "F" or M.last_move.func == "T" then
if opts.forward then
vim.cmd([[normal! ]] .. vim.v.count1 .. ",")
else
vim.cmd([[normal! ]] .. vim.v.count1 .. ";")
end
else
M.last_move.func(opts, unpack(M.last_move.additional_args))
end
return true
end
return false
Expand All @@ -122,7 +136,49 @@ M.repeat_last_move_previous = function()
return M.repeat_last_move { forward = false }
end

-- NOTE: map builtin_f_expr, builtin_F_expr, builtin_t_expr, builtin_T_expr with { expr = true }.
--
-- We are not using M.make_repeatable_move or M.set_last_move and instead registering at M.last_move manually
-- because move_fn is not a function (but string f, F, t, T).
-- We don't want to execute a move function, but instead return an expression (f, F, t, T).
M.builtin_f_expr = function()
M.last_move = {
func = "f",
opts = { forward = true },
additional_args = {},
}
return "f"
end

M.builtin_F_expr = function()
M.last_move = {
func = "F",
opts = { forward = false },
additional_args = {},
}
return "F"
end

M.builtin_t_expr = function()
M.last_move = {
func = "t",
opts = { forward = true },
additional_args = {},
}
return "t"
end

M.builtin_T_expr = function()
M.last_move = {
func = "T",
opts = { forward = false },
additional_args = {},
}
return "T"
end

-- implements naive f, F, t, T with repeat support
---@deprecated
local function builtin_find(opts)
-- opts include forward, inclusive, char, repeating, winid
-- forward = true -> f, t
Expand Down Expand Up @@ -206,7 +262,9 @@ end
-- because we don't want to behave the same way as the first movement.
-- For example, we want to repeat the search character given to f, F, t, T.
-- Also, we want to be able to to find the next occurence when using t, T with repeat, excluding the current position.
---@deprecated
M.builtin_f = function()
vim.notify_once("nvim-treesitter-textobjects: map `builtin_f_expr` with `{expr=true}` instead.", vim.log.levels.WARN)
local opts = { forward = true, inclusive = true }
local char = builtin_find(opts)
if char ~= nil then
Expand All @@ -216,7 +274,9 @@ M.builtin_f = function()
end
end

---@deprecated
M.builtin_F = function()
vim.notify_once("nvim-treesitter-textobjects: map `builtin_F_expr` with `{expr=true}` instead.", vim.log.levels.WARN)
local opts = { forward = false, inclusive = true }
local char = builtin_find(opts)
if char ~= nil then
Expand All @@ -226,7 +286,9 @@ M.builtin_F = function()
end
end

---@deprecated
M.builtin_t = function()
vim.notify_once("nvim-treesitter-textobjects: map `builtin_t_expr` with `{expr=true}` instead.", vim.log.levels.WARN)
local opts = { forward = true, inclusive = false }
local char = builtin_find(opts)
if char ~= nil then
Expand All @@ -236,7 +298,9 @@ M.builtin_t = function()
end
end

---@deprecated
M.builtin_T = function()
vim.notify_once("nvim-treesitter-textobjects: map `builtin_T_expr` with `{expr=true}` instead.", vim.log.levels.WARN)
local opts = { forward = false, inclusive = false }
local char = builtin_find(opts)
if char ~= nil then
Expand Down
8 changes: 4 additions & 4 deletions scripts/minimal_init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,7 @@ vim.keymap.set({ "n", "x", "o" }, ";", ts_repeat_move.repeat_last_move)
vim.keymap.set({ "n", "x", "o" }, ",", ts_repeat_move.repeat_last_move_opposite)

-- Optionally, make builtin f, F, t, T also repeatable with ; and ,
vim.keymap.set({ "n", "x", "o" }, "f", ts_repeat_move.builtin_f)
vim.keymap.set({ "n", "x", "o" }, "F", ts_repeat_move.builtin_F)
vim.keymap.set({ "n", "x", "o" }, "t", ts_repeat_move.builtin_t)
vim.keymap.set({ "n", "x", "o" }, "T", ts_repeat_move.builtin_T)
vim.keymap.set({ "n", "x", "o" }, "f", ts_repeat_move.builtin_f_expr, { expr = true })
vim.keymap.set({ "n", "x", "o" }, "F", ts_repeat_move.builtin_F_expr, { expr = true })
vim.keymap.set({ "n", "x", "o" }, "t", ts_repeat_move.builtin_t_expr, { expr = true })
vim.keymap.set({ "n", "x", "o" }, "T", ts_repeat_move.builtin_T_expr, { expr = true })