* Unconditionally place a '\' at the start of the command buffer when

autocompleting -- you're still all WRONG :p
* Fix bugette where the completee didn't get its case copied from
  the completed token
* Add functionality to autocomplete key names
* Don't build client command completion on the dedicated server
This commit is contained in:
Tim Angus 2007-10-12 22:34:45 +00:00
parent 66b31c94b9
commit aa5e852056
3 changed files with 105 additions and 38 deletions

View file

@ -1062,6 +1062,18 @@ void Key_Bindlist_f( void ) {
} }
} }
/*
============
Key_KeynameCompletion
============
*/
void Key_KeynameCompletion( void(*callback)(const char *s) ) {
int i;
for( i = 0; keynames[ i ].name != NULL; i++ )
callback( keynames[ i ].name );
}
/* /*
=================== ===================
CL_InitKeyCommands CL_InitKeyCommands

View file

@ -3085,6 +3085,40 @@ static char *Field_FindFirstSeparator( char *s )
return NULL; return NULL;
} }
#ifndef DEDICATED
/*
===============
Field_CompleteKeyname
===============
*/
static void Field_CompleteKeyname( void )
{
matchCount = 0;
shortestMatch[ 0 ] = 0;
Key_KeynameCompletion( FindMatches );
if( matchCount == 0 )
return;
Q_strncpyz( &completionField->buffer[ strlen( completionField->buffer ) -
strlen( completionString ) ], shortestMatch,
sizeof( completionField->buffer ) );
completionField->cursor = strlen( completionField->buffer );
if( matchCount == 1 )
{
Q_strcat( completionField->buffer, sizeof( completionField->buffer ), " " );
completionField->cursor++;
return;
}
Com_Printf( "]%s\n", completionField->buffer );
Key_KeynameCompletion( PrintMatches );
}
#endif
/* /*
=============== ===============
Field_CompleteFilename Field_CompleteFilename
@ -3101,8 +3135,9 @@ static void Field_CompleteFilename( const char *dir,
if( matchCount == 0 ) if( matchCount == 0 )
return; return;
Q_strcat( completionField->buffer, sizeof( completionField->buffer ), Q_strncpyz( &completionField->buffer[ strlen( completionField->buffer ) -
shortestMatch + strlen( completionString ) ); strlen( completionString ) ], shortestMatch,
sizeof( completionField->buffer ) );
completionField->cursor = strlen( completionField->buffer ); completionField->cursor = strlen( completionField->buffer );
if( matchCount == 1 ) if( matchCount == 1 )
@ -3143,20 +3178,36 @@ static void Field_CompleteCommand( char *cmd,
else else
completionString = Cmd_Argv( completionArgument - 1 ); completionString = Cmd_Argv( completionArgument - 1 );
#ifndef DEDICATED
// Unconditionally add a '\' to the start of the buffer
if( completionField->buffer[ 0 ] &&
completionField->buffer[ 0 ] != '\\' )
{
if( completionField->buffer[ 0 ] != '/' )
{
// Buffer is full, refuse to complete
if( strlen( completionField->buffer ) + 1 >=
sizeof( completionField->buffer ) )
return;
memmove( &completionField->buffer[ 1 ],
&completionField->buffer[ 0 ],
strlen( completionField->buffer ) + 1 );
completionField->cursor++;
}
completionField->buffer[ 0 ] = '\\';
}
#endif
if( completionArgument > 1 ) if( completionArgument > 1 )
{ {
const char *baseCmd = Cmd_Argv( 0 ); const char *baseCmd = Cmd_Argv( 0 );
#ifndef DEDICATED #ifndef DEDICATED
// If the very first token does not have a leading \ or /, // This should always be true
// refuse to autocomplete if( baseCmd[ 0 ] == '\\' || baseCmd[ 0 ] == '/' )
if( cmd == completionField->buffer )
{
if( baseCmd[ 0 ] != '\\' && baseCmd[ 0 ] != '/' )
return;
baseCmd++; baseCmd++;
}
#endif #endif
if( ( p = Field_FindFirstSeparator( cmd ) ) ) if( ( p = Field_FindFirstSeparator( cmd ) ) )
@ -3187,13 +3238,6 @@ static void Field_CompleteCommand( char *cmd,
{ {
Field_CompleteFilename( "", "txt", qfalse ); Field_CompleteFilename( "", "txt", qfalse );
} }
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, "toggle" ) || else if( ( !Q_stricmp( baseCmd, "toggle" ) ||
!Q_stricmp( baseCmd, "vstr" ) || !Q_stricmp( baseCmd, "vstr" ) ||
!Q_stricmp( baseCmd, "set" ) || !Q_stricmp( baseCmd, "set" ) ||
@ -3208,6 +3252,14 @@ static void Field_CompleteCommand( char *cmd,
if( p > cmd ) if( p > cmd )
Field_CompleteCommand( p, qfalse, qtrue ); 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 ) else if( !Q_stricmp( baseCmd, "rcon" ) && completionArgument == 2 )
{ {
// Skip "rcon " // Skip "rcon "
@ -3216,14 +3268,26 @@ static void Field_CompleteCommand( char *cmd,
if( p > cmd ) if( p > cmd )
Field_CompleteCommand( p, qtrue, qtrue ); Field_CompleteCommand( p, qtrue, qtrue );
} }
else if( !Q_stricmp( baseCmd, "bind" ) && completionArgument >= 3 ) else if( !Q_stricmp( baseCmd, "bind" ) )
{ {
// Skip "bind <key> " if( completionArgument == 2 )
p = Com_SkipTokens( cmd, 2, " " ); {
// Skip "bind "
p = Com_SkipTokens( cmd, 1, " " );
if( p > cmd ) if( p > cmd )
Field_CompleteCommand( p, qtrue, qtrue ); Field_CompleteKeyname( );
}
else if( completionArgument >= 3 )
{
// Skip "bind <key> "
p = Com_SkipTokens( cmd, 2, " " );
if( p > cmd )
Field_CompleteCommand( p, qtrue, qtrue );
}
} }
#endif
} }
} }
else else
@ -3244,23 +3308,11 @@ static void Field_CompleteCommand( char *cmd,
Cvar_CommandCompletion( FindMatches ); Cvar_CommandCompletion( FindMatches );
if( matchCount == 0 ) if( matchCount == 0 )
return; // no matches return; // no matches
if( cmd == completionField->buffer ) Q_strncpyz( &completionField->buffer[ strlen( completionField->buffer ) -
{ strlen( completionString ) ], shortestMatch,
#ifndef DEDICATED sizeof( completionField->buffer ) );
Com_sprintf( completionField->buffer,
sizeof( completionField->buffer ), "\\%s", shortestMatch );
#else
Com_sprintf( completionField->buffer,
sizeof( completionField->buffer ), "%s", shortestMatch );
#endif
}
else
{
Q_strcat( completionField->buffer, sizeof( completionField->buffer ),
shortestMatch + strlen( completionString ) );
}
completionField->cursor = strlen( completionField->buffer ); completionField->cursor = strlen( completionField->buffer );

View file

@ -926,6 +926,9 @@ void CL_FlushMemory( void );
void CL_StartHunkUsers( qboolean rendererOnly ); void CL_StartHunkUsers( qboolean rendererOnly );
// start all the client stuff using the hunk // start all the client stuff using the hunk
void Key_KeynameCompletion( void(*callback)(const char *s) );
// for keyname autocompletion
void Key_WriteBindings( fileHandle_t f ); void Key_WriteBindings( fileHandle_t f );
// for writing the config files // for writing the config files