add classic, migrating nodes classes

This commit is contained in:
Alexander Courtis 2024-11-04 13:17:33 +11:00
parent 610a1c189b
commit 35015149e2
11 changed files with 181 additions and 138 deletions

77
lua/nvim-tree/classic.lua Normal file
View File

@ -0,0 +1,77 @@
--
-- classic
--
-- Copyright (c) 2014, rxi
--
-- This module is free software; you can redistribute it and/or modify it under
-- the terms of the MIT license. See LICENSE for details.
--
local Object = {}
Object.__index = Object
function Object:new()
end
function Object:extend()
local cls = {}
for k, v in pairs(self) do
if k:find("__") == 1 then
cls[k] = v
end
end
cls.__index = cls
cls.super = self
setmetatable(cls, self)
return cls
end
function Object:implement(...)
for _, cls in pairs({...}) do
for k, v in pairs(cls) do
if self[k] == nil and type(v) == "function" then
self[k] = v
end
end
end
end
function Object:is(T)
local mt = getmetatable(self)
while mt do
if mt == T then
return true
end
mt = getmetatable(mt)
end
return false
end
---Return object if it is an instance of class, otherwise nil
---@generic T
---@param cls T
---@return T|nil
function Object:as(cls)
return self:is(cls) and self or nil
end
function Object:__tostring()
return "Object"
end
function Object:__call(...)
local obj = setmetatable({}, self)
obj:new(...)
return obj
end
return Object

View File

@ -1,4 +1,5 @@
local events = require("nvim-tree.events")
local notify = require("nvim-tree.notify")
local view = require("nvim-tree.view")
local log = require("nvim-tree.log")
@ -15,7 +16,21 @@ function M.init(foldername)
if TreeExplorer then
TreeExplorer:destroy()
end
TreeExplorer = require("nvim-tree.explorer"):create(foldername)
local err, path
if foldername then
path, err = vim.loop.fs_realpath(foldername)
else
path, err = vim.loop.cwd()
end
if path then
TreeExplorer = require("nvim-tree.explorer")(path)
else
notify.error(err)
TreeExplorer = nil
end
if not first_init_done then
events._dispatch_ready()
first_init_done = true

View File

@ -3,7 +3,6 @@ local buffers = require("nvim-tree.buffers")
local core = require("nvim-tree.core")
local git = require("nvim-tree.git")
local log = require("nvim-tree.log")
local notify = require("nvim-tree.notify")
local utils = require("nvim-tree.utils")
local view = require("nvim-tree.view")
local node_factory = require("nvim-tree.node.factory")
@ -36,51 +35,28 @@ local config
---@field sorters Sorter
---@field marks Marks
---@field clipboard Clipboard
local Explorer = RootNode:new()
local Explorer = RootNode:extend()
---Static factory method
---@param path string?
---@return Explorer?
function Explorer:create(path)
local err
---@param path string
function Explorer:new(path)
Explorer.super.new(self, self, path, "..", nil)
if path then
path, err = vim.loop.fs_realpath(path)
else
path, err = vim.loop.cwd()
end
if not path then
notify.error(err)
return nil
end
self.uid_explorer = vim.loop.hrtime()
self.augroup_id = vim.api.nvim_create_augroup("NvimTree_Explorer_" .. self.uid_explorer, {})
---@type Explorer
local explorer_placeholder = nil
self.open = true
self.opts = config
local o = RootNode:create(explorer_placeholder, path, "..", nil)
self.sorters = Sorters:create(config)
self.renderer = Renderer:new(config, self)
self.filters = Filters:new(config, self)
self.live_filter = LiveFilter:new(config, self)
self.marks = Marks:new(config, self)
self.clipboard = Clipboard:new(config, self)
o = self:new(o)
self:create_autocmds()
o.explorer = o
o.uid_explorer = vim.loop.hrtime()
o.augroup_id = vim.api.nvim_create_augroup("NvimTree_Explorer_" .. o.uid_explorer, {})
o.open = true
o.opts = config
o.sorters = Sorters:create(config)
o.renderer = Renderer:new(config, o)
o.filters = Filters:new(config, o)
o.live_filter = LiveFilter:new(config, o)
o.marks = Marks:new(config, o)
o.clipboard = Clipboard:new(config, o)
o:create_autocmds()
o:_load(o)
return o
self:_load(self)
end
function Explorer:destroy()

View File

@ -3,12 +3,9 @@ local utils = require("nvim-tree.utils")
local DirectoryNode = require("nvim-tree.node.directory")
---@class (exact) DirectoryLinkNode: DirectoryNode
---@field link_to string absolute path
---@field private fs_stat_target uv.fs_stat.result
local DirectoryLinkNode = DirectoryNode:new()
---@class (exact) DirectoryLinkNode: DirectoryNode, LinkNode
local DirectoryLinkNode = DirectoryNode:extend()
---Static factory method
---@param explorer Explorer
---@param parent DirectoryNode
---@param absolute_path string
@ -16,21 +13,16 @@ local DirectoryLinkNode = DirectoryNode:new()
---@param name string
---@param fs_stat uv.fs_stat.result?
---@param fs_stat_target uv.fs_stat.result
---@return DirectoryLinkNode? nil on vim.loop.fs_realpath failure
function DirectoryLinkNode:create(explorer, parent, absolute_path, link_to, name, fs_stat, fs_stat_target)
function DirectoryLinkNode:new(explorer, parent, absolute_path, link_to, name, fs_stat, fs_stat_target)
-- create DirectoryNode with the target path for the watcher
local o = DirectoryNode:create(explorer, parent, link_to, name, fs_stat)
o = self:new(o)
DirectoryLinkNode.super.new(self, explorer, parent, link_to, name, fs_stat)
-- reset absolute path to the link itself
o.absolute_path = absolute_path
self.absolute_path = absolute_path
o.type = "link"
o.link_to = link_to
o.fs_stat_target = fs_stat_target
return o
self.type = "link"
self.link_to = link_to
self.fs_stat_target = fs_stat_target
end
function DirectoryLinkNode:destroy()

View File

@ -10,45 +10,38 @@ local Node = require("nvim-tree.node")
---@field open boolean
---@field hidden_stats table? -- Each field of this table is a key for source and value for count
---@field private watcher Watcher?
local DirectoryNode = Node:new()
local DirectoryNode = Node:extend()
---Static factory method
---@param explorer Explorer
---@param parent DirectoryNode?
---@param absolute_path string
---@param name string
---@param fs_stat uv.fs_stat.result|nil
---@return DirectoryNode
function DirectoryNode:create(explorer, parent, absolute_path, name, fs_stat)
function DirectoryNode:new(explorer, parent, absolute_path, name, fs_stat)
DirectoryNode.super.new(self)
local handle = vim.loop.fs_scandir(absolute_path)
local has_children = handle and vim.loop.fs_scandir_next(handle) ~= nil or false
---@type DirectoryNode
local o = {
type = "directory",
explorer = explorer,
absolute_path = absolute_path,
executable = false,
fs_stat = fs_stat,
git_status = nil,
hidden = false,
name = name,
parent = parent,
watcher = nil,
diag_status = nil,
is_dot = false,
self.type = "directory"
self.explorer = explorer
self.absolute_path = absolute_path
self.executable = false
self.fs_stat = fs_stat
self.git_status = nil
self.hidden = false
self.name = name
self.parent = parent
self.watcher = nil
self.diag_status = nil
has_children = has_children,
group_next = nil,
nodes = {},
open = false,
hidden_stats = nil,
}
o = self:new(o)
self.has_children = has_children
self.group_next = nil
self.nodes = {}
self.open = false
self.hidden_stats = nil
o.watcher = require("nvim-tree.explorer.watch").create_watcher(o)
return o
self.watcher = require("nvim-tree.explorer.watch").create_watcher(self)
end
function DirectoryNode:destroy()

View File

@ -21,11 +21,11 @@ function M.create_node(explorer, parent, absolute_path, stat, name)
if stat.type == "directory" then
-- directory must be readable and enumerable
if vim.loop.fs_access(absolute_path, "R") and Watcher.is_fs_event_capable(absolute_path) then
return DirectoryNode:create(explorer, parent, absolute_path, name, stat)
return DirectoryNode(explorer, parent, absolute_path, name, stat)
end
elseif stat.type == "file" then
-- any file
return FileNode:create(explorer, parent, absolute_path, name, stat)
return FileNode(explorer, parent, absolute_path, name, stat)
elseif stat.type == "link" then
-- link target path and stat must resolve
local link_to = vim.loop.fs_realpath(absolute_path)
@ -36,9 +36,9 @@ function M.create_node(explorer, parent, absolute_path, stat, name)
-- choose directory or file
if link_to_stat.type == "directory" then
return DirectoryLinkNode:create(explorer, parent, absolute_path, link_to, name, stat, link_to_stat)
return DirectoryLinkNode(explorer, parent, absolute_path, link_to, name, stat, link_to_stat)
else
return FileLinkNode:create(explorer, parent, absolute_path, link_to, name, stat, link_to_stat)
return FileLinkNode(explorer, parent, absolute_path, link_to, name, stat, link_to_stat)
end
end

View File

@ -3,12 +3,9 @@ local utils = require("nvim-tree.utils")
local FileNode = require("nvim-tree.node.file")
---@class (exact) FileLinkNode: FileNode
---@field link_to string absolute path
---@field private fs_stat_target uv.fs_stat.result
local FileLinkNode = FileNode:new()
---@class (exact) FileLinkNode: FileNode, LinkNode
local FileLinkNode = FileNode:extend()
---Static factory method
---@param explorer Explorer
---@param parent DirectoryNode
---@param absolute_path string
@ -16,17 +13,12 @@ local FileLinkNode = FileNode:new()
---@param name string
---@param fs_stat uv.fs_stat.result?
---@param fs_stat_target uv.fs_stat.result
---@return FileLinkNode? nil on vim.loop.fs_realpath failure
function FileLinkNode:create(explorer, parent, absolute_path, link_to, name, fs_stat, fs_stat_target)
local o = FileNode:create(explorer, parent, absolute_path, name, fs_stat)
function FileLinkNode:new(explorer, parent, absolute_path, link_to, name, fs_stat, fs_stat_target)
FileLinkNode.super.new(self, explorer, parent, absolute_path, name, fs_stat)
o = self:new(o)
o.type = "link"
o.link_to = link_to
o.fs_stat_target = fs_stat_target
return o
self.type = "link"
self.link_to = link_to
self.fs_stat_target = fs_stat_target
end
function FileLinkNode:destroy()

View File

@ -15,35 +15,28 @@ local PICTURE_MAP = {
---@class (exact) FileNode: Node
---@field extension string
local FileNode = Node:new()
local FileNode = Node:extend()
---Static factory method
---@param explorer Explorer
---@param parent DirectoryNode
---@param absolute_path string
---@param name string
---@param fs_stat uv.fs_stat.result?
---@return FileNode
function FileNode:create(explorer, parent, absolute_path, name, fs_stat)
---@type FileNode
local o = {
type = "file",
explorer = explorer,
absolute_path = absolute_path,
executable = utils.is_executable(absolute_path),
fs_stat = fs_stat,
git_status = nil,
hidden = false,
name = name,
parent = parent,
diag_status = nil,
is_dot = false,
function FileNode:new(explorer, parent, absolute_path, name, fs_stat)
FileNode.super.new(self)
extension = string.match(name, ".?[^.]+%.(.*)") or "",
}
o = self:new(o)
self.type = "file"
self.explorer = explorer
self.absolute_path = absolute_path
self.executable = utils.is_executable(absolute_path)
self.fs_stat = fs_stat
self.git_status = nil
self.hidden = false
self.name = name
self.parent = parent
self.diag_status = nil
return o
self.extension = string.match(name, ".?[^.]+%.(.*)") or ""
end
function FileNode:destroy()

View File

@ -1,8 +1,7 @@
local Class = require("nvim-tree.class")
local Object = require("nvim-tree.classic")
---Abstract Node class.
---Uses the abstract factory pattern to instantiate child instances.
---@class (exact) Node: Class
---@class (exact) Node: Object
---@field type NODE_TYPE
---@field explorer Explorer
---@field absolute_path string
@ -14,7 +13,11 @@ local Class = require("nvim-tree.class")
---@field parent DirectoryNode?
---@field diag_status DiagStatus?
---@field private is_dot boolean cached is_dotfile
local Node = Class:new()
local Node = Object:extend()
function Node:new()
self.is_dot = false
end
function Node:destroy()
end

View File

@ -0,0 +1,8 @@
local Object = require("nvim-tree.classic")
---@class (exact) LinkNode: Object
---@field link_to string
---@field protected fs_stat_target uv.fs_stat.result
local LinkNode = Object:extend()
return LinkNode

View File

@ -1,20 +1,14 @@
local DirectoryNode = require("nvim-tree.node.directory")
---@class (exact) RootNode: DirectoryNode
local RootNode = DirectoryNode:new()
local RootNode = DirectoryNode:extend()
---Static factory method
---@param explorer Explorer
---@param absolute_path string
---@param name string
---@param fs_stat uv.fs_stat.result|nil
---@return RootNode
function RootNode:create(explorer, absolute_path, name, fs_stat)
local o = DirectoryNode:create(explorer, nil, absolute_path, name, fs_stat)
o = self:new(o)
return o
function RootNode:new(explorer, absolute_path, name, fs_stat)
RootNode.super.new(self, explorer, nil, absolute_path, name, fs_stat)
end
---Root is never a dotfile