diff --git a/Lua API.rst b/Lua API.rst index 60906edc6..86233470a 100644 --- a/Lua API.rst +++ b/Lua API.rst @@ -3457,6 +3457,30 @@ Note that this function lets errors propagate to the caller. This will not be an issue in most cases. This function also permits circular dependencies of scripts. +* ``dfhack.reqscript(name)`` or ``reqscript(name)`` + + Nearly identical to script_environment() but requires scripts being loaded to + include a line similar to:: + + --@ module = true + + This is intended to only allow scripts that take appropriate action when used + as a module to be loaded. + +Enabling and disabling scripts +============================== + +Scripts can choose to recognize the built-in ``enable`` and ``disable`` commands +by including the following line anywhere in their file:: + + --@ enable = true + +When the ``enable`` and ``disable`` commands are invoked, a ``dfhack_flags`` +table will be passed to the script with the following fields set: + +* ``enable``: Always true if the script is being enabled *or* disabled +* ``enable_state``: True if the script is being enabled, false otherwise + Save init script ================ diff --git a/NEWS b/NEWS index e88f2213f..debc7e6f8 100644 --- a/NEWS +++ b/NEWS @@ -4,6 +4,8 @@ DFHack Future Developer plugins can be ignored on startup by setting the DFHACK_NO_DEV_PLUGINS environment variable The console on Linux and OS X now recognizes keyboard input between prompts Lua + Scripts can be enabled with the built-in enable/disable commands + A new function, reqscript(), is available as a safer alternative to script_environment() New internal commands New plugins New scripts diff --git a/library/lua/dfhack.lua b/library/lua/dfhack.lua index bdf9a1227..8af680bb6 100644 --- a/library/lua/dfhack.lua +++ b/library/lua/dfhack.lua @@ -440,7 +440,14 @@ end local valid_script_flags = { enable = {required = true, error = 'Does not recognize enable/disable commands'}, enable_state = {required = false}, - module = {required = true, error = 'Cannot be used as a module'}, + module = { + required = function(flags) + if flags.module_strict == false then return false end + return true + end, + error = 'Cannot be used as a module' + }, + module_strict = {required = false}, } function dfhack.run_script(name,...) @@ -455,10 +462,16 @@ function dfhack.enable_script(name, state) end end -function dfhack.script_environment(name) +function dfhack.reqscript(name) _, env = dfhack.run_script_with_env(nil, name, {module=true}) return env end +reqscript = dfhack.reqscript + +function dfhack.script_environment(name) + _, env = dfhack.run_script_with_env(nil, name, {module=true, module_strict=false}) + return env +end function dfhack.run_script_with_env(envVars, name, flags, ...) if type(flags) ~= 'table' then flags = {} end @@ -473,11 +486,15 @@ function dfhack.run_script_with_env(envVars, name, flags, ...) local script_flags = scripts[file]:get_flags() for flag, value in pairs(flags) do if value then - if not valid_script_flags[flag] then + local v = valid_script_flags[flag] + if not v then error('Invalid flag: ' .. flag) - elseif valid_script_flags[flag].required and not script_flags[flag] then - local msg = valid_script_flags[flag].error or 'Flag "' .. flag .. '" not recognized' - error(name .. ': ' .. msg) + elseif ((type(v.required) == 'boolean' and v.required) or + (type(v.required) == 'function' and v.required(flags))) then + if not script_flags[flag] then + local msg = v.error or 'Flag "' .. flag .. '" not recognized' + error(name .. ': ' .. msg) + end end end end