feat: quickfix (#293)
* feat: quickfix (not implemented) * [WIP]: Wed 09 Dec 2020 11:11:30 PM EST * somewhat working linked list impl * getting closer * might be working * might be working for real * works and implemented basic example * dont forget to close prompt * fix descending and add more tests * test fixes * fix test * more logging * Fix some more tests * Fix logging messing up tests * fix: lint * fix: multi select stuffs
This commit is contained in:
222
lua/telescope/algos/linked_list.lua
Normal file
222
lua/telescope/algos/linked_list.lua
Normal file
@@ -0,0 +1,222 @@
|
||||
|
||||
local LinkedList = {}
|
||||
LinkedList.__index = LinkedList
|
||||
|
||||
function LinkedList:new(opts)
|
||||
opts = opts or {}
|
||||
local track_at = opts.track_at
|
||||
|
||||
return setmetatable({
|
||||
size = 0,
|
||||
head = false,
|
||||
tail = false,
|
||||
|
||||
-- track_at: Track at can track a particular node
|
||||
-- Use to keep a node tracked at a particular index
|
||||
-- This greatly decreases looping for checking values at this location.
|
||||
track_at = track_at,
|
||||
_tracked_node = nil,
|
||||
tracked = nil,
|
||||
}, self)
|
||||
end
|
||||
|
||||
function LinkedList:_increment()
|
||||
self.size = self.size + 1
|
||||
return self.size
|
||||
end
|
||||
|
||||
local create_node = function(item)
|
||||
return {
|
||||
item = item
|
||||
}
|
||||
end
|
||||
|
||||
function LinkedList:append(item)
|
||||
local final_size = self:_increment()
|
||||
|
||||
local node = create_node(item)
|
||||
|
||||
if not self.head then
|
||||
self.head = node
|
||||
end
|
||||
|
||||
if self.tail then
|
||||
self.tail.next = node
|
||||
node.prev = self.tail
|
||||
end
|
||||
|
||||
self.tail = node
|
||||
|
||||
if self.track_at then
|
||||
if final_size == self.track_at then
|
||||
self.tracked = item
|
||||
self._tracked_node = node
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function LinkedList:prepend(item)
|
||||
local final_size = self:_increment()
|
||||
local node = create_node(item)
|
||||
|
||||
if not self.tail then
|
||||
self.tail = node
|
||||
end
|
||||
|
||||
if self.head then
|
||||
self.head.prev = node
|
||||
node.next = self.head
|
||||
end
|
||||
|
||||
self.head = node
|
||||
|
||||
if self.track_at then
|
||||
if final_size == self.track_at then
|
||||
self._tracked_node = self.tail
|
||||
elseif final_size > self.track_at then
|
||||
self._tracked_node = self._tracked_node.prev
|
||||
else
|
||||
return
|
||||
end
|
||||
|
||||
self.tracked = self._tracked_node.item
|
||||
end
|
||||
end
|
||||
|
||||
-- [a, b, c]
|
||||
-- b.prev = a
|
||||
-- b.next = c
|
||||
--
|
||||
-- a.next = b
|
||||
-- c.prev = c
|
||||
--
|
||||
-- insert d after b
|
||||
-- [a, b, d, c]
|
||||
--
|
||||
-- b.next = d
|
||||
-- b.prev = a
|
||||
--
|
||||
-- Place "item" after "node" (which is at index `index`)
|
||||
function LinkedList:place_after(index, node, item)
|
||||
local new_node = create_node(item)
|
||||
|
||||
assert(node.prev ~= node)
|
||||
assert(node.next ~= node)
|
||||
local final_size = self:_increment()
|
||||
|
||||
-- Update tail to be the next node.
|
||||
if self.tail == node then
|
||||
self.tail = new_node
|
||||
end
|
||||
|
||||
new_node.prev = node
|
||||
new_node.next = node.next
|
||||
|
||||
node.next = new_node
|
||||
|
||||
if new_node.prev then
|
||||
new_node.prev.next = new_node
|
||||
end
|
||||
|
||||
if new_node.next then
|
||||
new_node.next.prev = new_node
|
||||
end
|
||||
|
||||
|
||||
if self.track_at then
|
||||
if index == self.track_at then
|
||||
self._tracked_node = new_node
|
||||
elseif index < self.track_at then
|
||||
if final_size == self.track_at then
|
||||
self._tracked_node = self.tail
|
||||
elseif final_size > self.track_at then
|
||||
self._tracked_node = self._tracked_node.prev
|
||||
else
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
self.tracked = self._tracked_node.item
|
||||
end
|
||||
end
|
||||
|
||||
function LinkedList:place_before(index, node, item)
|
||||
local new_node = create_node(item)
|
||||
|
||||
assert(node.prev ~= node)
|
||||
assert(node.next ~= node)
|
||||
local final_size = self:_increment()
|
||||
|
||||
-- Update head to be the node we are inserting.
|
||||
if self.head == node then
|
||||
self.head = new_node
|
||||
end
|
||||
|
||||
new_node.prev = node.prev
|
||||
new_node.next = node
|
||||
|
||||
node.prev = new_node
|
||||
-- node.next = node.next
|
||||
|
||||
if new_node.prev then
|
||||
new_node.prev.next = new_node
|
||||
end
|
||||
|
||||
if new_node.next then
|
||||
new_node.next.prev = new_node
|
||||
end
|
||||
|
||||
|
||||
if self.track_at then
|
||||
if index == self.track_at - 1 then
|
||||
self._tracked_node = node
|
||||
elseif index < self.track_at then
|
||||
if final_size == self.track_at then
|
||||
self._tracked_node = self.tail
|
||||
elseif final_size > self.track_at then
|
||||
self._tracked_node = self._tracked_node.prev
|
||||
else
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
self.tracked = self._tracked_node.item
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
-- Do you even do this in linked lists...?
|
||||
-- function LinkedList:remove(item)
|
||||
-- end
|
||||
|
||||
function LinkedList:iter()
|
||||
local current_node = self.head
|
||||
|
||||
return function()
|
||||
local node = current_node
|
||||
if not node then
|
||||
return nil
|
||||
end
|
||||
|
||||
current_node = current_node.next
|
||||
return node.item
|
||||
end
|
||||
end
|
||||
|
||||
function LinkedList:ipairs()
|
||||
local index = 0
|
||||
local current_node = self.head
|
||||
|
||||
return function()
|
||||
local node = current_node
|
||||
if not node then
|
||||
return nil
|
||||
end
|
||||
|
||||
current_node = current_node.next
|
||||
index = index + 1
|
||||
return index, node.item, node
|
||||
end
|
||||
end
|
||||
|
||||
return LinkedList
|
||||
Reference in New Issue
Block a user