fix(stdpath): remove duplicate directories (#26653)

This commit is contained in:
Raphael 2024-04-03 18:44:57 +08:00 committed by GitHub
parent ab0d3c4098
commit dbc0fa9bd6
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 55 additions and 8 deletions

View File

@ -2,13 +2,16 @@
#include <stdbool.h> #include <stdbool.h>
#include <string.h> #include <string.h>
#include "klib/kvec.h"
#include "nvim/ascii_defs.h" #include "nvim/ascii_defs.h"
#include "nvim/fileio.h" #include "nvim/fileio.h"
#include "nvim/globals.h" #include "nvim/globals.h"
#include "nvim/memory.h" #include "nvim/memory.h"
#include "nvim/os/os.h" #include "nvim/os/os.h"
#include "nvim/os/os_defs.h"
#include "nvim/os/stdpaths_defs.h" #include "nvim/os/stdpaths_defs.h"
#include "nvim/path.h" #include "nvim/path.h"
#include "nvim/strings.h"
#ifdef INCLUDE_GENERATED_DECLARATIONS #ifdef INCLUDE_GENERATED_DECLARATIONS
# include "os/stdpaths.c.generated.h" # include "os/stdpaths.c.generated.h"
@ -93,6 +96,46 @@ bool appname_is_valid(void)
return true; return true;
} }
/// Remove duplicate directories in the given XDG directory.
/// @param[in] List of directories possibly with duplicates
/// @param[out] List of directories without duplicates
static char *xdg_remove_duplicate(char *ret, const char *sep)
{
kvec_t(char *) data = KV_INITIAL_VALUE;
char *saveptr;
char *token = os_strtok(ret, sep, &saveptr);
while (token != NULL) {
// Check if the directory is not already in the list
bool is_duplicate = false;
for (size_t i = 0; i < data.size; i++) {
if (path_fnamecmp(kv_A(data, i), token) == 0) {
is_duplicate = true;
break;
}
}
// If it's not a duplicate, add it to the list
if (!is_duplicate) {
kv_push(data, token);
}
token = os_strtok(NULL, sep, &saveptr);
}
StringBuilder result = KV_INITIAL_VALUE;
for (size_t i = 0; i < data.size; i++) {
if (i == 0) {
kv_printf(result, "%s", kv_A(data, i));
} else {
kv_printf(result, "%s%s", sep, kv_A(data, i));
}
}
kv_destroy(data);
xfree(ret);
return result.items;
}
/// Return XDG variable value /// Return XDG variable value
/// ///
/// @param[in] idx XDG variable to use. /// @param[in] idx XDG variable to use.
@ -131,6 +174,10 @@ char *stdpaths_get_xdg_var(const XDGVarType idx)
ret = xmemdupz(ret, len >= 2 ? len - 1 : 0); // Trim trailing slash. ret = xmemdupz(ret, len >= 2 ? len - 1 : 0); // Trim trailing slash.
} }
if ((idx == kXDGDataDirs || idx == kXDGConfigDirs) && ret != NULL) {
ret = xdg_remove_duplicate(ret, ENV_SEPSTR);
}
return ret; return ret;
} }

View File

@ -378,7 +378,7 @@ describe('XDG defaults', function()
.. root_path .. root_path
.. ('/b'):rep(2048) .. ('/b'):rep(2048)
.. '/nvim' .. '/nvim'
.. (',' .. root_path .. '/c/nvim'):rep(512) .. (',' .. root_path .. '/c/nvim')
.. ',' .. ','
.. root_path .. root_path
.. ('/X'):rep(4096) .. ('/X'):rep(4096)
@ -393,12 +393,12 @@ describe('XDG defaults', function()
.. root_path .. root_path
.. ('/B'):rep(2048) .. ('/B'):rep(2048)
.. '/nvim/site' .. '/nvim/site'
.. (',' .. root_path .. '/C/nvim/site'):rep(512) .. (',' .. root_path .. '/C/nvim/site')
.. ',' .. ','
.. vimruntime .. vimruntime
.. ',' .. ','
.. libdir .. libdir
.. (',' .. root_path .. '/C/nvim/site/after'):rep(512) .. (',' .. root_path .. '/C/nvim/site/after')
.. ',' .. ','
.. root_path .. root_path
.. ('/B'):rep(2048) .. ('/B'):rep(2048)
@ -413,7 +413,7 @@ describe('XDG defaults', function()
.. '/' .. '/'
.. data_dir .. data_dir
.. '/site/after' .. '/site/after'
.. (',' .. root_path .. '/c/nvim/after'):rep(512) .. (',' .. root_path .. '/c/nvim/after')
.. ',' .. ','
.. root_path .. root_path
.. ('/b'):rep(2048) .. ('/b'):rep(2048)
@ -449,7 +449,7 @@ describe('XDG defaults', function()
.. root_path .. root_path
.. ('/b'):rep(2048) .. ('/b'):rep(2048)
.. '/nvim' .. '/nvim'
.. (',' .. root_path .. '/c/nvim'):rep(512) .. (',' .. root_path .. '/c/nvim')
.. ',' .. ','
.. root_path .. root_path
.. ('/X'):rep(4096) .. ('/X'):rep(4096)
@ -464,12 +464,12 @@ describe('XDG defaults', function()
.. root_path .. root_path
.. ('/B'):rep(2048) .. ('/B'):rep(2048)
.. '/nvim/site' .. '/nvim/site'
.. (',' .. root_path .. '/C/nvim/site'):rep(512) .. (',' .. root_path .. '/C/nvim/site')
.. ',' .. ','
.. vimruntime .. vimruntime
.. ',' .. ','
.. libdir .. libdir
.. (',' .. root_path .. '/C/nvim/site/after'):rep(512) .. (',' .. root_path .. '/C/nvim/site/after')
.. ',' .. ','
.. root_path .. root_path
.. ('/B'):rep(2048) .. ('/B'):rep(2048)
@ -484,7 +484,7 @@ describe('XDG defaults', function()
.. '/' .. '/'
.. data_dir .. data_dir
.. '/site/after' .. '/site/after'
.. (',' .. root_path .. '/c/nvim/after'):rep(512) .. (',' .. root_path .. '/c/nvim/after')
.. ',' .. ','
.. root_path .. root_path
.. ('/b'):rep(2048) .. ('/b'):rep(2048)