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) {}
74 msg_label = find_widget<scroll_label>(&
window,
"msg",
false,
true);
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.";
325 std::unique_ptr<char[]> cmd_cstr(
new char[cmd.length()+1]);
326 strcpy (cmd_cstr.get(), cmd.c_str());
330 int result = history_expand(cmd_cstr.get(), &expansion);
332 if (result < 0 || result == 2) {
359 const std::unique_ptr<lua_interpreter::lua_model>
lua_model_;
361 const std::unique_ptr<lua_interpreter::view>
view_;
365 void search(
int direction);
385 const SDL_Keycode key,
399 LOG_LUA <<
"lua_interpreter::model::execute...";
413 raw_log_ <<
msg <<
'\n';
423 LOG_LUA <<
"lua_interpreter update_view...";
427 view_->update_contents(lua_model_->get_log());
429 LOG_LUA <<
"lua_interpreter update_view finished";
435 LOG_LUA <<
"Entering lua_interpreter::controller::bind";
439 text_entry = find_widget<text_box>(&
window,
"text_entry",
false,
true);
450 std::placeholders::_3,
451 std::placeholders::_4,
452 std::placeholders::_5,
455 copy_button = find_widget<button>(&
window,
"copy",
false,
true);
462 clear_button = find_widget<button>(&
window,
"clear",
false,
true);
470 copy_button->set_active(
false);
471 copy_button->set_tooltip(
_(
"Clipboard support not found, contact your packager"));
474 LOG_LUA <<
"Exiting lua_interpreter::controller::bind";
488 lua_model_->clear_log();
490 view_->update_contents(
"");
496 const SDL_Keycode key,
502 LOG_LUA <<
"keypress_callback";
503 if(key == SDLK_RETURN || key == SDLK_KP_ENTER) {
513 LOG_LUA <<
"finished executing";
514 }
else if(key == SDLK_TAB) {
518 }
else if(key == SDLK_UP) {
522 }
else if(key == SDLK_DOWN) {
526 }
else if(key == SDLK_PAGEUP) {
530 }
else if(key == SDLK_PAGEDOWN) {
539 std::string cmd = text_entry->get_value();
540 if (cmd.empty())
return;
542 cmd.erase(cmd.find_last_not_of(
" \n\r\t")+1);
544 LOG_LUA <<
"Executing '"<< cmd <<
"'";
546 if (cmd.size() >= 13 && (cmd.substr(0,13) ==
"history clear" || cmd.substr(0,13) ==
"clear history")) {
547 lua_model_->add_dialog_message(input_model_->clear_history());
548 text_entry->set_value(
"");
553 if (cmd.size() >= 7 && (cmd.substr(0,7) ==
"history")) {
554 lua_model_->add_dialog_message(input_model_->list_history());
555 text_entry->set_value(
"");
560 if (input_model_->do_history_expansion(cmd)) {
561 lua_model_->add_dialog_message(cmd);
566 if (lua_model_->execute(cmd)) {
567 input_model_->add_to_history(cmd);
568 text_entry->set_value(
"");
575 std::string text = text_entry->get_value();
578 std::size_t prefix_end_pos = text.find_last_of(
" (");
579 if (prefix_end_pos != std::string::npos) {
580 prefix = text.substr(0, prefix_end_pos + 1);
581 text = text.substr(prefix_end_pos + 1);
584 static std::vector<std::string> static_matches {
604 std::vector<std::string> matches;
606 if (text.find(
'.') == std::string::npos) {
607 matches = lua_model_->get_globals();
608 matches.insert(matches.end(), static_matches.begin(), static_matches.end());
610 matches = lua_model_->get_attribute_names(text);
614 if (text.size() > 0) {
618 if(matches.empty()) {
625 if (matches.size() > 1) {
628 const std::size_t wrap_limit = 80;
631 for (std::size_t idx = 0; idx < matches.size(); ++idx) {
632 if (buffer.size() + 1 + matches.at(idx).size() > wrap_limit) {
633 lua_model_->add_dialog_message(buffer);
634 buffer = matches.at(idx);
637 buffer += (
" " + matches.at(idx));
639 buffer = matches.at(idx);
644 lua_model_->add_dialog_message(buffer);
647 text_entry->set_value(prefix + text);
652 std::string current_text = text_entry->get_value();
653 input_model_->maybe_update_prefix(current_text);
654 text_entry->set_value(input_model_->search(direction));
657 lua_model_->add_dialog_message(
"History is disabled, you did not compile with GNU history support.");
667 #ifndef ALWAYS_HAVE_LUA_CONSOLE
670 const std::string&
message =
_(
"The lua console can only be used in debug mode! (Run ':debug' first)");
676 ERR_LUA <<
"Tried to open console with a null lua kernel pointer.";
695 LOG_LUA <<
"Entering lua_interpreter::view::pre_show";
699 label *kernel_type_label = find_widget<label>(&
window,
"kernel_type",
false,
true);
704 LOG_LUA <<
"Exiting lua_interpreter::view::pre_show";
711 LOG_LUA <<
"entering lua_interpreter ctor...";
712 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_clear_button_clicked(window &window)
Clear the text.
void search(int direction)
void handle_copy_button_clicked(window &window)
Copy text to the clipboard.
void update_view()
Update the view based on the model.
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.
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)
virtual void pre_show(window &window) override
Bind the controller, initialize one of the static labels with info about this kernel,...
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 label displays text that can be wrapped but no scrollbars are provided.
Class for a single line text area.
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, const bool)
Copies text to the clipboard.
bool available()
Whether wesnoth was compiled with support for a clipboard.
std::string get_user_config_dir()
static bool file_exists(const bfs::path &fpath)
std::string escape_text(const std::string &text)
Escapes the pango markup characters in a text.
REGISTER_DIALOG(tod_new_schedule)
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.
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