From 0df1a9b21b3cf319eb48aba8cabe9d39e5f5f752 Mon Sep 17 00:00:00 2001 From: terencehill Date: Thu, 26 Sep 2024 02:18:09 +0200 Subject: [PATCH] Implement autocompletion of player names after typing just a #: press SHIFT-TAB until you see the desired player name in console, then press TAB to autocomplete it --- console.c | 57 ++++++++++++++++++++++++++++++++++++++++++------------- console.h | 3 ++- keys.c | 14 +++++++++++--- 3 files changed, 57 insertions(+), 17 deletions(-) diff --git a/console.c b/console.c index 9598e2cf..4b5dc816 100644 --- a/console.c +++ b/console.c @@ -34,6 +34,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. float con_cursorspeed = 4; // lines up from bottom to display +int hash_completion_player; int con_backscroll; conbuffer_t con; @@ -2517,7 +2518,7 @@ static int Nicks_strncasecmp(char *a, char *b, unsigned int a_len) Count the number of possible nicks to complete */ -static int Nicks_CompleteCountPossible(char *line, int pos, char *s, qbool isCon, qbool only_pnumbers) +static int Nicks_CompleteCountPossible(char *line, int pos, char *s, qbool isCon, int hash_completion) { char name[MAX_SCOREBOARDNAME]; int i, p; @@ -2532,6 +2533,20 @@ static int Nicks_CompleteCountPossible(char *line, int pos, char *s, qbool isCon if(!line[0])// || !line[1]) // we want at least... 2 written characters return 0; + if(hash_completion == 1) // cycle through players + { + int initial; + if (hash_completion_player < 0) + hash_completion_player = 0; + initial = hash_completion_player; + while(true) + { + hash_completion_player = (hash_completion_player + 1) % cl.maxclients; + if (hash_completion_player == initial || cl.scores[hash_completion_player].name[0]) + break; + } + } + for(i = 0; i < cl.maxclients; ++i) { p = i; @@ -2559,16 +2574,25 @@ static int Nicks_CompleteCountPossible(char *line, int pos, char *s, qbool isCon } if(isCon && spos == 0) break; - if(only_pnumbers) + if(hash_completion) { if(line[spos] == '#') { int len = (int) strspn(line+spos+1, "0123456789"); // number of digits - if (line[pos-1] == ' ') - ++len; - // word lenght EQUAL digits count OR digits count + 1 trailing space - if(((pos)-(spos+1)) == len && p == (atoi(line+spos+1)-1)) - match = spos; + if (len == 0) + { + if (p == hash_completion_player) + match = spos; + } + else + { + hash_completion_player = -1; + if (line[pos-1] == ' ') + ++len; + // word lenght EQUAL digits count OR digits count + 1 trailing space + if(((pos)-(spos+1)) == len && p == (atoi(line+spos+1)-1)) + match = spos; + } } } else if(Nicks_strncasecmp(line+spos, name, pos-spos) == 0) @@ -2595,11 +2619,16 @@ static int Nicks_CompleteCountPossible(char *line, int pos, char *s, qbool isCon return count; } -static void Cmd_CompleteNicksPrint(int count) +static void Cmd_CompleteNicksPrint(int count, int hash_completion) { int i; for(i = 0; i < count; ++i) - Con_Printf("%s\n", Nicks_list[i]); + { + if (hash_completion == 1 && hash_completion_player >= 0) + Con_Printf("#%d %s\n", hash_completion_player + 1, Nicks_list[i]); + else + Con_Printf("%s\n", Nicks_list[i]); + } } static void Nicks_CutMatchesNormal(int count) @@ -2884,7 +2913,7 @@ static size_t Con_EscapeSpaces(char *dst, const char *src, size_t dsize) Directory support by divVerent Escaping support by bones_was_here */ -int Con_CompleteCommandLine(cmd_state_t *cmd, qbool is_console, qbool only_pnumbers) +int Con_CompleteCommandLine(cmd_state_t *cmd, qbool is_console, int hash_completion) { const char *text = ""; char *s; @@ -2930,7 +2959,7 @@ int Con_CompleteCommandLine(cmd_state_t *cmd, qbool is_console, qbool only_pnumb line[linepos] = 0; //hide them c = v = a = n = cmd_len = 0; - if (!is_console || only_pnumbers) + if (!is_console || hash_completion) goto nicks; space = strchr(line + 1, ' '); @@ -3149,11 +3178,13 @@ int Con_CompleteCommandLine(cmd_state_t *cmd, qbool is_console, qbool only_pnumb } nicks: - n = Nicks_CompleteCountPossible(line, linepos, s, is_console, only_pnumbers); + n = Nicks_CompleteCountPossible(line, linepos, s, is_console, hash_completion); if (n) { Con_Printf("\n%i possible nick%s\n", n, (n > 1) ? "s: " : ":"); - Cmd_CompleteNicksPrint(n); + Cmd_CompleteNicksPrint(n, hash_completion); + if (hash_completion == 1 && hash_completion_player >= 0) + n = 0; // cycle player names without autocompleting } if (!(c + v + a + n)) // No possible matches diff --git a/console.h b/console.h index 503f14e5..2edb0a0d 100644 --- a/console.h +++ b/console.h @@ -30,6 +30,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // // console // +extern int hash_completion_player; extern int con_totallines; extern int con_backscroll; extern qbool con_initialized; @@ -80,7 +81,7 @@ size_t GetMapList (const char *s, char *completedname, int completednamebuffersi /// or to list possible matches grouped by type /// (i.e. will display possible variables, aliases, commands /// that match what they've typed so far) -int Con_CompleteCommandLine(cmd_state_t *cmd, qbool is_console, qbool only_pnumbers); +int Con_CompleteCommandLine(cmd_state_t *cmd, qbool is_console, int hash_completion); /// Generic libs/util/console.c function to display a list /// formatted in columns on the console diff --git a/keys.c b/keys.c index 0b9f60c1..c1f497a0 100644 --- a/keys.c +++ b/keys.c @@ -864,10 +864,18 @@ int Key_Parse_CommonKeys(cmd_state_t *cmd, qbool is_console, int key, int unicod return linepos; } - if (KM_SHIFT) // only complete player references #N as names - return Con_CompleteCommandLine(cmd, is_console, true); + if (KM_SHIFT) // SHIFT-TAB after #N autocompletes the name of player N; after # it cycles through player names + return Con_CompleteCommandLine(cmd, is_console, 1); if (KM_NONE) - return Con_CompleteCommandLine(cmd, is_console, false); + { + if (hash_completion_player >= 0) // TAB after # autocompletes the name of hash_completion_player + { + int r = Con_CompleteCommandLine(cmd, is_console, 2); + hash_completion_player = -1; + return r; + } + return Con_CompleteCommandLine(cmd, is_console, 0); + } } // Advanced Console Editing by Radix radix@planetquake.com -- 2.39.2