31#include "nlua_camera.h"
33#include "nlua_colour.h"
34#include "nlua_linopt.h"
35#include "nlua_music.h"
42#define BUTTON_WIDTH 50
43#define BUTTON_HEIGHT 20
57#define CLI_MAX_INPUT \
60#define CLI_WIDTH ( SCREEN_W - 100 )
61#define CLI_HEIGHT ( SCREEN_H - 100 )
68static int cli_height = 0;
69static int cli_max_lines = 0;
71#define CLI_MAX_LINES ( cli_max_lines )
85static int cli_keyhandler(
unsigned int wid, SDL_Keycode key, SDL_Keymod mod,
87static void cli_render(
double bx,
double by,
double w,
double h,
void *data );
88static int cli_printCore( lua_State *L,
int cli_only,
int escape );
92static int cli_initLua(
void );
94static char *cli_escapeString(
int *len_out,
const char *s,
int len )
96 char *buf = malloc( 2 * len + 1 );
98 for (
int i = 0; i < len; i++ ) {
99 if ( s[i] == FONT_COLOUR_CODE )
100 buf[b++] = FONT_COLOUR_CODE;
119 char *buf = cli_escapeString( &len, &s[iter.l_begin],
120 iter.
l_end - iter.l_begin );
131static int cli_printCore( lua_State *L,
int cli_only,
int escape )
133 int n = lua_gettop( L );
134 lua_getglobal( L,
"tostring" );
135 lua_pushstring( L,
"" );
136 for (
int i = 1; i <= n; i++ ) {
138 lua_pushvalue( L, -2 );
139 lua_pushvalue( L, i );
140 if ( lua_pcall( L, 1, 1, 0 ) != 0 ) {
141 WARN( _(
"Error calling 'tostring':\n%s" ), lua_tostring( L, -1 ) );
145 s = lua_tostring( L, -1 );
148 L, LUA_QL(
"tostring" )
" must return a string to " LUA_QL(
151 lua_pushstring( L,
"\t" );
155 const char *s = lua_tostring( L, -1 );
172 return nlua_warn( L, 1 );
205 fname = luaL_checkstring( L, 1 );
216 nlua_getenv( L,
cli_env, NLUA_LOAD_TABLE );
217 if ( lua_istable( L, -1 ) ) {
219 while ( lua_next( L, -2 ) != 0 ) {
221 lua_pushvalue( L, -1 );
231 if ( luaL_loadbuffer( L, buf, blen, fname ) != 0 )
236 if ( nlua_pcall(
cli_env, 0, LUA_MULTRET ) != 0 ) {
237 WARN( _(
"Error running 'script':\n%s" ), lua_tostring( L, -1 ) );
241 return lua_gettop( L ) - n;
255 buf = strdup( ( msg != NULL ) ? msg :
"" );
272 buf =
strndup( ( msg != NULL ) ? msg :
"", l );
280static void cli_render(
double bx,
double by,
double w,
double h,
void *data )
284 const glColour col = COL_ALPHA( cBlack, 0.5 );
295 by + h - ( i - start ) * (
cli_font->h + 5 ), &cFontWhite,
302static int cli_keyhandler(
unsigned int wid, SDL_Keycode key, SDL_Keymod mod,
313 if ( strncmp(
cli_buffer[i],
"#C>", 3 ) == 0 ) {
318 strcmp( window_getInput( wid,
"inpInput" ), str ) == 0 ) {
322 window_setInput( wid,
"inpInput", str );
334 window_setInput( wid,
"inpInput", NULL );
340 if ( strncmp(
cli_buffer[i],
"#C>", 3 ) == 0 ) {
343 window_setInput( wid,
"inpInput", str );
349 window_setInput( wid,
"inpInput", NULL );
385 const char *match, *old;
386 char *str, *cur, *
new;
388 old = window_getInput( wid,
"inpInput" );
393 for (
int i = 0; str[i] !=
'\0'; i++ ) {
394 if ( str[i] ==
'.' || str[i] ==
':' ) {
396 lua_getfield(
naevL, -1, cur );
399 if ( !lua_istable(
naevL, -1 ) ) {
400 if ( luaL_getmetafield(
naevL, -1,
"__index" ) ) {
401 if ( lua_istable(
naevL, -1 ) ) {
403 lua_remove(
naevL, -2 );
406 lua_newtable(
naevL );
410 lua_newtable(
naevL );
414 lua_remove(
naevL, -2 );
417 }
else if ( !isalnum( str[i] ) && str[i] !=
'_' ) {
424 if ( strlen( cur ) > 0 ) {
425 lua_pushnil(
naevL );
426 while ( lua_next(
naevL, -2 ) != 0 ) {
427 if ( lua_isstring(
naevL, -2 ) ) {
428 match = lua_tostring(
naevL, -2 );
429 if ( strncmp( cur, match, strlen( cur ) ) == 0 ) {
431 malloc( strlen( old ) + strlen( match ) - strlen( cur ) + 1 );
433 strcat(
new, match + strlen( cur ) );
434 window_setInput( wid,
"inpInput",
new );
447static int cli_initLua(
void )
456 cli_env = nlua_newEnv(
"console" );
469 lua_settop(
naevL, 0 );
471 if ( conf.lua_repl ) {
473 status = nlua_dobufenv(
cli_env, buf, blen,
"@rep.lua" );
476 WARN( _(
"Lua console '%s' Lua error:\n%s" ),
"rep.lua",
477 lua_tostring(
naevL, -1 ) );
478 lua_settop(
naevL, 0 );
481 if ( lua_gettop(
naevL ) != 1 ) {
482 WARN( _(
"rep.lua failed to return a single coroutine." ) );
483 lua_settop(
naevL, 0 );
489 WARN( _(
"rep.lua failed to return a single coroutine." ) );
490 lua_settop(
naevL, 0 );
496 WARN( _(
"REPL thread exited." ) );
498 }
else if ( status != LUA_YIELD ) {
514 FONT_PATH_PREFIX, 0 );
521 WARN( _(
"Failed to initialize console Lua!" ) );
556static void cli_input(
unsigned int wid,
const char *unused )
560 const char *str, *prompt;
562 char buf[CLI_MAX_INPUT + 7];
565 str = window_getInput( wid,
"inpInput" );
568 if ( str == NULL || ( conf.lua_repl &&
cli_thread == NULL ) )
572 escaped = cli_escapeString( &len, str, strlen( str ) );
578 snprintf( buf, CLI_MAX_INPUT + 7,
"#C%s %s#0", prompt, escaped );
582 if ( conf.lua_repl ) {
595 if ( status != LUA_YIELD )
601 lua_pushliteral(
naevL,
"\n" );
604 lua_pushstring(
naevL, str );
608 lua_concat(
naevL, 3 );
610 status = luaL_loadbuffer(
naevL, lua_tostring(
naevL, -1 ),
611 lua_strlen(
naevL, -1 ),
"=cli" );
614 if ( status == LUA_ERRSYNTAX ) {
616 const char *msg = lua_tolstring(
naevL, -1, &lmsg );
617 const char *tp = msg + lmsg - (
sizeof( LUA_QL(
"<eof>" ) ) - 1 );
618 if ( strstr( msg, LUA_QL(
"<eof>" ) ) == tp ) {
624 const char *s = lua_tostring(
naevL, -1 );
627 lua_settop(
naevL, 0 );
632 else if ( status == 0 ) {
633 lua_remove(
naevL, 1 );
635 if ( nlua_pcall(
cli_env, 0, LUA_MULTRET ) ) {
640 if ( lua_gettop(
naevL ) > 0 ) {
642 lua_insert(
naevL, 1 );
643 if ( nlua_pcall(
cli_env, lua_gettop(
naevL ) - 1, 0 ) != 0 )
648 lua_settop(
naevL, 0 );
654 window_setInput( wid,
"inpInput", NULL );
699 "inpInput", CLI_MAX_INPUT, 1,
cli_font );
710 cli_height = line_height * cli_max_lines - ( line_height -
cli_font->h );
711 window_addCust( wid, 20, -40,
CLI_WIDTH - 40, cli_height,
"cstConsole", 0,
718int cli_isOpen(
void )
Provides macros to work with dynamic arrays.
#define array_free(ptr_array)
Frees memory allocated and sets array to NULL.
static ALWAYS_INLINE int array_size(const void *array)
Returns number of elements in the array.
#define array_grow(ptr_array)
Increases the number of elements by one and returns the last element.
#define array_create(basic_type)
Creates a new dynamic array of ‘basic_type’.
void cli_open(void)
Opens the console.
int cli_warn(lua_State *L)
Barebones warn implementation for Lua, allowing scripts to print warnings to stderr.
static int cli_printCore(lua_State *L, int cli_only, int escape)
Back end for the Lua print functionality.
int cli_printRaw(lua_State *L)
Prints raw markup to the console.
int cli_print(lua_State *L)
Replacement for the internal Lua print to print to both the console and the terminal.
static void cli_addMessageMax(const char *msg, const int l)
Adds a message to the buffer.
void cli_exit(void)
Destroys the CLI environment.
static char ** cli_buffer
static lua_State * cli_thread
int cli_init(void)
Initializes the CLI environment.
static int cli_keyhandler(unsigned int wid, SDL_Keycode key, SDL_Keymod mod, int isrepeat)
Key handler for the console window.
static const luaL_Reg cli_methods[]
static void cli_addMessage(const char *msg)
Adds a message to the buffer.
void cli_printCoreString(const char *s, int escape)
Prints a string.
static void cli_render(double bx, double by, double w, double h, void *data)
Render function for the custom widget.
void cli_tabComplete(unsigned int wid)
Basic tab completion for console.
static void cli_input(unsigned int wid, const char *unused)
Handles the CLI input.
static int cli_thread_ref
static int cli_script(lua_State *L)
Would be like "dofile" from the base Lua lib.
static int cli_scroll_pos
int gl_printLineIteratorNext(glPrintLineIterator *iter)
Updates iter with the next line's information.
void gl_freeFont(glFont *font)
Frees a loaded font. Caution: its glFontStash still has a slot in avail_fonts. At the time of writing...
void gl_printLineIteratorInit(glPrintLineIterator *iter, const glFont *ft_font, const char *text, int width)
Initialize an iterator object for breaking text into lines.
int gl_printMaxRaw(const glFont *ft_font, const int max, double x, double y, const glColour *c, double outlineR, const char *text)
Behaves like gl_printRaw but stops displaying text after a certain distance.
int gl_fontInit(glFont *font, const char *fname, const unsigned int h, const char *prefix, unsigned int flags)
Initializes a font.
Header file with generic functions and naev-specifics.
const char * naev_version(int long_version)
Returns the version in a human readable string.
void * ndata_read(const char *path, size_t *filesize)
Reads a file from the ndata (will be NUL terminated).
int nlua_loadStandard(nlua_env env)
Loads the standard Naev Lua API.
void lua_clearCache(void)
Clears the cached stuff.
int nlua_loadBackground(nlua_env env)
Loads the graphics library.
int nlua_loadCamera(nlua_env env)
Loads the camera library.
int nlua_loadCLI(nlua_env env)
Loads the CLI Lua library.
int nlua_loadCol(nlua_env env)
Loads the colour library.
int nlua_loadLinOpt(nlua_env env)
Loads the linopt library.
int nlua_loadMusic(nlua_env env)
Music Lua module.
int nlua_loadTex(nlua_env env)
Loads the texture library.
int nlua_loadTk(nlua_env env)
Loads the Toolkit Lua library.
char * strndup(const char *s, size_t n)
Return a pointer to a new string, which is a duplicate of the string s (or, if necessary,...
void gl_renderRect(double x, double y, double w, double h, const glColour *c)
Renders a rectangle.
Represents a font in memory.
The state of a line iteration. This matches the process of rendering text into an on-screen box: An e...