Skip to content

feat(#2364): add option to show files first #2366

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 9 commits into from
Aug 26, 2023

Conversation

Akmadan23
Copy link
Collaborator

This is a simple and straight forward implementation of the feature requested in #2364. For the configuration I think that since sort.folders_first is enabled by default, sort.files_first = true should override it. I made a minor refactoring in explorer/sorter.lua, moving the folders-first logic in a separate function so that it's easier to manage and enhance.

@alex-courtis
Copy link
Member

FYI: you're a repo member: you can push a branch to this repo instead of using a fork.

Copy link
Member

@alex-courtis alex-courtis left a comment

Choose a reason for hiding this comment

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

This is nice, simplifies things a little as well.

Tested:

  • all permutations of folders_first and files_first
  • sort function

end

if x ~= nil then
if M.config.sort.files_first then
Copy link
Member

Choose a reason for hiding this comment

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

Could we flip this around? Test this config at the start of the function?

That would remove the need for the mystery x

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Yeah, I stored in x what should be returned if sort.folders_first is enabled and reverse it with sort.files_first, but now that I think about it maybe something like this would be more readable and intuitive.

local a_and_not_b, not_a_and_b

if M.config.sort.files_first then
  a_and_not_b = false
  not_a_and_b = true
elseif M.config.sort.folders_first then
  a_and_not_b = true
  not_a_and_b = false
else
  return
end

if a.nodes and not b.nodes then
  return a_and_not_b
elseif not a.nodes and b.nodes then
  return not_a_and_b
elseif a.nodes and b.nodes and third_option_callback ~= nil then
  return third_option_callback()
end

Copy link
Member

Choose a reason for hiding this comment

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

Much more readable. Could we go simpler?

if a.nodes and not b.nodes then
  return M.config.sort.folders_first

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

After several tests I think that would not work because the function should return true or false only if one (or both) of sort.folders_first and sort.files_first are enabled, otherwise it should return nil and continue without altering entries' order.

Copy link
Member

Choose a reason for hiding this comment

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

Ah of course. How about an early exit?

if not M.config.sort.files_first and not M.config.sort.folders_first then
  return
end

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Ok, this is the simplest and most concise way I got it to work:

if not (M.config.sort.folders_first or M.config.sort.files_first) then
  return
end

local x = M.config.sort.files_first or not M.config.sort.folders_first

if not a.nodes and b.nodes then
  return x
elseif a.nodes and not b.nodes then
  return not x
elseif fallback and a.nodes and b.nodes then
  return fallback()
end

Now we just have to give a sensible name to x.

Copy link
Member

Choose a reason for hiding this comment

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

This should do it:

---Evaluate `sort.folders_first` and `sort.files_first`, files takes precedence.
---@param a table node
---@param b table node
---@param fallback function|nil function should return `boolean`. Evaluated when both are folders.
---@return boolean|nil
local function folders_or_files_first(a, b, fallback)
  if not M.config.sort.folders_first and not M.config.sort.files_first then
    return
  end

  if not a.nodes and b.nodes then
    -- file <> folder
    return M.config.sort.files_first
  elseif a.nodes and not b.nodes then
    -- folder <> file
    return not M.config.sort.files_first
  elseif fallback and a.nodes and b.nodes then
    -- folder <> folder
    return fallback()
  end
end

Yes, we could be tricky with ternaries but readability is more important.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Oh, I didn't consider to completely ignore sort.folders_first but it works so that's fine.

@Akmadan23
Copy link
Collaborator Author

FYI: you're a repo member: you can push a branch to this repo instead of using a fork.

I didn't think about that, next time I'll push a new branch here.

@Akmadan23
Copy link
Collaborator Author

With the last commit I removed the fallback because it's used only once, I think this way is even more simple and clear.

@alex-courtis
Copy link
Member

With the last commit I removed the fallback because it's used only once, I think this way is even more simple and clear.

That's great... simple is best.

I'll test this one on the weekend.

Copy link
Member

@alex-courtis alex-courtis left a comment

Choose a reason for hiding this comment

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

Tested:

  • all permutations of folders_first and files_first
  • sort function

Many thanks for your contribution!

@alex-courtis alex-courtis merged commit d11d701 into nvim-tree:master Aug 26, 2023
@Akmadan23 Akmadan23 deleted the files_first branch August 27, 2023 16:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants