-
Reading the Aliasing (2.4) section of the help file, it suggests creating mappings for motions of single-character aliases: vim.keymap.set("o", "ir", "i[")
vim.keymap.set("o", "ar", "a[")
vim.keymap.set("o", "ia", "i<")
vim.keymap.set("o", "aa", "a<") I would like to do something similar, but for tabular aliases (e.g. mapping "vaq" to "select around the closest pair of quotes". However, this doesn't seem trivial. It must be possible since treesitter kind of does this. Does anyone have an idea for this? Thanks in advance. |
Beta Was this translation helpful? Give feedback.
Answered by
Frankwii
May 20, 2025
Replies: 1 comment
-
For anyone reading this: I ended up writing some custom Lua code for this. --- @param keys string
local function blocking_feedkeys(keys)
vim.api.nvim_feedkeys(vim.api.nvim_replace_termcodes(keys, true, true, true), 'x', false)
end
--- @param pos1 Position
--- @param pos2 Position
--- @return number
local function compute_distance(pos1, pos2)
local d = vim.api.nvim_win_get_width(0) * (math.abs(pos1[1] - pos2[1])) + math.abs(pos1[2] - pos2[2])
return d
end
--- @param motion string
--- @param initial_position Position
local function attempt_motion(motion, initial_position)
blocking_feedkeys("v" .. motion)
local right_position = vim.api.nvim_win_get_cursor(0)
blocking_feedkeys("o")
local left_position = vim.api.nvim_win_get_cursor(0)
blocking_feedkeys('<esc>')
vim.api.nvim_win_set_cursor(0, initial_position)
return { left_position, right_position }
end
--- @param d1 number
--- @param d2 number
--- @return number
local function process_distances(d1, d2)
if math.max(d1, d2) == 0 then
return math.huge
else
return math.min(d1, d2)
end
end
--- @param aliased table<string>
local perfom_closest_motion = function(aliased)
local initial_position = vim.api.nvim_win_get_cursor(0)
local distances = {}
for idx, motion in ipairs(aliased) do
local positions = attempt_motion(motion, initial_position)
distances[idx] =
process_distances(compute_distance(initial_position, positions[1]), compute_distance(initial_position, positions[2]))
end
local final_motion = "FINAL"
local max_distance = math.huge
for idx, _ in pairs(distances) do
local distance = distances[idx]
local motion = aliased[idx]
if distance < max_distance then
max_distance = distance
final_motion = motion
end
end
blocking_feedkeys("v" .. final_motion)
end
--- @param aliased table<string>
--- @param alias string
M.map_alias_motion = function(alias, aliased)
vim.keymap.set({ "o", "v" }, alias, function()
blocking_feedkeys("<esc>")
perfom_closest_motion(aliased)
end, { noremap = true, silent = false, desc = "Operator alias: " .. alias})
end Then just call it like this (map it however you prefer): M.map_alias_motion('aq', {"a\"", "a'", "a`"})
M.map_alias_motion('iq', {"i\"", "i'", "i`"}) |
Beta Was this translation helpful? Give feedback.
0 replies
Answer selected by
Frankwii
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
For anyone reading this: I ended up writing some custom Lua code for this.