15 #define GETTEXT_DOMAIN "wesnoth-lib"
47 #include <boost/scoped_ptr.hpp>
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)
85 view() : msg_label(nullptr) {}
89 msg_label = &find_widget<tscroll_label>(&window,
"msg",
false);
134 DBG_LUA <<
"constructing a tlua_interpreter::model\n";
141 DBG_LUA <<
"finished constructing a tlua_interpreter::model\n";
146 DBG_LUA <<
"destroying a tlua_interpreter::model\n";
186 , end_of_history_(true)
191 read_history (filename_.c_str());
201 const size_t history_max = 500;
203 append_history (history_max,filename_.c_str());
205 write_history (filename_.c_str());
208 history_truncate_file (filename_.c_str(), history_max);
209 }
catch (...) { std::cerr <<
"Swallowed an exception when trying to write lua command line history\n";}
216 add_history(str.c_str());
218 end_of_history_ =
true;
223 LOG_LUA <<
"maybe update prefix\n";
224 LOG_LUA <<
"prefix_: '"<< prefix_ <<
"'\t text='"<< text <<
"'\n";
226 if (!end_of_history_)
return;
234 LOG_LUA <<
"searching in direction " << direction <<
" from position " << where_history() <<
"\n";
236 HIST_ENTRY *
e =
nullptr;
237 if (end_of_history_) {
240 history_set_pos(history_length);
242 if (prefix_.size() > 0) {
243 int result = history_search_prefix(prefix_.c_str(), direction);
245 e = current_history();
248 e = previous_history();
252 e = (direction > 0) ? next_history() : previous_history();
253 if (prefix_.size() > 0 &&
e) {
254 int result = history_search_prefix(prefix_.c_str(), direction);
256 e = current_history();
259 end_of_history_ =
true;
265 LOG_LUA <<
"found something at " << where_history() <<
"\n";
267 end_of_history_ =
false;
272 LOG_LUA <<
"didn't find anything\n";
275 end_of_history_ =
true;
285 write_history (filename_.c_str());
286 return "Cleared history.";
288 return "History is disabled, you did not compile with GNU history support.";
294 HIST_ENTRY **the_list;
296 the_list = history_list ();
299 return "History is empty.";
303 for (
int i = 0; the_list[
i];
i++) {
306 result += the_list[
i]->line;
311 return "Couldn't find history.";
314 return "History is disabled, you did not compile with GNU history support.";
324 char * cmd_cstr =
new char [cmd.length()+1];
325 strcpy (cmd_cstr, cmd.c_str());
329 int result = history_expand(cmd_cstr, &expansion);
332 if (result < 0 || result == 2) {
361 boost::scoped_ptr<tlua_interpreter::view>
view_;
365 void search(
int direction);
368 : copy_button(nullptr)
369 , text_entry(nullptr)
396 LOG_LUA <<
"tlua_interpreter::model::execute...\n";
419 LOG_LUA <<
"tlua_interpreter update_view...\n";
423 view_->update_contents(lua_model_->get_log());
425 LOG_LUA <<
"tlua_interpreter update_view finished\n";
431 LOG_LUA <<
"Entering tlua_interpreter::controller::bind" << std::endl;
435 text_entry = &find_widget<ttext_box>(&window,
"text_entry",
false);
438 window.keyboard_capture(text_entry);
439 window.set_click_dismiss(
false);
440 window.set_enter_disabled(
true);
452 copy_button = &find_widget<tbutton>(&window,
"copy",
false);
460 copy_button->set_active(
false);
461 copy_button->set_tooltip(
_(
"Clipboard support not found, contact your packager"));
464 LOG_LUA <<
"Exiting tlua_interpreter::controller::bind" << std::endl;
483 LOG_LUA <<
"keypress_callback\n";
484 if(key == SDLK_RETURN || key == SDLK_KP_ENTER) {
489 LOG_LUA <<
"finished executing\n";
490 }
else if(key == SDLK_TAB) {
494 }
else if(key == SDLK_UP) {
498 }
else if(key == SDLK_DOWN) {
502 }
else if(key == SDLK_PAGEUP) {
506 }
else if(key == SDLK_PAGEDOWN) {
517 if (cmd.size() == 0)
return;
519 cmd.erase(cmd.find_last_not_of(
" \n\r\t")+1);
521 LOG_LUA <<
"Executing '"<< cmd <<
"'\n";
523 if (cmd.size() >= 13 && (cmd.substr(0,13) ==
"history clear" || cmd.substr(0,13) ==
"clear history")) {
524 lua_model_->add_dialog_message(input_model_->clear_history());
525 text_entry->set_value(
"");
530 if (cmd.size() >= 7 && (cmd.substr(0,7) ==
"history")) {
531 lua_model_->add_dialog_message(input_model_->list_history());
532 text_entry->set_value(
"");
537 if (input_model_->do_history_expansion(cmd)) {
538 lua_model_->add_dialog_message(cmd);
543 if (lua_model_->execute(cmd)) {
544 input_model_->add_to_history(cmd);
545 text_entry->set_value(
"");
555 size_t idx = text.find_last_of(
" (");
556 if (idx != std::string::npos) {
557 prefix = text.substr(0, idx+1);
558 text = text.substr(idx+1);
561 std::vector<std::string> matches;
563 if (text.find(
'.') == std::string::npos) {
564 matches = lua_model_->get_globals();
565 matches.push_back(
"and");
566 matches.push_back(
"break");
567 matches.push_back(
"else");
568 matches.push_back(
"elseif");
569 matches.push_back(
"end");
570 matches.push_back(
"false");
571 matches.push_back(
"for");
572 matches.push_back(
"function");
573 matches.push_back(
"local");
574 matches.push_back(
"nil");
575 matches.push_back(
"not");
576 matches.push_back(
"repeat");
577 matches.push_back(
"return");
578 matches.push_back(
"then");
579 matches.push_back(
"true");
580 matches.push_back(
"until");
581 matches.push_back(
"while");
583 matches = lua_model_->get_attribute_names(text);
587 if (text.size() > 0) {
591 if(matches.empty()) {
598 if (matches.size() > 1) {
601 const size_t wrap_limit = 80;
604 for (
size_t idx = 0; idx < matches.size(); ++idx) {
605 if (buffer.size() + 1 + matches.at(idx).size() > wrap_limit) {
606 lua_model_->add_dialog_message(buffer);
607 buffer = matches.at(idx);
610 buffer += (
" " + matches.at(idx));
612 buffer = matches.at(idx);
617 lua_model_->add_dialog_message(buffer);
620 text_entry->set_value(prefix + text);
625 std::string current_text = text_entry->get_value();
626 input_model_->maybe_update_prefix(current_text);
627 text_entry->set_value(input_model_->search(direction));
630 lua_model_->add_dialog_message(
"History is disabled, you did not compile with GNU history support.");
640 #ifndef ALWAYS_HAVE_LUA_CONSOLE
646 ERR_LUA <<
"Tried to open console with a null lua kernel pointer.\n";
671 LOG_LUA <<
"Entering tlua_interpreter::view::pre_show" << std::endl;
675 tlabel *kernel_type_label = &find_widget<tlabel>(&window,
"kernel_type",
false);
680 LOG_LUA <<
"Exiting tlua_interpreter::view::pre_show" << std::endl;
686 LOG_LUA <<
"entering tlua_interpreter ctor...\n";
687 LOG_LUA <<
"finished tlua_interpreter ctor...\n";
void add_dialog_message(const std::string &msg)
Add a message from the dialog, formatted in blue to distinguish from issued commands.
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...
void connect_signal_pre_key_press(tdispatcher &dispatcher, const tsignal_keyboard_function &signal)
Connects the signal for 'snooping' on the keypress.
void bind(twindow &window)
Bind the scroll label widget to my pointer, and configure.
GLvoid **typedef void(GLAPIENTRY *PFNGLGETVERTEXATTRIBDVPROC)(GLuint
static void display(CVideo &video, lua_kernel_base *lk)
Display a new console, using given video and lua kernel.
bool available()
Whether wesnoth was compiled with support for a clipboard.
const char * what() const
twindow * build(CVideo &video, const twindow_builder::tresolution *definition)
Builds a window.
REGISTER_DIALOG(label_settings)
virtual void set_label(const t_string &label)
std::string get_name() const
Get a string describing the name of lua kernel.
void connect_signal_mouse_left_click(tdispatcher &dispatcher, const tsignal_function &signal)
Connects a signal handler for a left mouse button click.
Class for a single line text area.
boost::scoped_ptr< tlua_interpreter::view > view_
Implements some helper classes to ease adding fields to a dialog and hide the synchronization needed...
To lexical_cast(From value)
Lexical cast converts one type to another.
virtual const std::string & window_id() const
Inherited from tdialog, implemented by REGISTER_DIALOG.
void update_view()
Update the view based on the model.
base class of top level items, the only item which needs to store the final canvases to draw on ...
A class inherited from ttext_box that displays its input as stars.
std::vector< std::string > get_globals()
void pre_show(twindow &window)
Inherited from tdialog.
static UNUSEDNOWARN std::string _(const char *str)
boost::scoped_ptr< tlua_interpreter::input_model > input_model_
std::string get_log() const
Get the log string.
boost::scoped_ptr< tlua_interpreter::lua_model > lua_model_
tscroll_label * msg_label
void update_contents(const std::string &str)
Update the scroll label contents.
std::string escape_text(const std::string &text)
Escapes the markup characters in a text.
tlua_interpreter(lua_kernel_base &lk)
controller(lua_kernel_base &lk)
static std::string flush(std::ostringstream &s)
lua_model(lua_kernel_base &lk)
static void msg(const char *act, debug_info &i, const char *to="", const char *result="")
Declarations for File-IO.
The lua model is responsible to interact with the lua kernel base and keep track of what should be di...
std::vector< std::string > get_attribute_names(const std::string &s)
void set_external_log(std::ostream *lg)
void bind(twindow &window)
Bind my pointers to the widgets found in the window.
std::vector< std::string > get_global_var_names()
Gets all the global variable names in the Lua environment.
twindow * build_window(CVideo &video)
Inherited from tdialog.
std::string get_user_config_dir()
void copy_to_clipboard(const std::string &text, const bool)
Copies text to the clipboard.
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()
Standard logging facilities (interface).
game_lua_kernel * lua_kernel
void search(int direction)
virtual std::string my_name()
static lg::log_domain log_lua_int("lua/interpreter")
void input_keypress_callback(bool &handled, bool &halt, const SDLKey key, twindow &window)
Handle return key (execute) or tab key (tab completion)
The controller is responsible to hold all the input widgets, and a pointer to the model and view...
bool file_exists(const std::string &name)
Returns true if a file or directory with such name already exists.
tfield_text * register_text(const std::string &id, const bool mandatory, const std::function< std::string()> &callback_load_value=std::function< std::string()>(), const std::function< void(const std::string &)> &callback_save_value=std::function< void(const std::string &)>(), const bool capture_focus=false)
Creates a new text field.
GLsizei const GLcharARB ** string
bool word_completion(std::string &text, std::vector< std::string > &wordlist)
Try to complete the last word of 'text' with the 'wordlist'.
boost::scoped_ptr< controller > controller_
static plugins_manager * get()
bool execute(const std::string &cmd)
Ask the lua kernel to execute a command.
void handle_copy_button_clicked(twindow &window)
Copy text to the clipboard.
Error used to report an error in a lua script or in the lua interpreter.