mirror of
https://github.com/YGGverse/xash3d-fwgs.git
synced 2025-01-30 08:44:31 +00:00
Move command autocomplete to common engine files, as it used by Wcon and may be used by curses console in future
This commit is contained in:
parent
572705bc08
commit
f15e2c2dcf
@ -37,7 +37,6 @@ static qboolean g_utf8 = false;
|
||||
#define COLOR_DEFAULT '7'
|
||||
#define CON_HISTORY 64
|
||||
#define MAX_DBG_NOTIFY 128
|
||||
#define CON_MAXCMDS 4096 // auto-complete intermediate list
|
||||
#define CON_NUMFONTS 3 // maxfonts
|
||||
|
||||
#define CON_LINES( i ) (con.lines[(con.lines_first + (i)) % con.maxlines])
|
||||
@ -60,14 +59,6 @@ rgba_t g_color_table[8] =
|
||||
{ 240, 180, 24, 255 }, // default color (can be changed by user)
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
string buffer;
|
||||
int cursor;
|
||||
int scroll;
|
||||
int widthInChars;
|
||||
} field_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
string szNotify;
|
||||
@ -126,14 +117,6 @@ typedef struct
|
||||
|
||||
notify_t notify[MAX_DBG_NOTIFY]; // for Con_NXPrintf
|
||||
qboolean draw_notify; // true if we have NXPrint message
|
||||
|
||||
// console auto-complete
|
||||
string shortestMatch;
|
||||
field_t *completionField; // con.input or dedicated server fake field-line
|
||||
const char *completionString;
|
||||
const char *completionBuffer;
|
||||
char *cmds[CON_MAXCMDS];
|
||||
int matchCount;
|
||||
} console_t;
|
||||
|
||||
static console_t con;
|
||||
@ -193,18 +176,6 @@ void Con_ClearNotify( void )
|
||||
CON_LINES( i ).addtime = 0.0;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
Con_ClearField
|
||||
================
|
||||
*/
|
||||
void Con_ClearField( field_t *edit )
|
||||
{
|
||||
memset( edit->buffer, 0, MAX_STRING );
|
||||
edit->cursor = 0;
|
||||
edit->scroll = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
Con_ClearTyping
|
||||
@ -217,13 +188,7 @@ void Con_ClearTyping( void )
|
||||
Con_ClearField( &con.input );
|
||||
con.input.widthInChars = con.linewidth;
|
||||
|
||||
// free the old autocomplete list
|
||||
for( i = 0; i < con.matchCount; i++ )
|
||||
{
|
||||
freestring( con.cmds[i] );
|
||||
}
|
||||
|
||||
con.matchCount = 0;
|
||||
Cmd_AutoCompleteClear();
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1368,216 +1333,15 @@ EDIT FIELDS
|
||||
=============================================================================
|
||||
*/
|
||||
/*
|
||||
===============
|
||||
Con_AddCommandToList
|
||||
|
||||
===============
|
||||
================
|
||||
Con_ClearField
|
||||
================
|
||||
*/
|
||||
static void Con_AddCommandToList( const char *s, const char *unused1, const char *unused2, void *unused3 )
|
||||
void Con_ClearField(field_t *edit)
|
||||
{
|
||||
if( *s == '@' ) return; // never show system cvars or cmds
|
||||
if( con.matchCount >= CON_MAXCMDS ) return; // list is full
|
||||
|
||||
if( Q_strnicmp( s, con.completionString, Q_strlen( con.completionString )))
|
||||
return; // no match
|
||||
|
||||
con.cmds[con.matchCount++] = copystring( s );
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
Con_SortCmds
|
||||
=================
|
||||
*/
|
||||
static int Con_SortCmds( const char **arg1, const char **arg2 )
|
||||
{
|
||||
return Q_stricmp( *arg1, *arg2 );
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
Con_PrintCmdMatches
|
||||
===============
|
||||
*/
|
||||
static void Con_PrintCmdMatches( const char *s, const char *unused1, const char *m, void *unused2 )
|
||||
{
|
||||
if( !Q_strnicmp( s, con.shortestMatch, Q_strlen( con.shortestMatch )))
|
||||
{
|
||||
if( COM_CheckString( m )) Con_Printf( " %s ^3\"%s\"\n", s, m );
|
||||
else Con_Printf( " %s\n", s ); // variable or command without description
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
Con_PrintCvarMatches
|
||||
===============
|
||||
*/
|
||||
static void Con_PrintCvarMatches( const char *s, const char *value, const char *m, void *unused2 )
|
||||
{
|
||||
if( !Q_strnicmp( s, con.shortestMatch, Q_strlen( con.shortestMatch )))
|
||||
{
|
||||
if( COM_CheckString( m )) Con_Printf( " %s (%s) ^3\"%s\"\n", s, value, m );
|
||||
else Con_Printf( " %s (%s)\n", s, value ); // variable or command without description
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
Con_ConcatRemaining
|
||||
===============
|
||||
*/
|
||||
static void Con_ConcatRemaining( const char *src, const char *start )
|
||||
{
|
||||
const char *arg;
|
||||
int i;
|
||||
|
||||
arg = Q_strstr( src, start );
|
||||
|
||||
if( !arg )
|
||||
{
|
||||
for( i = 1; i < Cmd_Argc(); i++ )
|
||||
{
|
||||
Q_strncat( con.completionField->buffer, " ", sizeof( con.completionField->buffer ));
|
||||
arg = Cmd_Argv( i );
|
||||
while( *arg )
|
||||
{
|
||||
if( *arg == ' ' )
|
||||
{
|
||||
Q_strncat( con.completionField->buffer, "\"", sizeof( con.completionField->buffer ));
|
||||
break;
|
||||
}
|
||||
arg++;
|
||||
}
|
||||
|
||||
Q_strncat( con.completionField->buffer, Cmd_Argv( i ), sizeof( con.completionField->buffer ));
|
||||
if( *arg == ' ' ) Q_strncat( con.completionField->buffer, "\"", sizeof( con.completionField->buffer ));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
arg += Q_strlen( start );
|
||||
Q_strncat( con.completionField->buffer, arg, sizeof( con.completionField->buffer ));
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
Con_CompleteCommand
|
||||
|
||||
perform Tab expansion
|
||||
===============
|
||||
*/
|
||||
void Con_CompleteCommand( field_t *field )
|
||||
{
|
||||
field_t temp;
|
||||
string filename;
|
||||
qboolean nextcmd;
|
||||
int i;
|
||||
|
||||
// setup the completion field
|
||||
con.completionField = field;
|
||||
|
||||
// only look at the first token for completion purposes
|
||||
Cmd_TokenizeString( con.completionField->buffer );
|
||||
|
||||
nextcmd = ( con.completionField->buffer[Q_strlen( con.completionField->buffer ) - 1] == ' ' ) ? true : false;
|
||||
|
||||
con.completionString = Cmd_Argv( 0 );
|
||||
con.completionBuffer = Cmd_Argv( 1 );
|
||||
|
||||
// skip backslash
|
||||
while( *con.completionString && ( *con.completionString == '\\' || *con.completionString == '/' ))
|
||||
con.completionString++;
|
||||
|
||||
// skip backslash
|
||||
while( *con.completionBuffer && ( *con.completionBuffer == '\\' || *con.completionBuffer == '/' ))
|
||||
con.completionBuffer++;
|
||||
|
||||
if( !Q_strlen( con.completionString ))
|
||||
return;
|
||||
|
||||
// free the old autocomplete list
|
||||
for( i = 0; i < con.matchCount; i++ )
|
||||
{
|
||||
if( con.cmds[i] != NULL )
|
||||
{
|
||||
Mem_Free( con.cmds[i] );
|
||||
con.cmds[i] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
con.matchCount = 0;
|
||||
con.shortestMatch[0] = 0;
|
||||
|
||||
// find matching commands and variables
|
||||
Cmd_LookupCmds( NULL, NULL, Con_AddCommandToList );
|
||||
Cvar_LookupVars( 0, NULL, NULL, Con_AddCommandToList );
|
||||
|
||||
if( !con.matchCount ) return; // no matches
|
||||
|
||||
memcpy( &temp, con.completionField, sizeof( field_t ));
|
||||
|
||||
// autocomplete second arg
|
||||
if(( Cmd_Argc() == 2 ) || (( Cmd_Argc() == 1 ) && nextcmd ))
|
||||
{
|
||||
if( !Q_strlen( con.completionBuffer ))
|
||||
return;
|
||||
|
||||
if( Cmd_AutocompleteName( con.completionBuffer, filename, sizeof( filename )))
|
||||
{
|
||||
Q_sprintf( con.completionField->buffer, "%s %s", Cmd_Argv( 0 ), filename );
|
||||
con.completionField->cursor = Q_strlen( con.completionField->buffer );
|
||||
}
|
||||
|
||||
// don't adjusting cursor pos if we nothing found
|
||||
return;
|
||||
}
|
||||
else if( Cmd_Argc() >= 3 )
|
||||
{
|
||||
// disable autocomplete for all next args
|
||||
return;
|
||||
}
|
||||
|
||||
if( con.matchCount == 1 )
|
||||
{
|
||||
Q_sprintf( con.completionField->buffer, "\\%s", con.cmds[0] );
|
||||
if( Cmd_Argc() == 1 ) Q_strncat( con.completionField->buffer, " ", sizeof( con.completionField->buffer ));
|
||||
else Con_ConcatRemaining( temp.buffer, con.completionString );
|
||||
con.completionField->cursor = Q_strlen( con.completionField->buffer );
|
||||
}
|
||||
else
|
||||
{
|
||||
char *first, *last;
|
||||
int len = 0;
|
||||
|
||||
qsort( con.cmds, con.matchCount, sizeof( char* ), Con_SortCmds );
|
||||
|
||||
// find the number of matching characters between the first and
|
||||
// the last element in the list and copy it
|
||||
first = con.cmds[0];
|
||||
last = con.cmds[con.matchCount-1];
|
||||
|
||||
while( *first && *last && Q_tolower( *first ) == Q_tolower( *last ))
|
||||
{
|
||||
first++;
|
||||
last++;
|
||||
|
||||
con.shortestMatch[len] = con.cmds[0][len];
|
||||
len++;
|
||||
}
|
||||
con.shortestMatch[len] = 0;
|
||||
|
||||
// multiple matches, complete to shortest
|
||||
Q_sprintf( con.completionField->buffer, "\\%s", con.shortestMatch );
|
||||
con.completionField->cursor = Q_strlen( con.completionField->buffer );
|
||||
Con_ConcatRemaining( temp.buffer, con.completionString );
|
||||
|
||||
Con_Printf( "]%s\n", con.completionField->buffer );
|
||||
|
||||
// run through again, printing matches
|
||||
Cmd_LookupCmds( NULL, NULL, Con_PrintCmdMatches );
|
||||
Cvar_LookupVars( 0, NULL, NULL, Con_PrintCvarMatches );
|
||||
}
|
||||
memset(edit->buffer, 0, MAX_STRING);
|
||||
edit->cursor = 0;
|
||||
edit->scroll = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -2563,32 +2327,6 @@ void Con_InvalidateFonts( void )
|
||||
con.curFont = con.lastUsedFont = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
=========
|
||||
Cmd_AutoComplete
|
||||
|
||||
NOTE: input string must be equal or longer than MAX_STRING
|
||||
=========
|
||||
*/
|
||||
void Cmd_AutoComplete( char *complete_string )
|
||||
{
|
||||
field_t input;
|
||||
|
||||
if( !complete_string || !*complete_string )
|
||||
return;
|
||||
|
||||
// setup input
|
||||
Q_strncpy( input.buffer, complete_string, sizeof( input.buffer ));
|
||||
input.cursor = input.scroll = 0;
|
||||
|
||||
Con_CompleteCommand( &input );
|
||||
|
||||
// setup output
|
||||
if( input.buffer[0] == '\\' || input.buffer[0] == '/' )
|
||||
Q_strncpy( complete_string, input.buffer + 1, sizeof( input.buffer ));
|
||||
else Q_strncpy( complete_string, input.buffer, sizeof( input.buffer ));
|
||||
}
|
||||
|
||||
/*
|
||||
=========
|
||||
Con_FastClose
|
||||
|
@ -364,6 +364,15 @@ typedef enum
|
||||
|
||||
#include "net_ws.h"
|
||||
|
||||
// console field
|
||||
typedef struct
|
||||
{
|
||||
string buffer;
|
||||
int cursor;
|
||||
int scroll;
|
||||
int widthInChars;
|
||||
} field_t;
|
||||
|
||||
typedef struct host_redirect_s
|
||||
{
|
||||
rdtype_t target;
|
||||
@ -892,6 +901,13 @@ void pfnResetTutorMessageDecayData( void );
|
||||
#define Z_Realloc( ptr, size ) Mem_Realloc( host.mempool, ptr, size )
|
||||
#define Z_Free( ptr ) if( ptr != NULL ) Mem_Free( ptr )
|
||||
|
||||
//
|
||||
// con_utils.c
|
||||
//
|
||||
qboolean Cmd_AutocompleteName( const char *source, char *buffer, size_t bufsize );
|
||||
void Cmd_AutoComplete( char *complete_string );
|
||||
void Cmd_AutoCompleteClear( void );
|
||||
|
||||
//
|
||||
// crclib.c
|
||||
//
|
||||
@ -1053,8 +1069,6 @@ void Info_WriteVars( file_t *f );
|
||||
void Info_Print( const char *s );
|
||||
void Cmd_WriteVariables( file_t *f );
|
||||
int Cmd_CheckMapsList( int fRefresh );
|
||||
qboolean Cmd_AutocompleteName( const char *source, char *buffer, size_t bufsize );
|
||||
void Cmd_AutoComplete( char *complete_string );
|
||||
void COM_SetRandomSeed( long lSeed );
|
||||
int COM_RandomLong( int lMin, int lMax );
|
||||
float COM_RandomFloat( float fMin, float fMax );
|
||||
|
@ -20,16 +20,32 @@ GNU General Public License for more details.
|
||||
|
||||
extern convar_t *con_gamemaps;
|
||||
|
||||
#define CON_MAXCMDS 4096 // auto-complete intermediate list
|
||||
|
||||
typedef struct autocomplete_list_s
|
||||
{
|
||||
const char *name;
|
||||
qboolean (*func)( const char *s, char *name, int length );
|
||||
} autocomplete_list_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
// console auto-complete
|
||||
string shortestMatch;
|
||||
field_t *completionField; // con.input or dedicated server fake field-line
|
||||
const char *completionString;
|
||||
const char *completionBuffer;
|
||||
char *cmds[CON_MAXCMDS];
|
||||
int matchCount;
|
||||
} con_autocomplete_t;
|
||||
|
||||
static con_autocomplete_t con;
|
||||
|
||||
/*
|
||||
=======================================================================
|
||||
|
||||
FILENAME AUTOCOMPLETION
|
||||
|
||||
=======================================================================
|
||||
*/
|
||||
/*
|
||||
@ -869,6 +885,268 @@ qboolean Cmd_AutocompleteName( const char *source, char *buffer, size_t bufsize
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
Con_AddCommandToList
|
||||
|
||||
===============
|
||||
*/
|
||||
static void Con_AddCommandToList( const char *s, const char *unused1, const char *unused2, void *unused3 )
|
||||
{
|
||||
if( *s == '@' ) return; // never show system cvars or cmds
|
||||
if( con.matchCount >= CON_MAXCMDS ) return; // list is full
|
||||
|
||||
if( Q_strnicmp( s, con.completionString, Q_strlen( con.completionString ) ) )
|
||||
return; // no match
|
||||
|
||||
con.cmds[con.matchCount++] = copystring( s );
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
Con_SortCmds
|
||||
=================
|
||||
*/
|
||||
static int Con_SortCmds( const char **arg1, const char **arg2 )
|
||||
{
|
||||
return Q_stricmp( *arg1, *arg2 );
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
Con_PrintCmdMatches
|
||||
===============
|
||||
*/
|
||||
static void Con_PrintCmdMatches( const char *s, const char *unused1, const char *m, void *unused2 )
|
||||
{
|
||||
if( !Q_strnicmp( s, con.shortestMatch, Q_strlen( con.shortestMatch ) ) )
|
||||
{
|
||||
if( COM_CheckString( m ) ) Con_Printf( " %s ^3\"%s\"\n", s, m );
|
||||
else Con_Printf( " %s\n", s ); // variable or command without description
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
Con_PrintCvarMatches
|
||||
===============
|
||||
*/
|
||||
static void Con_PrintCvarMatches( const char *s, const char *value, const char *m, void *unused2 )
|
||||
{
|
||||
if( !Q_strnicmp( s, con.shortestMatch, Q_strlen( con.shortestMatch ) ) )
|
||||
{
|
||||
if( COM_CheckString( m ) ) Con_Printf( " %s (%s) ^3\"%s\"\n", s, value, m );
|
||||
else Con_Printf( " %s (%s)\n", s, value ); // variable or command without description
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
Con_ConcatRemaining
|
||||
===============
|
||||
*/
|
||||
static void Con_ConcatRemaining( const char *src, const char *start )
|
||||
{
|
||||
const char *arg;
|
||||
int i;
|
||||
|
||||
arg = Q_strstr( src, start );
|
||||
|
||||
if( !arg )
|
||||
{
|
||||
for( i = 1; i < Cmd_Argc(); i++ )
|
||||
{
|
||||
Q_strncat( con.completionField->buffer, " ", sizeof( con.completionField->buffer ) );
|
||||
arg = Cmd_Argv( i );
|
||||
while( *arg )
|
||||
{
|
||||
if( *arg == ' ' )
|
||||
{
|
||||
Q_strncat( con.completionField->buffer, "\"", sizeof( con.completionField->buffer ) );
|
||||
break;
|
||||
}
|
||||
arg++;
|
||||
}
|
||||
|
||||
Q_strncat( con.completionField->buffer, Cmd_Argv( i ), sizeof( con.completionField->buffer ) );
|
||||
if( *arg == ' ' ) Q_strncat( con.completionField->buffer, "\"", sizeof( con.completionField->buffer ) );
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
arg += Q_strlen( start );
|
||||
Q_strncat( con.completionField->buffer, arg, sizeof( con.completionField->buffer ) );
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
Con_CompleteCommand
|
||||
|
||||
perform Tab expansion
|
||||
===============
|
||||
*/
|
||||
void Con_CompleteCommand( field_t *field )
|
||||
{
|
||||
field_t temp;
|
||||
string filename;
|
||||
qboolean nextcmd;
|
||||
int i;
|
||||
|
||||
// setup the completion field
|
||||
con.completionField = field;
|
||||
|
||||
// only look at the first token for completion purposes
|
||||
Cmd_TokenizeString( con.completionField->buffer );
|
||||
|
||||
nextcmd = (con.completionField->buffer[Q_strlen( con.completionField->buffer ) - 1] == ' ') ? true : false;
|
||||
|
||||
con.completionString = Cmd_Argv( 0 );
|
||||
con.completionBuffer = Cmd_Argv( 1 );
|
||||
|
||||
// skip backslash
|
||||
while( *con.completionString && (*con.completionString == '\\' || *con.completionString == '/') )
|
||||
con.completionString++;
|
||||
|
||||
// skip backslash
|
||||
while( *con.completionBuffer && (*con.completionBuffer == '\\' || *con.completionBuffer == '/') )
|
||||
con.completionBuffer++;
|
||||
|
||||
if( !Q_strlen( con.completionString ) )
|
||||
return;
|
||||
|
||||
// free the old autocomplete list
|
||||
for( i = 0; i < con.matchCount; i++ )
|
||||
{
|
||||
if( con.cmds[i] != NULL )
|
||||
{
|
||||
Mem_Free( con.cmds[i] );
|
||||
con.cmds[i] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
con.matchCount = 0;
|
||||
con.shortestMatch[0] = 0;
|
||||
|
||||
// find matching commands and variables
|
||||
Cmd_LookupCmds( NULL, NULL, Con_AddCommandToList );
|
||||
Cvar_LookupVars( 0, NULL, NULL, Con_AddCommandToList );
|
||||
|
||||
if( !con.matchCount ) return; // no matches
|
||||
|
||||
memcpy( &temp, con.completionField, sizeof( field_t ) );
|
||||
|
||||
// autocomplete second arg
|
||||
if( (Cmd_Argc() == 2) || ((Cmd_Argc() == 1) && nextcmd) )
|
||||
{
|
||||
if( !Q_strlen( con.completionBuffer ) )
|
||||
return;
|
||||
|
||||
if( Cmd_AutocompleteName( con.completionBuffer, filename, sizeof( filename ) ) )
|
||||
{
|
||||
Q_sprintf( con.completionField->buffer, "%s %s", Cmd_Argv( 0 ), filename );
|
||||
con.completionField->cursor = Q_strlen( con.completionField->buffer );
|
||||
}
|
||||
|
||||
// don't adjusting cursor pos if we nothing found
|
||||
return;
|
||||
}
|
||||
else if( Cmd_Argc() >= 3 )
|
||||
{
|
||||
// disable autocomplete for all next args
|
||||
return;
|
||||
}
|
||||
|
||||
if( con.matchCount == 1 )
|
||||
{
|
||||
Q_sprintf( con.completionField->buffer, "\\%s", con.cmds[0] );
|
||||
if( Cmd_Argc() == 1 ) Q_strncat( con.completionField->buffer, " ", sizeof( con.completionField->buffer ) );
|
||||
else Con_ConcatRemaining( temp.buffer, con.completionString );
|
||||
con.completionField->cursor = Q_strlen( con.completionField->buffer );
|
||||
}
|
||||
else
|
||||
{
|
||||
char *first, *last;
|
||||
int len = 0;
|
||||
|
||||
qsort( con.cmds, con.matchCount, sizeof( char* ), Con_SortCmds );
|
||||
|
||||
// find the number of matching characters between the first and
|
||||
// the last element in the list and copy it
|
||||
first = con.cmds[0];
|
||||
last = con.cmds[con.matchCount - 1];
|
||||
|
||||
while( *first && *last && Q_tolower( *first ) == Q_tolower( *last ) )
|
||||
{
|
||||
first++;
|
||||
last++;
|
||||
|
||||
con.shortestMatch[len] = con.cmds[0][len];
|
||||
len++;
|
||||
}
|
||||
con.shortestMatch[len] = 0;
|
||||
|
||||
// multiple matches, complete to shortest
|
||||
Q_sprintf( con.completionField->buffer, "\\%s", con.shortestMatch );
|
||||
con.completionField->cursor = Q_strlen( con.completionField->buffer );
|
||||
Con_ConcatRemaining( temp.buffer, con.completionString );
|
||||
|
||||
Con_Printf( "]%s\n", con.completionField->buffer );
|
||||
|
||||
// run through again, printing matches
|
||||
Cmd_LookupCmds( NULL, NULL, Con_PrintCmdMatches );
|
||||
Cvar_LookupVars( 0, NULL, NULL, Con_PrintCvarMatches );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
=========
|
||||
Cmd_AutoComplete
|
||||
|
||||
NOTE: input string must be equal or longer than MAX_STRING
|
||||
=========
|
||||
*/
|
||||
void Cmd_AutoComplete( char *complete_string )
|
||||
{
|
||||
field_t input;
|
||||
|
||||
if( !complete_string || !*complete_string )
|
||||
return;
|
||||
|
||||
// setup input
|
||||
Q_strncpy( input.buffer, complete_string, sizeof( input.buffer ) );
|
||||
input.cursor = input.scroll = 0;
|
||||
|
||||
Con_CompleteCommand( &input );
|
||||
|
||||
// setup output
|
||||
if( input.buffer[0] == '\\' || input.buffer[0] == '/' )
|
||||
Q_strncpy( complete_string, input.buffer + 1, sizeof( input.buffer ) );
|
||||
else Q_strncpy( complete_string, input.buffer, sizeof( input.buffer ) );
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
Cmd_AutoCompleteClear
|
||||
|
||||
============
|
||||
*/
|
||||
void Cmd_AutoCompleteClear( void )
|
||||
{
|
||||
int i;
|
||||
|
||||
// free the old autocomplete list
|
||||
for( i = 0; i < con.matchCount; i++ )
|
||||
{
|
||||
if( con.cmds[i] != NULL )
|
||||
{
|
||||
Mem_Free( con.cmds[i] );
|
||||
con.cmds[i] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
con.matchCount = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
Cmd_WriteVariables
|
||||
|
Loading…
x
Reference in New Issue
Block a user