@@ -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
257284local NIL_STATE = {}
258285
@@ -378,7 +405,7 @@ API.coroutine = {}
378405local 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
384411if not table.pack then
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 ] )
743770 end
744771end
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
10431083local 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