From b4c641bc57bc22be5a5d49655b63422166d2145a Mon Sep 17 00:00:00 2001 From: whosit Date: Tue, 25 Mar 2025 00:11:08 +0300 Subject: [PATCH 1/7] add `dir` convenience function to list table keys Useful to explore tables --- init.lua | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/init.lua b/init.lua index 41ea8c0..d816e56 100644 --- a/init.lua +++ b/init.lua @@ -77,6 +77,7 @@ local function create_shared_environment(player_name) { my_name = player_name, print = function(...) + -- print to chat, instead of console local msg = '< ' for i = 1, select('#', ...) do if i > 1 then msg = msg .. '\t' end @@ -84,6 +85,28 @@ local function create_shared_environment(player_name) end core.chat_send_player(player_name, msg) end, + dir = function(t) + -- collect all keys of the table + if type(t) == "table" then + local keys = {} + for k, _ in pairs(t) do + local key = k + local t = type(key) + if t == "string" then + key = '"' .. key .. '"' + elseif t == "number" then + key = '[' .. key .. ']' + else + key = '[' .. tostring(key) .. ']' + end + table.insert(keys, key) + end + table.sort(keys) + core.chat_send_player(player_name, table.concat(keys, ',\n')) + else + core.chat_send_player(player_name, string.format("Not a table: %s", dump(t))) + end + end, --global = _G, -- this works, but dumps whole global env if you just print `cmd_eval` value _G = global_proxy, -- use our proxy to get warnings global = global_proxy, -- just a different name for globals -- 2.47.2 From 1688a712cb863ab9492a24ae542294750fe38ec2 Mon Sep 17 00:00:00 2001 From: whosit Date: Tue, 25 Mar 2025 00:28:33 +0300 Subject: [PATCH 2/7] provide dir and dir2 functions for listing table keys Both functions don't expand tables used as keys/values. `dir(table)` will list `key = value` pairs, but non-recursively. `dir2(table)` will only list the keys. These functions return nothing and are to be used only interactively. --- dump.lua | 33 ++++++++++++++++++++++++++++++++- init.lua | 15 ++++++++++----- 2 files changed, 42 insertions(+), 6 deletions(-) diff --git a/dump.lua b/dump.lua index 670ad21..b1b2518 100644 --- a/dump.lua +++ b/dump.lua @@ -119,4 +119,35 @@ local function repl_dump(o, indent, nested, level) return "{"..table.concat(ret, ", ").."}" end -return repl_dump + +local function dump_dir(o) + -- dump only top-level key = value pairs + local t = type(o) + if t ~= "table" then + return basic_dump(o) + end + + local ret = {} + local dumped_indexes = {} + for i, v in ipairs(o) do + ret[#ret + 1] = string.format("[%s] = %s", i, basic_dump(v)) + dumped_indexes[i] = true + end + for k, v in pairs(o) do + if not dumped_indexes[k] then + if type(k) ~= "string" or not is_valid_identifier(k) then + k = "["..basic_dump(k).."]" + end + v = basic_dump(v) + ret[#ret + 1] = k.." = "..v + end + end + return "{\n "..table.concat(ret, ",\n ").."\n}" +end + +local dump_funcs = { + repl_dump = repl_dump, + dump_dir = dump_dir, +} + +return dump_funcs diff --git a/init.lua b/init.lua index d816e56..0d865ba 100644 --- a/init.lua +++ b/init.lua @@ -2,7 +2,9 @@ local MODNAME = core.get_current_modname() local MODPATH = core.get_modpath(MODNAME) local util = dofile(MODPATH .. DIR_DELIM .. "util.lua") -local repl_dump = dofile(MODPATH .. DIR_DELIM .. "dump.lua") +local dump_funcs = dofile(MODPATH .. DIR_DELIM .. "dump.lua") +local repl_dump = dump_funcs.repl_dump +local dump_dir = dump_funcs.dump_dir local api = {} _G[MODNAME] = api @@ -85,11 +87,14 @@ local function create_shared_environment(player_name) end core.chat_send_player(player_name, msg) end, - dir = function(t) - -- collect all keys of the table - if type(t) == "table" then + dir = function(o) + core.chat_send_player(player_name, dump_dir(o)) + end, + dir2 = function(o) + -- collect all keys of the table, no values + if type(o) == "table" then local keys = {} - for k, _ in pairs(t) do + for k, _ in pairs(o) do local key = k local t = type(key) if t == "string" then -- 2.47.2 From 723bab7fd8fe084cbfc4449f845dd584260d4d84 Mon Sep 17 00:00:00 2001 From: whosit Date: Tue, 25 Mar 2025 00:36:35 +0300 Subject: [PATCH 3/7] rename dir2() to keys() --- init.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/init.lua b/init.lua index 0d865ba..8f2cd41 100644 --- a/init.lua +++ b/init.lua @@ -90,7 +90,7 @@ local function create_shared_environment(player_name) dir = function(o) core.chat_send_player(player_name, dump_dir(o)) end, - dir2 = function(o) + keys = function(o) -- collect all keys of the table, no values if type(o) == "table" then local keys = {} -- 2.47.2 From 82502c833b44bb8c4d768cdc8d9c718c0c1e7a54 Mon Sep 17 00:00:00 2001 From: whosit Date: Tue, 25 Mar 2025 11:51:34 +0300 Subject: [PATCH 4/7] move code around --- init.lua | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/init.lua b/init.lua index 8f2cd41..266dee4 100644 --- a/init.lua +++ b/init.lua @@ -77,6 +77,9 @@ local function create_shared_environment(player_name) local eval_env = setmetatable( { + --global = _G, -- this works, but dumps whole global env if you just print `cmd_eval` value + _G = global_proxy, -- use our proxy to get warnings + global = global_proxy, -- just a different name for globals my_name = player_name, print = function(...) -- print to chat, instead of console @@ -112,9 +115,6 @@ local function create_shared_environment(player_name) core.chat_send_player(player_name, string.format("Not a table: %s", dump(t))) end end, - --global = _G, -- this works, but dumps whole global env if you just print `cmd_eval` value - _G = global_proxy, -- use our proxy to get warnings - global = global_proxy, -- just a different name for globals --dump = repl_dump, }, { -- 2.47.2 From ed80ef004dafb6bbd32430ebf7527abde6ee4538 Mon Sep 17 00:00:00 2001 From: whosit Date: Tue, 25 Mar 2025 13:01:33 +0300 Subject: [PATCH 5/7] add docs for dir() and keys() --- README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/README.md b/README.md index 4e29dd5..cab823f 100644 --- a/README.md +++ b/README.md @@ -135,3 +135,9 @@ already existed. > cmd_eval | nil -- wiped for real ``` + +### Other shortcuts + +#### `dir()` and `keys()` + +List keys of the table (useful for exploring data structures, without flooding your chat). -- 2.47.2 From a5a6ba6630564ef004292832d3014acad9d3a76a Mon Sep 17 00:00:00 2001 From: whosit Date: Tue, 25 Mar 2025 13:01:52 +0300 Subject: [PATCH 6/7] add goir() and oir() --- README.md | 11 +++++++++++ init.lua | 26 ++++++++++++++++++++++++++ 2 files changed, 37 insertions(+) diff --git a/README.md b/README.md index cab823f..8d11c39 100644 --- a/README.md +++ b/README.md @@ -141,3 +141,14 @@ already existed. #### `dir()` and `keys()` List keys of the table (useful for exploring data structures, without flooding your chat). + +#### `get_objects_inside_radius()` shortcuts: `goir()` and `oir()` + +`goir(radius)` returns a list of objects around you +`oir(radius)` returns an iterator of objects around you + +``` +> goir(100) -- return a list of objects within 100 units around you + +> for v in oir(100) do print((v:get_luaentity() or {}).name) end +``` diff --git a/init.lua b/init.lua index 266dee4..6e79af9 100644 --- a/init.lua +++ b/init.lua @@ -116,6 +116,32 @@ local function create_shared_environment(player_name) end end, --dump = repl_dump, + goir = function(radius) + local me = core.get_player_by_name(player_name) + if me then + local objs = core.get_objects_inside_radius(me:get_pos(), radius) + return objs + else + return {} + end + end, + oir = function(radius) + local me = core.get_player_by_name(player_name) + if me then + local objs = core.get_objects_inside_radius(me:get_pos(), radius) + local nextkey, v + --local i = 1 + return function() + -- FIXME skip invalid objects here? + nextkey, v = next(objs, nextkey) + return v + -- i = i + 1 + -- return objs[i] + end + else + return function() return nil end + end + end, }, { __index = function(self, key) -- 2.47.2 From 94abeadbf3f89f8a215d27d82bdd6e92efc1026b Mon Sep 17 00:00:00 2001 From: whosit Date: Tue, 25 Mar 2025 13:54:20 +0300 Subject: [PATCH 7/7] add boring "help" variable --- README.md | 2 ++ init.lua | 22 ++++++++++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/README.md b/README.md index 8d11c39..ad004c6 100644 --- a/README.md +++ b/README.md @@ -59,6 +59,8 @@ Some special variables are provided: - `point` - point in the world you're pointing at with your crosshair - `this_obj` - entity you're pointing at (can be `nil`) +Do `/eval help` to get a quick reminder of these vars and functions. + ### Better output for arrays and some `userdata` objects ``` > me diff --git a/init.lua b/init.lua index 6e79af9..c7edac9 100644 --- a/init.lua +++ b/init.lua @@ -57,6 +57,25 @@ local function create_shared_environment(player_name) end return vector.round(me:get_pos()) end, + help = function() + local msg = [[ +# Variables: +me -- your player object +my_pos -- your position +here -- your position where command was executed at (does not change) +point -- the exact pos you're pointing with the crosshair +this_obj -- the obj you're pointing at with the crosshair or nil +this_node_pos -- the node position you're pointing at +global -- actual global environment (same as _G) + +# Functions: +dir(t) -- print table key/values (returns nothing) +keys(t) -- print table keys (returns nothing) +goir(radius) -- return list of objects around you +oir(radius) -- return iterator for objects around you +]] + core.chat_send_player(player_name, msg) + end, } local g = {} -- "do not warn again" flags @@ -177,6 +196,9 @@ local function create_command_environment(player_name) local me = core.get_player_by_name(player_name) local here = me:get_pos() local cmd_env = { + -- This is a special _per-command_ environment. + -- The rationale is: each command should have it's own "here" + -- It may matter when we start long-running tasks or something. here = here, } setmetatable( -- 2.47.2