summaryrefslogtreecommitdiff
path: root/source/prompt.c
diff options
context:
space:
mode:
Diffstat (limited to 'source/prompt.c')
-rw-r--r--source/prompt.c213
1 files changed, 69 insertions, 144 deletions
diff --git a/source/prompt.c b/source/prompt.c
index 0c92ae3..ca058fd 100644
--- a/source/prompt.c
+++ b/source/prompt.c
@@ -26,79 +26,9 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "q_field.h"
#include "prompt.h"
-static char *matches[MAX_MATCHES];
-static char *sortedMatches[MAX_MATCHES];
-static int numMatches;
-static int numCommands;
-static int numCvars;
-static int numAliases;
-
static cvar_t *com_completion_mode;
static cvar_t *com_completion_treshold;
-/*
-====================
-Prompt_FreeMatches
-====================
-*/
-static void Prompt_FreeMatches( void ) {
- int i;
-
- // free them
- for( i = 0; i < numMatches; i++ ) {
- Z_Free( matches[i] );
- }
-
- numMatches = 0;
- numCommands = 0;
- numCvars = 0;
- numAliases = 0;
-
-}
-
-static void Prompt_RunCompleter( xcompleter_t completer, const char *partial, int argnum ) {
- const char *match;
-
- match = (*completer)( partial, argnum, 0 );
- while( match ) {
- matches[numMatches++] = Z_CopyString( match );
- if( numMatches == MAX_MATCHES ) {
- (*completer)( partial, argnum, 2 );
- return;
- }
- match = (*completer)( partial, argnum, 1 );
- }
-}
-
-static void Prompt_RunGenerator( xgenerator_t generator, const char *partial ) {
- const char *match;
-
- match = (*generator)( partial, 0 );
- while( match ) {
- matches[numMatches++] = Z_CopyString( match );
- if( numMatches == MAX_MATCHES ) {
- (*generator)( partial, 2 );
- return;
- }
- match = (*generator)( partial, 1 );
- }
-}
-
-static void Prompt_GenerateMatches( const char *partial ) {
- Prompt_RunGenerator( Cmd_CommandGenerator, partial );
- numCommands = numMatches;
-
- if( numMatches != MAX_MATCHES ) {
- Prompt_RunGenerator( Cvar_Generator, partial );
- numCvars = numMatches - numCommands;
-
- if( numMatches != MAX_MATCHES ) {
- Prompt_RunGenerator( Cmd_AliasGenerator, partial );
- numAliases = numMatches - numCvars - numCommands;
- }
- }
-}
-
static void Prompt_ShowMatches( commandPrompt_t *prompt, char **matches,
int start, int end )
{
@@ -152,75 +82,54 @@ static void Prompt_ShowMatches( commandPrompt_t *prompt, char **matches,
}
-static void Prompt_ShowIndividualMatches( commandPrompt_t *prompt ) {
+static void Prompt_ShowIndividualMatches(
+ commandPrompt_t *prompt,
+ char **matches,
+ int numCommands,
+ int numAliases,
+ int numCvars )
+{
int offset = 0;
if( numCommands ) {
- qsort( matches + offset, numCommands,
- sizeof( matches[0] ), SortStrcmp );
+ qsort( matches + offset, numCommands, sizeof( matches[0] ), SortStrcmp );
prompt->printf( "\n" S_COLOR_YELLOW "%i possible command%s:\n",
- numCommands, ( numCommands % 10 ) != 1 ? "s" : "" );
+ numCommands, numCommands != 1 ? "s" : "" );
Prompt_ShowMatches( prompt, matches, offset, offset + numCommands );
offset += numCommands;
}
if( numCvars ) {
- qsort( matches + offset, numCvars,
- sizeof( matches[0] ), SortStrcmp );
+ qsort( matches + offset, numCvars, sizeof( matches[0] ), SortStrcmp );
prompt->printf( "\n" S_COLOR_YELLOW "%i possible variable%s:\n",
- numCvars, ( numCvars % 10 ) != 1 ? "s" : "" );
+ numCvars, numCvars != 1 ? "s" : "" );
Prompt_ShowMatches( prompt, matches, offset, offset + numCvars );
offset += numCvars;
}
if( numAliases ) {
- qsort( matches + offset, numAliases,
- sizeof( matches[0] ), SortStrcmp );
+ qsort( matches + offset, numAliases, sizeof( matches[0] ), SortStrcmp );
prompt->printf( "\n" S_COLOR_YELLOW "%i possible alias%s:\n",
- numAliases, ( numAliases % 10 ) != 1 ? "es" : "" );
+ numAliases, numAliases != 1 ? "es" : "" );
Prompt_ShowMatches( prompt, matches, offset, offset + numAliases );
offset += numAliases;
}
}
-const char *Prompt_Completer( const char *partial, int firstarg, int argnum, int state ) {
- static xcompleter_t completer;
- static xgenerator_t generator;
- int relative = argnum - firstarg;
-
- if( relative < 0 ) {
- return NULL;
+qboolean Prompt_AddMatch( genctx_t *ctx, const char *s ) {
+ if( ctx->count >= ctx->size ) {
+ return qfalse;
}
-
- if( !state ) {
- if( relative > 0 ) {
- char *s = Cmd_Argv( firstarg );
-
- generator = NULL;
- completer = Cmd_FindCompleter( s );
- if( !completer && relative == 1 ) {
- cvar_t *v = Cvar_FindVar( s );
- generator = v->generator;
- }
- } else {
- completer = NULL;
- generator = Cmd_MixedGenerator;
- }
- }
-
- if( completer ) {
- return (*completer)( partial, relative, state );
- } else if( generator ) {
- return (*generator)( partial, state );
- } else {
- return NULL;
+ if( !strncmp( ctx->partial, s, ctx->length ) ) {
+ ctx->matches[ctx->count++] = Z_CopyString( s );
}
+ return qtrue;
}
/*
@@ -231,18 +140,25 @@ Prompt_CompleteCommand
void Prompt_CompleteCommand( commandPrompt_t *prompt, qboolean backslash ) {
inputField_t *inputLine = &prompt->inputLine;
char *text, *partial, *s;
- int i, argc, pos, currentArg, size, length, relative;
+ int i, argc, pos, currentArg, size, length, argnum;
char *first, *last;
+ genctx_t ctx;
+ char *matches[MAX_MATCHES], *sortedMatches[MAX_MATCHES];
+ int numCommands = 0, numCvars = 0, numAliases = 0;
text = inputLine->text;
size = sizeof( inputLine->text );
pos = inputLine->cursorPos;
+
+ // prepend backslash if missing
if( backslash ) {
if( inputLine->text[0] != '\\' && inputLine->text[0] != '/' ) {
memmove( inputLine->text + 1, inputLine->text, size - 1 );
inputLine->text[0] = '\\';
}
- text++; size--; pos--;
+ text++;
+ size--;
+ pos--;
}
Cmd_TokenizeString( text, qfalse );
@@ -256,14 +172,14 @@ void Prompt_CompleteCommand( commandPrompt_t *prompt, qboolean backslash ) {
currentArg++;
}
}
- relative = 0;
+ argnum = 0;
s = Cmd_Argv( 0 );
for( i = 0; i < currentArg; i++ ) {
partial = Cmd_Argv( i );
- relative++;
+ argnum++;
if( *partial == ';' ) {
s = Cmd_Argv( i + 1 );
- relative = 0;
+ argnum = 0;
}
}
@@ -271,24 +187,31 @@ void Prompt_CompleteCommand( commandPrompt_t *prompt, qboolean backslash ) {
if( *partial == ';' ) {
currentArg++;
partial = Cmd_Argv( currentArg );
- relative = 0;
+ argnum = 0;
}
- if( relative ) {
- xcompleter_t completer = Cmd_FindCompleter( s );
- if( completer ) {
- Prompt_RunCompleter( completer, partial, relative );
- } else if( relative == 1 ) {
- cvar_t *v = Cvar_FindVar( s );
- if( v && v->generator ) {
- Prompt_RunGenerator( v->generator, partial );
- }
- }
+ // generate matches
+ memset( &ctx, 0, sizeof( ctx ) );
+ ctx.partial = partial;
+ ctx.length = strlen( partial );
+ ctx.argnum = currentArg;
+ ctx.matches = matches;
+ ctx.size = MAX_MATCHES;
+
+ if( argnum ) {
+ Com_Generic_c( &ctx, argnum );
} else {
- Prompt_GenerateMatches( partial );
+ Cmd_Command_g( &ctx );
+ numCommands = ctx.count;
+
+ Cvar_Variable_g( &ctx );
+ numCvars = ctx.count - numCommands;
+
+ Cmd_Alias_g( &ctx );
+ numAliases = ctx.count - numCvars - numCommands;
}
- if( !numMatches ) {
+ if( !ctx.count ) {
inputLine->cursorPos = strlen( inputLine->text );
prompt->tooMany = qfalse;
return; // nothing found
@@ -298,7 +221,7 @@ void Prompt_CompleteCommand( commandPrompt_t *prompt, qboolean backslash ) {
text += pos;
size -= pos;
- if( numMatches == 1 ) {
+ if( ctx.count == 1 ) {
// we have finished completion!
s = Cmd_RawArgsFrom( currentArg + 1 );
if( COM_HasSpaces( matches[0] ) ) {
@@ -308,30 +231,28 @@ void Prompt_CompleteCommand( commandPrompt_t *prompt, qboolean backslash ) {
}
inputLine->cursorPos = pos + 1;
prompt->tooMany = qfalse;
- Prompt_FreeMatches();
- return;
+ goto finish;
}
- if( numMatches > com_completion_treshold->integer && !prompt->tooMany ) {
+ if( ctx.count > com_completion_treshold->integer && !prompt->tooMany ) {
prompt->printf( "Press TAB again to display all %d possibilities.\n",
- numMatches );
+ ctx.count );
inputLine->cursorPos = strlen( inputLine->text );
prompt->tooMany = qtrue;
- Prompt_FreeMatches();
- return;
+ goto finish;
}
prompt->tooMany = qfalse;
// sort matches alphabethically
- for( i = 0; i < numMatches; i++ ) {
+ for( i = 0; i < ctx.count; i++ ) {
sortedMatches[i] = matches[i];
}
- qsort( sortedMatches, numMatches, sizeof( sortedMatches[0] ), SortStrcmp );
+ qsort( sortedMatches, ctx.count, sizeof( sortedMatches[0] ), SortStrcmp );
// copy matching part
first = sortedMatches[0];
- last = sortedMatches[ numMatches - 1 ];
+ last = sortedMatches[ ctx.count - 1 ];
length = 0;
do {
if( *first != *last ) {
@@ -358,30 +279,34 @@ void Prompt_CompleteCommand( commandPrompt_t *prompt, qboolean backslash ) {
inputLine->cursorPos = pos + 1;
prompt->printf( "]\\%s\n", Cmd_ArgsFrom( 0 ) );
- if( relative ) {
+ if( argnum ) {
goto multi;
}
switch( com_completion_mode->integer ) {
case 0:
// print in solid list
- for( i = 0 ; i < numMatches; i++ ) {
+ for( i = 0 ; i < ctx.count; i++ ) {
prompt->printf( "%s\n", sortedMatches[i] );
}
break;
case 1:
multi:
// print in multiple columns
- Prompt_ShowMatches( prompt, sortedMatches, 0, numMatches );
+ Prompt_ShowMatches( prompt, sortedMatches, 0, ctx.count );
break;
case 2:
default:
// resort matches by type and print in multiple columns
- Prompt_ShowIndividualMatches( prompt );
+ Prompt_ShowIndividualMatches( prompt, matches, numCommands, numAliases, numCvars );
break;
}
-
- Prompt_FreeMatches();
+
+finish:
+ // free matches
+ for( i = 0; i < ctx.count; i++ ) {
+ Z_Free( matches[i] );
+ }
}
/*