diff --git a/src/nvim/arglist.c b/src/nvim/arglist.c index abe81202da..bf9883ce24 100644 --- a/src/nvim/arglist.c +++ b/src/nvim/arglist.c @@ -216,9 +216,6 @@ void alist_add(alist_T *al, char *fname, int set_fnum) arglist_locked = true; wp->w_locked++; -#ifdef BACKSLASH_IN_FILENAME - slash_adjust(fname); -#endif AARGLIST(al)[al->al_ga.ga_len].ae_fname = fname; if (set_fnum > 0) { AARGLIST(al)[al->al_ga.ga_len].ae_fnum = diff --git a/src/nvim/ascii_defs.h b/src/nvim/ascii_defs.h index 7bd0b21889..fb8546833f 100644 --- a/src/nvim/ascii_defs.h +++ b/src/nvim/ascii_defs.h @@ -75,13 +75,8 @@ #define Ctrl__ 31 // Character that separates dir names in a path. -#ifdef BACKSLASH_IN_FILENAME -# define PATHSEP psepc -# define PATHSEPSTR pseps -#else -# define PATHSEP '/' -# define PATHSEPSTR "/" -#endif +#define PATHSEP '/' +#define PATHSEPSTR "/" /// Checks if `c` is a space or tab character. /// diff --git a/src/nvim/cmdexpand.c b/src/nvim/cmdexpand.c index cfcc9c033e..9c30f516cf 100644 --- a/src/nvim/cmdexpand.c +++ b/src/nvim/cmdexpand.c @@ -316,6 +316,7 @@ int nextwild(expand_T *xp, int type, int options, bool escape) } // Translate string into pattern and expand it. const int use_options = (options + | WILD_USE_COMPLETESLASH | WILD_HOME_REPLACE | WILD_ADD_SLASH | WILD_SILENT @@ -2725,16 +2726,13 @@ static int expand_files_and_dirs(expand_T *xp, char *pat, char ***matches, int * xfree(pat); } #ifdef BACKSLASH_IN_FILENAME - if (p_csl[0] != NUL && (options & WILD_IGNORE_COMPLETESLASH) == 0) { + if ((options & WILD_USE_COMPLETESLASH) && ((p_csl[0] == NUL && !p_ssl) || p_csl[0] == 'b')) { for (int j = 0; j < *numMatches; j++) { char *ptr = (*matches)[j]; - while (*ptr != NUL) { - if (p_csl[0] == 's' && *ptr == '\\') { - *ptr = '/'; - } else if (p_csl[0] == 'b' && *ptr == '/') { + for (; *ptr; ptr++) { + if (*ptr == '/') { *ptr = '\\'; } - ptr += utfc_ptr2len(ptr); } } } diff --git a/src/nvim/cmdexpand.h b/src/nvim/cmdexpand.h index 51b90b311e..198b178f71 100644 --- a/src/nvim/cmdexpand.h +++ b/src/nvim/cmdexpand.h @@ -36,7 +36,7 @@ enum { WILD_ESCAPE = 0x80, WILD_ICASE = 0x100, WILD_ALLLINKS = 0x200, - WILD_IGNORE_COMPLETESLASH = 0x400, + WILD_USE_COMPLETESLASH = 0x400, WILD_NOERROR = 0x800, ///< sets EW_NOERROR WILD_BUFLASTUSED = 0x1000, BUF_DIFF_FILTER = 0x2000, diff --git a/src/nvim/eval/fs.c b/src/nvim/eval/fs.c index 7e4dc1801b..abec37c9c8 100644 --- a/src/nvim/eval/fs.c +++ b/src/nvim/eval/fs.c @@ -462,12 +462,6 @@ void f_exepath(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) os_can_exe(tv_get_string(&argvars[0]), &path, true); -#ifdef BACKSLASH_IN_FILENAME - if (path != NULL) { - slash_adjust(path); - } -#endif - rettv->v_type = VAR_STRING; rettv->vval.v_string = path; } @@ -878,7 +872,7 @@ void f_glob(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) /// "globpath()" function void f_globpath(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { - int flags = WILD_IGNORE_COMPLETESLASH; // Flags for globpath. + int flags = 0; // Flags for globpath. bool error = false; // Return a string, or a list if the optional third argument is non-zero. diff --git a/src/nvim/event/libuv_proc.c b/src/nvim/event/libuv_proc.c index 01076670c3..c12e7b0509 100644 --- a/src/nvim/event/libuv_proc.c +++ b/src/nvim/event/libuv_proc.c @@ -11,6 +11,7 @@ #include "nvim/log.h" #include "nvim/os/os.h" #include "nvim/os/os_defs.h" +#include "nvim/path.h" #include "nvim/types_defs.h" #include "nvim/ui_client.h" @@ -29,6 +30,8 @@ int libuv_proc_spawn(LibuvProc *uvproc) // expects a different syntax (must be prepared by the caller before now). if (os_shell_is_cmdexe(proc->argv[0])) { uvproc->uvopts.flags |= UV_PROCESS_WINDOWS_VERBATIM_ARGUMENTS; + // cmd.exe compatibility: backslashes required for path. + TO_BACKSLASH(proc->argv[0]); } if (proc->detach) { uvproc->uvopts.flags |= UV_PROCESS_DETACHED; diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c index 3a761136c0..373e111eec 100644 --- a/src/nvim/ex_docmd.c +++ b/src/nvim/ex_docmd.c @@ -4145,6 +4145,8 @@ int expand_filename(exarg_T *eap, char **cmdlinep, const char **errormsgp) } repl_cmdline(eap, eap->arg, strlen(eap->arg), p, cmdlinep); xfree(p); + } else { + TO_SLASH(eap->arg); } } return OK; @@ -5673,7 +5675,7 @@ int expand_findfunc(char *pat, char ***files, int *numMatches) int idx = 0; TV_LIST_ITER_CONST(l, li, { if (TV_LIST_ITEM_TV(li)->v_type == VAR_STRING) { - (*files)[idx] = xstrdup(TV_LIST_ITEM_TV(li)->vval.v_string); + (*files)[idx] = TO_SLASH_SAVE(TV_LIST_ITEM_TV(li)->vval.v_string); idx++; } }); @@ -5704,7 +5706,7 @@ static char *findfunc_find_file(char *findarg, size_t findarg_len, int count) } else { listitem_T *li = tv_list_find(fname_list, count - 1); if (li != NULL && TV_LIST_ITEM_TV(li)->v_type == VAR_STRING) { - ret_fname = xstrdup(TV_LIST_ITEM_TV(li)->vval.v_string); + ret_fname = TO_SLASH_SAVE(TV_LIST_ITEM_TV(li)->vval.v_string); } } } diff --git a/src/nvim/file_search.c b/src/nvim/file_search.c index a043da3f17..66254a15f1 100644 --- a/src/nvim/file_search.c +++ b/src/nvim/file_search.c @@ -1593,6 +1593,7 @@ theend: char *grab_file_name(int count, linenr_T *file_lnum) { int options = FNAME_MESS | FNAME_EXP | FNAME_REL | FNAME_UNESC; + char *fname; if (VIsual_active) { size_t len; char *ptr; @@ -1605,9 +1606,12 @@ char *grab_file_name(int count, linenr_T *file_lnum) *file_lnum = getdigits_int32(&p, false, 0); } - return find_file_name_in_path(ptr, len, options, count, curbuf->b_ffname); + fname = find_file_name_in_path(ptr, len, options, count, curbuf->b_ffname); + } else { + fname = file_name_at_cursor(options | FNAME_HYP, count, file_lnum); } - return file_name_at_cursor(options | FNAME_HYP, count, file_lnum); + TO_SLASH(fname); + return fname; } /// Return the file name under or after the cursor. diff --git a/src/nvim/insexpand.c b/src/nvim/insexpand.c index 97b84a0e8b..ce676a8639 100644 --- a/src/nvim/insexpand.c +++ b/src/nvim/insexpand.c @@ -4038,30 +4038,9 @@ static void get_next_filename_completion(void) int max_score = 0; Direction dir = compl_direction; -#ifdef BACKSLASH_IN_FILENAME - char pathsep = (curbuf->b_p_csl[0] == 's') - ? '/' : (curbuf->b_p_csl[0] == 'b') ? '\\' : PATHSEP; -#else - char pathsep = PATHSEP; -#endif - if (in_fuzzy_collect) { -#ifdef BACKSLASH_IN_FILENAME - if (curbuf->b_p_csl[0] == 's') { - for (size_t i = 0; i < leader_len; i++) { - if (leader[i] == '\\') { - leader[i] = '/'; - } - } - } else if (curbuf->b_p_csl[0] == 'b') { - for (size_t i = 0; i < leader_len; i++) { - if (leader[i] == '/') { - leader[i] = '\\'; - } - } - } -#endif - char *last_sep = strrchr(leader, pathsep); + TO_SLASH(leader); + char *last_sep = strrchr(leader, PATHSEP); if (last_sep == NULL) { // No path separator or separator is the last character, // fuzzy match the whole leader @@ -4093,16 +4072,12 @@ static void get_next_filename_completion(void) // May change home directory back to "~". tilde_replace(compl_pattern.data, num_matches, matches); #ifdef BACKSLASH_IN_FILENAME - if (curbuf->b_p_csl[0] != NUL) { + if ((curbuf->b_p_csl[0] == NUL && !p_ssl) || curbuf->b_p_csl[0] == 'b') { for (int i = 0; i < num_matches; i++) { - char *ptr = matches[i]; - while (*ptr != NUL) { - if (curbuf->b_p_csl[0] == 's' && *ptr == '\\') { - *ptr = '/'; - } else if (curbuf->b_p_csl[0] == 'b' && *ptr == '/') { + for (char *ptr = matches[i]; *ptr; ptr++) { + if (*ptr == '/') { *ptr = '\\'; } - ptr += utfc_ptr2len(ptr); } } } diff --git a/src/nvim/main.c b/src/nvim/main.c index 08e741b3a7..a1320648a4 100644 --- a/src/nvim/main.c +++ b/src/nvim/main.c @@ -256,6 +256,7 @@ int main(int argc, char **argv) #endif { argv0 = argv[0]; + TO_SLASH(argv0); if (!appname_is_valid()) { fprintf(stderr, "$NVIM_APPNAME must be a name or relative path.\n"); @@ -1461,6 +1462,7 @@ scripterror: break; case 'u': // "-u {vimrc}" vim inits file parmp->use_vimrc = argv[0]; + TO_SLASH(argv[0]); break; case 'U': // "-U {gvimrc}" gvim inits file break; @@ -1505,6 +1507,7 @@ scripterror: xfree(p); p = tilde_expanded; } + TO_SLASH(p); #endif if (parmp->diff_mode && os_isdir(p) && GARGCOUNT > 0 diff --git a/src/nvim/memline.c b/src/nvim/memline.c index b5ac0cdb28..334ab935d2 100644 --- a/src/nvim/memline.c +++ b/src/nvim/memline.c @@ -913,6 +913,7 @@ void ml_recover(bool checkext) // If .swp file name given directly, use name from swapfile for buffer. if (directly) { + TO_SLASH(b0p->b0_fname); expand_env(b0p->b0_fname, NameBuff, MAXPATHL); if (setfname(curbuf, NameBuff, NULL, true) == FAIL) { goto theend; @@ -3510,6 +3511,7 @@ static char *findswapname(buf_T *buf, char **dirp, char *old_fname, bool *found_ fd = os_open(fname, O_RDONLY, 0); if (fd >= 0) { if (read_eintr(fd, &b0, sizeof(b0)) == sizeof(b0)) { + TO_SLASH(b0.b0_fname); proc_running = swapfile_proc_running(&b0, fname); // If the swapfile has the same directory as the diff --git a/src/nvim/option.c b/src/nvim/option.c index 4644fba49a..a392412d53 100644 --- a/src/nvim/option.c +++ b/src/nvim/option.c @@ -365,7 +365,7 @@ void set_init_1(bool clean_arg) memmove(backupdir + 2, backupdir, backupdir_len + 1); memmove(backupdir, ".,", 2); set_string_default(kOptBackupdir, backupdir, true); - set_string_default(kOptViewdir, stdpaths_user_state_subpath("view", 2, true), + set_string_default(kOptViewdir, stdpaths_user_state_subpath("view", 2, false), true); set_string_default(kOptDirectory, stdpaths_user_state_subpath("swap", 2, true), true); @@ -2650,6 +2650,8 @@ static const char *did_set_scrollbind(optset_T *args) #ifdef BACKSLASH_IN_FILENAME /// Process the updated 'shellslash' option value. +/// TODO(ntdiary): Remove this once we're confident that the `shellslash` +/// option is no longer needed. static const char *did_set_shellslash(optset_T *args FUNC_ATTR_UNUSED) { if (p_ssl) { @@ -2662,10 +2664,11 @@ static const char *did_set_shellslash(optset_T *args FUNC_ATTR_UNUSED) pseps[0] = '\\'; } + // TODO(ntdiary): Remove these in the follow PR. // need to adjust the file name arguments and buffer names. - buflist_slash_adjust(); - alist_slash_adjust(); - scriptnames_slash_adjust(); + // buflist_slash_adjust(); + // alist_slash_adjust(); + // scriptnames_slash_adjust(); return NULL; } #endif @@ -3903,6 +3906,29 @@ static const char *set_option(const OptIndex opt_idx, OptVal value, int opt_flag } } +#ifdef BACKSLASH_IN_FILENAME + // Ensure "/" slashes in various options. + uint32_t flags = options[opt_idx].flags; + if ((flags & kOptFlagExpand) + && opt_idx != kOptEqualprg + && opt_idx != kOptFormatprg + && opt_idx != kOptGrepprg + && opt_idx != kOptKeywordprg + && opt_idx != kOptMakeprg + && opt_idx != kOptShell) { + bool allow_comma = flags & kOptFlagComma; + bool allow_space = (opt_idx == kOptCdpath || opt_idx == kOptPath || opt_idx == kOptTags); + for (char *p = value.data.string.data; *p; p++) { + if (*p != '\\' + || (p[1] == ',' && allow_comma) + || (p[1] == ' ' && allow_space)) { + continue; + } + *p = '/'; + } + } +#endif + vimoption_T *opt = &options[opt_idx]; const bool scope_local = opt_flags & OPT_LOCAL; const bool scope_global = opt_flags & OPT_GLOBAL; diff --git a/src/nvim/os/env.c b/src/nvim/os/env.c index 329e6ebadb..8e21a8c7db 100644 --- a/src/nvim/os/env.c +++ b/src/nvim/os/env.c @@ -618,6 +618,7 @@ size_t expand_env_esc(const char *restrict srcp, char *restrict dst, int dstlen, #endif *var = NUL; var = vim_getenv(dst); + TO_SLASH(var); mustfree = true; #ifdef UNIX } @@ -661,21 +662,6 @@ size_t expand_env_esc(const char *restrict srcp, char *restrict dst, int dstlen, #endif // UNIX } -#ifdef BACKSLASH_IN_FILENAME - // If 'shellslash' is set change backslashes to forward slashes. - // Can't use slash_adjust(), p_ssl may be set temporarily. - if (p_ssl && var != NULL && vim_strchr(var, '\\') != NULL) { - char *p = xstrdup(var); - - if (mustfree) { - xfree(var); - } - var = p; - mustfree = true; - forward_slash(var); - } -#endif - // If "var" contains white space, escape it with a backslash. // Required for ":e ~/tt" when $HOME includes a space. if (esc && var != NULL && strpbrk(var, " \t") != NULL) { @@ -1034,6 +1020,7 @@ size_t home_replace(const buf_T *const buf, const char *src, char *const dst, si homedir_env = os_getenv("USERPROFILE"); } #endif + TO_SLASH(homedir_env); char *homedir_env_mod = homedir_env; bool must_free = false; diff --git a/src/nvim/os/fs.c b/src/nvim/os/fs.c index 032e4e32f0..1d1f26349d 100644 --- a/src/nvim/os/fs.c +++ b/src/nvim/os/fs.c @@ -113,6 +113,7 @@ int os_dirname(char *buf, size_t len) xstrlcpy(buf, uv_strerror(error_number), len); return FAIL; } + TO_SLASH(buf); return OK; } @@ -224,7 +225,9 @@ int os_nodetype(const char *name) int os_exepath(char *buffer, size_t *size) FUNC_ATTR_NONNULL_ALL { - return uv_exepath(buffer, size); + int r = uv_exepath(buffer, size); + TO_SLASH(buffer); + return r; } /// Checks if the file `name` is executable. @@ -1112,6 +1115,7 @@ int os_mkdtemp(const char *templ, char *path) int result = uv_fs_mkdtemp(NULL, &request, templ, NULL); if (result == kLibuvSuccess) { xstrlcpy(path, request.path, TEMP_FILE_PATH_MAXLEN); + TO_SLASH(path); } uv_fs_req_cleanup(&request); return result; @@ -1345,6 +1349,7 @@ char *os_realpath(const char *name, char *buf, size_t len) buf = xmalloc(len); } xstrlcpy(buf, request.ptr, len); + TO_SLASH(buf); } uv_fs_req_cleanup(&request); return result == kLibuvSuccess ? buf : NULL; @@ -1430,6 +1435,7 @@ shortcut_end: } CoUninitialize(); + TO_SLASH(rfname); return rfname; } diff --git a/src/nvim/os/pty_proc_win.c b/src/nvim/os/pty_proc_win.c index 14aacc9800..8cc66bf319 100644 --- a/src/nvim/os/pty_proc_win.c +++ b/src/nvim/os/pty_proc_win.c @@ -11,6 +11,7 @@ #include "nvim/os/os.h" #include "nvim/os/pty_conpty_win.h" #include "nvim/os/pty_proc_win.h" +#include "nvim/path.h" #include "os/pty_proc_win.c.generated.h" @@ -261,6 +262,9 @@ static int build_cmd_line(char **argv, wchar_t **cmd_line, bool is_cmdexe) arg_node->arg = xmalloc(buf_len); if (is_cmdexe) { xstrlcpy(arg_node->arg, *argv, buf_len); + if (argc == 0) { + TO_BACKSLASH(arg_node->arg); + } } else { quote_cmd_arg(arg_node->arg, buf_len, *argv); } diff --git a/src/nvim/os/stdpaths.c b/src/nvim/os/stdpaths.c index 19f541d252..907f7259c8 100644 --- a/src/nvim/os/stdpaths.c +++ b/src/nvim/os/stdpaths.c @@ -43,10 +43,10 @@ static const char *const xdg_defaults_env_vars[] = { /// Used in case environment variables contain nothing. Need to be expanded. static const char *const xdg_defaults[] = { #ifdef MSWIN - [kXDGConfigHome] = "~\\AppData\\Local", - [kXDGDataHome] = "~\\AppData\\Local", - [kXDGCacheHome] = "~\\AppData\\Local\\Temp", - [kXDGStateHome] = "~\\AppData\\Local", + [kXDGConfigHome] = "~/AppData/Local", + [kXDGDataHome] = "~/AppData/Local", + [kXDGCacheHome] = "~/AppData/Local/Temp", + [kXDGStateHome] = "~/AppData/Local", [kXDGRuntimeDir] = NULL, // Decided by vim_mktempdir(). [kXDGConfigDirs] = NULL, [kXDGDataDirs] = NULL, @@ -166,6 +166,7 @@ char *stdpaths_get_xdg_var(const XDGVarType idx) env_val = xstrdup(""); } #endif + TO_SLASH(env_val); char *ret = NULL; if (env_val != NULL) { @@ -213,10 +214,6 @@ char *get_xdg_home(const XDGVarType idx) } #endif dir = concat_fnames_realloc(dir, IObuff, true); - -#ifdef BACKSLASH_IN_FILENAME - slash_adjust(dir); -#endif } return dir; } @@ -266,21 +263,22 @@ char *stdpaths_user_state_subpath(const char *fname, const size_t trailing_paths FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL FUNC_ATTR_NONNULL_RET { char *ret = concat_fnames_realloc(get_xdg_home(kXDGStateHome), fname, true); - const size_t len = strlen(ret); + size_t len = strlen(ret); const size_t numcommas = (escape_commas ? memcnt(ret, ',', len) : 0); if (numcommas || trailing_pathseps) { - ret = xrealloc(ret, len + trailing_pathseps + numcommas + 1); - for (size_t i = 0; i < len + numcommas; i++) { - if (ret[i] == ',') { - memmove(ret + i + 1, ret + i, len - i + numcommas); - ret[i] = '\\'; - i++; + size_t newlen = len + numcommas + trailing_pathseps; + ret = xrealloc(ret, newlen + 1); + ret[newlen] = NUL; + + memset(ret + len + numcommas, PATHSEP, trailing_pathseps); + newlen -= trailing_pathseps; + + while (numcommas && len > 0) { + ret[--newlen] = ret[--len]; + if (ret[newlen] == ',') { + ret[--newlen] = '\\'; } } - if (trailing_pathseps) { - memset(ret + len + numcommas, PATHSEP, trailing_pathseps); - } - ret[len + trailing_pathseps + numcommas] = NUL; } return ret; } diff --git a/src/nvim/path.c b/src/nvim/path.c index 999194895b..295993f971 100644 --- a/src/nvim/path.c +++ b/src/nvim/path.c @@ -537,7 +537,7 @@ char *FullName_save(const char *fname, bool force) char *buf = xmalloc(MAXPATHL); if (vim_FullName(fname, buf, MAXPATHL, force) == FAIL) { xfree(buf); - return xstrdup(fname); + return TO_SLASH_SAVE(fname); } return buf; } @@ -551,7 +551,7 @@ char *save_abs_path(const char *name) if (!path_is_absolute(name)) { return FullName_save(name, true); } - return xstrdup(name); + return TO_SLASH_SAVE(name); } /// Checks if a path has a wildcard character including '~', unless at the end. @@ -1516,6 +1516,30 @@ void slash_adjust(char *p) } #endif +/// Convert all slashes to backslashes in-place. +char *path_to_backslash(char *p) +{ + if (p != NULL) { + strchrsub(p, PATHSEP, '\\'); + } + return p; +} + +/// Convert all backslashes to forward slashes in-place. +char *path_to_slash(char *p) +{ + if (p != NULL) { + strchrsub(p, '\\', PATHSEP); + } + return p; +} + +/// Get an allocated copy of path to convert backslashes. +char *path_to_slash_save(const char *p) +{ + return p == NULL ? NULL : path_to_slash(xstrdup(p)); +} + /// Add a file to a file list. Accepted flags: /// EW_DIR add directories /// EW_FILE add files @@ -1561,9 +1585,7 @@ void addfile(garray_T *gap, char *f, int flags) char *p = xmalloc(strlen(f) + 1 + isdir); STRCPY(p, f); -#ifdef BACKSLASH_IN_FILENAME - slash_adjust(p); -#endif + TO_SLASH(p); // Append a slash or backslash after directory names if none is present. if (isdir && (flags & EW_ADDSLASH)) { add_pathsep(p); @@ -1849,9 +1871,7 @@ int vim_FullName(const char *fname, char *buf, size_t len, bool force) if (strlen(fname) > (len - 1)) { xstrlcpy(buf, fname, len); // truncate -#ifdef MSWIN - slash_adjust(buf); -#endif + TO_SLASH(buf); return FAIL; } @@ -1864,9 +1884,7 @@ int vim_FullName(const char *fname, char *buf, size_t len, bool force) if (rv == FAIL) { xstrlcpy(buf, fname, len); // something failed; use the filename } -#ifdef MSWIN - slash_adjust(buf); -#endif + TO_SLASH(buf); return rv; } @@ -1899,7 +1917,7 @@ char *fix_fname(const char *fname) return FullName_save(fname, false); } - fname = xstrdup(fname); + fname = TO_SLASH_SAVE(fname); # ifdef CASE_INSENSITIVE_FILENAME path_fix_case((char *)fname); // set correct case for file name @@ -2476,6 +2494,7 @@ void path_guess_exepath(const char *argv0, char *buf, size_t bufsize) xstrlcat(NameBuff, argv0, sizeof(NameBuff)); if (os_can_exe(NameBuff, NULL, false)) { xstrlcpy(buf, NameBuff, bufsize); + TO_SLASH(buf); return; } } while (iter != NULL); diff --git a/src/nvim/path.h b/src/nvim/path.h index ff898d3550..48f5250e53 100644 --- a/src/nvim/path.h +++ b/src/nvim/path.h @@ -41,4 +41,14 @@ typedef enum file_comparison { kEqualFileNames = 7, ///< Both don't exist and file names are same. } FileComparison; +#ifdef BACKSLASH_IN_FILENAME +# define TO_SLASH(p) path_to_slash(p) +# define TO_SLASH_SAVE(p) path_to_slash_save(p) +# define TO_BACKSLASH(p) path_to_backslash(p) +#else +# define TO_SLASH(...) +# define TO_SLASH_SAVE(p) xstrdup(p) +# define TO_BACKSLASH(...) +#endif + #include "path.h.generated.h" diff --git a/src/nvim/quickfix.c b/src/nvim/quickfix.c index 9e90aabc5d..4a2f158232 100644 --- a/src/nvim/quickfix.c +++ b/src/nvim/quickfix.c @@ -2314,12 +2314,6 @@ static int qf_get_fnum(qf_list_T *qfl, char *directory, char *fname) return 0; } -#ifdef BACKSLASH_IN_FILENAME - if (directory != NULL) { - slash_adjust(directory); - } - slash_adjust(fname); -#endif String fname_str = cstr_as_string(fname); if (directory != NULL && !vim_isAbsName(fname)) { ptr = concat_fnames(cstr_as_string(directory), fname_str, true); @@ -2341,6 +2335,7 @@ static int qf_get_fnum(qf_list_T *qfl, char *directory, char *fname) } else { bufname = fname_str; } + TO_SLASH(bufname.data); if (qf_last_bufname != NULL && strcmp(bufname.data, qf_last_bufname) == 0 && bufref_valid(&qf_last_bufref)) { diff --git a/src/nvim/runtime.c b/src/nvim/runtime.c index e8fbda49b9..ec3c8ac9d8 100644 --- a/src/nvim/runtime.c +++ b/src/nvim/runtime.c @@ -710,6 +710,7 @@ static ArrayOf(String) runtime_get_named_common(bool lua, Array pat, bool all, item->path, pat_item.data.string.data); if (size < buf_len) { if (os_file_is_readable(buf)) { + TO_SLASH(buf); ADD_C(rv, CSTR_TO_ARENA_OBJ(arena, buf)); if (!all) { goto done; @@ -1843,10 +1844,11 @@ char *runtimepath_default(bool clean_arg) char *const config_home = clean_arg ? NULL : stdpaths_get_xdg_var(kXDGConfigHome); - char *const vimruntime = vim_getenv("VIMRUNTIME"); char *const libdir = get_lib_dir(); char *const data_dirs = stdpaths_get_xdg_var(kXDGDataDirs); char *const config_dirs = stdpaths_get_xdg_var(kXDGConfigDirs); + char *vimruntime = vim_getenv("VIMRUNTIME"); + TO_SLASH(vimruntime); #define SITE_SIZE (sizeof("site") - 1) #define AFTER_SIZE (sizeof("after") - 1) size_t data_len = 0; @@ -2537,6 +2539,7 @@ void ex_scriptnames(exarg_T *eap) } else { expand_env(eap->arg, NameBuff, MAXPATHL); eap->arg = NameBuff; + TO_SLASH(eap->arg); } do_exedit(eap, NULL); } diff --git a/src/nvim/shada.c b/src/nvim/shada.c index afeecd9542..7034c84908 100644 --- a/src/nvim/shada.c +++ b/src/nvim/shada.c @@ -3272,6 +3272,7 @@ shada_read_next_item_start: } if (HAS_KEY(&it, _shada_mark, f)) { entry->data.filemark.fname = xmemdupz(it.f.data, it.f.size); + TO_SLASH(entry->data.filemark.fname); } if (entry->data.filemark.fname == NULL) { @@ -3458,6 +3459,7 @@ shada_read_next_item_start: } if (HAS_KEY(&it, _shada_buflist_item, f)) { e->fname = xmemdupz(it.f.data, it.f.size); + TO_SLASH(e->fname); } if (e->pos.lnum <= 0) { diff --git a/src/nvim/syntax.c b/src/nvim/syntax.c index 9dd3231b48..29f2d1de9f 100644 --- a/src/nvim/syntax.c +++ b/src/nvim/syntax.c @@ -3985,6 +3985,8 @@ static void syn_cmd_include(exarg_T *eap, int syncing) } return; } + } else { + TO_SLASH(eap->arg); } // Save and restore the existing top-level grouplist id and ":syn diff --git a/src/nvim/tag.c b/src/nvim/tag.c index 78f2a53f7b..dc4c59e767 100644 --- a/src/nvim/tag.c +++ b/src/nvim/tag.c @@ -2017,11 +2017,6 @@ static void findtags_add_match(findtags_state_T *st, tagptrs_T *tagpp, findtags_ char *p = mfp; p[0] = (char)(mtt + 1); STRCPY(p + 1, st->tag_fname); -#ifdef BACKSLASH_IN_FILENAME - // Ignore differences in slashes, avoid adding - // both path/file and path\file. - slash_adjust(p + 1); -#endif p[tag_fname_len + 1] = TAG_SEP; char *s = p + 1 + tag_fname_len + 1; STRCPY(s, st->lbuf); @@ -2438,9 +2433,6 @@ static bool found_tagfile_cb(int num_fnames, char **fnames, bool all, void *cook for (int i = 0; i < num_fnames; i++) { char *const tag_fname = xstrdup(fnames[i]); -#ifdef BACKSLASH_IN_FILENAME - slash_adjust(tag_fname); -#endif simplify_filename(tag_fname); GA_APPEND(char *, &tag_fnames, tag_fname); @@ -2502,9 +2494,6 @@ int get_tagfname(tagname_T *tnp, int first, char *buf) tnp->tn_hf_idx++; xstrlcpy(buf, p_hf, MAXPATHL - STRLEN_LITERAL("tags")); STRCPY(path_tail(buf), "tags"); -#ifdef BACKSLASH_IN_FILENAME - slash_adjust(buf); -#endif simplify_filename(buf); for (int i = 0; i < tag_fnames.ga_len; i++) { @@ -3075,6 +3064,8 @@ static char *expand_tag_fname(char *fname, char *const tag_fname, const bool exp char *expanded_fname = NULL; expand_T xpc; + fname = TO_SLASH_SAVE(fname); + // Expand file name (for environment variables) when needed. // Disallow backticks, they could execute arbitrary shell // commands. This is not needed for tag filenames. @@ -3084,6 +3075,7 @@ static char *expand_tag_fname(char *fname, char *const tag_fname, const bool exp expanded_fname = ExpandOne(&xpc, fname, NULL, WILD_LIST_NOTFOUND|WILD_SILENT, WILD_EXPAND_FREE); if (expanded_fname != NULL) { + xfree(fname); fname = expanded_fname; } } @@ -3101,7 +3093,7 @@ static char *expand_tag_fname(char *fname, char *const tag_fname, const bool exp retval = xstrdup(fname); } - xfree(expanded_fname); + xfree(fname); return retval; } diff --git a/test/functional/api/vim_spec.lua b/test/functional/api/vim_spec.lua index fc91a655e0..74434225fc 100644 --- a/test/functional/api/vim_spec.lua +++ b/test/functional/api/vim_spec.lua @@ -5395,7 +5395,7 @@ describe('API', function() end, { nargs = 1 }) ]]) eq( - uv.cwd(), + t.fix_slashes(assert(uv.cwd())), api.nvim_cmd( { cmd = 'Foo', args = { '%:p:h' }, magic = { file = true } }, { output = true } diff --git a/test/functional/core/path_spec.lua b/test/functional/core/path_spec.lua index 9128cd8aab..8a48cfb7d5 100644 --- a/test/functional/core/path_spec.lua +++ b/test/functional/core/path_spec.lua @@ -14,8 +14,7 @@ local rmdir = n.rmdir local write_file = t.write_file local function join_path(...) - local pathsep = (is_os('win') and '\\' or '/') - return table.concat({ ... }, pathsep) + return table.concat({ ... }, '/') end describe('path collapse', function() diff --git a/test/functional/core/startup_spec.lua b/test/functional/core/startup_spec.lua index c627a69f33..f7e167f10b 100644 --- a/test/functional/core/startup_spec.lua +++ b/test/functional/core/startup_spec.lua @@ -1628,7 +1628,7 @@ end) describe('runtime:', function() local xhome = 'Xhome' - local pathsep = n.get_pathsep() + local pathsep = '/' local xconfig = xhome .. pathsep .. 'Xconfig' local xdata = xhome .. pathsep .. 'Xdata' local xenv = { XDG_CONFIG_HOME = xconfig, XDG_DATA_HOME = xdata } diff --git a/test/functional/ex_cmds/mksession_spec.lua b/test/functional/ex_cmds/mksession_spec.lua index 71961a2f7b..d205881fd3 100644 --- a/test/functional/ex_cmds/mksession_spec.lua +++ b/test/functional/ex_cmds/mksession_spec.lua @@ -145,7 +145,7 @@ describe(':mksession', function() it('restores buffers with tab-local CWD', function() local tmpfile_base = file_prefix .. '-tmpfile' - local cwd_dir = fn.getcwd() + local cwd_dir = t.fix_slashes(fn.getcwd()) local session_path = cwd_dir .. get_pathsep() .. session_file command('edit ' .. tmpfile_base .. '1') @@ -161,9 +161,9 @@ describe(':mksession', function() -- Use :silent to avoid hit-enter prompt due to long path command('silent source ' .. session_path) command('tabnext 1') - eq(cwd_dir .. get_pathsep() .. tmpfile_base .. '1', fn.expand('%:p')) + eq(cwd_dir .. '/' .. tmpfile_base .. '1', fn.expand('%:p')) command('tabnext 2') - eq(cwd_dir .. get_pathsep() .. tmpfile_base .. '2', fn.expand('%:p')) + eq(cwd_dir .. '/' .. tmpfile_base .. '2', fn.expand('%:p')) end) it('restores CWD for :terminal buffers #11288', function() diff --git a/test/functional/ex_cmds/source_spec.lua b/test/functional/ex_cmds/source_spec.lua index f7351dbf0c..7ce5c95fa6 100644 --- a/test/functional/ex_cmds/source_spec.lua +++ b/test/functional/ex_cmds/source_spec.lua @@ -47,7 +47,7 @@ describe(':source', function() os.remove(test_file) end) - it("changing 'shellslash' changes the result of expand()", function() + it("changing 'shellslash' doesn't affect the result of expand()", function() t.skip(not is_os('win'), "N/A: 'shellslash' only works on Windows") api.nvim_set_option_value('shellslash', false, {}) @@ -66,9 +66,9 @@ describe(':source', function() for _ = 1, 2 do command([[source Xshellslash/Xstack.vim]]) - matches([[Xshellslash\Xstack%.vim]], api.nvim_get_var('stack1')) + matches([[Xshellslash/Xstack%.vim]], api.nvim_get_var('stack1')) matches([[Xshellslash/Xstack%.vim]], api.nvim_get_var('stack2')) - matches([[Xshellslash\Xstack%.vim]], api.nvim_get_var('stack3')) + matches([[Xshellslash/Xstack%.vim]], api.nvim_get_var('stack3')) end write_file( @@ -84,9 +84,9 @@ describe(':source', function() for _ = 1, 2 do command([[source Xshellslash/Xstack.lua]]) - matches([[Xshellslash\Xstack%.lua]], api.nvim_get_var('stack1')) + matches([[Xshellslash/Xstack%.lua]], api.nvim_get_var('stack1')) matches([[Xshellslash/Xstack%.lua]], api.nvim_get_var('stack2')) - matches([[Xshellslash\Xstack%.lua]], api.nvim_get_var('stack3')) + matches([[Xshellslash/Xstack%.lua]], api.nvim_get_var('stack3')) end rmdir('Xshellslash') @@ -326,14 +326,13 @@ describe(':source', function() end) it('$HOME is not shortened in filepath in v:stacktrace from sourced file', function() - local sep = n.get_pathsep() - local xhome = table.concat({ vim.uv.cwd(), 'Xhome' }, sep) + local xhome = t.fix_slashes(assert(vim.uv.cwd())) .. '/Xhome' mkdir(xhome) clear({ env = { HOME = xhome } }) finally(function() rmdir(xhome) end) - local filepath = table.concat({ xhome, 'Xstacktrace.vim' }, sep) + local filepath = xhome .. '/Xstacktrace.vim' local script = [[ func Xfunc() throw 'Exception from Xfunc' diff --git a/test/functional/ex_cmds/verbose_spec.lua b/test/functional/ex_cmds/verbose_spec.lua index 67ce9d894c..148059c12a 100644 --- a/test/functional/ex_cmds/verbose_spec.lua +++ b/test/functional/ex_cmds/verbose_spec.lua @@ -17,9 +17,9 @@ local function last_set_lua_verbose_tests(cmd, v1) setup(function() clear(v1 and { args = { '-V1' } } or nil) script_file = 'test_verbose.lua' - local current_dir = fn.getcwd() + local current_dir = assert(t.fix_slashes(fn.getcwd())) current_dir = fn.fnamemodify(current_dir, ':~') - script_location = table.concat({ current_dir, n.get_pathsep(), script_file }) + script_location = current_dir .. '/' .. script_file write_file( script_file, @@ -326,9 +326,9 @@ describe(':verbose when using API from Vimscript', function() setup(function() clear() script_file = 'test_verbose.vim' - local current_dir = fn.getcwd() + local current_dir = assert(t.fix_slashes(fn.getcwd())) current_dir = fn.fnamemodify(current_dir, ':~') - script_location = table.concat({ current_dir, n.get_pathsep(), script_file }) + script_location = current_dir .. '/' .. script_file write_file( script_file, diff --git a/test/functional/legacy/097_glob_path_spec.lua b/test/functional/legacy/097_glob_path_spec.lua index 4d4bb9e78f..b2d22e2a89 100644 --- a/test/functional/legacy/097_glob_path_spec.lua +++ b/test/functional/legacy/097_glob_path_spec.lua @@ -41,15 +41,6 @@ describe('glob() and globpath()', function() command([[$put =string(globpath('sautest\autoload', '*.vim'))]]) command([[$put =string(globpath('sautest\autoload', '*.vim', 0, 1))]]) - expect([=[ - - - - Xxx{ - Xxx$ - 'sautest\autoload\Test104.vim - sautest\autoload\footest.vim' - ['sautest\autoload\Test104.vim', 'sautest\autoload\footest.vim']]=]) else command([[$put =glob('Xxx\{')]]) command([[$put =glob('Xxx\$')]]) @@ -61,16 +52,16 @@ describe('glob() and globpath()', function() command("$put =string(globpath('sautest/autoload', '*.vim'))") command("$put =string(globpath('sautest/autoload', '*.vim', 0, 1))") - expect([=[ - - - - Xxx{ - Xxx$ - 'sautest/autoload/Test104.vim - sautest/autoload/footest.vim' - ['sautest/autoload/Test104.vim', 'sautest/autoload/footest.vim']]=]) end + expect([=[ + + + + Xxx{ + Xxx$ + 'sautest/autoload/Test104.vim + sautest/autoload/footest.vim' + ['sautest/autoload/Test104.vim', 'sautest/autoload/footest.vim']]=]) end) teardown(function() diff --git a/test/functional/options/defaults_spec.lua b/test/functional/options/defaults_spec.lua index ca8bbd370e..f87cfa747d 100644 --- a/test/functional/options/defaults_spec.lua +++ b/test/functional/options/defaults_spec.lua @@ -291,10 +291,8 @@ describe('XDG defaults', function() clear() local rtp = eval('split(&runtimepath, ",")') local rv = {} - local expected = ( - is_os('win') and { [[\nvim-data\site]], [[\nvim-data\site\after]] } - or { '/nvim/site', '/nvim/site/after' } - ) + local data_dir = is_os('win') and '/nvim-data' or '/nvim' + local expected = { data_dir .. '/site', data_dir .. '/site/after' } for _, v in ipairs(rtp) do local m = string.match(v, [=[[/\]nvim[^/\]*[/\]site.*$]=]) @@ -695,7 +693,7 @@ describe('XDG defaults', function() it('are escaped properly', function() local vimruntime, libdir = vimruntime_and_libdir() - local path_sep = is_os('win') and '\\' or '/' + local path_sep = '/' eq( ( '\\, \\, \\,' @@ -869,17 +867,7 @@ describe('XDG defaults', function() .. (path_sep):rep(2), api.nvim_get_option_value('undodir', {}) ) - eq( - '\\,=\\,=\\,' - .. path_sep - .. '' - .. state_dir - .. '' - .. path_sep - .. 'view' - .. (path_sep):rep(2), - api.nvim_get_option_value('viewdir', {}) - ) + eq(',=,=,/' .. state_dir .. '/view//', api.nvim_get_option_value('viewdir', {})) end) end) end) diff --git a/test/functional/terminal/ex_terminal_spec.lua b/test/functional/terminal/ex_terminal_spec.lua index d6ecd816e1..62f238e6b5 100644 --- a/test/functional/terminal/ex_terminal_spec.lua +++ b/test/functional/terminal/ex_terminal_spec.lua @@ -314,11 +314,7 @@ local function test_terminal_with_fake_shell(backslash) eq('term://', string.match(eval('bufname("%")'), '^term://')) feed([[]]) command([[find */Xuniquefile]]) - if is_os('win') then - eq('Xsomedir\\Xuniquefile', eval('bufname("%")')) - else - eq('Xsomedir/Xuniquefile', eval('bufname("%")')) - end + eq('Xsomedir/Xuniquefile', eval('bufname("%")')) end) it('works with gf', function() diff --git a/test/functional/ui/title_spec.lua b/test/functional/ui/title_spec.lua index 1004c1e77b..e2a0881569 100644 --- a/test/functional/ui/title_spec.lua +++ b/test/functional/ui/title_spec.lua @@ -21,7 +21,7 @@ describe('title', function() end) it('defaults to "No Name" and the PWD in the title if the buffer is unnamed', function() - local expected = (is_os('win') and '[No Name] (C:\\) - Nvim' or '[No Name] (/) - Nvim') + local expected = (is_os('win') and '[No Name] (C:/) - Nvim' or '[No Name] (/) - Nvim') command(is_os('win') and 'cd C:\\' or 'cd /') command('set title') screen:expect(function() @@ -32,7 +32,7 @@ describe('title', function() it( 'defaults to the filename and its directory in the title if the buffer is named as a path outside the PWD', function() - local expected = (is_os('win') and 'myfile (C:\\mydir) - Nvim' or 'myfile (/mydir) - Nvim') + local expected = (is_os('win') and 'myfile (C:/mydir) - Nvim' or 'myfile (/mydir) - Nvim') command('set title') command(is_os('win') and 'file C:\\mydir\\myfile' or 'file /mydir/myfile') screen:expect(function() @@ -44,7 +44,7 @@ describe('title', function() it( 'defaults to the filename and the PWD in the title if the buffer is a file in the PWD', function() - local expected = (is_os('win') and 'myfile (C:\\) - Nvim' or 'myfile (/) - Nvim') + local expected = (is_os('win') and 'myfile (C:/) - Nvim' or 'myfile (/) - Nvim') command('set title') command(is_os('win') and 'cd C:\\' or 'cd /') command('file myfile') @@ -58,12 +58,12 @@ describe('title', function() command(is_os('win') and 'cd C:\\' or 'cd /') api.nvim_set_option_value('title', true, {}) screen:expect(function() - local expected = (is_os('win') and '[No Name] (C:\\) - Nvim' or '[No Name] (/) - Nvim') + local expected = (is_os('win') and '[No Name] (C:/) - Nvim' or '[No Name] (/) - Nvim') eq(expected, screen.title) end) feed('ifoo') screen:expect(function() - local expected = (is_os('win') and '[No Name] + (C:\\) - Nvim' or '[No Name] + (/) - Nvim') + local expected = (is_os('win') and '[No Name] + (C:/) - Nvim' or '[No Name] + (/) - Nvim') eq(expected, screen.title) end) feed('') @@ -126,7 +126,7 @@ describe('title', function() describe('is not changed by', function() local file1 = is_os('win') and 'C:\\mydir\\myfile1' or '/mydir/myfile1' local file2 = is_os('win') and 'C:\\mydir\\myfile2' or '/mydir/myfile2' - local expected = (is_os('win') and 'myfile1 (C:\\mydir) - Nvim' or 'myfile1 (/mydir) - Nvim') + local expected = (is_os('win') and 'myfile1 (C:/mydir) - Nvim' or 'myfile1 (/mydir) - Nvim') local buf2 before_each(function() diff --git a/test/functional/vimscript/buf_functions_spec.lua b/test/functional/vimscript/buf_functions_spec.lua index c73f4b5197..a4389ca97a 100644 --- a/test/functional/vimscript/buf_functions_spec.lua +++ b/test/functional/vimscript/buf_functions_spec.lua @@ -6,7 +6,6 @@ local clear = n.clear local fn = n.fn local api = n.api local command = n.command -local get_pathsep = n.get_pathsep local rmdir = n.rmdir local pcall_err = t.pcall_err local mkdir = t.mkdir @@ -81,8 +80,8 @@ describe('bufname() function', function() it('returns expected buffer name', function() eq('', fn.bufname('%')) -- Buffer has no name yet command('file ' .. fname) - local wd = vim.uv.cwd() - local sep = get_pathsep() + local wd = assert(t.fix_slashes(assert(vim.uv.cwd()))) + local sep = '/' local curdirname = fn.fnamemodify(wd, ':t') for _, arg in ipairs({ '%', 1, 'X', wd }) do eq(fname, fn.bufname(arg)) diff --git a/test/functional/vimscript/eval_spec.lua b/test/functional/vimscript/eval_spec.lua index eeebdd9aa0..415780e030 100644 --- a/test/functional/vimscript/eval_spec.lua +++ b/test/functional/vimscript/eval_spec.lua @@ -85,7 +85,7 @@ describe('backtick expansion', function() eq({ 'file2' }, eval('argv()')) if t.is_os('win') then command(':silent args `dir /s/b *4`') - eq({ 'subdir\\file4' }, eval('map(argv(), \'fnamemodify(v:val, ":.")\')')) + eq({ 'subdir/file4' }, eval('map(argv(), \'fnamemodify(v:val, ":.")\')')) else command(':silent args `echo */*4`') eq({ 'subdir/file4' }, eval('argv()')) diff --git a/test/functional/vimscript/executable_spec.lua b/test/functional/vimscript/executable_spec.lua index 943e2e10d0..bb52c861f0 100644 --- a/test/functional/vimscript/executable_spec.lua +++ b/test/functional/vimscript/executable_spec.lua @@ -19,13 +19,13 @@ describe('executable()', function() end) if is_os('win') then - it('exepath respects shellslash', function() + it('exepath returns consistent slashes #13787', function() -- test/ cannot be a symlink in this test. n.api.nvim_set_current_dir(t.paths.test_source_path) command('let $PATH = fnamemodify("./test/functional/fixtures/bin", ":p")') eq( - [[test\functional\fixtures\bin\null.CMD]], + [[test/functional/fixtures/bin/null.CMD]], call('fnamemodify', call('exepath', 'null'), ':.') ) command('set shellslash') @@ -35,12 +35,12 @@ describe('executable()', function() ) end) - it('stdpath respects shellslash', function() + it('stdpath returns consistent slashes #13787', function() -- Needs to check paths relative to repo root dir. n.api.nvim_set_current_dir(t.paths.test_source_path) t.matches( - [[build\Xtest_xdg[%w_]*\share\nvim%-data]], + [[build/Xtest_xdg[%w_]*/share/nvim%-data]], call('fnamemodify', call('stdpath', 'data'), ':.') ) command('set shellslash') diff --git a/test/functional/vimscript/fnamemodify_spec.lua b/test/functional/vimscript/fnamemodify_spec.lua index 380471320e..7b581c225f 100644 --- a/test/functional/vimscript/fnamemodify_spec.lua +++ b/test/functional/vimscript/fnamemodify_spec.lua @@ -29,21 +29,20 @@ describe('fnamemodify()', function() end) it('handles the root path', function() - local root = n.pathroot() + local root = assert(t.fix_slashes(n.pathroot())) eq(root, fnamemodify([[/]], ':p:h')) eq(root, fnamemodify([[/]], ':p')) if is_os('win') then eq(root, fnamemodify([[\]], ':p:h')) eq(root, fnamemodify([[\]], ':p')) command('set shellslash') - root = string.sub(root, 1, -2) .. '/' eq(root, fnamemodify([[\]], ':p:h')) eq(root, fnamemodify([[\]], ':p')) eq(root, fnamemodify([[/]], ':p:h')) eq(root, fnamemodify([[/]], ':p')) local letter_colon = root:sub(1, 2) - local old_dir = getcwd() .. '/' + local old_dir = t.fix_slashes(getcwd()) .. '/' local foo_dir = old_dir .. 'foo/' eq(old_dir, fnamemodify(letter_colon, ':p')) eq(old_dir, fnamemodify(letter_colon .. '.', ':p')) diff --git a/test/old/testdir/test_expand_func.vim b/test/old/testdir/test_expand_func.vim index 281e7c13e2..a6488f07f2 100644 --- a/test/old/testdir/test_expand_func.vim +++ b/test/old/testdir/test_expand_func.vim @@ -72,12 +72,12 @@ func Test_expand_sfile_and_stack() let g:stack3 = expand('') END call writefile(lines, 'Xshellslash/Xstack') - " Test that changing 'shellslash' always affects the result of expand() + " Test that changing 'shellslash' doesn't affect the result of expand() " when sourcing a script multiple times. for i in range(2) source Xshellslash/Xstack call assert_match('\