static int dfhack_lineedit_sync(lua_State *S, Console *pstream) { if (!pstream) return 2; const char *prompt = luaL_optstring(S, 1, ">> "); const char *hfile = luaL_optstring(S, 2, NULL); 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; } }
bool DFHack::Lua::RunCoreQueryLoop(color_ostream &out, lua_State *state, bool (*init)(color_ostream&, lua_State*, void*), void *arg) { if (!lua_checkstack(state, 20)) return false; lua_State *thread; int rv; std::string prompt; std::string histfile; DFHack::CommandHistory hist; std::string histname; { CoreSuspender suspend; int base = lua_gettop(state); if (!init(out, state, arg)) { lua_settop(state, base); return false; } // If not interactive, run without coroutine and bail out if (!out.is_console()) return SafeCall(out, state, lua_gettop(state)-base-1, 0); lua_rawgetp(state, LUA_REGISTRYINDEX, &DFHACK_QUERY_COROTABLE_TOKEN); lua_pushvalue(state, base+1); lua_remove(state, base+1); thread = Lua::NewCoroutine(state); lua_rawsetp(state, -2, thread); lua_pop(state, 1); rv = resume_query_loop(out, thread, state, lua_gettop(state)-base, prompt, histfile); } Console &con = static_cast<Console&>(out); while (rv == LUA_YIELD) { if (histfile != histname) { if (!histname.empty()) hist.save(histname.c_str()); hist.clear(); histname = histfile; if (!histname.empty()) hist.load(histname.c_str()); } if (prompt.empty()) prompt = ">> "; std::string curline; con.lineedit(prompt,curline,hist); hist.add(curline); { CoreSuspender suspend; lua_pushlstring(state, curline.data(), curline.size()); rv = resume_query_loop(out, thread, state, 1, prompt, histfile); } } if (!histname.empty()) hist.save(histname.c_str()); { CoreSuspender suspend; lua_rawgetp(state, LUA_REGISTRYINDEX, &DFHACK_QUERY_COROTABLE_TOKEN); lua_pushnil(state); lua_rawsetp(state, -2, thread); lua_pop(state, 1); } return (rv == LUA_OK); }