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 events = require("nvim-tree.events")
local notify = require("nvim-tree.notify")
local view = require("nvim-tree.view") local view = require("nvim-tree.view")
local log = require("nvim-tree.log") local log = require("nvim-tree.log")
@@ -15,7 +16,21 @@ function M.init(foldername)
if TreeExplorer then if TreeExplorer then
TreeExplorer:destroy() TreeExplorer:destroy()
end 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 if not first_init_done then
events._dispatch_ready() events._dispatch_ready()
first_init_done = true first_init_done = true

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -15,35 +15,28 @@ local PICTURE_MAP = {
---@class (exact) FileNode: Node ---@class (exact) FileNode: Node
---@field extension string ---@field extension string
local FileNode = Node:new() local FileNode = Node:extend()
---Static factory method
---@param explorer Explorer ---@param explorer Explorer
---@param parent DirectoryNode ---@param parent DirectoryNode
---@param absolute_path string ---@param absolute_path string
---@param name string ---@param name string
---@param fs_stat uv.fs_stat.result? ---@param fs_stat uv.fs_stat.result?
---@return FileNode function FileNode:new(explorer, parent, absolute_path, name, fs_stat)
function FileNode:create(explorer, parent, absolute_path, name, fs_stat) FileNode.super.new(self)
---@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,
extension = string.match(name, ".?[^.]+%.(.*)") or "", self.type = "file"
} self.explorer = explorer
o = self:new(o) 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 end
function FileNode:destroy() function FileNode:destroy()

View File

@@ -1,8 +1,7 @@
local Class = require("nvim-tree.class") local Object = require("nvim-tree.classic")
---Abstract Node class. ---Abstract Node class.
---Uses the abstract factory pattern to instantiate child instances. ---@class (exact) Node: Object
---@class (exact) Node: Class
---@field type NODE_TYPE ---@field type NODE_TYPE
---@field explorer Explorer ---@field explorer Explorer
---@field absolute_path string ---@field absolute_path string
@@ -14,7 +13,11 @@ local Class = require("nvim-tree.class")
---@field parent DirectoryNode? ---@field parent DirectoryNode?
---@field diag_status DiagStatus? ---@field diag_status DiagStatus?
---@field private is_dot boolean cached is_dotfile ---@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() function Node:destroy()
end 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") local DirectoryNode = require("nvim-tree.node.directory")
---@class (exact) RootNode: DirectoryNode ---@class (exact) RootNode: DirectoryNode
local RootNode = DirectoryNode:new() local RootNode = DirectoryNode:extend()
---Static factory method
---@param explorer Explorer ---@param explorer Explorer
---@param absolute_path string ---@param absolute_path string
---@param name string ---@param name string
---@param fs_stat uv.fs_stat.result|nil ---@param fs_stat uv.fs_stat.result|nil
---@return RootNode function RootNode:new(explorer, absolute_path, name, fs_stat)
function RootNode:create(explorer, absolute_path, name, fs_stat) RootNode.super.new(self, explorer, nil, absolute_path, name, fs_stat)
local o = DirectoryNode:create(explorer, nil, absolute_path, name, fs_stat)
o = self:new(o)
return o
end end
---Root is never a dotfile ---Root is never a dotfile