local M = {} local function escape_lua_pattern(s) local matches = { ["^"] = "%^", ["$"] = "%$", ["("] = "%(", [")"] = "%)", ["%"] = "%%", ["."] = "%.", ["["] = "%[", ["]"] = "%]", ["*"] = "%*", ["+"] = "%+", ["-"] = "%-", ["?"] = "%?", } return s:gsub(".", matches) end local targets = { '"', "'", "(", ")", "{", "}", "[", "]", "`" } function M.setup(config) vim.validate({ config = { config, "table", true } }) vim.validate({ additional_targets = { config.additional_targets, "table", true } }) vim.validate({ targets = { config.targets, "table", true } }) -- if config and config.targets then targets = config.targets return end if config and config.additional_targets then for _, target in ipairs(config.additional_targets) do targets[#targets + 1] = target end end end function M.in_and_out() local current_row, current_col = unpack(vim.api.nvim_win_get_cursor(0)) local lines_in_buf = vim.api.nvim_buf_get_lines(0, current_row - 1, -1, false) local target_row = 0 local target_col = nil for i, line in ipairs(lines_in_buf) do for _, char in ipairs(targets) do local found_col = string.find(line, escape_lua_pattern(char), current_col + 1) if found_col and (not target_col or found_col < target_col) then -- If char is a multibyte character, we need to take into account the extra bytes. target_col = found_col + vim.fn.strlen(char) - 1 end end if target_col then target_row = current_row + i - 1 break end current_col = 0 end if target_col then vim.api.nvim_win_set_cursor(0, { target_row, target_col }) end end function M.in_and_out_cmd() local current_pos = vim.fn.getcmdpos() local target_pos = nil local line = vim.fn.getcmdline() vim.notify(current_pos .. line) for _, char in ipairs(targets) do local found_pos = string.find(line, escape_lua_pattern(char), current_pos + 1) if found_pos and (not target_pos or found_pos < target_pos) then -- If char is a multibyte character, we need to take into account the extra bytes. target_pos = found_pos + vim.fn.strlen(char) - 1 end end if target_pos then vim.print("target pos " .. target_pos) local worked = vim.fn.setcmdpos(target_pos + 1) vim.print("worked = " .. worked) end -- vim.fn.setcmdpos(1) end return M