Add color output and input prompt support to core lua api.

develop
Alexander Gavrilov 2012-04-04 10:40:33 +04:00
parent 2d4af4ac3e
commit 81fb57a853
2 changed files with 91 additions and 16 deletions

@ -410,9 +410,18 @@ Currently it defines the following features:
Same as println; intended for errors. Uses red color and logs to stderr.log.
* ``safecall(f[,args...])``, ``dfhack.safecall(f[,args...])``
* ``dfhack.color([color])``
Just like pcall, but prints the error with traceback using printerr.
Sets the current output color. If color is *nil* or *-1*, resets to default.
* ``dfhack.is_interactive()``
Checks if the thread can access the interactive console and returns *true* or *false*.
* ``dfhack.lineedit([prompt[,history_filename]])``
If the thread owns the interactive console, shows a prompt
and returns the entered string. Otherwise returns *nil, error*.
* ``dfhack.interpreter([prompt[,env[,history_filename]]])``
@ -421,6 +430,10 @@ Currently it defines the following features:
If the interactive console is not accessible, returns *nil, error*.
* ``safecall(f[,args...])``, ``dfhack.safecall(f[,args...])``
Just like pcall, but prints the error with traceback using printerr.
* ``dfhack.with_suspend(f[,args...])``
Calls ``f`` with arguments after grabbing the DF core suspend lock.

@ -76,6 +76,27 @@ static void set_dfhack_output(lua_State *L, color_ostream *p)
lua_rawsetp(L, LUA_REGISTRYINDEX, &DFHACK_OSTREAM_TOKEN);
}
static Console *get_console(lua_State *state)
{
color_ostream *pstream = Lua::GetOutput(state);
if (!pstream)
{
lua_pushnil(state);
lua_pushstring(state, "no output stream");
return NULL;
}
if (!pstream->is_console())
{
lua_pushnil(state);
lua_pushstring(state, "not an interactive console");
return NULL;
}
return static_cast<Console*>(pstream);
}
static std::string lua_print_fmt(lua_State *L)
{
/* Copied from lua source to fully replicate builtin print */
@ -130,6 +151,56 @@ static int lua_dfhack_printerr(lua_State *S)
return 0;
}
static int lua_dfhack_color(lua_State *S)
{
int cv = luaL_optint(S, 1, -1);
if (cv < -1 || cv > color_ostream::COLOR_MAX)
luaL_argerror(S, 1, "invalid color value");
color_ostream *out = Lua::GetOutput(S);
if (out)
out->color(color_ostream::color_value(cv));
return 0;
}
static int lua_dfhack_is_interactive(lua_State *S)
{
lua_pushboolean(S, get_console(S) != NULL);
return 1;
}
static int lua_dfhack_lineedit(lua_State *S)
{
const char *prompt = luaL_optstring(S, 1, ">> ");
const char *hfile = luaL_optstring(S, 2, NULL);
Console *pstream = get_console(S);
if (!pstream)
return 2;
DFHack::CommandHistory hist;
if (hfile)
hist.load(hfile);
std::string ret;
int rv = pstream->lineedit(prompt, ret, hist);
if (rv < 0)
{
lua_pushnil(S);
lua_pushstring(S, "input error");
return 2;
}
else
{
if (hfile)
hist.save(hfile);
lua_pushlstring(S, ret.data(), ret.size());
return 1;
}
}
static int traceback (lua_State *L) {
const char *msg = lua_tostring(L, 1);
if (msg)
@ -387,21 +458,9 @@ bool DFHack::Lua::InterpreterLoop(color_ostream &out, lua_State *state,
static int lua_dfhack_interpreter(lua_State *state)
{
color_ostream *pstream = Lua::GetOutput(state);
Console *pstream = get_console(state);
if (!pstream)
{
lua_pushnil(state);
lua_pushstring(state, "no output stream");
return 2;
}
if (!pstream->is_console())
{
lua_pushnil(state);
lua_pushstring(state, "not an interactive console");
return 2;
}
int argc = lua_gettop(state);
@ -447,9 +506,12 @@ static const luaL_Reg dfhack_funcs[] = {
{ "print", lua_dfhack_print },
{ "println", lua_dfhack_println },
{ "printerr", lua_dfhack_printerr },
{ "color", lua_dfhack_color },
{ "is_interactive", lua_dfhack_is_interactive },
{ "lineedit", lua_dfhack_lineedit },
{ "interpreter", lua_dfhack_interpreter },
{ "safecall", lua_dfhack_safecall },
{ "onerror", traceback },
{ "interpreter", lua_dfhack_interpreter },
{ "with_suspend", lua_dfhack_with_suspend },
{ NULL, NULL }
};