The Battle for Wesnoth  1.15.9+dev
lua_interpreter.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2014 - 2018 by Chris Beck <render787@gmail.com>
3  Part of the Battle for Wesnoth Project https://www.wesnoth.org/
4 
5  This program is free software; you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation; either version 2 of the License, or
8  (at your option) any later version.
9  This program is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY.
11 
12  See the COPYING file for more details.
13 */
14 
15 #define GETTEXT_DOMAIN "wesnoth-lib"
16 
18 
19 #include "gui/auxiliary/field.hpp"
22 #include "gui/widgets/button.hpp"
23 #include "gui/widgets/label.hpp"
25 #include "gui/widgets/settings.hpp"
26 #include "gui/widgets/text_box.hpp"
27 #include "gui/widgets/window.hpp"
28 
29 #include "desktop/clipboard.hpp"
30 #include "game_config.hpp"
31 #include "game_errors.hpp"
32 #include "gettext.hpp"
33 #include "play_controller.hpp"
34 #include "resources.hpp" //for help fetching lua kernel pointers
35 #include "scripting/plugins/manager.hpp" //needed for the WHICH_KERNEL version of display
36 #include "scripting/game_lua_kernel.hpp" //needed for the WHICH_KERNEL version of display
40 #include "lexical_cast.hpp"
41 #include "log.hpp"
42 #include "font/pango/escape.hpp"
43 
44 #include <sstream>
45 #include <string>
46 #include <vector>
47 #include <functional>
48 
49 #ifdef HAVE_HISTORY
50 #include "filesystem.hpp"
51 #include <readline/history.h>
52 #endif
53 
54 static lg::log_domain log_lua_int("lua/interpreter");
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)
59 
60 namespace gui2
61 {
62 namespace dialogs
63 {
64 
65 REGISTER_DIALOG(lua_interpreter)
66 
67 // Model, View, Controller definitions
68 
70 private:
71  scroll_label* msg_label; //the view is extremely simple, it's pretty much just this one widget that gets updated
73 
74 public:
75  view() : msg_label(nullptr), window_(nullptr) {}
76 
77  /** Bind the scroll label widget to my pointer, and configure */
78  void bind(window& window) {
79  window_ = &window;
80  msg_label = find_widget<scroll_label>(&window, "msg", false, true);
81  msg_label->set_use_markup(true);
83  msg_label->set_label("");
84  }
85 
86  /** Update the scroll label contents */
87  void update_contents(const std::string & str)
88  {
89  assert(msg_label);
90 
91  msg_label->set_label(str);
92  window_->set_callback_next_draw([this]()
93  {
95  });
96  }
97 
98  void pg_up()
99  {
100  assert(msg_label);
102  }
103 
104  void pg_down()
105  {
106  assert(msg_label);
108  }
109 };
110 
111 /**
112  * The lua model is responsible to interact with the lua kernel base and keep track of what should be displayed in the console.
113  * It registers its stringstream with the lua kernel when it is created, and unregisters when it is destroyed.
114  *
115  * It is responsible to execute commands as strings, or add dialog messages for the user. It is also responsible to ask
116  * the lua kernel for help with tab completion.
117  */
119 private:
121  std::stringstream log_;
122  std::stringstream raw_log_;
123 
124 public:
126  : L_(lk)
127  , log_()
128  , raw_log_()
129  {
130  DBG_LUA << "constructing a lua_interpreter::model\n";
131  //DBG_LUA << "incoming:\n" << lk.get_log().rdbuf() << "\n.\n";
132  log_ << font::escape_text(lk.get_log().str()) << std::flush;
133  raw_log_ << lk.get_log().str() << std::flush;
134  // Lua kernel sends log strings to this function
135  L_.set_external_log([this](const std::string & str) {
136  log_ << font::escape_text(str);
137  raw_log_ << str;
138  });
139  //DBG_LUA << "received:\n" << log_.str() << "\n.\n";
140 
141  DBG_LUA << "finished constructing a lua_interpreter::model\n";
142  }
143 
145  {
146  DBG_LUA << "destroying a lua_interpreter::model\n";
147  L_.set_external_log(nullptr); //deregister our log since it's about to be destroyed
148  }
149 
150  /** Ask the lua kernel to execute a command. No throw of game::lua_error, instead the error message is formatted and printed to console.*/
151  bool execute(const std::string & cmd);
152 
153  /** Add a message from the dialog, formatted in blue to distinguish from issued commands.
154  * This message gets put in the interpreter log, but does not get entered in the kernel log, so if the window is closed this message will
155  * not appear the next time it is opened.
156  **/
157  void add_dialog_message(const std::string & msg);
158 
159  /** Get the log string */
160  std::string get_log() const { return log_.str(); }
161  /** Get the unescaped log */
162  std::string get_raw_log() const { return raw_log_.str(); }
163  /** Get a string describing the name of lua kernel */
164  std::string get_name() const { return L_.my_name(); }
165 
166  /** Clear the console log */
167  void clear_log() {
168  L_.clear_log();
169  log_.str("");
170  log_.clear();
171  raw_log_.str("");
172  raw_log_.clear();
173  }
174 
175  //* Tab completion: Get list of presently defined global variables */
176  std::vector<std::string> get_globals() { return L_.get_global_var_names(); }
177  //* Tab completion: Get list of attributes for variable corresponding to this path. */
178  std::vector<std::string> get_attribute_names(const std::string & s) { return L_.get_attribute_names(s); }
179 };
180 
181 /**
182  * The input_model keeps track of what commands were executed before, and figures out what
183  * should be displayed when the user presses up / down arrows in the input.
184  * It is essentially part of the model, but it isn't connected to the lua kernel so I have implemented it
185  * separately. Putatively it could all be refactored so that there is a single model with private subclass "lua_model"
186  * and also a "command_history_model" but I have decided simply to not implement it that way.
187  */
189 private:
190  std::string prefix_;
192 #ifdef HAVE_HISTORY
193  std::string filename_;
194 #endif
195 
196 public:
198  : prefix_()
199  , end_of_history_(true)
200 #ifdef HAVE_HISTORY
201  , filename_(filesystem::get_user_config_dir() + "/lua_command_history")
202  {
203  using_history();
204  read_history (filename_.c_str());
205  }
206 #else
207  {}
208 #endif
209 
210 #ifdef HAVE_HISTORY
211  ~input_model()
212  {
213  try {
214  const std::size_t history_max = 500;
215  if (filesystem::file_exists(filename_)) {
216  append_history (history_max,filename_.c_str());
217  } else {
218  write_history (filename_.c_str());
219  }
220 
221  history_truncate_file (filename_.c_str(), history_max);
222  } catch (...) { std::cerr << "Swallowed an exception when trying to write lua command line history\n";}
223  }
224 #endif
225  void add_to_history (const std::string& str) {
226  prefix_ = "";
227  UNUSED(str);
228 #ifdef HAVE_HISTORY
229  add_history(str.c_str());
230 #endif
231  end_of_history_ = true;
232 
233  }
234 
235  void maybe_update_prefix (const std::string & text) {
236  LOG_LUA << "maybe update prefix\n";
237  LOG_LUA << "prefix_: '"<< prefix_ << "'\t text='"<< text << "'\n";
238 
239  if (!end_of_history_) return;
240 
241  prefix_ = text;
242  LOG_LUA << "updated prefix\n";
243  }
244 
245  std::string search( int direction ) {
246 #ifdef HAVE_HISTORY
247  LOG_LUA << "searching in direction " << direction << " from position " << where_history() << "\n";
248 
249  HIST_ENTRY * e = nullptr;
250  if (end_of_history_) {
251  // if the direction is > 0, do nothing because searching down only takes place when we are in the history records.
252  if (direction < 0) {
253  history_set_pos(history_length);
254 
255  if (prefix_.size() > 0) {
256  int result = history_search_prefix(prefix_.c_str(), direction);
257  if (result == 0) {
258  e = current_history();
259  }
260  } else {
261  e = previous_history();
262  }
263  }
264  } else {
265  e = (direction > 0) ? next_history() : previous_history();
266  if (prefix_.size() > 0 && e) {
267  int result = history_search_prefix(prefix_.c_str(), direction);
268  if (result == 0) {
269  e = current_history();
270  } else {
271  e = nullptr; // if the search misses, it leaves the state as it was, which might not have been on an entry matching prefix.
272  end_of_history_ = true; // we actually want to force it to be null and treat as off the end of history in this case.
273  }
274  }
275  }
276 
277  if (e) {
278  LOG_LUA << "found something at " << where_history() << "\n";
279  std::string ret = e->line;
280  end_of_history_ = false;
281  return ret;
282  }
283 #endif
284 
285  LOG_LUA << "didn't find anything\n";
286 
287  // reset, set history to the end and prefix_ to empty, and return the current prefix_ for the user to edit
288  end_of_history_ = true;
289  UNUSED(direction);
290  std::string temp = prefix_;
291  prefix_ = "";
292  return temp;
293  }
294 
295  std::string clear_history() {
296 #ifdef HAVE_HISTORY
297  ::clear_history();
298  write_history (filename_.c_str());
299  return "Cleared history.";
300 #else
301  return "History is disabled, you did not compile with GNU history support.";
302 #endif
303  }
304 
305  std::string list_history() {
306 #ifdef HAVE_HISTORY
307  HIST_ENTRY **the_list;
308 
309  the_list = history_list ();
310  if (the_list) {
311  if (!*the_list) {
312  return "History is empty.";
313  }
314 
315  std::string result;
316  for (int i = 0; the_list[i]; i++) {
317  result += lexical_cast<std::string, int>(i+history_base);
318  result += ": ";
319  result += the_list[i]->line;
320  result += "\n";
321  }
322  return result;
323  } else {
324  return "Couldn't find history.";
325  }
326 #else
327  return "History is disabled, you did not compile with GNU history support.";
328 #endif
329  }
330 
331  // Does history expansion in a command line. A return value of true indicates an error,
332  // the error message will be returned in the string argument. A return value of false
333  // indicates success and that execution should proceed.
334  bool do_history_expansion (std::string & cmd) {
335 #ifdef HAVE_HISTORY
336  // Do history expansions
337  std::unique_ptr<char[]> cmd_cstr(new char[cmd.length()+1]);
338  strcpy (cmd_cstr.get(), cmd.c_str());
339 
340  char * expansion;
341 
342  int result = history_expand(cmd_cstr.get(), &expansion);
343 
344  if (result < 0 || result == 2) {
345  cmd = expansion; // return error message in cmd var
346  free(expansion);
347  return true;
348  }
349 
350  cmd = expansion;
351  free(expansion);
352 #endif
353  UNUSED(cmd);
354  return false;
355  }
356 };
357 
358 /**
359  * The controller is responsible to hold all the input widgets, and a pointer to the model and view.
360  * It is responsible to bind the input signals to appropriate handler methods, which it holds.
361  * It is also responsible to ask the view to update based on the output of the model, typically in
362  * response to some input.
363  */
365 private:
368 
370  std::string text_entry_;
371 
372  const std::unique_ptr<lua_interpreter::lua_model> lua_model_;
373  const std::unique_ptr<lua_interpreter::input_model> input_model_;
374  const std::unique_ptr<lua_interpreter::view> view_;
375 
376  void execute();
377  void tab();
378  void search(int direction);
379 public:
381  : copy_button(nullptr)
382  , clear_button(nullptr)
383  , text_entry(nullptr)
384  , text_entry_()
385  , lua_model_(new lua_interpreter::lua_model(lk))
386  , input_model_(new lua_interpreter::input_model())
387  , view_(new lua_interpreter::view())
388  {}
389 
390  /** Bind my pointers to the widgets found in the window */
391  void bind(window& window);
392 
393  void handle_copy_button_clicked(window & window);
394  void handle_clear_button_clicked(window & window);
395 
396  void input_keypress_callback(bool& handled,
397  bool& halt,
398  const SDL_Keycode key,
399  window& window);
400 
401  /** Update the view based on the model */
402  void update_view();
403 
404  friend class lua_interpreter;
405 };
406 
407 // Model impl
408 
409 /** Execute a command, and report any errors encountered. */
410 bool lua_interpreter::lua_model::execute (const std::string & cmd)
411 {
412  LOG_LUA << "lua_interpreter::model::execute...\n";
413 
414  try {
415  L_.interactive_run(cmd.c_str());
416  return true;
417  } catch (const game::lua_error & e) {
418  add_dialog_message(std::string(e.what()));
419  return false;
420  }
421 }
422 
423 /** Add a dialog message, which will appear in blue. */
425  log_ << "<span color='#8888FF'>" << font::escape_text(msg) << "</span>\n";
426  raw_log_ << msg << '\n';
427 }
428 
429 // View impl
430 
431 // Controller impl
432 
433 /** Update the view based on the model. */
435 {
436  LOG_LUA << "lua_interpreter update_view...\n";
437  assert(lua_model_);
438  assert(view_);
439 
440  view_->update_contents(lua_model_->get_log());
441 
442  LOG_LUA << "lua_interpreter update_view finished\n";
443 }
444 
445 /** Find all the widgets managed by the controller and connect them to handler methods. */
447 {
448  LOG_LUA << "Entering lua_interpreter::controller::bind" << std::endl;
449  assert(view_);
450  view_->bind(window);
451 
452  text_entry = find_widget<text_box>(&window, "text_entry", false, true);
453  //text_entry->set_text_changed_callback(
454  // std::bind(&view::filter, this, std::ref(window)));
455  window.keyboard_capture(text_entry);
456  window.set_click_dismiss(false);
457  window.set_enter_disabled(true);
458 
460  *text_entry,
462  this,
463  std::placeholders::_3,
464  std::placeholders::_4,
465  std::placeholders::_5,
466  std::ref(window)));
467 
468  copy_button = find_widget<button>(&window, "copy", false, true);
470  *copy_button,
472  this,
473  std::ref(window)));
474 
475  clear_button = find_widget<button>(&window, "clear", false, true);
477  *clear_button,
479  this,
480  std::ref(window)));
481 
483  copy_button->set_active(false);
484  copy_button->set_tooltip(_("Clipboard support not found, contact your packager"));
485  }
486 
487  LOG_LUA << "Exiting lua_interpreter::controller::bind" << std::endl;
488 }
489 
490 /** Copy text to the clipboard */
492 {
493  assert(lua_model_);
494  desktop::clipboard::copy_to_clipboard(lua_model_->get_raw_log(), false);
495 }
496 
497 /** Clear the text */
499 {
500  assert(lua_model_);
501  lua_model_->clear_log();
502  assert(view_);
503  view_->update_contents("");
504 }
505 
506 /** Handle return key (execute) or tab key (tab completion) */
508  bool& halt,
509  const SDL_Keycode key,
510  window& window)
511 {
512  assert(lua_model_);
513  assert(text_entry);
514 
515  LOG_LUA << "keypress_callback\n";
516  if(key == SDLK_RETURN || key == SDLK_KP_ENTER) { // handle executing whatever is in the command entry field
517  LOG_LUA << "executing...\n";
518  execute();
519  handled = true;
520  halt = true;
521 
522  // Commands such as `wesnoth.interface.zoom` might cause the display to redraw and leave the window half-drawn.
523  // This preempts that.
524  window.set_is_dirty(true);
525 
526  LOG_LUA << "finished executing\n";
527  } else if(key == SDLK_TAB) { // handle tab completion
528  tab();
529  handled = true;
530  halt = true;
531  } else if(key == SDLK_UP) {
532  search(-1);
533  handled = true;
534  halt = true;
535  } else if(key == SDLK_DOWN) {
536  search(1);
537  handled = true;
538  halt = true;
539  } else if(key == SDLK_PAGEUP) {
540  view_->pg_up();
541  handled = true;
542  halt = true;
543  } else if(key == SDLK_PAGEDOWN) {
544  view_->pg_down();
545  handled = true;
546  halt = true;
547  }
548 }
549 
551 {
552  std::string cmd = text_entry->get_value();
553  if (cmd.empty()) return; //don't bother with empty string
554 
555  cmd.erase(cmd.find_last_not_of(" \n\r\t")+1); //right trim the string
556 
557  LOG_LUA << "Executing '"<< cmd << "'\n";
558 
559  if (cmd.size() >= 13 && (cmd.substr(0,13) == "history clear" || cmd.substr(0,13) == "clear history")) {
560  lua_model_->add_dialog_message(input_model_->clear_history());
561  text_entry->set_value("");
562  update_view();
563  return;
564  }
565 
566  if (cmd.size() >= 7 && (cmd.substr(0,7) == "history")) {
567  lua_model_->add_dialog_message(input_model_->list_history());
568  text_entry->set_value("");
569  update_view();
570  return;
571  }
572 
573  if (input_model_->do_history_expansion(cmd)) {
574  lua_model_->add_dialog_message(cmd);
575  update_view();
576  return;
577  }
578 
579  if (lua_model_->execute(cmd)) {
580  input_model_->add_to_history(cmd);
581  text_entry->set_value("");
582  }
583  update_view();
584 }
585 
587 {
588  std::string text = text_entry->get_value();
589 
590  std::string prefix;
591  std::size_t prefix_end_pos = text.find_last_of(" (");
592  if (prefix_end_pos != std::string::npos) {
593  prefix = text.substr(0, prefix_end_pos + 1);
594  text = text.substr(prefix_end_pos + 1);
595  }
596 
597  static std::vector<std::string> static_matches {
598  "and",
599  "break",
600  "else",
601  "elseif",
602  "end",
603  "false",
604  "for",
605  "function",
606  "local",
607  "nil",
608  "not",
609  "repeat",
610  "return",
611  "then",
612  "true",
613  "until",
614  "while"
615  };
616 
617  std::vector<std::string> matches;
618 
619  if (text.find('.') == std::string::npos) {
620  matches = lua_model_->get_globals();
621  matches.insert(matches.end(), static_matches.begin(), static_matches.end());
622  } else {
623  matches = lua_model_->get_attribute_names(text);
624  }
625 
626  //bool line_start = utils::word_completion(text, matches);
627  if (text.size() > 0) { // this if is to avoid weird behavior in word_completion, where it thinks nothing matches the empty string
628  utils::word_completion(text, matches);
629  }
630 
631  if(matches.empty()) {
632  return;
633  }
634 
635  //if(matches.size() == 1) {
636  //text.append(" "); //line_start ? ": " : " ");
637  //} else {
638  if (matches.size() > 1) {
639  //std::string completion_list = utils::join(matches, " ");
640 
641  const std::size_t wrap_limit = 80;
642  std::string buffer;
643 
644  for (std::size_t idx = 0; idx < matches.size(); ++idx) {
645  if (buffer.size() + 1 + matches.at(idx).size() > wrap_limit) {
646  lua_model_->add_dialog_message(buffer);
647  buffer = matches.at(idx);
648  } else {
649  if (buffer.size()) {
650  buffer += (" " + matches.at(idx));
651  } else {
652  buffer = matches.at(idx);
653  }
654  }
655  }
656 
657  lua_model_->add_dialog_message(buffer);
658  update_view();
659  }
660  text_entry->set_value(prefix + text);
661 }
662 
664 {
665  std::string current_text = text_entry->get_value();
666  input_model_->maybe_update_prefix(current_text);
667  text_entry->set_value(input_model_->search(direction));
668 
669 #ifndef HAVE_HISTORY
670  lua_model_->add_dialog_message("History is disabled, you did not compile with GNU history support.");
671  update_view();
672 #endif
673 
674 }
675 
676 // Dialog implementation
677 
678 /** Display a new console, using given video and lua kernel */
680 #ifndef ALWAYS_HAVE_LUA_CONSOLE
683  const std::string& message = _("The lua console can only be used in debug mode! (Run ':debug' first)");
684  chat_man.add_chat_message(time(nullptr), _("lua console"), 0, message, events::chat_handler::MESSAGE_PRIVATE, false);
685  return;
686  }
687 #endif
688  if (!lk) {
689  ERR_LUA << "Tried to open console with a null lua kernel pointer.\n";
690  return;
691  }
692 
693  lua_interpreter(*lk).show();
694 }
695 
696 /** Helper function to assist those callers which don't want to include resources.hpp */
698  if (which == lua_interpreter::APP) {
699  display(plugins_manager::get()->get_kernel_base());
700  } else if (which == lua_interpreter::GAME) {
702  }
703 }
704 
705 /** Bind the controller, initialize one of the static labels with info about this kernel, and update the view. */
707 {
708  LOG_LUA << "Entering lua_interpreter::view::pre_show" << std::endl;
709  register_text("text_entry", false, controller_->text_entry_, true);
710  controller_->bind(window);
711 
712  label *kernel_type_label = find_widget<label>(&window, "kernel_type", false, true);
713  kernel_type_label->set_label(controller_->lua_model_->get_name());
714 
715  controller_->update_view();
716  //window.invalidate_layout(); // workaround for assertion failure
717  LOG_LUA << "Exiting lua_interpreter::view::pre_show" << std::endl;
718 }
719 
722 {
723  LOG_LUA << "entering lua_interpreter ctor...\n";
724  LOG_LUA << "finished lua_interpreter ctor...\n";
725 }
726 
727 } // namespace dialogs
728 } // namespace gui2
std::string get_name() const
Get a string describing the name of lua kernel.
play_controller * controller
Definition: resources.cpp:21
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...
virtual void set_use_markup(bool use_markup) override
See styled_widget::set_use_markup.
bool available()
Whether wesnoth was compiled with support for a clipboard.
Definition: clipboard.cpp:54
Main class to show messages to the user.
Definition: message.hpp:34
New lexcical_cast header.
game_display & get_display() override
Get a reference to a display member a derived class uses.
const std::unique_ptr< lua_interpreter::lua_model > lua_model_
static bool file_exists(const bfs::path &fpath)
Definition: filesystem.cpp:263
This file contains the window object, this object is a top level container which has the event manage...
void set_vertical_scrollbar_mode(const scrollbar_mode scrollbar_mode)
std::vector< std::string > get_attribute_names(const std::string &s)
#define ERR_LUA
void clear_log()
Clear the console log.
static void msg(const char *act, debug_info &i, const char *to="", const char *result="")
Definition: debugger.cpp:109
A label displays a text, the text can be wrapped but no scrollbars are provided.
Definition: label.hpp:56
Implements some helper classes to ease adding fields to a dialog and hide the synchronization needed...
static std::string _(const char *str)
Definition: gettext.hpp:92
To lexical_cast(From value)
Lexical cast converts one type to another.
lua_interpreter(lua_kernel_base &lk)
std::string get_raw_log() const
Get the unescaped log.
void bind(window &window)
Bind my pointers to the widgets found in the window.
Class for a single line text area.
Definition: text_box.hpp:140
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)
static void display(lua_kernel_base *lk)
Display a new console, using given video and lua kernel.
virtual void set_label(const t_string &label) override
See styled_widget::set_label.
std::string filename_
Definition: action_wml.cpp:562
const std::unique_ptr< controller > controller_
Generic file dialog.
Definition: field-fwd.hpp:22
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.
Go to the end position.
Definition: scrollbar.hpp:60
The lua model is responsible to interact with the lua kernel base and keep track of what should be di...
virtual void set_label(const t_string &label)
void add_dialog_message(const std::string &msg)
Add a message from the dialog, formatted in blue to distinguish from issued commands.
void handle_clear_button_clicked(window &window)
Clear the text.
This file contains the settings handling of the widget library.
const std::unique_ptr< lua_interpreter::input_model > input_model_
void connect_signal_mouse_left_click(dispatcher &dispatcher, const signal_function &signal)
Connects a signal handler for a left mouse button click.
Definition: dispatcher.cpp:171
void set_is_dirty(const bool is_dirty)
Definition: widget.cpp:465
virtual void pre_show(window &window) override
Inherited from modal_dialog.
std::string get_log() const
Get the log string.
const char * what() const noexcept
Definition: exceptions.hpp:37
Label showing a text.
const std::unique_ptr< lua_interpreter::view > view_
void update_view()
Update the view based on the model.
Various uncategorised dialogs.
#define UNUSED(x)
Definition: global.hpp:40
void maybe_update_prefix(const std::string &text)
std::string escape_text(const std::string &text)
Escapes the pango markup characters in a text.
Definition: escape.hpp:32
std::size_t i
Definition: function.cpp:933
Go the visible items towards the begin.
Definition: scrollbar.hpp:59
static map_location::DIRECTION s
void set_external_log(external_log_type lg)
void scroll_vertical_scrollbar(const scrollbar_base::scroll_mode scroll)
Scrolls the vertical scrollbar.
static std::string flush(std::ostringstream &s)
Definition: reports.cpp:91
bool execute(const std::string &cmd)
Ask the lua kernel to execute a command.
Declarations for File-IO.
const bool & debug
The controller is responsible to hold all the input widgets, and a pointer to the model and view...
The scrollbar is always shown, whether needed or not.
std::vector< std::string > get_global_var_names()
Get tab completion strings.
std::string get_user_config_dir()
Definition: filesystem.cpp:762
display_chat_manager & get_chat_manager()
std::vector< std::string > get_globals()
void copy_to_clipboard(const std::string &text, const bool)
Copies text to the clipboard.
Definition: clipboard.cpp:33
void connect_signal_pre_key_press(dispatcher &dispatcher, const signal_keyboard_function &signal)
Connects the signal for &#39;snooping&#39; on the keypress.
Definition: dispatcher.cpp:166
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.
The input_model keeps track of what commands were executed before, and figures out what should be dis...
void handle_copy_button_clicked(window &window)
Copy text to the clipboard.
Simple push button.
Definition: button.hpp:35
Standard logging facilities (interface).
game_lua_kernel * lua_kernel
Definition: resources.cpp:25
virtual std::string my_name()
User-visible name of the lua kernel that they are talking to.
#define e
static lg::log_domain log_lua_int("lua/interpreter")
void update_contents(const std::string &str)
Update the scroll label contents.
void input_keypress_callback(bool &handled, bool &halt, const SDL_Keycode key, window &window)
Handle return key (execute) or tab key (tab completion)
#define LOG_LUA
base class of top level items, the only item which needs to store the final canvases to draw on...
Definition: window.hpp:64
bool word_completion(std::string &text, std::vector< std::string > &wordlist)
Try to complete the last word of &#39;text&#39; with the &#39;wordlist&#39;.
void bind(window &window)
Bind the scroll label widget to my pointer, and configure.
void set_callback_next_draw(std::function< void()> func)
Sets a callback that will be called after the window is drawn next time.
Definition: window.hpp:422
static plugins_manager * get()
Definition: manager.cpp:58
void add_to_history(const std::string &str)
#define DBG_LUA
Error used to report an error in a lua script or in the lua interpreter.
Definition: game_errors.hpp:53