* 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

View file

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

View file

@ -926,6 +926,9 @@ void CL_FlushMemory( void );
void CL_StartHunkUsers( qboolean rendererOnly );
// 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 );
// for writing the config files