diff --git a/lua/import/find_imports.lua b/lua/import/find_imports.lua index ad6d058..a246db4 100644 --- a/lua/import/find_imports.lua +++ b/lua/import/find_imports.lua @@ -31,7 +31,7 @@ local function find_imports(languages) end local types = format_types(config.extensions) - local flags = { "--no-heading", "--no-line-number", "--color=never", "--no-filename" } + local flags = { "--no-heading", "--no-line-number", "--color=never" } local find_command = "rg " .. types @@ -50,7 +50,12 @@ local function find_imports(languages) local imports = {} for _, result in ipairs(results) do - table.insert(imports, { value = result }) + local colonIndex = string.find(result, ":") + + local path = string.sub(result, 1, colonIndex - 1) + local value = string.sub(result, colonIndex + 1) + + table.insert(imports, { value = value, path = path }) end return imports diff --git a/lua/import/picker.lua b/lua/import/picker.lua index c9c88cc..de18c91 100644 --- a/lua/import/picker.lua +++ b/lua/import/picker.lua @@ -7,6 +7,12 @@ local utils = require("import.utils") local default_languages = require("import.languages") local find_imports = require("import.find_imports") local insert_line = require("import.insert_line") +local update_path = require("import.update_path") + +local function is_relative(import_path) + -- Check if the import path is relative or absolute + return import_path:match("^%.%./") or import_path:match("^%./") or import_path:match("^/") +end local function picker(opts) local languages = utils.table_concat(default_languages, opts.custom_languages) @@ -34,6 +40,7 @@ local function picker(opts) value = import.value, display = import.value, ordinal = import.value, + path = import.path, } end, }), @@ -41,7 +48,18 @@ local function picker(opts) actions.select_default:replace(function() actions.close(prompt_bufnr) local selection = action_state.get_selected_entry() - insert_line(selection.value, opts.insert_at_top) + local import_path = utils.extract_path(selection.value) + + if is_relative(import_path) then + local current_path = vim.fn.expand("%:p") + local sel_path = vim.fn.systemlist("git rev-parse --show-toplevel")[1] + .. "/" + .. selection.path + local updated_path = update_path(import_path, sel_path, current_path) + import_path = utils.replace_in_quotes(selection.value, updated_path) + end + + insert_line(import_path, opts.insert_at_top) end) return true end, diff --git a/lua/import/update_path.lua b/lua/import/update_path.lua new file mode 100644 index 0000000..5183d3b --- /dev/null +++ b/lua/import/update_path.lua @@ -0,0 +1,64 @@ +function update_import_path(import_string, old_file_path, new_file_path) + local function split(str, sep) + local fields = {} + str:gsub("[^" .. sep .. "]+", function(c) + fields[#fields + 1] = c + end) + return fields + end + + local function resolve_path(base, relative) + local path_parts = split(base, "/") + table.remove(path_parts) -- Remove the file part from the path + + for part in relative:gmatch("[^/]+") do + if part == ".." then + table.remove(path_parts) -- Go up one directory + elseif part ~= "." then + table.insert(path_parts, part) -- Go into a subdirectory + end + end + + return table.concat(path_parts, "/") + end + + local function compute_relative_path(from, to) + local from_parts = split(from, "/") + local to_parts = split(to, "/") + + -- Remove the file names + table.remove(from_parts) + table.remove(to_parts) + + local common_length = 0 + for i = 1, math.min(#from_parts, #to_parts) do + if from_parts[i] ~= to_parts[i] then + break + end + common_length = i + end + + -- Construct the new relative path + local new_path = "" + for i = 1, #from_parts - common_length do + new_path = new_path .. "../" + end + + for i = common_length + 1, #to_parts do + new_path = new_path .. to_parts[i] .. "/" + end + + -- Add the file name from the resolved path + local resolved_file_name = select(#split(to, "/"), unpack(split(to, "/"))) + new_path = new_path .. resolved_file_name + + return new_path + end + + -- Resolve the absolute path of the original import + local resolved_path = resolve_path(old_file_path, import_string) + -- Compute the new relative path from the new file location + return compute_relative_path(new_file_path, resolved_path) +end + +return update_import_path diff --git a/lua/import/utils.lua b/lua/import/utils.lua index 783ad09..307f26a 100644 --- a/lua/import/utils.lua +++ b/lua/import/utils.lua @@ -1,5 +1,14 @@ local M = {} +M.extract_path = function(input_string) + local extracted_string = input_string:match("['\"]([^']+)['\"]") + return extracted_string +end + +M.replace_in_quotes = function(str, replacement) + return (str:gsub("([\"'])(.-)%1", "%1" .. replacement .. "%1")) +end + M.get_filetype = function() local bufnr = vim.api.nvim_get_current_buf() local filetype = vim.api.nvim_buf_get_option(bufnr, "filetype")