diff --git a/docs/Lua API.rst b/docs/Lua API.rst index 9bab6b494..527a9f3b4 100644 --- a/docs/Lua API.rst +++ b/docs/Lua API.rst @@ -524,6 +524,20 @@ Input & Output lock. Using an explicit ``dfhack.with_suspend`` will prevent this, forcing the function to block on input with lock held. +* ``dfhack.getCommandHistory(history_id, history_filename)`` + + Returns the list of strings in the specified history. Intended to be used by + GUI scripts that don't have access to a console and so can't use + ``dfhack.lineedit``. The ``history_id`` parameter is some unique string that + the script uses to identify its command history, such as the script's name. If + this is the first time the history with the given ``history_id`` is being + accessed, it is initialized from the given file. + +* ``dfhack.addCommandToHistory(history_id, history_filename, command)`` + + Adds a command to the specified history and saves the updated history to the + specified file. + * ``dfhack.interpreter([prompt[,history_filename[,env]]])`` Starts an interactive lua interpreter, using the specified prompt @@ -837,6 +851,7 @@ can be omitted. * ``dfhack.getGitXmlExpectedCommit()`` * ``dfhack.gitXmlMatch()`` * ``dfhack.isRelease()`` +* ``dfhack.isPrerelease()`` Return information about the DFHack build in use. @@ -890,7 +905,6 @@ can be omitted. from ``dfhack.TranslateName()``), use ``print(dfhack.df2console(text))`` to ensure proper display on all platforms. - * ``dfhack.utf2df(string)`` Convert a string from UTF-8 to DF's CP437 encoding. diff --git a/docs/changelog.txt b/docs/changelog.txt index 3afcd3e5c..d64c2ab0d 100644 --- a/docs/changelog.txt +++ b/docs/changelog.txt @@ -66,6 +66,7 @@ changelog.txt uses a syntax similar to RST, with a few special sequences: - ``Gui::getSelectedItem()``, ``Gui::getAnyItem()``: added support for the artifacts screen ## Lua +- History: added ``dfhack.getCommandHistory(history_id, history_filename)`` and ``dfhack.addCommandToHistory(history_id, history_filename, command)`` so gui scripts can access a commandline history without requiring a terminal. - ``tile-material``: fix the order of declarations. The ``GetTileMat`` function now returns the material as intended (always returned nil before). Also changed the license info, with permission of the original author. - ``widgets.EditField``: new ``onsubmit2`` callback attribute is called when the user hits Shift-Enter. - ``widgets.EditField``: new function: ``setCursor(position)`` sets the input cursor. diff --git a/library/LuaApi.cpp b/library/LuaApi.cpp index 101b645fd..12b0a7310 100644 --- a/library/LuaApi.cpp +++ b/library/LuaApi.cpp @@ -1359,6 +1359,38 @@ static void OpenRandom(lua_State *state) lua_pop(state, 1); } + +/********************************* +* Commandline history repository * +**********************************/ + +static std::map commandHistories; + +static CommandHistory * ensureCommandHistory(std::string id, + std::string src_file) { + if (!commandHistories.count(id)) { + commandHistories[id].load(src_file.c_str()); + } + return &commandHistories[id]; +} + +static int getCommandHistory(lua_State *state) +{ + std::string id = lua_tostring(state, 1); + std::string src_file = lua_tostring(state, 2); + std::vector entries; + ensureCommandHistory(id, src_file)->getEntries(entries); + Lua::PushVector(state, entries); + return 1; +} + +static void addCommandToHistory(std::string id, std::string src_file, + std::string command) { + CommandHistory *history = ensureCommandHistory(id, src_file); + history->add(command); + history->save(src_file.c_str()); +} + /************************ * Wrappers for C++ API * ************************/ @@ -1450,6 +1482,12 @@ static const LuaWrapper::FunctionReg dfhack_module[] = { WRAP_VERSION_FUNC(gitXmlMatch, git_xml_match), WRAP_VERSION_FUNC(isRelease, is_release), WRAP_VERSION_FUNC(isPrerelease, is_prerelease), + WRAP(addCommandToHistory), + { NULL, NULL } +}; + +static const luaL_Reg dfhack_funcs[] = { + { "getCommandHistory", getCommandHistory }, { NULL, NULL } }; @@ -3113,6 +3151,7 @@ void OpenDFHackApi(lua_State *state) OpenRandom(state); LuaWrapper::SetFunctionWrappers(state, dfhack_module); + luaL_setfuncs(state, dfhack_funcs, 0); OpenModule(state, "gui", dfhack_gui_module, dfhack_gui_funcs); OpenModule(state, "job", dfhack_job_module, dfhack_job_funcs); OpenModule(state, "units", dfhack_units_module, dfhack_units_funcs); diff --git a/library/include/Console.h b/library/include/Console.h index f0f56ca85..39a19b152 100644 --- a/library/include/Console.h +++ b/library/include/Console.h @@ -32,6 +32,7 @@ distribution. #include #include #include +#include namespace tthread { class mutex; @@ -114,6 +115,12 @@ namespace DFHack { history.pop_front(); } + /// adds the current list of entries to the given vector + void getEntries(std::vector &entries) + { + for (auto &entry : history) + entries.push_back(entry); + } private: std::size_t capacity; std::deque history;