mirror of
https://github.com/ioquake/ioq3.git
synced 2024-11-10 07:11:46 +00:00
* Move command argument completion from being hard coded to being associated
with the individual commands to be completed
This commit is contained in:
parent
47ee177430
commit
130c0c6575
8 changed files with 195 additions and 89 deletions
|
@ -302,6 +302,17 @@ void Con_CheckResize (void)
|
|||
con.display = con.current;
|
||||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
Cmd_CompleteTxtName
|
||||
==================
|
||||
*/
|
||||
void Cmd_CompleteTxtName( char *args, int argNum ) {
|
||||
if( argNum == 2 ) {
|
||||
Field_CompleteFilename( "", "txt", qfalse );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
================
|
||||
|
@ -329,6 +340,7 @@ void Con_Init (void) {
|
|||
Cmd_AddCommand ("messagemode4", Con_MessageMode4_f);
|
||||
Cmd_AddCommand ("clear", Con_Clear_f);
|
||||
Cmd_AddCommand ("condump", Con_Dump_f);
|
||||
Cmd_SetCommandCompletionFunc( "condump", Cmd_CompleteTxtName );
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1057,6 +1057,50 @@ void Key_KeynameCompletion( void(*callback)(const char *s) ) {
|
|||
callback( keynames[ i ].name );
|
||||
}
|
||||
|
||||
/*
|
||||
====================
|
||||
Key_CompleteUnbind
|
||||
====================
|
||||
*/
|
||||
static void Key_CompleteUnbind( char *args, int argNum )
|
||||
{
|
||||
if( argNum == 2 )
|
||||
{
|
||||
// Skip "unbind "
|
||||
char *p = Com_SkipTokens( args, 1, " " );
|
||||
|
||||
if( p > args )
|
||||
Field_CompleteKeyname( );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
====================
|
||||
Key_CompleteBind
|
||||
====================
|
||||
*/
|
||||
static void Key_CompleteBind( char *args, int argNum )
|
||||
{
|
||||
char *p;
|
||||
|
||||
if( argNum == 2 )
|
||||
{
|
||||
// Skip "bind "
|
||||
p = Com_SkipTokens( args, 1, " " );
|
||||
|
||||
if( p > args )
|
||||
Field_CompleteKeyname( );
|
||||
}
|
||||
else if( argNum >= 3 )
|
||||
{
|
||||
// Skip "bind <key> "
|
||||
p = Com_SkipTokens( args, 2, " " );
|
||||
|
||||
if( p > args )
|
||||
Field_CompleteCommand( p, qtrue, qtrue );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
===================
|
||||
CL_InitKeyCommands
|
||||
|
@ -1065,7 +1109,9 @@ CL_InitKeyCommands
|
|||
void CL_InitKeyCommands( void ) {
|
||||
// register our functions
|
||||
Cmd_AddCommand ("bind",Key_Bind_f);
|
||||
Cmd_SetCommandCompletionFunc( "bind", Key_CompleteBind );
|
||||
Cmd_AddCommand ("unbind",Key_Unbind_f);
|
||||
Cmd_SetCommandCompletionFunc( "unbind", Key_CompleteUnbind );
|
||||
Cmd_AddCommand ("unbindall",Key_Unbindall_f);
|
||||
Cmd_AddCommand ("bindlist",Key_Bindlist_f);
|
||||
}
|
||||
|
|
|
@ -870,6 +870,22 @@ static void CL_WalkDemoExt(char *arg, char *name, int *demofile)
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
====================
|
||||
CL_CompleteDemoName
|
||||
====================
|
||||
*/
|
||||
static void CL_CompleteDemoName( char *args, int argNum )
|
||||
{
|
||||
if( argNum == 2 )
|
||||
{
|
||||
char demoExt[ 16 ];
|
||||
|
||||
Com_sprintf( demoExt, sizeof( demoExt ), ".dm_%d", PROTOCOL_VERSION );
|
||||
Field_CompleteFilename( "demos", demoExt, qtrue );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
====================
|
||||
CL_PlayDemo_f
|
||||
|
@ -1565,6 +1581,23 @@ void CL_Connect_f( void ) {
|
|||
|
||||
#define MAX_RCON_MESSAGE 1024
|
||||
|
||||
/*
|
||||
==================
|
||||
CL_CompleteRcon
|
||||
==================
|
||||
*/
|
||||
static void CL_CompleteRcon( char *args, int argNum )
|
||||
{
|
||||
if( argNum == 2 )
|
||||
{
|
||||
// Skip "rcon "
|
||||
char *p = Com_SkipTokens( args, 1, " " );
|
||||
|
||||
if( p > args )
|
||||
Field_CompleteCommand( p, qtrue, qtrue );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
=====================
|
||||
CL_Rcon_f
|
||||
|
@ -3150,6 +3183,7 @@ void CL_Init( void ) {
|
|||
Cmd_AddCommand ("disconnect", CL_Disconnect_f);
|
||||
Cmd_AddCommand ("record", CL_Record_f);
|
||||
Cmd_AddCommand ("demo", CL_PlayDemo_f);
|
||||
Cmd_SetCommandCompletionFunc( "demo", CL_CompleteDemoName );
|
||||
Cmd_AddCommand ("cinematic", CL_PlayCinematic_f);
|
||||
Cmd_AddCommand ("stoprecord", CL_StopRecord_f);
|
||||
Cmd_AddCommand ("connect", CL_Connect_f);
|
||||
|
@ -3157,6 +3191,7 @@ void CL_Init( void ) {
|
|||
Cmd_AddCommand ("localservers", CL_LocalServers_f);
|
||||
Cmd_AddCommand ("globalservers", CL_GlobalServers_f);
|
||||
Cmd_AddCommand ("rcon", CL_Rcon_f);
|
||||
Cmd_SetCommandCompletionFunc( "rcon", CL_CompleteRcon );
|
||||
Cmd_AddCommand ("setenv", CL_Setenv_f );
|
||||
Cmd_AddCommand ("ping", CL_Ping_f );
|
||||
Cmd_AddCommand ("serverstatus", CL_ServerStatus_f );
|
||||
|
|
|
@ -313,6 +313,7 @@ typedef struct cmd_function_s
|
|||
struct cmd_function_s *next;
|
||||
char *name;
|
||||
xcommand_t function;
|
||||
completionFunc_t complete;
|
||||
} cmd_function_t;
|
||||
|
||||
|
||||
|
@ -584,10 +585,26 @@ void Cmd_AddCommand( const char *cmd_name, xcommand_t function ) {
|
|||
cmd = S_Malloc (sizeof(cmd_function_t));
|
||||
cmd->name = CopyString( cmd_name );
|
||||
cmd->function = function;
|
||||
cmd->complete = NULL;
|
||||
cmd->next = cmd_functions;
|
||||
cmd_functions = cmd;
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
Cmd_SetCommandCompletionFunc
|
||||
============
|
||||
*/
|
||||
void Cmd_SetCommandCompletionFunc( const char *command, completionFunc_t complete ) {
|
||||
cmd_function_t *cmd;
|
||||
|
||||
for( cmd = cmd_functions; cmd; cmd = cmd->next ) {
|
||||
if( !Q_stricmp( command, cmd->name ) ) {
|
||||
cmd->complete = complete;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
Cmd_RemoveCommand
|
||||
|
@ -629,6 +646,21 @@ void Cmd_CommandCompletion( void(*callback)(const char *s) ) {
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
Cmd_CompleteArgument
|
||||
============
|
||||
*/
|
||||
void Cmd_CompleteArgument( const char *command, char *args, int argNum ) {
|
||||
cmd_function_t *cmd;
|
||||
|
||||
for( cmd = cmd_functions; cmd; cmd = cmd->next ) {
|
||||
if( !Q_stricmp( command, cmd->name ) && cmd->complete ) {
|
||||
cmd->complete( args, argNum );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
============
|
||||
|
@ -719,6 +751,17 @@ void Cmd_List_f (void)
|
|||
Com_Printf ("%i commands\n", i);
|
||||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
Cmd_CompleteCfgName
|
||||
==================
|
||||
*/
|
||||
void Cmd_CompleteCfgName( char *args, int argNum ) {
|
||||
if( argNum == 2 ) {
|
||||
Field_CompleteFilename( "", "cfg", qfalse );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
Cmd_Init
|
||||
|
@ -727,7 +770,9 @@ Cmd_Init
|
|||
void Cmd_Init (void) {
|
||||
Cmd_AddCommand ("cmdlist",Cmd_List_f);
|
||||
Cmd_AddCommand ("exec",Cmd_Exec_f);
|
||||
Cmd_SetCommandCompletionFunc( "exec", Cmd_CompleteCfgName );
|
||||
Cmd_AddCommand ("vstr",Cmd_Vstr_f);
|
||||
Cmd_SetCommandCompletionFunc( "vstr", Cvar_CompleteCvarName );
|
||||
Cmd_AddCommand ("echo",Cmd_Echo_f);
|
||||
Cmd_AddCommand ("wait", Cmd_Wait_f);
|
||||
}
|
||||
|
|
|
@ -2621,6 +2621,7 @@ void Com_Init( char *commandLine ) {
|
|||
Cmd_AddCommand ("quit", Com_Quit_f);
|
||||
Cmd_AddCommand ("changeVectors", MSG_ReportChangeVectors_f );
|
||||
Cmd_AddCommand ("writeconfig", Com_WriteConfig_f );
|
||||
Cmd_SetCommandCompletionFunc( "writeconfig", Cmd_CompleteCfgName );
|
||||
|
||||
s = va("%s %s %s", Q3_VERSION, PLATFORM_STRING, __DATE__ );
|
||||
com_version = Cvar_Get ("version", s, CVAR_ROM | CVAR_SERVERINFO );
|
||||
|
@ -3168,7 +3169,7 @@ static qboolean Field_Complete( void )
|
|||
Field_CompleteKeyname
|
||||
===============
|
||||
*/
|
||||
static void Field_CompleteKeyname( void )
|
||||
void Field_CompleteKeyname( void )
|
||||
{
|
||||
matchCount = 0;
|
||||
shortestMatch[ 0 ] = 0;
|
||||
|
@ -3185,7 +3186,7 @@ static void Field_CompleteKeyname( void )
|
|||
Field_CompleteFilename
|
||||
===============
|
||||
*/
|
||||
static void Field_CompleteFilename( const char *dir,
|
||||
void Field_CompleteFilename( const char *dir,
|
||||
const char *ext, qboolean stripExt )
|
||||
{
|
||||
matchCount = 0;
|
||||
|
@ -3202,11 +3203,10 @@ static void Field_CompleteFilename( const char *dir,
|
|||
Field_CompleteCommand
|
||||
===============
|
||||
*/
|
||||
static void Field_CompleteCommand( char *cmd,
|
||||
void Field_CompleteCommand( char *cmd,
|
||||
qboolean doCommands, qboolean doCvars )
|
||||
{
|
||||
int completionArgument = 0;
|
||||
char *p;
|
||||
|
||||
// Skip leading whitespace and quotes
|
||||
cmd = Com_SkipCharset( cmd, " \"" );
|
||||
|
@ -3248,6 +3248,7 @@ static void Field_CompleteCommand( char *cmd,
|
|||
if( completionArgument > 1 )
|
||||
{
|
||||
const char *baseCmd = Cmd_Argv( 0 );
|
||||
char *p;
|
||||
|
||||
#ifndef DEDICATED
|
||||
// This should always be true
|
||||
|
@ -3256,92 +3257,9 @@ static void Field_CompleteCommand( char *cmd,
|
|||
#endif
|
||||
|
||||
if( ( p = Field_FindFirstSeparator( cmd ) ) )
|
||||
{
|
||||
// Compound command
|
||||
Field_CompleteCommand( p + 1, qtrue, qtrue );
|
||||
}
|
||||
Field_CompleteCommand( p + 1, qtrue, qtrue ); // Compound command
|
||||
else
|
||||
{
|
||||
// FIXME: all this junk should really be associated with the respective
|
||||
// commands, instead of being hard coded here
|
||||
if( ( !Q_stricmp( baseCmd, "map" ) ||
|
||||
!Q_stricmp( baseCmd, "devmap" ) ||
|
||||
!Q_stricmp( baseCmd, "spmap" ) ||
|
||||
!Q_stricmp( baseCmd, "spdevmap" ) ) &&
|
||||
completionArgument == 2 )
|
||||
{
|
||||
Field_CompleteFilename( "maps", "bsp", qtrue );
|
||||
}
|
||||
else if( ( !Q_stricmp( baseCmd, "exec" ) ||
|
||||
!Q_stricmp( baseCmd, "writeconfig" ) ) &&
|
||||
completionArgument == 2 )
|
||||
{
|
||||
Field_CompleteFilename( "", "cfg", qfalse );
|
||||
}
|
||||
else if( !Q_stricmp( baseCmd, "condump" ) &&
|
||||
completionArgument == 2 )
|
||||
{
|
||||
Field_CompleteFilename( "", "txt", qfalse );
|
||||
}
|
||||
else if( ( !Q_stricmp( baseCmd, "toggle" ) ||
|
||||
!Q_stricmp( baseCmd, "vstr" ) ||
|
||||
!Q_stricmp( baseCmd, "set" ) ||
|
||||
!Q_stricmp( baseCmd, "seta" ) ||
|
||||
!Q_stricmp( baseCmd, "setu" ) ||
|
||||
!Q_stricmp( baseCmd, "sets" ) ) &&
|
||||
completionArgument == 2 )
|
||||
{
|
||||
// Skip "<cmd> "
|
||||
p = Com_SkipTokens( cmd, 1, " " );
|
||||
|
||||
if( p > cmd )
|
||||
Field_CompleteCommand( p, qfalse, qtrue );
|
||||
}
|
||||
#ifndef DEDICATED
|
||||
else if( !Q_stricmp( baseCmd, "demo" ) && completionArgument == 2 )
|
||||
{
|
||||
char demoExt[ 16 ];
|
||||
|
||||
Com_sprintf( demoExt, sizeof( demoExt ), ".dm_%d", PROTOCOL_VERSION );
|
||||
Field_CompleteFilename( "demos", demoExt, qtrue );
|
||||
}
|
||||
else if( !Q_stricmp( baseCmd, "rcon" ) && completionArgument == 2 )
|
||||
{
|
||||
// Skip "rcon "
|
||||
p = Com_SkipTokens( cmd, 1, " " );
|
||||
|
||||
if( p > cmd )
|
||||
Field_CompleteCommand( p, qtrue, qtrue );
|
||||
}
|
||||
else if( !Q_stricmp( baseCmd, "bind" ) )
|
||||
{
|
||||
if( completionArgument == 2 )
|
||||
{
|
||||
// Skip "bind "
|
||||
p = Com_SkipTokens( cmd, 1, " " );
|
||||
|
||||
if( p > cmd )
|
||||
Field_CompleteKeyname( );
|
||||
}
|
||||
else if( completionArgument >= 3 )
|
||||
{
|
||||
// Skip "bind <key> "
|
||||
p = Com_SkipTokens( cmd, 2, " " );
|
||||
|
||||
if( p > cmd )
|
||||
Field_CompleteCommand( p, qtrue, qtrue );
|
||||
}
|
||||
}
|
||||
else if( !Q_stricmp( baseCmd, "unbind" ) && completionArgument == 2 )
|
||||
{
|
||||
// Skip "unbind "
|
||||
p = Com_SkipTokens( cmd, 1, " " );
|
||||
|
||||
if( p > cmd )
|
||||
Field_CompleteKeyname( );
|
||||
}
|
||||
#endif
|
||||
}
|
||||
Cmd_CompleteArgument( baseCmd, cmd, completionArgument );
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -1055,6 +1055,22 @@ void Cvar_Update( vmCvar_t *vmCvar ) {
|
|||
vmCvar->integer = cv->integer;
|
||||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
Cvar_CompleteCvarName
|
||||
==================
|
||||
*/
|
||||
void Cvar_CompleteCvarName( char *args, int argNum )
|
||||
{
|
||||
if( argNum == 2 )
|
||||
{
|
||||
// Skip "<cmd> "
|
||||
char *p = Com_SkipTokens( args, 1, " " );
|
||||
|
||||
if( p > args )
|
||||
Field_CompleteCommand( p, qfalse, qtrue );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
|
@ -1068,11 +1084,17 @@ void Cvar_Init (void) {
|
|||
|
||||
Cmd_AddCommand ("print", Cvar_Print_f);
|
||||
Cmd_AddCommand ("toggle", Cvar_Toggle_f);
|
||||
Cmd_SetCommandCompletionFunc( "toggle", Cvar_CompleteCvarName );
|
||||
Cmd_AddCommand ("set", Cvar_Set_f);
|
||||
Cmd_SetCommandCompletionFunc( "set", Cvar_CompleteCvarName );
|
||||
Cmd_AddCommand ("sets", Cvar_Set_f);
|
||||
Cmd_SetCommandCompletionFunc( "sets", Cvar_CompleteCvarName );
|
||||
Cmd_AddCommand ("setu", Cvar_Set_f);
|
||||
Cmd_SetCommandCompletionFunc( "setu", Cvar_CompleteCvarName );
|
||||
Cmd_AddCommand ("seta", Cvar_Set_f);
|
||||
Cmd_SetCommandCompletionFunc( "seta", Cvar_CompleteCvarName );
|
||||
Cmd_AddCommand ("reset", Cvar_Reset_f);
|
||||
Cmd_SetCommandCompletionFunc( "reset", Cvar_CompleteCvarName );
|
||||
Cmd_AddCommand ("cvarlist", Cvar_List_f);
|
||||
Cmd_AddCommand ("cvar_restart", Cvar_Restart_f);
|
||||
}
|
||||
|
|
|
@ -421,8 +421,14 @@ void Cmd_AddCommand( const char *cmd_name, xcommand_t function );
|
|||
|
||||
void Cmd_RemoveCommand( const char *cmd_name );
|
||||
|
||||
typedef void (*completionFunc_t)( char *args, int argNum );
|
||||
|
||||
void Cmd_CommandCompletion( void(*callback)(const char *s) );
|
||||
// callback with each valid string
|
||||
void Cmd_SetCommandCompletionFunc( const char *command,
|
||||
completionFunc_t complete );
|
||||
void Cmd_CompleteArgument( const char *command, char *args, int argNum );
|
||||
void Cmd_CompleteCfgName( char *args, int argNum );
|
||||
|
||||
int Cmd_Argc (void);
|
||||
char *Cmd_Argv (int arg);
|
||||
|
@ -533,6 +539,8 @@ void Cvar_CheckRange( cvar_t *cv, float minVal, float maxVal, qboolean shouldBeI
|
|||
|
||||
void Cvar_Restart_f( void );
|
||||
|
||||
void Cvar_CompleteCvarName( char *args, int argNum );
|
||||
|
||||
extern int cvar_modifiedFlags;
|
||||
// whenever a cvar is modifed, its flags will be OR'd into this, so
|
||||
// a single check can determine if any CVAR_USERINFO, CVAR_SERVERINFO,
|
||||
|
@ -712,6 +720,11 @@ typedef struct {
|
|||
|
||||
void Field_Clear( field_t *edit );
|
||||
void Field_AutoComplete( field_t *edit );
|
||||
void Field_CompleteKeyname( void );
|
||||
void Field_CompleteFilename( const char *dir,
|
||||
const char *ext, qboolean stripExt );
|
||||
void Field_CompleteCommand( char *cmd,
|
||||
qboolean doCommands, qboolean doCvars );
|
||||
|
||||
/*
|
||||
==============================================================
|
||||
|
|
|
@ -1051,6 +1051,17 @@ static void SV_KillServer_f( void ) {
|
|||
|
||||
//===========================================================
|
||||
|
||||
/*
|
||||
==================
|
||||
SV_CompleteMapName
|
||||
==================
|
||||
*/
|
||||
static void SV_CompleteMapName( char *args, int argNum ) {
|
||||
if( argNum == 2 ) {
|
||||
Field_CompleteFilename( "maps", "bsp", qtrue );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
SV_AddOperatorCommands
|
||||
|
@ -1081,10 +1092,14 @@ void SV_AddOperatorCommands( void ) {
|
|||
Cmd_AddCommand ("map_restart", SV_MapRestart_f);
|
||||
Cmd_AddCommand ("sectorlist", SV_SectorList_f);
|
||||
Cmd_AddCommand ("map", SV_Map_f);
|
||||
Cmd_SetCommandCompletionFunc( "map", SV_CompleteMapName );
|
||||
#ifndef PRE_RELEASE_DEMO
|
||||
Cmd_AddCommand ("devmap", SV_Map_f);
|
||||
Cmd_SetCommandCompletionFunc( "devmap", SV_CompleteMapName );
|
||||
Cmd_AddCommand ("spmap", SV_Map_f);
|
||||
Cmd_SetCommandCompletionFunc( "spmap", SV_CompleteMapName );
|
||||
Cmd_AddCommand ("spdevmap", SV_Map_f);
|
||||
Cmd_SetCommandCompletionFunc( "spdevmap", SV_CompleteMapName );
|
||||
#endif
|
||||
Cmd_AddCommand ("killserver", SV_KillServer_f);
|
||||
if( com_dedicated->integer ) {
|
||||
|
|
Loading…
Reference in a new issue