1
0
mirror of https://github.com/SpaceVim/SpaceVim.git synced 2025-01-23 13:10:04 +08:00
SpaceVim/bundle/neo-tree.nvim/lua/neo-tree/collections.lua
2023-05-30 21:09:18 +08:00

128 lines
2.8 KiB
Lua

local log = require("neo-tree.log")
Node = {}
function Node:new(value)
local props = { prev = nil, next = nil, value = value }
setmetatable(props, self)
self.__index = self
return props
end
LinkedList = {}
function LinkedList:new()
local props = { head = nil, tail = nil, size = 0 }
setmetatable(props, self)
self.__index = self
return props
end
function LinkedList:add_node(node)
if self.head == nil then
self.head = node
self.tail = node
else
self.tail.next = node
node.prev = self.tail
self.tail = node
end
self.size = self.size + 1
return node
end
function LinkedList:remove_node(node)
if node.prev ~= nil then
node.prev.next = node.next
end
if node.next ~= nil then
node.next.prev = node.prev
end
if self.head == node then
self.head = node.next
end
if self.tail == node then
self.tail = node.prev
end
self.size = self.size - 1
node.prev = nil
node.next = nil
node.value = nil
end
-- First in Last Out
Queue = {}
function Queue:new()
local props = { _list = LinkedList:new() }
setmetatable(props, self)
self.__index = self
return props
end
---Add an element to the end of the queue.
---@param value any The value to add.
function Queue:add(value)
self._list:add_node(Node:new(value))
end
---Iterates over the entire list, running func(value) on each element.
---If func returns true, the element is removed from the list.
---@param func function The function to run on each element.
function Queue:for_each(func)
local node = self._list.head
while node ~= nil do
local result = func(node.value)
local node_is_next = false
if result then
if type(result) == "boolean" then
local node_to_remove = node
node = node.next
node_is_next = true
self._list:remove_node(node_to_remove)
elseif type(result) == "table" then
if type(result.handled) == "boolean" and result.handled == true then
log.trace(
"Handler ",
node.value.id,
" for "
.. node.value.event
.. " returned handled = true, skipping the rest of the queue."
)
return result
end
end
end
if not node_is_next then
node = node.next
end
end
end
function Queue:is_empty()
return self._list.size == 0
end
function Queue:remove_by_id(id)
local current = self._list.head
while current ~= nil do
local is_match = false
local item = current.value
if item ~= nil then
local item_id = item.id or item
if item_id == id then
is_match = true
end
end
if is_match then
local next = current.next
self._list:remove_node(current)
current = next
else
current = current.next
end
end
end
return {
Queue = Queue,
LinkedList = LinkedList,
}