16 #define GETTEXT_DOMAIN "wesnoth-lib"
47 #include <readline/history.h>
51 #define DBG_LUA LOG_STREAM(debug, log_lua_int)
52 #define LOG_LUA LOG_STREAM(info, log_lua_int)
53 #define WRN_LUA LOG_STREAM(warn, log_lua_int)
54 #define ERR_LUA LOG_STREAM(err, log_lua_int)
69 view() : msg_label(nullptr), window_(nullptr) {}
120 DBG_LUA <<
"constructing a lua_interpreter::model";
131 DBG_LUA <<
"finished constructing a lua_interpreter::model";
136 DBG_LUA <<
"destroying a lua_interpreter::model";
141 bool execute(
const std::string & cmd);
204 const std::size_t history_max = 500;
206 append_history (history_max,
filename_.c_str());
211 history_truncate_file (
filename_.c_str(), history_max);
212 }
catch (...) {
PLAIN_LOG <<
"Swallowed an exception when trying to write lua command line history";}
218 add_history(str.c_str());
225 LOG_LUA <<
"maybe update prefix";
234 std::string
search([[maybe_unused]]
int direction ) {
236 LOG_LUA <<
"searching in direction " << direction <<
" from position " << where_history();
238 HIST_ENTRY *
e =
nullptr;
242 history_set_pos(history_length);
245 int result = history_search_prefix(
prefix_.c_str(), direction);
247 e = current_history();
250 e = previous_history();
254 e = (direction > 0) ? next_history() : previous_history();
256 int result = history_search_prefix(
prefix_.c_str(), direction);
258 e = current_history();
267 LOG_LUA <<
"found something at " << where_history();
268 std::string ret =
e->line;
274 LOG_LUA <<
"didn't find anything";
287 return "Cleared history.";
289 return "History is disabled, you did not compile with GNU history support.";
295 HIST_ENTRY **the_list;
297 the_list = history_list ();
300 return "History is empty.";
304 for (
int i = 0; the_list[
i];
i++) {
305 result += std::to_string(
i+history_base);
307 result += the_list[
i]->line;
312 return "Couldn't find history.";
315 return "History is disabled, you did not compile with GNU history support.";
334 const std::unique_ptr<lua_interpreter::lua_model>
lua_model_;
336 const std::unique_ptr<lua_interpreter::view>
view_;
340 void search(
int direction);
360 const SDL_Keycode key,
374 LOG_LUA <<
"lua_interpreter::model::execute...";
388 raw_log_ <<
msg <<
'\n';
398 LOG_LUA <<
"lua_interpreter update_view...";
402 view_->update_contents(lua_model_->get_log());
404 LOG_LUA <<
"lua_interpreter update_view finished";
410 LOG_LUA <<
"Entering lua_interpreter::controller::bind";
423 std::placeholders::_3,
424 std::placeholders::_4,
425 std::placeholders::_5,
438 LOG_LUA <<
"Exiting lua_interpreter::controller::bind";
452 lua_model_->clear_log();
454 view_->update_contents(
"");
460 const SDL_Keycode key,
466 LOG_LUA <<
"keypress_callback";
467 if(key == SDLK_RETURN || key == SDLK_KP_ENTER) {
477 LOG_LUA <<
"finished executing";
478 }
else if(key == SDLK_TAB) {
482 }
else if(key == SDLK_UP) {
486 }
else if(key == SDLK_DOWN) {
490 }
else if(key == SDLK_PAGEUP) {
494 }
else if(key == SDLK_PAGEDOWN) {
503 std::string cmd = text_entry->get_value();
504 if (cmd.empty())
return;
506 cmd.erase(cmd.find_last_not_of(
" \n\r\t")+1);
508 LOG_LUA <<
"Executing '"<< cmd <<
"'";
510 if (cmd.size() >= 13 && (cmd.substr(0,13) ==
"history clear" || cmd.substr(0,13) ==
"clear history")) {
511 lua_model_->add_dialog_message(input_model_->clear_history());
512 text_entry->set_value(
"");
517 if (cmd.size() >= 7 && (cmd.substr(0,7) ==
"history")) {
518 lua_model_->add_dialog_message(input_model_->list_history());
519 text_entry->set_value(
"");
524 if (lua_model_->execute(cmd)) {
525 input_model_->add_to_history(cmd);
526 text_entry->set_value(
"");
533 std::string text = text_entry->get_value();
536 std::size_t prefix_end_pos = text.find_last_of(
" (");
537 if (prefix_end_pos != std::string::npos) {
538 prefix = text.substr(0, prefix_end_pos + 1);
539 text = text.substr(prefix_end_pos + 1);
542 static std::vector<std::string> static_matches {
562 std::vector<std::string> matches;
564 if (text.find(
'.') == std::string::npos) {
565 matches = lua_model_->get_globals();
566 matches.insert(matches.end(), static_matches.begin(), static_matches.end());
568 matches = lua_model_->get_attribute_names(text);
572 if (text.size() > 0) {
576 if(matches.empty()) {
583 if (matches.size() > 1) {
586 const std::size_t wrap_limit = 80;
589 for (std::size_t idx = 0; idx < matches.size(); ++idx) {
590 if (buffer.size() + 1 + matches.at(idx).size() > wrap_limit) {
591 lua_model_->add_dialog_message(buffer);
592 buffer = matches.at(idx);
595 buffer += (
" " + matches.at(idx));
597 buffer = matches.at(idx);
602 lua_model_->add_dialog_message(buffer);
605 text_entry->set_value(prefix + text);
610 std::string current_text = text_entry->get_value();
611 input_model_->maybe_update_prefix(current_text);
612 text_entry->set_value(input_model_->search(direction));
615 lua_model_->add_dialog_message(
"History is disabled, you did not compile with GNU history support.");
625 #ifndef ALWAYS_HAVE_LUA_CONSOLE
628 const std::string&
message =
_(
"The lua console can only be used in debug mode! (Run ‘:debug’ first)");
634 ERR_LUA <<
"Tried to open console with a null lua kernel pointer.";
653 LOG_LUA <<
"Entering lua_interpreter::view::pre_show";
657 label *kernel_type_label = find_widget<label>(
"kernel_type",
false,
true);
662 LOG_LUA <<
"Exiting lua_interpreter::view::pre_show";
669 LOG_LUA <<
"entering lua_interpreter ctor...";
670 LOG_LUA <<
"finished lua_interpreter ctor...";
void add_chat_message(const std::time_t &time, const std::string &speaker, int side, const std::string &msg, events::chat_handler::MESSAGE_TYPE type, bool bell)
display_chat_manager & get_chat_manager()
The controller is responsible to hold all the input widgets, and a pointer to the model and view.
void handle_copy_button_clicked()
Copy text to the clipboard.
void search(int direction)
void update_view()
Update the view based on the model.
void handle_clear_button_clicked()
Clear the text.
const std::unique_ptr< lua_interpreter::view > view_
void input_keypress_callback(bool &handled, bool &halt, const SDL_Keycode key, window &window)
Handle return key (execute) or tab key (tab completion)
const std::unique_ptr< lua_interpreter::lua_model > lua_model_
void bind(window &window)
Bind my pointers to the widgets found in the window.
const std::unique_ptr< lua_interpreter::input_model > input_model_
controller(lua_kernel_base &lk)
The lua model is responsible to interact with the lua kernel base and keep track of what should be di...
lua_model(lua_kernel_base &lk)
void clear_log()
Clear the console log.
bool execute(const std::string &cmd)
Ask the lua kernel to execute a command.
std::vector< std::string > get_globals()
std::stringstream raw_log_
std::string get_log() const
Get the log string.
std::string get_name() const
Get a string describing the name of lua kernel.
void add_dialog_message(const std::string &msg)
Add a message from the dialog, formatted in blue to distinguish from issued commands.
std::string get_raw_log() const
Get the unescaped log.
std::vector< std::string > get_attribute_names(const std::string &s)
void bind(window &window)
Bind the scroll label widget to my pointer, and configure.
void update_contents(const std::string &str)
Update the scroll label contents.
virtual void pre_show() override
Bind the controller, initialize one of the static labels with info about this kernel,...
static void display(lua_kernel_base *lk)
Display a new console, using given video and lua kernel.
virtual const std::string & window_id() const override
The ID of the window to build.
const std::unique_ptr< controller > controller_
lua_interpreter(lua_kernel_base &lk)
Main class to show messages to the user.
Abstract base class for all modal dialogs.
field_text * register_text(const std::string &id, const bool mandatory, const std::function< std::string()> callback_load_value=nullptr, const std::function< void(const std::string &)> callback_save_value=nullptr, const bool capture_focus=false)
Creates a new text field.
A widget that allows the user to input text in single line.
base class of top level items, the only item which needs to store the final canvases to draw on.
void set_enter_disabled(const bool enter_disabled)
Disable the enter key.
void keyboard_capture(widget *widget)
void set_click_dismiss(const bool click_dismiss)
void set_external_log(external_log_type lg)
std::vector< std::string > get_global_var_names()
Get tab completion strings.
void interactive_run(char const *prog)
Tests if a program resolves to an expression, and pretty prints it if it is, otherwise it runs it nor...
std::vector< std::string > get_attribute_names(const std::string &var_path)
Gets all attribute names of an extended variable name.
const std::stringstream & get_log()
Access / manipulate logging of lua kernel activities.
virtual std::string my_name()
User-visible name of the lua kernel that they are talking to.
game_display & get_display() override
Get a reference to a display member a derived class uses.
static plugins_manager * get()
Declarations for File-IO.
static std::string _(const char *str)
Standard logging facilities (interface).
static lg::log_domain log_lua_int("lua/interpreter")
void copy_to_clipboard(const std::string &text)
Copies text to the clipboard.
static bool file_exists(const bfs::path &fpath)
std::string get_lua_history_file()
std::string escape_text(const std::string &text)
Escapes the pango markup characters in a text.
REGISTER_DIALOG(editor_edit_unit)
void connect_signal_pre_key_press(dispatcher &dispatcher, const signal_keyboard &signal)
Connects the signal for 'snooping' on the keypress.
void connect_signal_mouse_left_click(dispatcher &dispatcher, const signal &signal)
Connects a signal handler for a left mouse button click.
std::string span_color(const color_t &color, Args &&... data)
game_lua_kernel * lua_kernel
play_controller * controller
bool word_completion(std::string &text, std::vector< std::string > &wordlist)
Try to complete the last word of 'text' with the 'wordlist'.
static void msg(const char *act, debug_info &i, const char *to="", const char *result="")
static std::string flush(std::ostringstream &s)
Error used to report an error in a lua script or in the lua interpreter.
static map_location::direction s