diff --git a/include/QF/cbuf.h b/include/QF/cbuf.h index 656fc0021..32d0114d7 100644 --- a/include/QF/cbuf.h +++ b/include/QF/cbuf.h @@ -80,6 +80,7 @@ typedef struct cbuf_interpreter_s { void (*insert) (struct cbuf_s *cbuf, const char *str); void (*execute) (struct cbuf_s *cbuf); void (*execute_sets) (struct cbuf_s *cbuf); + const char** (*complete) (struct cbuf_s *cbuf, const char *str); } cbuf_interpreter_t; extern cbuf_t *cbuf_active; diff --git a/include/QF/cmd.h b/include/QF/cmd.h index 5c9379c53..dce18e25d 100644 --- a/include/QF/cmd.h +++ b/include/QF/cmd.h @@ -45,6 +45,14 @@ typedef enum { src_command, // from a command buffer } cmd_source_t; +typedef struct cmd_function_s { + struct cmd_function_s *next; + const char *name; + xcommand_t function; + const char *description; + qboolean pure; +} cmd_function_t; + extern cmd_source_t cmd_source; void Cmd_Init_Hash (void); @@ -74,6 +82,7 @@ struct cbuf_interpreter_s *Cmd_GetProvider(const char *name); extern struct cbuf_args_s *cmd_args; extern struct cvar_s *cmd_warncmd; +extern cmd_function_t *cmd_functions; // possible commands to execute //@} diff --git a/libs/console/complete.c b/libs/console/complete.c index e25a6181f..eb16544ef 100644 --- a/libs/console/complete.c +++ b/libs/console/complete.c @@ -40,10 +40,13 @@ static __attribute__ ((used)) const char rcsid[] = #include +#include "QF/cbuf.h" #include "QF/cmd.h" #include "QF/console.h" #include "QF/cvar.h" - +#include "QF/plugin.h" +#include "QF/va.h" +#include "compat.h" /* Con_BasicCompleteCommandLine @@ -59,33 +62,66 @@ Con_BasicCompleteCommandLine (inputline_t *il) { char *s; const char *cmd = "", **list[3] = {0, 0, 0}; - int cmd_len, c, i, v; + int cmd_len, c, i, v, o; s = il->lines[il->edit_line] + 1; + if (*s == '\\' || *s == '/') s++; - // Count number of possible matches - c = Cmd_CompleteCountPossible(s); - v = Cvar_CompleteCountPossible(s); + s = strdup(s); + + cbuf_t* cbuf = con_module->data->console->cbuf; + + if (cbuf->interpreter->complete) + { + const char** completions = cbuf->interpreter->complete(cbuf, s); + const char** com; + + for (o = 0, com = completions; *com; com++, o++) + { + } + + c = v = 0; + + list[2] = completions; + } + else + { + // Count number of possible matches + c = Cmd_CompleteCountPossible(s); + v = Cvar_CompleteCountPossible(s); + o = 0; + } - if (!(c + v)) // No possible matches + if (!(c + v + o)) // No possible matches return; - if (c + v == 1) { + if (c + v + o == 1) { if (c) + { list[0] = Cmd_CompleteBuildList(s); - else + cmd = *list[0]; + } + else if (v) + { list[0] = Cvar_CompleteBuildList(s); - cmd = *list[0]; + cmd = *list[0]; + } + else + { + cmd = *list[2]; + } cmd_len = strlen (cmd); } else { if (c) cmd = *(list[0] = Cmd_CompleteBuildList(s)); if (v) cmd = *(list[1] = Cvar_CompleteBuildList(s)); + if (o) + cmd = *(list[2]); - cmd_len = strlen (s); + cmd_len = 0; do { for (i = 0; i < 3; i++) { char ch = cmd[cmd_len]; @@ -116,13 +152,29 @@ Con_BasicCompleteCommandLine (inputline_t *il) Con_Printf("%i possible variable%s\n", v, (v > 1) ? "s: " : ":"); Con_DisplayList(list[1], con_linewidth); } + if (o) { + Con_Printf("%i possible matche%s\n", o, (o > 1) ? "s: " : ":"); + Con_DisplayList(list[2], con_linewidth); + } } if (cmd) { + int bound = strlen(s); + int match = bound; + + if (cmd_len > 0) while (bound >= 0) + { + if (!strncmp(s+bound, cmd, min(strlen(s+bound), (unsigned int) cmd_len))) + match = bound; + bound--; + } + + const char* overwrite = va("%.*s%.*s", match, s, cmd_len, cmd); + il->lines[il->edit_line][1] = '/'; - strncpy(il->lines[il->edit_line] + 2, cmd, cmd_len); - il->linepos = cmd_len + 2; - if (c + v == 1) { + strncpy(il->lines[il->edit_line] + 2, overwrite, strlen(overwrite)); + il->linepos = strlen(overwrite) + 2; + if (c + v + o == 1) { il->lines[il->edit_line][il->linepos] = ' '; il->linepos++; } @@ -131,4 +183,6 @@ Con_BasicCompleteCommandLine (inputline_t *il) for (i = 0; i < 3; i++) if (list[i]) free (list[i]); + + free(s); } diff --git a/libs/util/cmd.c b/libs/util/cmd.c index db5b203f4..f0afe2c85 100644 --- a/libs/util/cmd.c +++ b/libs/util/cmd.c @@ -81,15 +81,7 @@ VISIBLE cmd_source_t cmd_source; /* Command parsing functions */ -typedef struct cmd_function_s { - struct cmd_function_s *next; - const char *name; - xcommand_t function; - const char *description; - qboolean pure; -} cmd_function_t; - -static cmd_function_t *cmd_functions; // possible commands to execute +VISIBLE cmd_function_t *cmd_functions; // possible commands to execute VISIBLE int Cmd_Argc (void) diff --git a/libs/util/idparse.c b/libs/util/idparse.c index 107fd4060..f8854ed3e 100644 --- a/libs/util/idparse.c +++ b/libs/util/idparse.c @@ -244,4 +244,5 @@ VISIBLE cbuf_interpreter_t id_interp = { COM_insert, COM_execute, COM_execute_sets, + NULL };