The Battle for Wesnoth  1.13.4+dev
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
lua_interpreter.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2014 - 2016 by Chris Beck <[email protected]>
3  Part of the Battle for Wesnoth Project http://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/dialogs/helper.hpp"
23 #include "gui/widgets/button.hpp"
24 #include "gui/widgets/label.hpp"
26 #include "gui/widgets/settings.hpp"
27 #include "gui/widgets/text_box.hpp"
28 #include "gui/widgets/window.hpp"
29 
30 #include "desktop/clipboard.hpp"
31 #include "game_config.hpp"
32 #include "game_errors.hpp"
33 #include "gettext.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 "log.hpp"
41 #include "text.hpp"
42 
43 #include <sstream>
44 #include <string>
45 #include <vector>
46 #include "utils/functional.hpp"
47 #include <boost/scoped_ptr.hpp>
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 class CVideo;
61 
62 namespace gui2
63 {
64 
65 /*WIKI
66  * @page = GUIWindowDefinitionWML
67  * @order = 3_lua_interpretter
68  *
69  * == Settings manager ==
70  *
71  * This shows the settings manager
72  *
73  */
74 
75 
76 REGISTER_DIALOG(lua_interpreter)
77 
78 // Model, View, Controller definitions
79 
81 private:
82  tscroll_label* msg_label; //the view is extremely simple, it's pretty much just this one widget that gets updated
83 
84 public:
85  view() : msg_label(nullptr) {}
86 
87  /** Bind the scroll label widget to my pointer, and configure */
88  void bind(twindow& window) {
89  msg_label = &find_widget<tscroll_label>(&window, "msg", false);
90  msg_label->set_use_markup(true);
92  msg_label->set_label("");
93  }
94 
95  /** Update the scroll label contents */
96  void update_contents(const std::string & str)
97  {
98  assert(msg_label);
99 
100  msg_label->set_label(str);
102  }
103 
104  void pg_up()
105  {
106  assert(msg_label);
108  }
109 
110  void pg_down()
111  {
112  assert(msg_label);
114  }
115 };
116 
117 /**
118  * The lua model is responsible to interact with the lua kernel base and keep track of what should be displayed in the console.
119  * It registers its stringstream with the lua kernel when it is created, and unregisters when it is destroyed.
120  *
121  * It is responsible to execute commands as strings, or add dialog messages for the user. It is also responsible to ask
122  * the lua kernel for help with tab completion.
123  */
125 private:
127  std::stringstream log_;
128 
129 public:
131  : L_(lk)
132  , log_()
133  {
134  DBG_LUA << "constructing a tlua_interpreter::model\n";
135  //DBG_LUA << "incoming:\n" << lk.get_log().rdbuf() << "\n.\n";
136  log_ << lk.get_log().str() << std::flush;
137  //FIXME: we should escapte th input that we get from L_ with escape_text
138  L_.set_external_log(&log_); //register our log to get commands and output from the lua interpreter
139  //DBG_LUA << "recieved:\n" << log_.str() << "\n.\n";
140 
141  DBG_LUA << "finished constructing a tlua_interpreter::model\n";
142  }
143 
145  {
146  DBG_LUA << "destroying a tlua_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  std::string get_log() const { return log_.str(); } ///< Get the log string
160  std::string get_name() const { return L_.my_name(); } ///< Get a string describing the name of lua kernel
161 
162  //* Tab completion: Get list of presently defined global variables */
163  std::vector<std::string> get_globals() { return L_.get_global_var_names(); }
164  //* Tab completion: Get list of attributes for variable corresponding to this path. */
165  std::vector<std::string> get_attribute_names(const std::string & s) { return L_.get_attribute_names(s); }
166 };
167 
168 /**
169  * The input_model keeps track of what commands were executed before, and figures out what
170  * should be displayed when the user presses up / down arrows in the input.
171  * It is essentially part of the model, but it isn't connected to the lua kernel so I have implemented it
172  * separately. Putatively it could all be refactored so that there is a single model with private subclass "lua_model"
173  * and also a "command_history_model" but I have decided simply to not implement it that way.
174  */
176 private:
179 #ifdef HAVE_HISTORY
181 #endif
182 
183 public:
185  : prefix_()
186  , end_of_history_(true)
187 #ifdef HAVE_HISTORY
188  , filename_(filesystem::get_user_config_dir() + "/lua_command_history")
189  {
190  using_history();
191  read_history (filename_.c_str());
192  }
193 #else
194  {}
195 #endif
196 
197 #ifdef HAVE_HISTORY
198  ~input_model()
199  {
200  try {
201  const size_t history_max = 500;
202  if (filesystem::file_exists(filename_)) {
203  append_history (history_max,filename_.c_str());
204  } else {
205  write_history (filename_.c_str());
206  }
207 
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";}
210  }
211 #endif
213  prefix_ = "";
214  (void) str;
215 #ifdef HAVE_HISTORY
216  add_history(str.c_str());
217 #endif
218  end_of_history_ = true;
219 
220  }
221 
222  void maybe_update_prefix (const std::string & text) {
223  LOG_LUA << "maybe update prefix\n";
224  LOG_LUA << "prefix_: '"<< prefix_ << "'\t text='"<< text << "'\n";
225 
226  if (!end_of_history_) return;
227 
228  prefix_ = text;
229  LOG_LUA << "updated prefix\n";
230  }
231 
232  std::string search( int direction ) {
233 #ifdef HAVE_HISTORY
234  LOG_LUA << "searching in direction " << direction << " from position " << where_history() << "\n";
235 
236  HIST_ENTRY * e = nullptr;
237  if (end_of_history_) {
238  // if the direction is > 0, do nothing because searching down only takes place when we are in the history records.
239  if (direction < 0) {
240  history_set_pos(history_length);
241 
242  if (prefix_.size() > 0) {
243  int result = history_search_prefix(prefix_.c_str(), direction);
244  if (result == 0) {
245  e = current_history();
246  }
247  } else {
248  e = previous_history();
249  }
250  }
251  } else {
252  e = (direction > 0) ? next_history() : previous_history();
253  if (prefix_.size() > 0 && e) {
254  int result = history_search_prefix(prefix_.c_str(), direction);
255  if (result == 0) {
256  e = current_history();
257  } else {
258  e = nullptr; // if the search misses, it leaves the state as it was, which might not have been on an entry matching prefix.
259  end_of_history_ = true; // we actually want to force it to be null and treat as off the end of history in this case.
260  }
261  }
262  }
263 
264  if (e) {
265  LOG_LUA << "found something at " << where_history() << "\n";
266  std::string ret = e->line;
267  end_of_history_ = false;
268  return ret;
269  }
270 #endif
271 
272  LOG_LUA << "didn't find anything\n";
273 
274  // reset, set history to the end and prefix_ to empty, and return the current prefix_ for the user to edit
275  end_of_history_ = true;
276  (void) direction;
277  std::string temp = prefix_;
278  prefix_ = "";
279  return temp;
280  }
281 
283 #ifdef HAVE_HISTORY
284  ::clear_history();
285  write_history (filename_.c_str());
286  return "Cleared history.";
287 #else
288  return "History is disabled, you did not compile with GNU history support.";
289 #endif
290  }
291 
293 #ifdef HAVE_HISTORY
294  HIST_ENTRY **the_list;
295 
296  the_list = history_list ();
297  if (the_list) {
298  if (!*the_list) {
299  return "History is empty.";
300  }
301 
303  for (int i = 0; the_list[i]; i++) {
304  result += lexical_cast<std::string, int>(i+history_base);
305  result += ": ";
306  result += the_list[i]->line;
307  result += "\n";
308  }
309  return result;
310  } else {
311  return "Couldn't find history.";
312  }
313 #else
314  return "History is disabled, you did not compile with GNU history support.";
315 #endif
316  }
317 
318  // Does history expansion in a command line. A return value of true indicates an error,
319  // the error message will be returned in the string argument. A return value of false
320  // indicates success and that execution should proceed.
322 #ifdef HAVE_HISTORY
323  // Do history expansions
324  char * cmd_cstr = new char [cmd.length()+1];
325  strcpy (cmd_cstr, cmd.c_str());
326 
327  char * expansion;
328 
329  int result = history_expand(cmd_cstr, &expansion);
330  free(cmd_cstr);
331 
332  if (result < 0 || result == 2) {
333  cmd = expansion; // return error message in cmd var
334  free(expansion);
335  return true;
336  }
337 
338  cmd = expansion;
339  free(expansion);
340 #endif
341  (void) cmd;
342  return false;
343  }
344 };
345 
346 /**
347  * The controller is responsible to hold all the input widgets, and a pointer to the model and view.
348  * It is responsible to bind the input signals to appropriate handler methods, which it holds.
349  * It is also responsible to ask the view to update based on the output of the model, typically in
350  * response to some input.
351  */
353 private:
355 
358 
359  boost::scoped_ptr<tlua_interpreter::lua_model> lua_model_;
360  boost::scoped_ptr<tlua_interpreter::input_model> input_model_;
361  boost::scoped_ptr<tlua_interpreter::view> view_;
362 
363  void execute();
364  void tab();
365  void search(int direction);
366 public:
368  : copy_button(nullptr)
369  , text_entry(nullptr)
370  , text_entry_()
371  , lua_model_(new tlua_interpreter::lua_model(lk))
372  , input_model_(new tlua_interpreter::input_model())
373  , view_(new tlua_interpreter::view())
374  {}
375 
376  /** Bind my pointers to the widgets found in the window */
377  void bind(twindow& window);
378 
379  void handle_copy_button_clicked(twindow & window);
380 
381  void input_keypress_callback(bool& handled,
382  bool& halt,
383  const SDLKey key,
384  twindow& window);
385 
386  void update_view(); ///< Update the view based on the model
387 
388  friend class tlua_interpreter;
389 };
390 
391 // Model impl
392 
393 /** Execute a command, and report any errors encountered. */
395 {
396  LOG_LUA << "tlua_interpreter::model::execute...\n";
397 
398  try {
399  L_.interactive_run(cmd.c_str());
400  return true;
401  } catch (game::lua_error & e) {
403  return false;
404  }
405 }
406 
407 /** Add a dialog message, which will appear in blue. */
409  log_ << "<span color='#8888FF'>" << font::escape_text(msg) << "</span>\n";
410 }
411 
412 // View impl
413 
414 // Controller impl
415 
416 /** Update the view based on the model. */
418 {
419  LOG_LUA << "tlua_interpreter update_view...\n";
420  assert(lua_model_);
421  assert(view_);
422 
423  view_->update_contents(lua_model_->get_log());
424 
425  LOG_LUA << "tlua_interpreter update_view finished\n";
426 }
427 
428 /** Find all the widgets managed by the controller and connect them to handler methods. */
430 {
431  LOG_LUA << "Entering tlua_interpreter::controller::bind" << std::endl;
432  assert(view_);
433  view_->bind(window);
434 
435  text_entry = &find_widget<ttext_box>(&window, "text_entry", false);
436  //text_entry->set_text_changed_callback(
437  // std::bind(&view::filter, this, std::ref(window)));
438  window.keyboard_capture(text_entry);
439  window.set_click_dismiss(false);
440  window.set_enter_disabled(true);
441 
443  *text_entry,
445  this,
446  _3,
447  _4,
448  _5,
449  std::ref(window)));
450 
451 
452  copy_button = &find_widget<tbutton>(&window, "copy", false);
454  *copy_button,
456  this,
457  std::ref(window)));
458 
460  copy_button->set_active(false);
461  copy_button->set_tooltip(_("Clipboard support not found, contact your packager"));
462  }
463 
464  LOG_LUA << "Exiting tlua_interpreter::controller::bind" << std::endl;
465 }
466 
467 /** Copy text to the clipboard */
469 {
470  assert(lua_model_);
471  desktop::clipboard::copy_to_clipboard(lua_model_->get_log(), false);
472 }
473 
474 /** Handle return key (execute) or tab key (tab completion) */
476  bool& halt,
477  const SDLKey key,
478  twindow& /*window*/)
479 {
480  assert(lua_model_);
481  assert(text_entry);
482 
483  LOG_LUA << "keypress_callback\n";
484  if(key == SDLK_RETURN || key == SDLK_KP_ENTER) { // handle executing whatever is in the command entry field
485  LOG_LUA << "executing...\n";
486  execute();
487  handled = true;
488  halt = true;
489  LOG_LUA << "finished executing\n";
490  } else if(key == SDLK_TAB) { // handle tab completion
491  tab();
492  handled = true;
493  halt = true;
494  } else if(key == SDLK_UP) {
495  search(-1);
496  handled = true;
497  halt = true;
498  } else if(key == SDLK_DOWN) {
499  search(1);
500  handled = true;
501  halt = true;
502  } else if(key == SDLK_PAGEUP) {
503  view_->pg_up();
504  handled = true;
505  halt = true;
506  } else if(key == SDLK_PAGEDOWN) {
507  view_->pg_down();
508  handled = true;
509  halt = true;
510  }
511 
512 }
513 
515 {
516  std::string cmd = text_entry->get_value();
517  if (cmd.size() == 0) return; //don't bother with empty string
518 
519  cmd.erase(cmd.find_last_not_of(" \n\r\t")+1); //right trim the string
520 
521  LOG_LUA << "Executing '"<< cmd << "'\n";
522 
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("");
526  update_view();
527  return;
528  }
529 
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("");
533  update_view();
534  return;
535  }
536 
537  if (input_model_->do_history_expansion(cmd)) {
538  lua_model_->add_dialog_message(cmd);
539  update_view();
540  return;
541  }
542 
543  if (lua_model_->execute(cmd)) {
544  input_model_->add_to_history(cmd);
545  text_entry->set_value("");
546  }
547  update_view();
548 }
549 
551 {
552  std::string text = text_entry->get_value();
553 
554  std::string prefix;
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);
559  }
560 
561  std::vector<std::string> matches;
562 
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");
582  } else {
583  matches = lua_model_->get_attribute_names(text);
584  }
585 
586  //bool line_start = utils::word_completion(text, matches);
587  if (text.size() > 0) { // this if is to avoid wierd behavior in word_completion, where it thinks nothing matches the empty string
588  utils::word_completion(text, matches);
589  }
590 
591  if(matches.empty()) {
592  return;
593  }
594 
595  //if(matches.size() == 1) {
596  //text.append(" "); //line_start ? ": " : " ");
597  //} else {
598  if (matches.size() > 1) {
599  //std::string completion_list = utils::join(matches, " ");
600 
601  const size_t wrap_limit = 80;
603 
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);
608  } else {
609  if (buffer.size()) {
610  buffer += (" " + matches.at(idx));
611  } else {
612  buffer = matches.at(idx);
613  }
614  }
615  }
616 
617  lua_model_->add_dialog_message(buffer);
618  update_view();
619  }
620  text_entry->set_value(prefix + text);
621 }
622 
624 {
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));
628 
629 #ifndef HAVE_HISTORY
630  lua_model_->add_dialog_message("History is disabled, you did not compile with GNU history support.");
631  update_view();
632 #endif
633 
634 }
635 
636 // Dialog implementation
637 
638 /** Display a new console, using given video and lua kernel */
640 #ifndef ALWAYS_HAVE_LUA_CONSOLE
641  if(!game_config::debug) {
642  return;
643  }
644 #endif
645  if (!lk) {
646  ERR_LUA << "Tried to open console with a null lua kernel pointer.\n";
647  return;
648  }
649 
650  tlua_interpreter(*lk).show(video);
651 }
652 
653 /** Helper function to assist those callers which don't want to include resources.hpp */
655  if (which == tlua_interpreter::APP) {
656  display(video, plugins_manager::get()->get_kernel_base());
657  } else if (which == tlua_interpreter::GAME) {
659  }
660 }
661 
662 /** Call inherited method */
664 {
665  return build(video, window_id());
666 }
667 
668 /** Bind the controller, initialize one of the static labels with info about this kernel, and update the view. */
670 {
671  LOG_LUA << "Entering tlua_interpreter::view::pre_show" << std::endl;
672  register_text("text_entry", false, controller_->text_entry_, true);
673  controller_->bind(window);
674 
675  tlabel *kernel_type_label = &find_widget<tlabel>(&window, "kernel_type", false);
676  kernel_type_label->set_label(controller_->lua_model_->get_name());
677 
678  controller_->update_view();
679  //window.invalidate_layout(); // workaround for assertion failure
680  LOG_LUA << "Exiting tlua_interpreter::view::pre_show" << std::endl;
681 }
682 
685 {
686  LOG_LUA << "entering tlua_interpreter ctor...\n";
687  LOG_LUA << "finished tlua_interpreter ctor...\n";
688 }
689 
690 
691 } // end of namespace gui2
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 maybe_update_prefix(const std::string &text)
void connect_signal_pre_key_press(tdispatcher &dispatcher, const tsignal_keyboard_function &signal)
Connects the signal for 'snooping' on the keypress.
Definition: dispatcher.hpp:703
void bind(twindow &window)
Bind the scroll label widget to my pointer, and configure.
Go the visibile items towards the begin.
Definition: scrollbar.hpp:60
GLvoid **typedef void(GLAPIENTRY *PFNGLGETVERTEXATTRIBDVPROC)(GLuint
Definition: glew.h:1806
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.
Definition: clipboard.cpp:61
const char * what() const
Definition: exceptions.hpp:35
twindow * build(CVideo &video, const twindow_builder::tresolution *definition)
Builds a window.
std::string search(int direction)
The input_model keeps track of what commands were executed before, and figures out what should be dis...
Definition: video.hpp:58
This file contains the window object, this object is a top level container which has the event manage...
REGISTER_DIALOG(label_settings)
void scroll_vertical_scrollbar(const tscrollbar_::tscroll scroll)
Scrolls the vertical scrollbar.
virtual void set_label(const t_string &label)
Definition: control.cpp:330
#define ERR_LUA
Go to the end position.
Definition: scrollbar.hpp:61
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.
Definition: dispatcher.hpp:710
virtual void set_use_markup(bool use_markup) override
See tcontrol::set_use_markup.
Class for a single line text area.
Definition: text_box.hpp:118
Label showing a text.
Definition: label.hpp:29
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.
#define SDLKey
Definition: compat.hpp:29
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 ...
Definition: window.hpp:62
std::string filename_
Definition: action_wml.cpp:506
A class inherited from ttext_box that displays its input as stars.
Definition: field-fwd.hpp:23
std::vector< std::string > get_globals()
Simple push button.
Definition: button.hpp:32
void pre_show(twindow &window)
Inherited from tdialog.
static UNUSEDNOWARN std::string _(const char *str)
Definition: gettext.hpp:82
virtual void set_label(const t_string &label) override
See tcontrol::set_label.
GLuint64EXT * result
Definition: glew.h:10727
void set_vertical_scrollbar_mode(const tscrollbar_mode scrollbar_mode)
This file contains the settings handling of the widget library.
boost::scoped_ptr< tlua_interpreter::input_model > input_model_
bool do_history_expansion(std::string &cmd)
std::string get_log() const
Get the log string.
boost::scoped_ptr< tlua_interpreter::lua_model > lua_model_
Label showing a text.
GLuint buffer
Definition: glew.h:1648
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.
Definition: text.cpp:75
tlua_interpreter(lua_kernel_base &lk)
size_t i
Definition: function.cpp:1057
static std::string flush(std::ostringstream &s)
Definition: reports.cpp:86
static void msg(const char *act, debug_info &i, const char *to="", const char *result="")
Definition: debugger.cpp:112
The scrollbar is always shown, whether needed or not.
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.
Definition: clipboard.cpp:40
GLenum GLint ref
Definition: glew.h:1813
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
Definition: resources.cpp:25
virtual std::string my_name()
#define e
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...
GLdouble s
Definition: glew.h:1358
#define LOG_LUA
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.
Definition: dialog.cpp:127
GLsizei const GLcharARB ** string
Definition: glew.h:4503
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()
Definition: manager.cpp:61
bool execute(const std::string &cmd)
Ask the lua kernel to execute a command.
#define DBG_LUA
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.
Definition: game_errors.hpp:53