From cfe61b563ddcedb901d68b2a4cee76c77ef03551 Mon Sep 17 00:00:00 2001 From: gmoney Date: Wed, 20 Nov 2024 23:40:43 -0700 Subject: [PATCH 1/3] add support for terminal-style completion to \exec command for *nix systems --- code/qcommon/cmd.c | 17 +++++++++++++++-- code/qcommon/common.c | 9 ++++++++- code/qcommon/files.c | 21 +++++++++++++++++++++ 3 files changed, 44 insertions(+), 3 deletions(-) diff --git a/code/qcommon/cmd.c b/code/qcommon/cmd.c index 2b8d91793..d138c0436 100644 --- a/code/qcommon/cmd.c +++ b/code/qcommon/cmd.c @@ -1011,8 +1011,21 @@ Cmd_CompleteCfgName ================== */ static void Cmd_CompleteCfgName( const char *args, int argNum ) { - if( argNum == 2 ) { - Field_CompleteFilename( "", "cfg", qfalse, FS_MATCH_ANY | FS_MATCH_STICK ); + if (argNum == 2) { + char path[MAX_OSPATH] = ""; + const char *arg = Cmd_Argv(1); + + // Look for the last forward slash to determine the + // directory portion of the path for file completion. + char *lastSlash = strrchr(arg, '/'); + + if (lastSlash) { + int newLength = lastSlash - arg + 1; + strncpy(path, arg, newLength); + path[newLength] = '\0'; + } + + Field_CompleteFilename(path, "cfg", qfalse, FS_MATCH_ANY | FS_MATCH_STICK); } } diff --git a/code/qcommon/common.c b/code/qcommon/common.c index c30ebbe39..2e4551976 100644 --- a/code/qcommon/common.c +++ b/code/qcommon/common.c @@ -4607,7 +4607,8 @@ static qboolean Field_Complete( void ) if( matchCount == 1 ) { - Field_AddSpace(); + if(completionField->buffer[completionField->cursor - 1] != '/') + Field_AddSpace(); return qtrue; } @@ -4765,6 +4766,12 @@ void Field_CompleteCommand( const char *cmd, qboolean doCommands, qboolean doCva } else completionString = Cmd_Argv( completionArgument - 1 ); + char *lastSlash = strrchr(completionString, '/'); + if (lastSlash) { + // If a slash is found, set the completion string to everything after the last slash + // This is done to ensure that the completion function works with the correct file or directory name + completionString = lastSlash + 1; + } #ifndef DEDICATED // Unconditionally add a '\' to the start of the buffer diff --git a/code/qcommon/files.c b/code/qcommon/files.c index 3189d770d..207e2d914 100644 --- a/code/qcommon/files.c +++ b/code/qcommon/files.c @@ -3334,6 +3334,7 @@ static char **FS_ListFilteredFiles( const char *path, const char *extension, con char zpath[MAX_ZPATH]; qboolean hasPatterns; const char *x; + char dirname[MAX_OSPATH*2]; if ( !fs_searchpaths ) { Com_Error( ERR_FATAL, "Filesystem call made without initialization" ); @@ -3441,9 +3442,12 @@ static char **FS_ListFilteredFiles( const char *path, const char *extension, con const char *netpath; int numSysFiles; char **sysFiles; + int numSysDirs; + char **sysDirs; const char *name; netpath = FS_BuildOSPath( search->dir->path, search->dir->gamedir, path ); + sysDirs = Sys_ListFiles( netpath, "", filter, &numSysDirs, qtrue ); sysFiles = Sys_ListFiles( netpath, extension, filter, &numSysFiles, qfalse ); for ( i = 0 ; i < numSysFiles ; i++ ) { // unique the match @@ -3458,6 +3462,23 @@ static char **FS_ListFilteredFiles( const char *path, const char *extension, con nfiles = FS_AddFileToList( name, list, nfiles ); } Sys_FreeFileList( sysFiles ); + + for ( i = 0 ; i < numSysDirs ; i++ ) { + name = sysDirs[ i ]; + // ignore . and .. + if ( strcmp(name, "." ) == 0 || strcmp( name, ".." ) == 0 ) { + continue; + } + Com_sprintf( dirname, sizeof(dirname), "%s/", name); + if ( fnamecallback ) { + // use custom filter + if ( !fnamecallback( dirname, strlen(dirname) ) ) + continue; + } + + nfiles = FS_AddFileToList( dirname, list, nfiles ); + } + Sys_FreeFileList( sysDirs ); } } From 2c037dfa439ffccc2a236f88a62ac260a7e629e9 Mon Sep 17 00:00:00 2001 From: gmoney Date: Sat, 23 Nov 2024 21:27:35 -0700 Subject: [PATCH 2/3] only match directories during filename completion --- code/qcommon/files.c | 38 ++++++++++++++++++++------------------ 1 file changed, 20 insertions(+), 18 deletions(-) diff --git a/code/qcommon/files.c b/code/qcommon/files.c index 207e2d914..309db60a9 100644 --- a/code/qcommon/files.c +++ b/code/qcommon/files.c @@ -3320,7 +3320,7 @@ Returns a unique list of files that match the given criteria from all search paths =============== */ -static char **FS_ListFilteredFiles( const char *path, const char *extension, const char *filter, int *numfiles, int flags ) { +static char **FS_ListFilteredFiles( const char *path, const char *extension, const char *filter, int *numfiles, int flags, qboolean includeDirs ) { int nfiles; char **listCopy; char *list[MAX_FOUND_FILES]; @@ -3447,7 +3447,6 @@ static char **FS_ListFilteredFiles( const char *path, const char *extension, con const char *name; netpath = FS_BuildOSPath( search->dir->path, search->dir->gamedir, path ); - sysDirs = Sys_ListFiles( netpath, "", filter, &numSysDirs, qtrue ); sysFiles = Sys_ListFiles( netpath, extension, filter, &numSysFiles, qfalse ); for ( i = 0 ; i < numSysFiles ; i++ ) { // unique the match @@ -3463,22 +3462,25 @@ static char **FS_ListFilteredFiles( const char *path, const char *extension, con } Sys_FreeFileList( sysFiles ); - for ( i = 0 ; i < numSysDirs ; i++ ) { - name = sysDirs[ i ]; - // ignore . and .. - if ( strcmp(name, "." ) == 0 || strcmp( name, ".." ) == 0 ) { - continue; - } - Com_sprintf( dirname, sizeof(dirname), "%s/", name); - if ( fnamecallback ) { - // use custom filter - if ( !fnamecallback( dirname, strlen(dirname) ) ) + if(includeDirs) { + sysDirs = Sys_ListFiles( netpath, "", filter, &numSysDirs, qtrue ); + for ( i = 0 ; i < numSysDirs ; i++ ) { + name = sysDirs[ i ]; + // ignore . and .. + if ( strcmp(name, "." ) == 0 || strcmp( name, ".." ) == 0 ) { continue; - } + } + Com_sprintf( dirname, sizeof(dirname), "%s/", name); + if ( fnamecallback ) { + // use custom filter + if ( !fnamecallback( dirname, strlen(dirname) ) ) + continue; + } - nfiles = FS_AddFileToList( dirname, list, nfiles ); + nfiles = FS_AddFileToList( dirname, list, nfiles ); + } + Sys_FreeFileList( sysDirs ); } - Sys_FreeFileList( sysDirs ); } } @@ -3506,7 +3508,7 @@ FS_ListFiles */ char **FS_ListFiles( const char *path, const char *extension, int *numfiles ) { - return FS_ListFilteredFiles( path, extension, NULL, numfiles, FS_MATCH_ANY ); + return FS_ListFilteredFiles( path, extension, NULL, numfiles, FS_MATCH_ANY, qfalse ); } @@ -3950,7 +3952,7 @@ static void FS_NewDir_f( void ) { Com_Printf( "---------------\n" ); - dirnames = FS_ListFilteredFiles( "", "", filter, &ndirs, FS_MATCH_ANY ); + dirnames = FS_ListFilteredFiles( "", "", filter, &ndirs, FS_MATCH_ANY, qfalse ); if ( ndirs >= 2 ) FS_SortFileList( dirnames, ndirs - 1 ); @@ -5600,7 +5602,7 @@ void FS_FilenameCompletion( const char *dir, const char *ext, int nfiles; int i; - filenames = FS_ListFilteredFiles( dir, ext, NULL, &nfiles, flags ); + filenames = FS_ListFilteredFiles( dir, ext, NULL, &nfiles, flags, qtrue ); if ( nfiles >= 2 ) FS_SortFileList( filenames, nfiles-1 ); From ad1433798249c5081083a1fe5077ffba67f91e8d Mon Sep 17 00:00:00 2001 From: gmoney Date: Tue, 3 Dec 2024 13:04:15 -0700 Subject: [PATCH 3/3] add missiung curlies to else block --- code/qcommon/common.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/code/qcommon/common.c b/code/qcommon/common.c index 2e4551976..22864e7fb 100644 --- a/code/qcommon/common.c +++ b/code/qcommon/common.c @@ -4765,6 +4765,7 @@ void Field_CompleteCommand( const char *cmd, qboolean doCommands, qboolean doCva completionArgument++; } else + { completionString = Cmd_Argv( completionArgument - 1 ); char *lastSlash = strrchr(completionString, '/'); if (lastSlash) { @@ -4772,6 +4773,7 @@ void Field_CompleteCommand( const char *cmd, qboolean doCommands, qboolean doCva // This is done to ensure that the completion function works with the correct file or directory name completionString = lastSlash + 1; } + } #ifndef DEDICATED // Unconditionally add a '\' to the start of the buffer