fix: I dont even know anymore

This commit is contained in:
Jan K9f 2025-07-28 19:52:08 +02:00
commit 12abc352c0
Signed by: jank
GPG key ID: 22BEAC760B3333D6

View file

@ -1,25 +1,13 @@
local M = {} local M = {}
M.options = {} -- Default options
local defaults = { local defaults = {
hotkey = "<leader>tq", hotkey = "<leader>tq",
quote_chars = { "'", '"', "`" }, quote_chars = { "'", '"', "`" },
} }
---Merges user-provided options with default options. -- Initialize options with a deep copy of the defaults
---@param user_options table|nil User-provided options M.options = vim.deepcopy(defaults)
function M.setup(user_options)
M.options = vim.tbl_deep_extend("force", {}, defaults, user_options or {})
local map_opts = {
desc = "Swaps the quotes around",
silent = true,
noremap = true,
}
vim.keymap.set("n", M.options.hotkey, M.toggle_quotes, map_opts)
end
--- Checks if a given character is one of the predefined quote characters. --- Checks if a given character is one of the predefined quote characters.
--- @param char string The character to check. --- @param char string The character to check.
@ -34,92 +22,67 @@ local function is_defined_quote_char(char)
end end
--- Finds the starting and ending indices of a quoted string on the current line --- Finds the starting and ending indices of a quoted string on the current line
--- that contains the cursor, using a predefined set of quote characters. --- that contains the cursor.
--- @param line string The current line of text. --- @param line string The current line of text.
--- @param cursor_col number The column index of the cursor (0-based). --- @param cursor_col number The column index of the cursor (0-based).
--- @return number start_index The 0-based starting index of the quote, or -1 if not found. --- @return number|nil start_index The 0-based starting index of the quote, or nil if not found.
--- @return number end_index The 0-based ending index of the quote, or -1 if not found. --- @return number|nil end_index The 0-based ending index of the quote, or nil if not found.
--- @return string current_quote_char The character of the identified quote, or nil. --- @return string|nil current_quote_char The character of the identified quote, or nil.
local function find_quoted_string_at_cursor(line, cursor_col) local function find_quoted_string_at_cursor(line, cursor_col)
local start_quote_index = -1 local quote_positions = {}
local end_quote_index = -1 for i = 1, #line do
local current_quote_char = nil local char = line:sub(i, i)
if is_defined_quote_char(char) then
-- Iterate through the line to find a matching pair of quotes that contain the cursor. table.insert(quote_positions, { char = char, index = i - 1 })
for i = 0, #line - 1 do
local char = line:sub(i + 1, i + 1)
if not is_defined_quote_char(char) then
goto continue_loop -- Not a quote character, skip.
end end
-- If we haven't found an opening quote yet, this is a potential candidate.
if start_quote_index == -1 then
start_quote_index = i
current_quote_char = char
elseif char == current_quote_char then
-- Found a closing quote that matches the current opening quote.
end_quote_index = i
-- Check if the cursor is within this identified quoted string (inclusive of quotes).
if (cursor_col >= start_quote_index and cursor_col <= end_quote_index) or (cursor_col <= start_quote_index and cursor_col <= end_quote_index) then
return start_quote_index, end_quote_index, current_quote_char
else
-- Cursor is not in this string, reset to look for the next potential string.
start_quote_index = -1
end_quote_index = -1
current_quote_char = nil
end
end
::continue_loop::
end end
-- No relevant quoted string found that contains the cursor. for i = 1, #quote_positions do
return -1, -1, nil local start_quote = quote_positions[i]
for j = i + 1, #quote_positions do
local end_quote = quote_positions[j]
if start_quote.char == end_quote.char then
if cursor_col >= start_quote.index and cursor_col <= end_quote.index then
return start_quote.index, end_quote.index, start_quote.char
end
-- Found a pair, so we skip the inner quote for the next outer loop iteration
i = j
goto next_outer_loop
end
end
::next_outer_loop::
end
return nil, nil, nil
end end
--- Cycles to the next quote character in the predefined list. --- Cycles to the next quote character in the predefined list.
--- @param current_char string The current quote character. --- @param current_char string The current quote character.
--- @return string The next quote character, or nil if current_char is not found. --- @return string The next quote character.
local function get_next_quote_char(current_char) local function get_next_quote_char(current_char)
local current_char_list_index = -1 local num_chars = #M.options.quote_chars
for i, qc in ipairs(M.options.quote_chars) do for i = 1, num_chars do
if qc == current_char then if M.options.quote_chars[i] == current_char then
current_char_list_index = i return M.options.quote_chars[(i % num_chars) + 1]
break
end end
end end
return M.options.quote_chars[1]
if current_char_list_index == -1 then
return nil -- Current character not in our defined list.
end
local next_char_list_index = (current_char_list_index % #M.options.quote_chars) + 1
return M.options.quote_chars[next_char_list_index]
end end
--- Toggles the quotes around the string at the cursor position --- Toggles the quotes around the string at the cursor position.
--- by cycling through a predefined list of quote characters.
function M.toggle_quotes() function M.toggle_quotes()
local current_line = vim.api.nvim_get_current_line() local current_line = vim.api.nvim_get_current_line()
local cursor_row, cursor_col = unpack(vim.api.nvim_win_get_cursor(0)) local cursor_row, cursor_col = unpack(vim.api.nvim_win_get_cursor(0))
local start_idx, end_idx, current_char = local start_idx, end_idx, current_char = find_quoted_string_at_cursor(current_line, cursor_col)
find_quoted_string_at_cursor(current_line, cursor_col)
-- If no quoted string containing the cursor was found, do nothing. if not start_idx then
if start_idx == -1 or end_idx == -1 or not current_char then
return return
end end
local next_char = get_next_quote_char(current_char) local next_char = get_next_quote_char(current_char)
if not next_char then
-- This should ideally not happen if current_char came from find_quoted_string_at_cursor
-- and QUOTE_CHARS is consistent, but acts as a safeguard.
return
end
-- Reconstruct the line with the new quote characters.
local new_line = local new_line =
current_line:sub(1, start_idx) .. current_line:sub(1, start_idx) ..
next_char .. next_char ..
@ -127,9 +90,22 @@ function M.toggle_quotes()
next_char .. next_char ..
current_line:sub(end_idx + 2) current_line:sub(end_idx + 2)
-- Update Neovim's buffer and cursor position.
vim.api.nvim_set_current_line(new_line) vim.api.nvim_set_current_line(new_line)
vim.api.nvim_win_set_cursor(0, { cursor_row, cursor_col }) vim.api.nvim_win_set_cursor(0, { cursor_row, cursor_col })
end end
return M --- Merges user-provided options with default options.
--- @param user_options table|nil User-provided options
function M.setup(user_options)
M.options = vim.tbl_deep_extend("force", vim.deepcopy(defaults), user_options or {})
local map_opts = {
desc = "JQuote: Swap quote characters",
silent = true,
noremap = true,
}
vim.keymap.set("n", M.options.hotkey, M.toggle_quotes, map_opts)
end
return M