feat: Use metatables to use less memory (#152)
Instead of storing everything in key / value pair hashes, we store as much as possible in an array and then reference the items in the array using metatables. This provides us with a much lower memory footprint and just one level of table lookup indirection (so I think the speed will not be noticeably different)
This commit is contained in:
@@ -7,11 +7,6 @@ local get_default = utils.get_default
|
|||||||
|
|
||||||
local make_entry = {}
|
local make_entry = {}
|
||||||
|
|
||||||
make_entry.types = {
|
|
||||||
GENERIC = 0,
|
|
||||||
FILE = 1,
|
|
||||||
}
|
|
||||||
|
|
||||||
local transform_devicons
|
local transform_devicons
|
||||||
if has_devicons then
|
if has_devicons then
|
||||||
transform_devicons = function(filename, display, disable_devicons)
|
transform_devicons = function(filename, display, disable_devicons)
|
||||||
@@ -29,88 +24,82 @@ else
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function make_entry.gen_from_string()
|
do
|
||||||
return function(line)
|
local lookup_keys = {
|
||||||
return {
|
display = 1,
|
||||||
valid = line ~= "",
|
ordinal = 1,
|
||||||
entry_type = make_entry.types.GENERIC,
|
value = 1,
|
||||||
|
}
|
||||||
|
|
||||||
value = line,
|
local mt_string_entry = {
|
||||||
ordinal = line,
|
__index = function(t, k)
|
||||||
display = line,
|
return rawget(t, rawget(lookup_keys, k))
|
||||||
}
|
end
|
||||||
|
}
|
||||||
|
|
||||||
|
function make_entry.gen_from_string()
|
||||||
|
return function(line)
|
||||||
|
return setmetatable({
|
||||||
|
line,
|
||||||
|
}, mt_string_entry)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function make_entry.gen_from_file(opts)
|
do
|
||||||
-- local opts = vim.deepcopy(init_opts or {})
|
local lookup_keys = {
|
||||||
opts = opts or {}
|
ordinal = 1,
|
||||||
|
value = 1,
|
||||||
|
filename = 1,
|
||||||
|
cwd = 2,
|
||||||
|
}
|
||||||
|
|
||||||
local cwd = vim.fn.expand(opts.cwd or vim.fn.getcwd())
|
function make_entry.gen_from_file(opts)
|
||||||
local disable_devicons = opts.disable_devicons
|
opts = opts or {}
|
||||||
local shorten_path = opts.shorten_path
|
|
||||||
|
|
||||||
local make_display = function(line)
|
local cwd = vim.fn.expand(opts.cwd or vim.fn.getcwd())
|
||||||
local display = line
|
|
||||||
if shorten_path then
|
local disable_devicons = opts.disable_devicons
|
||||||
display = utils.path_shorten(line)
|
local shorten_path = opts.shorten_path
|
||||||
|
|
||||||
|
local mt_file_entry = {}
|
||||||
|
|
||||||
|
mt_file_entry.cwd = cwd
|
||||||
|
mt_file_entry.display = function(entry)
|
||||||
|
local display = entry.value
|
||||||
|
if shorten_path then
|
||||||
|
display = utils.path_shorten(display)
|
||||||
|
end
|
||||||
|
|
||||||
|
return transform_devicons(entry.value, display, disable_devicons)
|
||||||
end
|
end
|
||||||
|
|
||||||
display = transform_devicons(line, display, disable_devicons)
|
mt_file_entry.__index = function(t, k)
|
||||||
|
local raw = rawget(mt_file_entry, k)
|
||||||
|
if raw then return raw end
|
||||||
|
|
||||||
return display
|
if k == "path" then
|
||||||
end
|
return t.cwd .. path.separator .. t.value
|
||||||
|
end
|
||||||
|
|
||||||
return function(line)
|
return rawget(t, rawget(lookup_keys, k))
|
||||||
local entry = {
|
end
|
||||||
ordinal = line,
|
|
||||||
value = line,
|
|
||||||
|
|
||||||
entry_type = make_entry.types.FILE,
|
return function(line)
|
||||||
filename = line,
|
return setmetatable({line}, mt_file_entry)
|
||||||
path = cwd .. utils.get_separator() .. line,
|
end
|
||||||
}
|
|
||||||
|
|
||||||
entry.display = make_display(line)
|
|
||||||
|
|
||||||
return entry
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function make_entry.gen_from_vimgrep(opts)
|
do
|
||||||
opts = opts or {}
|
local lookup_keys = {
|
||||||
|
value = 1,
|
||||||
|
ordinal = 1,
|
||||||
|
}
|
||||||
|
|
||||||
local display_string = "%s:%s%s"
|
-- Gets called only once to parse everything out for the vimgrep, after that looks up directly.
|
||||||
|
local parse = function(t)
|
||||||
local make_display = function(entry)
|
local _, _, filename, lnum, col, text = string.find(t.value, [[([^:]+):(%d+):(%d+):(.*)]])
|
||||||
local display = entry.value
|
|
||||||
|
|
||||||
local display_filename
|
|
||||||
if opts.shorten_path then
|
|
||||||
display_filename = utils.path_shorten(entry.filename)
|
|
||||||
else
|
|
||||||
display_filename = entry.filename
|
|
||||||
end
|
|
||||||
|
|
||||||
local coordinates = ""
|
|
||||||
if not opts.disable_coordinates then
|
|
||||||
coordinates = string.format("%s:%s:", entry.lnum, entry.col)
|
|
||||||
end
|
|
||||||
|
|
||||||
display = transform_devicons(
|
|
||||||
entry.filename,
|
|
||||||
string.format(display_string, display_filename, coordinates, entry.text),
|
|
||||||
opts
|
|
||||||
)
|
|
||||||
|
|
||||||
return display
|
|
||||||
end
|
|
||||||
|
|
||||||
return function(line)
|
|
||||||
-- TODO: Consider waiting to do this string.find
|
|
||||||
-- TODO: Is this the fastest way to get each of these?
|
|
||||||
-- Or could we just walk the text and check for colons faster?
|
|
||||||
local _, _, filename, lnum, col, text = string.find(line, [[([^:]+):(%d+):(%d+):(.*)]])
|
|
||||||
|
|
||||||
local ok
|
local ok
|
||||||
ok, lnum = pcall(tonumber, lnum)
|
ok, lnum = pcall(tonumber, lnum)
|
||||||
@@ -119,19 +108,89 @@ function make_entry.gen_from_vimgrep(opts)
|
|||||||
ok, col = pcall(tonumber, col)
|
ok, col = pcall(tonumber, col)
|
||||||
if not ok then col = nil end
|
if not ok then col = nil end
|
||||||
|
|
||||||
return {
|
t.filename = filename
|
||||||
valid = line ~= "",
|
t.lnum = lnum
|
||||||
|
t.col = col
|
||||||
|
t.text = text
|
||||||
|
|
||||||
value = line,
|
return {filename, lnum, col, text}
|
||||||
ordinal = line,
|
end
|
||||||
display = make_display,
|
|
||||||
|
|
||||||
entry_type = make_entry.types.FILE,
|
local execute_keys = {
|
||||||
filename = filename,
|
path = function(t)
|
||||||
lnum = lnum,
|
return t.cwd .. path.separator .. t.filename, false
|
||||||
col = col,
|
end,
|
||||||
text = text,
|
|
||||||
}
|
filename = function(t)
|
||||||
|
return parse(t)[1], true
|
||||||
|
end,
|
||||||
|
|
||||||
|
lnum = function(t)
|
||||||
|
return parse(t)[2], true
|
||||||
|
end,
|
||||||
|
|
||||||
|
col = function(t)
|
||||||
|
return parse(t)[3], true
|
||||||
|
end,
|
||||||
|
|
||||||
|
text = function(t)
|
||||||
|
return parse(t)[4], true
|
||||||
|
end,
|
||||||
|
}
|
||||||
|
|
||||||
|
function make_entry.gen_from_vimgrep(opts)
|
||||||
|
opts = opts or {}
|
||||||
|
|
||||||
|
local shorten_path = opts.shorten_path
|
||||||
|
local disable_coordinates = opts.disable_coordinates
|
||||||
|
local disable_devicons = opts.disable_devicons
|
||||||
|
|
||||||
|
local display_string = "%s:%s%s"
|
||||||
|
|
||||||
|
local mt_vimgrep_entry = {}
|
||||||
|
|
||||||
|
mt_vimgrep_entry.cwd = vim.fn.expand(opts.cwd or vim.fn.getcwd())
|
||||||
|
mt_vimgrep_entry.display = function(entry)
|
||||||
|
local display = entry.value
|
||||||
|
|
||||||
|
local display_filename
|
||||||
|
if shorten_path then
|
||||||
|
display_filename = utils.path_shorten(entry.filename)
|
||||||
|
else
|
||||||
|
display_filename = entry.filename
|
||||||
|
end
|
||||||
|
|
||||||
|
local coordinates = ""
|
||||||
|
if not disable_coordinates then
|
||||||
|
coordinates = string.format("%s:%s:", entry.lnum, entry.col)
|
||||||
|
end
|
||||||
|
|
||||||
|
display = transform_devicons(
|
||||||
|
entry.filename,
|
||||||
|
string.format(display_string, display_filename, coordinates, entry.text),
|
||||||
|
disable_devicons
|
||||||
|
)
|
||||||
|
|
||||||
|
return display
|
||||||
|
end
|
||||||
|
|
||||||
|
mt_vimgrep_entry.__index = function(t, k)
|
||||||
|
local raw = rawget(mt_vimgrep_entry, k)
|
||||||
|
if raw then return raw end
|
||||||
|
|
||||||
|
local executor = rawget(execute_keys, k)
|
||||||
|
if executor then
|
||||||
|
local val, save = executor(t)
|
||||||
|
if save then rawset(t, k, val) end
|
||||||
|
return val
|
||||||
|
end
|
||||||
|
|
||||||
|
return rawget(t, rawget(lookup_keys, k))
|
||||||
|
end
|
||||||
|
|
||||||
|
return function(line)
|
||||||
|
return setmetatable({line}, mt_vimgrep_entry)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -320,10 +379,7 @@ function make_entry.gen_from_tagfile(opts)
|
|||||||
end
|
end
|
||||||
|
|
||||||
return function(line)
|
return function(line)
|
||||||
local entry = {
|
local entry = {}
|
||||||
entry_type = make_entry.types.GENERIC,
|
|
||||||
|
|
||||||
}
|
|
||||||
local d = make_display(line)
|
local d = make_display(line)
|
||||||
entry.valid = next(d) ~= nil
|
entry.valid = next(d) ~= nil
|
||||||
entry.display = d.display
|
entry.display = d.display
|
||||||
@@ -338,8 +394,8 @@ function make_entry.gen_from_packages(opts)
|
|||||||
opts = opts or {}
|
opts = opts or {}
|
||||||
|
|
||||||
local make_display = function(module_name)
|
local make_display = function(module_name)
|
||||||
local path = package.searchpath(module_name, package.path) or ""
|
local p_path = package.searchpath(module_name, package.path) or ""
|
||||||
local display = string.format("%-" .. opts.column_len .. "s : %s", module_name, vim.fn.fnamemodify(path, ":~:."))
|
local display = string.format("%-" .. opts.column_len .. "s : %s", module_name, vim.fn.fnamemodify(p_path, ":~:."))
|
||||||
|
|
||||||
return display
|
return display
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
-- require('plenary.reload').reload_module('telescope')
|
require('plenary.reload').reload_module('telescope')
|
||||||
|
|
||||||
local finders = require('telescope.finders')
|
local finders = require('telescope.finders')
|
||||||
local pickers = require('telescope.pickers')
|
local pickers = require('telescope.pickers')
|
||||||
local sorters = require('telescope.sorters')
|
local sorters = require('telescope.sorters')
|
||||||
local previewers = require('telescope.previewers')
|
local previewers = require('telescope.previewers')
|
||||||
|
local make_entry = require('telescope.make_entry')
|
||||||
|
|
||||||
local my_list = {
|
local my_list = {
|
||||||
'lua/telescope/WIP.lua',
|
'lua/telescope/WIP.lua',
|
||||||
|
|||||||
Reference in New Issue
Block a user