Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

docs: functions in entry_manager.lua, pickers.lua and linked_list.lua #927

Closed
wants to merge 8 commits into from
2 changes: 1 addition & 1 deletion doc/telescope.txt
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ telescope.setup({opts}) *telescope.setup()*
history: ~
This field handles the configuration for prompt history.
By default it is a table, with default values (more below).
To disable history, set it to either false or nil.
To disable history, set it to false.

Currently mappings still need to be added, Example:
mappings = {
Expand Down
87 changes: 85 additions & 2 deletions lua/telescope/algos/linked_list.lua
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,49 @@
local LinkedList = {}
LinkedList.__index = LinkedList

---@brief [[
--- A linked list consists of a collection of "nodes", which contain information about:
--- - the identity of their predecessor, under the `prev` key
--- - the identity of their successor, under the `next` key
--- - some stored information associated to themselves, under the `item` key
---
--- So locally at each node the picture of the linked list looks like:
--- <pre>
--- ┌──────────┐ B.prev ┌──────────┐ C.prev ┌──────────┐
--- ◄────│ A │◄───────│ B │◄───────│ C │◄────
--- ... │ ┌──────┐ │ │ ┌──────┐ │ │ ┌──────┐ │ ...
--- ────►│ │A.item│ │───────►│ │B.item│ │───────►│ │C.item│ │────►
--- │ └──────┘ │ A.next │ └──────┘ │ B.next │ └──────┘ │
--- └──────────┘ └──────────┘ └──────────┘
--- </pre>
---
--- There are two special nodes in the linked list, the `head` and the `tail`.
--- The `head` is a node which has no predecessor, so `head.prev=nil`.
--- The `tail` is a node which has no successor, so `head.next=nil`.
---
--- The number of nodes in the linked list is stored under the `size` key.
---
--- This implementation also allows a specific index to be kept track of.
--- The index is called `track_at`, and the node at that index is called `_tracked_node`.
--- The information stored in the tracked node i.e. `_tracked_node.item` is stored under the
--- `tracked` key.
---
--- The global picture of a linked list looks like:
--- <pre>
--- ┌────────┐ ┌───────────────┐ ┌────────┐
--- │ `head` │◄─── ◄───│ _tracked_node │◄─── ◄───│ `tail` │
--- │ ┌────┐ │ ... │ ┌───────┐ │ ... │ ┌────┐ │
--- │ │item│ │───► ───►│ │tracked│ │───► ───►│ │item│ │
--- │ └────┘ │ │ └───────┘ │ │ └────┘ │
--- └────────┘ └───────────────┘ └────────┘
--- </pre>
---@brief ]]


--- Create a new linked list
---@param opts table
--- @key track_at number: the index of the node to track
Copy link
Member

@Conni2461 Conni2461 Jul 7, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@key is currently not a thing, but that also doesn't matter because right now we are not exporting documentation for this file

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's fine, was just matching what had been done elsewhere

---@return any
function LinkedList:new(opts)
opts = opts or {}
local track_at = opts.track_at
Expand All @@ -20,17 +63,26 @@ function LinkedList:new(opts)
}, self)
end

--- Increment the size of the linked list and return the new size
---@return number
function LinkedList:_increment()
self.size = self.size + 1
return self.size
end

--- Helper function that wraps `item` in a table at key `item`.
---@param item any
---@return table
local create_node = function(item)
return {
item = item
}
end

--- Add a node with information `item` at the end of the linked list.
--- The tracked information is updated as necessary.
---@note: the newly created node will be the `tail` of the linked list.
---@param item any
function LinkedList:append(item)
local final_size = self:_increment()

Expand All @@ -55,6 +107,10 @@ function LinkedList:append(item)
end
end

--- Add a node with information `item` at the beginning of the linked list.
--- The tracked information is updated as necessary.
---@note: the newly created node will be the `head` of the linked list.
---@param item any
function LinkedList:prepend(item)
local final_size = self:_increment()
local node = create_node(item)
Expand Down Expand Up @@ -94,9 +150,13 @@ end
-- [a, b, d, c]
--
-- b.next = d
-- b.prev = a
-- c.prev = d
--
-- Place "item" after "node" (which is at index `index`)

--- Place "item" after "node" (which is at index `index`)
---@param index number
---@param node table
---@param item any
function LinkedList:place_after(index, node, item)
local new_node = create_node(item)

Expand Down Expand Up @@ -140,6 +200,24 @@ function LinkedList:place_after(index, node, item)
end
end

-- [a, b, c]
-- b.prev = a
-- b.next = c
--
-- a.next = b
-- c.prev = c
--
-- insert d before b
-- [a, d, b, c]
--
-- a.next = d
-- b.prev = d
--

--- Place "item" before "node" (which is at index `index`)
---@param index number
---@param node table
---@param item any
function LinkedList:place_before(index, node, item)
local new_node = create_node(item)

Expand Down Expand Up @@ -189,6 +267,8 @@ end
-- function LinkedList:remove(item)
-- end

--- Convert the linked list to an iterator function for the node `item`s
---@return function
function LinkedList:iter()
local current_node = self.head

Expand All @@ -203,6 +283,9 @@ function LinkedList:iter()
end
end

--- Convert the linked list to an iterator of `index`, `item`, `node` triples
---@note: can also be used as an iterator of `index`, `item` pairs
---@return function
function LinkedList:ipairs()
local index = 0
local current_node = self.head
Expand Down
57 changes: 56 additions & 1 deletion lua/telescope/entry_manager.lua
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,18 @@ if past loop of must have scores,
local EntryManager = {}
EntryManager.__index = EntryManager

--- Create a new EntryManager object
---@param max_results number: the number of results to keep sorted at the head of the linked list
---@param set_entry function: handler function for object using the EntryManager
---@param info table: (optional) table containing information to keep track of
--- @key looped number: number of existing entries checked when adding new entries
--- @key find_loop number: number of entries checked when trying to find an entry
---@return any
function EntryManager:new(max_results, set_entry, info)
log.trace("Creating entry_manager...")

info = info or {}
info.looped = 0
info.inserted = 0
info.find_loop = 0

-- state contains list of
Expand All @@ -48,10 +54,15 @@ function EntryManager:new(max_results, set_entry, info)
}, self)
end

--- Get the number of entries in the manager
---@return number
function EntryManager:num_results()
return self.linked_states.size
end

--- Get the container in the EntryManager corresponding to `index`
---@param index number
---@return table: contains the entry at index 1 and the score at index 2
function EntryManager:get_container(index)
local count = 0
for val in self.linked_states:iter() do
Expand All @@ -65,18 +76,30 @@ function EntryManager:get_container(index)
return {}
end

--- Get the entry in the EntryManager corresponding to `index`
---@param index number
---@return table: table with information about the given entry
function EntryManager:get_entry(index)
return self:get_container(index)[1]
end

--- Get the score in the EntryManager corresponding to `index`
---@param index number
---@return number
function EntryManager:get_score(index)
return self:get_container(index)[2]
end

--- Get the `ordinal` (text to be filtered on) corresponding to `index`
---@param index number
---@return string
function EntryManager:get_ordinal(index)
return self:get_entry(index).ordinal
end

--- Get the index of the given entry in the EntryManager
---@param entry table: table with information about the given entry
---@return number|nil: the index of the entry if is present, nil otherwise
function EntryManager:find_entry(entry)
local info = self.info

Expand All @@ -95,6 +118,7 @@ function EntryManager:find_entry(entry)
return nil
end

--- Update the `worst_acceptable_score` based on the score of the tracked entry
function EntryManager:_update_score_from_tracked()
local linked = self.linked_states

Expand All @@ -103,20 +127,39 @@ function EntryManager:_update_score_from_tracked()
end
end

--- Insert the `new_container` before the `linked_node` which is in position `index` in the
--- associated linked list of the EntryManager and update tracked information accordingly
---@note: this is basically a wrapper for `linked_list.place_before`
---@param picker table: the associated picker for the entry manager
---@param index number: the position to place the entry
---@param linked_node table: the node currently in the `index` position of the linked list
---@param new_container table: the container to be inserted into the linked list
function EntryManager:_insert_container_before(picker, index, linked_node, new_container)
self.linked_states:place_before(index, linked_node, new_container)
self.set_entry(picker, index, new_container[1], new_container[2], true)

self:_update_score_from_tracked()
end

--- Insert the `new_container` after the `linked_node` which is in position `index` in the
--- associated linked list of the EntryManager and update tracked information accordingly
---@note: this is basically a wrapper for `linked_list.place_after`
---@param picker table: the associated picker for the entry manager
---@param index number: the position to place the entry
---@param linked_node table: the node currently in the `index` position of the linked list
---@param new_container table: the container to be inserted into the linked list
function EntryManager:_insert_container_after(picker, index, linked_node, new_container)
self.linked_states:place_after(index, linked_node, new_container)
self.set_entry(picker, index, new_container[1], new_container[2], true)

self:_update_score_from_tracked()
end

--- Append the `new_container` to the end of the linked list associated to the EntryManager.
--- If `should_update` is `true`, then the tracked information is updated.
---@param picker table: the associated picker for the entry manager
---@param new_container table: the container to be appended to the linked list
---@param should_update boolean
function EntryManager:_append_container(picker, new_container, should_update)
self.linked_states:append(new_container)
self.worst_acceptable_score = math.min(self.worst_acceptable_score, new_container[2])
Expand All @@ -126,6 +169,17 @@ function EntryManager:_append_container(picker, new_container, should_update)
end
end

--- Adds `new_container` to the associated linked list.
--- If `score` is less than `worst_acceptable_score` then
--- `new_container` is placed in the position that puts it
--- in order. Otherwise, `new_container` is simply appended
--- to the linked list.
--- The `worst_acceptable_score` and `info.maxed` are updated
--- when needed.
---@param picker table: the associated picker for the entry manager
---@param score number: the score of the entry to be added
---@param entry table: the entry to be added to the manager
---@return nil
function EntryManager:add_entry(picker, score, entry)
score = score or 0

Expand Down Expand Up @@ -173,6 +227,7 @@ function EntryManager:add_entry(picker, score, entry)
return self:_insert_container_after(picker, size + 1, self.linked_states.tail, new_container)
end

--- Get an iterator for the entries in the associated linked list
function EntryManager:iter()
return coroutine.wrap(function()
for val in self.linked_states:iter() do
Expand Down
Loading