16 #define GETTEXT_DOMAIN "wesnoth-lib"
51 #include <readline/history.h>
55 #define DBG_LUA LOG_STREAM(debug, log_lua_int)
56 #define LOG_LUA LOG_STREAM(info, log_lua_int)
57 #define WRN_LUA LOG_STREAM(warn, log_lua_int)
58 #define ERR_LUA LOG_STREAM(err, log_lua_int)
73 view() : msg_label(nullptr), window_(nullptr) {}
78 msg_label = find_widget<scroll_label>(&
window,
"msg",
false,
true);
124 DBG_LUA <<
"constructing a lua_interpreter::model";
135 DBG_LUA <<
"finished constructing a lua_interpreter::model";
140 DBG_LUA <<
"destroying a lua_interpreter::model";
145 bool execute(
const std::string & cmd);
208 const std::size_t history_max = 500;
210 append_history (history_max,
filename_.c_str());
215 history_truncate_file (
filename_.c_str(), history_max);
216 }
catch (...) {
PLAIN_LOG <<
"Swallowed an exception when trying to write lua command line history";}
222 add_history(str.c_str());
229 LOG_LUA <<
"maybe update prefix";
238 std::string
search([[maybe_unused]]
int direction ) {
240 LOG_LUA <<
"searching in direction " << direction <<
" from position " << where_history();
242 HIST_ENTRY *
e =
nullptr;
246 history_set_pos(history_length);
249 int result = history_search_prefix(
prefix_.c_str(), direction);
251 e = current_history();
254 e = previous_history();
258 e = (direction > 0) ? next_history() : previous_history();
260 int result = history_search_prefix(
prefix_.c_str(), direction);
262 e = current_history();
271 LOG_LUA <<
"found something at " << where_history();
272 std::string ret =
e->line;
278 LOG_LUA <<
"didn't find anything";
291 return "Cleared history.";
293 return "History is disabled, you did not compile with GNU history support.";
299 HIST_ENTRY **the_list;
301 the_list = history_list ();
304 return "History is empty.";
308 for (
int i = 0; the_list[
i];
i++) {
309 result += std::to_string(
i+history_base);
311 result += the_list[
i]->line;
316 return "Couldn't find history.";
319 return "History is disabled, you did not compile with GNU history support.";
329 std::unique_ptr<char[]> cmd_cstr(
new char[cmd.length()+1]);
330 strcpy (cmd_cstr.get(), cmd.c_str());
334 int result = history_expand(cmd_cstr.get(), &expansion);
336 if (result < 0 || result == 2) {
363 const std::unique_ptr<lua_interpreter::lua_model>
lua_model_;
365 const std::unique_ptr<lua_interpreter::view>
view_;
369 void search(
int direction);
389 const SDL_Keycode key,
403 LOG_LUA <<
"lua_interpreter::model::execute...";
417 raw_log_ <<
msg <<
'\n';
427 LOG_LUA <<
"lua_interpreter update_view...";
431 view_->update_contents(lua_model_->get_log());
433 LOG_LUA <<
"lua_interpreter update_view finished";
439 LOG_LUA <<
"Entering lua_interpreter::controller::bind";
443 text_entry = find_widget<text_box>(&
window,
"text_entry",
false,
true);
454 std::placeholders::_3,
455 std::placeholders::_4,
456 std::placeholders::_5,
459 copy_button = find_widget<button>(&
window,
"copy",
false,
true);
466 clear_button = find_widget<button>(&
window,
"clear",
false,
true);
474 copy_button->set_active(
false);
475 copy_button->set_tooltip(
_(
"Clipboard support not found, contact your packager"));
478 LOG_LUA <<
"Exiting lua_interpreter::controller::bind";
492 lua_model_->clear_log();
494 view_->update_contents(
"");
500 const SDL_Keycode key,
506 LOG_LUA <<
"keypress_callback";
507 if(key == SDLK_RETURN || key == SDLK_KP_ENTER) {
517 LOG_LUA <<
"finished executing";
518 }
else if(key == SDLK_TAB) {
522 }
else if(key == SDLK_UP) {
526 }
else if(key == SDLK_DOWN) {
530 }
else if(key == SDLK_PAGEUP) {
534 }
else if(key == SDLK_PAGEDOWN) {
543 std::string cmd = text_entry->get_value();
544 if (cmd.empty())
return;
546 cmd.erase(cmd.find_last_not_of(
" \n\r\t")+1);
548 LOG_LUA <<
"Executing '"<< cmd <<
"'";
550 if (cmd.size() >= 13 && (cmd.substr(0,13) ==
"history clear" || cmd.substr(0,13) ==
"clear history")) {
551 lua_model_->add_dialog_message(input_model_->clear_history());
552 text_entry->set_value(
"");
557 if (cmd.size() >= 7 && (cmd.substr(0,7) ==
"history")) {
558 lua_model_->add_dialog_message(input_model_->list_history());
559 text_entry->set_value(
"");
564 if (input_model_->do_history_expansion(cmd)) {
565 lua_model_->add_dialog_message(cmd);
570 if (lua_model_->execute(cmd)) {
571 input_model_->add_to_history(cmd);
572 text_entry->set_value(
"");
579 std::string text = text_entry->get_value();
582 std::size_t prefix_end_pos = text.find_last_of(
" (");
583 if (prefix_end_pos != std::string::npos) {
584 prefix = text.substr(0, prefix_end_pos + 1);
585 text = text.substr(prefix_end_pos + 1);
588 static std::vector<std::string> static_matches {
608 std::vector<std::string> matches;
610 if (text.find(
'.') == std::string::npos) {
611 matches = lua_model_->get_globals();
612 matches.insert(matches.end(), static_matches.begin(), static_matches.end());
614 matches = lua_model_->get_attribute_names(text);
618 if (text.size() > 0) {
622 if(matches.empty()) {
629 if (matches.size() > 1) {
632 const std::size_t wrap_limit = 80;
635 for (std::size_t idx = 0; idx < matches.size(); ++idx) {
636 if (buffer.size() + 1 + matches.at(idx).size() > wrap_limit) {
637 lua_model_->add_dialog_message(buffer);
638 buffer = matches.at(idx);
641 buffer += (
" " + matches.at(idx));
643 buffer = matches.at(idx);
648 lua_model_->add_dialog_message(buffer);
651 text_entry->set_value(prefix + text);
656 std::string current_text = text_entry->get_value();
657 input_model_->maybe_update_prefix(current_text);
658 text_entry->set_value(input_model_->search(direction));
661 lua_model_->add_dialog_message(
"History is disabled, you did not compile with GNU history support.");
671 #ifndef ALWAYS_HAVE_LUA_CONSOLE
674 const std::string&
message =
_(
"The lua console can only be used in debug mode! (Run ':debug' first)");
680 ERR_LUA <<
"Tried to open console with a null lua kernel pointer.";
699 LOG_LUA <<
"Entering lua_interpreter::view::pre_show";
703 label *kernel_type_label = find_widget<label>(&
window,
"kernel_type",
false,
true);
708 LOG_LUA <<
"Exiting lua_interpreter::view::pre_show";
715 LOG_LUA <<
"entering lua_interpreter ctor...";
716 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()
Implements some helper classes to ease adding fields to a dialog and hide the synchronization needed.
Declarations for File-IO.
static std::string _(const char *str)
Standard logging facilities (interface).
static lg::log_domain log_lua_int("lua/interpreter")
#define REGISTER_DIALOG(window_id)
Wrapper for REGISTER_DIALOG2.
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.
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)
This file contains the settings handling of the widget library.
Error used to report an error in a lua script or in the lua interpreter.
static map_location::DIRECTION s