summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'Sluift/core.lua')
-rw-r--r--Sluift/core.lua110
1 files changed, 109 insertions, 1 deletions
diff --git a/Sluift/core.lua b/Sluift/core.lua
index aeb3286..f387354 100644
--- a/Sluift/core.lua
+++ b/Sluift/core.lua
@@ -97,10 +97,31 @@ local function copy(object)
end
end
+local function clear(table)
+ setmetatable(table, nil)
+ for key, value in pairs(table) do
+ rawset(table, key, nil)
+ end
+end
+
local function trim(string)
return string:gsub("^%s*(.-)%s*$", "%1")
end
+local function keys(table)
+ local result = {}
+ for key in pairs(table) do
+ result[#result+1] = key
+ end
+ return result
+end
+
+local function insert_all(table, values)
+ for _, value in pairs(values) do
+ table[#table+1] = value
+ end
+end
+
--------------------------------------------------------------------------------
-- Help
--------------------------------------------------------------------------------
@@ -405,7 +426,9 @@ end
_H = {
[[ Client interface ]]
}
-local Client = {}
+local Client = {
+ _with_prompt = function(client) return client:jid() end
+}
Client.__index = Client
register_class_table_help(Client, "Client")
@@ -424,6 +447,90 @@ local PubSubNode = {}
PubSubNode.__index = PubSubNode
register_class_table_help(PubSubNode, "PubSubNode")
+
+--------------------------------------------------------------------------------
+-- with
+--------------------------------------------------------------------------------
+
+local original_G
+
+local function with (target, f)
+ -- Dynamic scope
+ if f then
+ with(target)
+ return call{f, finally = function() with() end}
+ end
+
+ -- No scope
+ if target then
+ if not original_G then
+ original_G = copy(_G)
+ setmetatable(original_G, getmetatable(_G))
+ clear(_G)
+ end
+
+ setmetatable(_G, {
+ __index = function(_, key)
+ local value = target[key]
+ if value then
+ if type(value) == 'function' then
+ -- Add 'self' argument to all functions
+ return function(...) return value(target, ...) end
+ else
+ return value
+ end
+ else
+ return original_G[key]
+ end
+ end,
+ __newindex = original_G,
+ _completions = function ()
+ local result = {}
+ if type(target) == "table" then
+ insert_all(result, keys(target))
+ end
+ local mt = getmetatable(target)
+ if mt and type(mt.__index) == 'table' then
+ insert_all(result, keys(mt.__index))
+ end
+ insert_all(result, keys(original_G))
+ return result
+ end
+ })
+
+ -- Set prompt
+ local prompt = nil
+
+ -- Try '_with_prompt' in metatable
+ local target_metatable = getmetatable(target)
+ if target_metatable then
+ if type(target_metatable._with_prompt) == "function" then
+ prompt = target_metatable._with_prompt(target)
+ else
+ prompt = target_metatable._with_prompt
+ end
+ end
+
+ if not prompt then
+ -- Use tostring()
+ local target_string = tostring(target)
+ if string.len(target_string) > 25 then
+ prompt = string.sub(target_string, 0, 22) .. "..."
+ else
+ prompt = target_string
+ end
+ end
+ rawset(_G, "_PROMPT", prompt .. '> ')
+ else
+ -- Reset _G
+ clear(_G)
+ for key, value in pairs(original_G) do
+ _G[key] = value
+ end
+ setmetatable(_G, original_G)
+ end
+end
+
--------------------------------------------------------------------------------
-- Client
--------------------------------------------------------------------------------
@@ -884,4 +991,5 @@ return {
help = help,
extra_help = extra_help,
copy = copy,
+ with = with
}