Skip to content

Commit a051677

Browse files
Allow pairs, ipairs, and next to work with read-only tables
1 parent 5505d42 commit a051677

File tree

1 file changed

+43
-3
lines changed

1 file changed

+43
-3
lines changed

file-browser.lua

Lines changed: 43 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -253,6 +253,33 @@ local compatible_file_extensions = {
253253
--------------------------------------------------------------------------------------------------------
254254
--------------------------------------------------------------------------------------------------------
255255

256+
local original_ipairs = _G.ipairs
257+
local original_next = _G.next
258+
local original_pairs = _G.pairs
259+
260+
--adds ipairs support for readonly tables
261+
function ipairs(t)
262+
if not API.is_read_only(t) then return original_ipairs(t) end
263+
264+
local function iter (a, i)
265+
i = i + 1
266+
if a[i] then return API.read_only_values(i, a[i]) end
267+
end
268+
return iter, t, 0
269+
end
270+
271+
--adds next support for readonly tables
272+
function next(t, ...)
273+
if API.is_read_only(t) then return API.read_only_values(original_next(getmetatable(t).mutable, ...))
274+
else return original_next(t, ...) end
275+
end
276+
277+
--this only needs to use the new next function in order to support readonly tables
278+
function pairs(t)
279+
if API.is_read_only(t) then return next, t, nil
280+
else return original_pairs(t) end
281+
end
282+
256283
--this value can be used to remove values when updating the current state
257284
local NIL_STATE = {}
258285

@@ -378,7 +405,7 @@ API.coroutine = {}
378405
local ABORT_ERROR = {
379406
msg = "browser is no longer waiting for list - aborting parse"
380407
}
381-
local newindex = function(t, k, v) error(("attempted to assign `%s` to key `%s` in read-only %s"):format(v, k, t), 2) end
408+
local readonly_newindex = function(t, k, v) error(("attempted to assign `%s` to key `%s` in read-only %s"):format(v, k, t), 2) end
382409

383410
--implements table.pack if on lua 5.1
384411
if not table.pack then
@@ -730,7 +757,7 @@ do
730757
if references[t] then return references[t] end
731758

732759
local ro = setmetatable({}, {
733-
__newindex = newindex,
760+
__newindex = readonly_newindex,
734761
mutable = t,
735762
__index = function(_, k)
736763
return API.read_only( t[k] )
@@ -743,6 +770,19 @@ do
743770
end
744771
end
745772

773+
--returns read-only references to all given values
774+
function API.read_only_values(...)
775+
local vals = table.pack(...)
776+
for i, v in ipairs(vals) do vals[i] = API.read_only(v) end
777+
return table.unpack(vals)
778+
end
779+
780+
--returns true if the given tale is read-only
781+
function API.is_read_only(t)
782+
local mt = getmetatable(t)
783+
return mt and mt.__newindex == readonly_newindex
784+
end
785+
746786

747787

748788
--------------------------------------------------------------------------------------------------------
@@ -1042,7 +1082,7 @@ end
10421082
--select all items in the list
10431083
local function select_all()
10441084
local selection = {}
1045-
for i,_ in ipairs(state.list) do
1085+
for i in ipairs(state.list) do
10461086
selection[i] = true
10471087
end
10481088

0 commit comments

Comments
 (0)