Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 47 additions & 1 deletion lua/neo-tree/sources/common/components.lua
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,54 @@ local utils = require("neo-tree.utils")
local file_nesting = require("neo-tree.sources.common.file-nesting")
local container = require("neo-tree.sources.common.container")
local log = require("neo-tree.log")
local path = require("plenary.path")

local M = {}

-- Workaround for https://github.com/nvim-lua/plenary.nvim/issues/411
local relative_path = function(original_path, reference_path)
-- Use plenary's make_relative to clean paths
original_path = path:new(original_path):make_relative(".")
reference_path = path:new(reference_path):make_relative(".")
Comment on lines +25 to +26
Copy link
Collaborator

@pynappo pynappo Dec 9, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The paths are already absolute before you pass them in, so this seems unneeded (alternatively, you could make them absolute here, and then not bother having to make them absolute before passing them in)

Suggested change
original_path = path:new(original_path):make_relative(".")
reference_path = path:new(reference_path):make_relative(".")

local o_path = path:new(original_path)
local ref_path = path:new(reference_path)
Comment on lines +18 to +28
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

path from plenary is capitalized in other modules:

Suggested change
local path = require("plenary.path")
local M = {}
-- Workaround for https://github.com/nvim-lua/plenary.nvim/issues/411
local relative_path = function(original_path, reference_path)
-- Use plenary's make_relative to clean paths
original_path = path:new(original_path):make_relative(".")
reference_path = path:new(reference_path):make_relative(".")
local o_path = path:new(original_path)
local ref_path = path:new(reference_path)
local Path = require("plenary.path")
local M = {}
-- Workaround for https://github.com/nvim-lua/plenary.nvim/issues/411
local relative_path = function(original_path, reference_path)
-- Use plenary's make_relative to clean paths
original_path = Path:new(original_path):make_relative(".")
reference_path = Path:new(reference_path):make_relative(".")
local o_path = Path:new(original_path)
local ref_path = Path:new(reference_path)

local parents = o_path:parents()
local ref_parents = ref_path:parents()

local path_elements = vim.split(o_path.filename, "/")
Copy link
Collaborator

@pynappo pynappo Dec 9, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Windows uses backslashes, so this might not always work. to take that into account:

Suggested change
local path_elements = vim.split(o_path.filename, "/")
local sep = o_path.path.sep
local path_elements = vim.split(o_path.filename, sep)

table.insert(parents, 1, original_path)
table.insert(ref_parents, 1, reference_path)

local result = ""
for i, ref_parent in ipairs(ref_parents) do
for j, par in ipairs(parents) do
if ref_parent == par then
if i == 1 and j == 1 then
return ""
end

result = result .. table.concat(path_elements, "/", #path_elements - j + 2)
return result
end
end

result = "../" .. result
end
Comment on lines +36 to +50
Copy link
Collaborator

@pynappo pynappo Dec 9, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This might be a slightly faster algorithm, although I haven't tested it much, feel free to ignore:

Suggested change
local result = ""
for i, ref_parent in ipairs(ref_parents) do
for j, par in ipairs(parents) do
if ref_parent == par then
if i == 1 and j == 1 then
return ""
end
result = result .. table.concat(path_elements, "/", #path_elements - j + 2)
return result
end
end
result = "../" .. result
end
if o_path.path.root ~= ref_path.path.root then
return o_path:absolute()
end
local i, j = #parents, #ref_parents
-- find the deepest common directory
while parents[i] == ref_parents[j] and math.min(j, i) > 0 do
i = i - 1
j = j - 1
end
local common_dir = parents[i + 1]
local steps_out = string.rep(".." .. sep, j)
return steps_out .. original_path:sub(#common_dir + 2)

end

local get_relative_target = function(node, state)
local cwd = path:new(state.path):absolute()
local target = path:new(node.link_to):absolute()
local node_dir = path:new(node.path):parent():absolute()

-- If target is inside cwd, make it relative
if target:find(cwd, 1, true) == 1 then
return relative_path(target, node_dir)
end

return node.link_to
end

local make_two_char = function(symbol)
if vim.fn.strchars(symbol) == 1 then
return symbol .. " "
Expand Down Expand Up @@ -528,8 +573,9 @@ end

M.symlink_target = function(config, node, state)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you could move the local methods to just above symlink_target so it's more organized.

if node.is_link then
local target = get_relative_target(node, state)
return {
text = string.format(" ➛ %s", node.link_to),
text = string.format(" ➛ %s", target),
highlight = config.highlight or highlights.SYMBOLIC_LINK_TARGET,
}
else
Expand Down
Loading