leap.nvim
leap.nvim copied to clipboard
Handling inclusive_op and exclusivity(till) with bi-directional search?
Discussed in https://github.com/ggandor/leap.nvim/discussions/92
Originally posted by austinliuigi January 5, 2023 I've been trying out bi-directional search and I find it really comfortable, but I'm not sure how to better tweak my config it so that it's the most intuitive for me in visual/operator-pending mode:
s -> Inclusive regardless of which direction I jump
x -> Exclusive regardless of which direction I jump
However, the only way that I've found to achieve this behavior is quite hacky and I'm wondering if there's a better way. This is my current configuration:
-- [[ `s` mappings ]]
vim.keymap.set({'n', 'x'}, 's', function()
require("leap").leap({
target_windows = { vim.fn.win_getid() },
inclusive_op = true
})
end, { noremap = true })
vim.keymap.set({'o'}, 's', function()
local pre_leap_pos = vim.fn.getpos(".")
require("leap").leap({
target_windows = { vim.fn.win_getid() },
inclusive_op = true
})
local post_leap_pos = vim.fn.getpos(".")
-- If jumping behind original position
if (pre_leap_pos[2] > post_leap_pos[2]) or ((pre_leap_pos[2] == post_leap_pos[2]) and (pre_leap_pos[3] > post_leap_pos[3])) then
vim.cmd("normal! h")
end
end, { remap = false })
-- [[ `x` mappings ]]
vim.keymap.set({'x'}, 'x', function()
local pre_leap_pos = vim.fn.getpos(".")
require("leap").leap({
target_windows = { vim.fn.win_getid() },
inclusive_op = true
})
local post_leap_pos = vim.fn.getpos(".")
-- If jumping behind original position
if (pre_leap_pos[2] > post_leap_pos[2]) or ((pre_leap_pos[2] == post_leap_pos[2]) and (pre_leap_pos[3] > post_leap_pos[3])) then
vim.cmd("normal! l")
else
vim.cmd("normal! h")
end
end, { remap = false })
vim.keymap.set({'o'}, 'x', function()
local pre_leap_pos = vim.fn.getpos(".")
require("leap").leap({
target_windows = { vim.fn.win_getid() },
inclusive_op = true
})
local post_leap_pos = vim.fn.getpos(".")
-- If jumping forward from original position
if (pre_leap_pos[2] > post_leap_pos[2]) or ((pre_leap_pos[2] == post_leap_pos[2]) and (pre_leap_pos[3] < post_leap_pos[3])) then
vim.cmd("normal! h")
end
end, { remap = false })
Insights
1. inclusive_op
The reason the separate operator-pending mappings are necessary is because inclusive_op behaves incorrectly(?)
Example ('|' is cursor, '1' is first label, '2' is second label)
abcdefg|abcdefg
Expected behavior:
inclusive_op = true
dsde1->abcabcdefgdsde2->abcdefgefg
inclusive_op = false
dsde1->abcdabcdefgdsde2->abcdefgdefg
Actual behavior:
inclusive_op = true
dsde1->abcdabcdefg×dsde2->abcdefgefg✓
inclusive_op = false
dsde1->abcabcdefg×dsde2->abcdefgefg✓
When jumping backwards, it seems like inclusive_op behaves opposite as expected. In hindsight, this is the main concern for this discussion thread.
2. Determining jump direction
For my visual mode x mapping, I do some logic to determine whether I jumped backwards or forwards using vim's getpos(). Is there a better way to do this using leap's api?