Skip to content

#3231 step 2: Lazy API requires post setup #3255

@alex-courtis

Description

@alex-courtis

Part of #3231 : Performance: Load Only Necessary Modules On setup and requiring API

Make all requires in post.lua lazy - executed at call time rather than hydration/setup time.

No Changes

wrap_explorer* is already lazy.

wrap_node* should work with lazy functions.

Trivial

edit can be made lazy with little effort.

Directly Wired

These should be simple to make lazy

api.node.show_info_popup = wrap_node(actions.node.file_popup.toggle_file_info)

Generic solution, obfuscates and prevents LSP validation:

  local lazy = function(module, path)
    return function(...)
      local f = require(module)
      for _, p in ipairs(path) do
        f = f and f[p] or nil
      end
      return f and f(...) or nil
    end
  end

  api.node.show_info_popup = wrap_node(lazy("nvim-tree.actions", { "node", "file_popup", "toggle_file_info" }))

Simple solution, actually less verbose than the generic:

    api.node.show_info_popup = wrap_node(function(...) require("nvim-tree.actions").node.file_popup.toggle_file_info(...) end)

Wire Actions Directly To Functions

The following use the pattern of returning a function from a function on setup. This adds no value and should be refactored to be wired to actual functions e.g. actions.moves.sibling.next

cat lua/nvim-tree/api/impl/post.lua | grep "  api." | grep '(".*")'  | grep actions
  api.fs.rename_node = wrap_node(actions.fs.rename_file.fn(":t"))
  api.fs.rename = wrap_node(actions.fs.rename_file.fn(":t"))
  api.fs.rename_sub = wrap_node(actions.fs.rename_file.fn(":p:h"))
  api.fs.rename_basename = wrap_node(actions.fs.rename_file.fn(":t:r"))
  api.fs.rename_full = wrap_node(actions.fs.rename_file.fn(":p"))
  api.node.navigate.sibling.next = wrap_node(actions.moves.sibling.fn("next"))
  api.node.navigate.sibling.prev = wrap_node(actions.moves.sibling.fn("prev"))
  api.node.navigate.sibling.first = wrap_node(actions.moves.sibling.fn("first"))
  api.node.navigate.sibling.last = wrap_node(actions.moves.sibling.fn("last"))

Rework open_or_expand

This follows the same pattern as Wire Actions Directly, returning a function.

It's not practical to create specific functions like actions.

The best approach might be to fold it into edit, which does not return a function.

Cleaning up edit is beyond the scope of this issue.

cat lua/nvim-tree/api/impl/post.lua | grep "  api." | grep '(".*")'  | grep open_or_expand
  api.node.open.edit = wrap_node(open_or_expand_or_dir_up("edit"))
  api.node.open.drop = wrap_node(open_or_expand_or_dir_up("drop"))
  api.node.open.tab_drop = wrap_node(open_or_expand_or_dir_up("tab_drop"))
  api.node.open.replace_tree_buffer = wrap_node(open_or_expand_or_dir_up("edit_in_place"))
  api.node.open.no_window_picker = wrap_node(open_or_expand_or_dir_up("edit_no_picker"))
  api.node.open.vertical = wrap_node(open_or_expand_or_dir_up("vsplit"))
  api.node.open.vertical_no_picker = wrap_node(open_or_expand_or_dir_up("vsplit_no_picker"))
  api.node.open.horizontal = wrap_node(open_or_expand_or_dir_up("split"))
  api.node.open.horizontal_no_picker = wrap_node(open_or_expand_or_dir_up("split_no_picker"))
  api.node.open.tab = wrap_node(open_or_expand_or_dir_up("tabnew"))
  api.node.open.preview = wrap_node(open_or_expand_or_dir_up("preview"))
  api.node.open.preview_no_picker = wrap_node(open_or_expand_or_dir_up("preview_no_picker"))

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions