diff options
| author | Alexander Gavrilov | 2012-03-30 11:57:27 +0400 |
|---|---|---|
| committer | Alexander Gavrilov | 2012-03-30 11:57:27 +0400 |
| commit | e989ca58db10b644bfe1f05d7d2f851c4d943deb (patch) | |
| tree | d98945fb748e68e2409c60f644589792e81d872d /plugins/Dfusion | |
| parent | 81bc73f435ce4d5a609304c322c55d4053bcde91 (diff) | |
| download | dfhack-e989ca58db10b644bfe1f05d7d2f851c4d943deb.tar.gz dfhack-e989ca58db10b644bfe1f05d7d2f851c4d943deb.tar.bz2 dfhack-e989ca58db10b644bfe1f05d7d2f851c4d943deb.tar.xz | |
Enhance the interactive interpreter mode of dfusion.
1. Reimplement Console.print* to behave exactly as the standard print
function, and apply print = Console.println from c++ init code.
2. Add a couple of convenience shortcuts to save some manual typing
when poking around data structures using the interactive prompt.
3. Change the prompt string to a more distinguished shape.
Diffstat (limited to 'plugins/Dfusion')
| -rw-r--r-- | plugins/Dfusion/dfusion.cpp | 68 | ||||
| -rw-r--r-- | plugins/Dfusion/luafiles/init.lua | 3 | ||||
| -rw-r--r-- | plugins/Dfusion/src/lua_Console.cpp | 55 |
3 files changed, 105 insertions, 21 deletions
diff --git a/plugins/Dfusion/dfusion.cpp b/plugins/Dfusion/dfusion.cpp index b7ff4747..a53bd45d 100644 --- a/plugins/Dfusion/dfusion.cpp +++ b/plugins/Dfusion/dfusion.cpp @@ -64,6 +64,11 @@ DFhackCExport command_result plugin_init ( Core * c, std::vector <PluginCommand> st.setglobal("WINDOWS"); #endif + st.getglobal("Console"); + st.getfield("println"); + st.setglobal("print"); + st.pop(); + commands.push_back(PluginCommand("dfusion","Run dfusion system (interactive i.e. can input further commands).",dfusion,true)); commands.push_back(PluginCommand("dfuse","Init dfusion system (not interactive).",dfuse,false)); commands.push_back(PluginCommand("lua", "Run interactive interpreter. Use 'lua <filename>' to run <filename> instead.",lua_run,true)); @@ -115,27 +120,74 @@ void InterpreterLoop(color_ostream &out) DFHack::CommandHistory hist; lua::state s=lua::glua::Get(); string curline; - out.print("Type quit to exit interactive mode\n"); + out.print("Type quit to exit interactive mode.\n" + "Shortcuts:\n" + " '= foo' => '_1,_2,... = foo'\n" + " '! foo' => 'print(foo)'\n"); assert(out.is_console()); Console &con = static_cast<Console&>(out); - con.lineedit(">>",curline,hist); + int vcnt = 1; + + s.settop(0); + + for (;;) { + con.lineedit("[lua]# ",curline,hist); + + if (curline.empty()) + continue; + if (curline == "quit") + break; - while (curline!="quit") { hist.add(curline); + try { - s.loadstring(curline); - s.pcall(); + if (curline[0] == '=') + { + curline = "return " + curline.substr(1); + + s.loadstring(curline); + s.pcall(0, LUA_MULTRET); + int numret = s.gettop(); + + for (int i = 1; i <= numret; i++) + { + if (i == 1) + { + s.pushvalue(i); + s.setglobal("_"); + } + + std::string name = stl_sprintf("_%d", vcnt++); + s.pushvalue(i); + s.setglobal(name); + + con.print("%s = ", name.c_str()); + s.getglobal("print"); + s.pushvalue(i); + s.pcall(1,0); + } + } + else if (curline[0] == '!') + { + curline = "print(" + curline.substr(1) + ")"; + s.loadstring(curline); + s.pcall(); + } + else + { + s.loadstring(curline); + s.pcall(); + } } catch(lua::exception &e) { con.printerr("Error:%s\n",e.what()); con.printerr("%s\n",lua::DebugDump(lua::glua::Get()).c_str()); - s.settop(0); } - con.lineedit(">>",curline,hist); + + s.settop(0); } - s.settop(0); } command_result lua_run_file (color_ostream &out, std::vector <std::string> ¶meters) { diff --git a/plugins/Dfusion/luafiles/init.lua b/plugins/Dfusion/luafiles/init.lua index aaf2677f..9ec8baf2 100644 --- a/plugins/Dfusion/luafiles/init.lua +++ b/plugins/Dfusion/luafiles/init.lua @@ -1,6 +1,3 @@ -function print(msg) - Console.print(msg.."\n") -end function err(msg) --make local maybe... print(msg) print(debug.traceback()) diff --git a/plugins/Dfusion/src/lua_Console.cpp b/plugins/Dfusion/src/lua_Console.cpp index 4f0d62f1..2a8222af 100644 --- a/plugins/Dfusion/src/lua_Console.cpp +++ b/plugins/Dfusion/src/lua_Console.cpp @@ -1,4 +1,7 @@ #include "lua_Console.h" + +#include <sstream> + //TODO error management. Using lua error? or something other? static DFHack::color_ostream* GetConsolePtr(lua::state &st) { @@ -9,22 +12,53 @@ static DFHack::color_ostream* GetConsolePtr(lua::state &st) st.settop(t); return c; } + +static std::string lua_print_fmt(lua_State *L) +{ + /* Copied from lua source to fully replicate builtin print */ + int n = lua_gettop(L); /* number of arguments */ + lua_getglobal(L, "tostring"); + + std::stringstream ss; + + for (int i=1; i<=n; i++) { + lua_pushvalue(L, -1); /* function to be called */ + lua_pushvalue(L, i); /* value to print */ + lua_call(L, 1, 1); + const char *s = lua_tostring(L, -1); /* get result */ + if (s == NULL) + luaL_error(L, "tostring must return a string to print"); + if (i>1) + ss << '\t'; + ss << s; + lua_pop(L, 1); /* pop result */ + } + + return ss.str(); +} + static int lua_Console_print(lua_State *S) { - lua::state st(S); - int t=st.gettop(); - DFHack::color_ostream* c=GetConsolePtr(st); - c->print("%s",st.as<string>(t).c_str()); - return 0; + lua::state st(S); + DFHack::color_ostream* c=GetConsolePtr(st); + c->print("%s", lua_print_fmt(S).c_str()); + return 0; +} + +static int lua_Console_println(lua_State *S) +{ + lua::state st(S); + DFHack::color_ostream* c=GetConsolePtr(st); + c->print("%s\n", lua_print_fmt(S).c_str()); + return 0; } static int lua_Console_printerr(lua_State *S) { - lua::state st(S); - int t=st.gettop(); - DFHack::color_ostream* c=GetConsolePtr(st); - c->printerr("%s",st.as<string>(t).c_str()); - return 0; + lua::state st(S); + DFHack::color_ostream* c=GetConsolePtr(st); + c->printerr("%s", lua_print_fmt(S).c_str()); + return 0; } static int lua_Console_clear(lua_State *S) @@ -123,6 +157,7 @@ static int lua_Console_lineedit(lua_State *S) const luaL_Reg lua_console_func[]= { {"print",lua_Console_print}, + {"println",lua_Console_println}, {"printerr",lua_Console_printerr}, {"clear",lua_Console_clear}, {"gotoxy",lua_Console_gotoxy}, |
