# HG changeset patch # User Christian Brabandt # Date 1532547006 -7200 # Node ID c62601adad6940e4aa1cf5d34ae7c227c9c8e5cc # Parent 3d1aca4a35f87f5e9d56c93ac638eb8695e245f0 patch 8.1.0211: expanding a file name "~" results in $HOME commit https://github.com/vim/vim/commit/00136dc321586800986e8f743c2f108f5eecbf92 Author: Bram Moolenaar Date: Wed Jul 25 21:19:13 2018 +0200 patch 8.1.0211: expanding a file name "~" results in $HOME Problem: Expanding a file name "~" results in $HOME. (Aidan Shafran) Solution: Change "~" to "./~" before expanding. (closes https://github.com/vim/vim/issues/3072) diff --git a/src/eval.c b/src/eval.c --- a/src/eval.c +++ b/src/eval.c @@ -9690,11 +9690,12 @@ shortpath_for_partial( */ int modify_fname( - char_u *src, /* string with modifiers */ - int *usedlen, /* characters after src that are used */ - char_u **fnamep, /* file name so far */ - char_u **bufp, /* buffer for allocated file name or NULL */ - int *fnamelen) /* length of fnamep */ + char_u *src, // string with modifiers + int tilde_file, // "~" is a file name, not $HOME + int *usedlen, // characters after src that are used + char_u **fnamep, // file name so far + char_u **bufp, // buffer for allocated file name or NULL + int *fnamelen) // length of fnamep { int valid = 0; char_u *tail; @@ -9724,8 +9725,8 @@ repeat: || (*fnamep)[1] == '\\' # endif || (*fnamep)[1] == NUL) - #endif + && !(tilde_file && (*fnamep)[1] == NUL) ) { *fnamep = expand_env_save(*fnamep); diff --git a/src/evalfunc.c b/src/evalfunc.c --- a/src/evalfunc.c +++ b/src/evalfunc.c @@ -3801,7 +3801,7 @@ f_fnamemodify(typval_T *argvars, typval_ else { len = (int)STRLEN(fname); - (void)modify_fname(mods, &usedlen, &fname, &fbuf, &len); + (void)modify_fname(mods, FALSE, &usedlen, &fname, &fbuf, &len); } rettv->v_type = VAR_STRING; diff --git a/src/ex_docmd.c b/src/ex_docmd.c --- a/src/ex_docmd.c +++ b/src/ex_docmd.c @@ -10654,6 +10654,7 @@ eval_vars( int resultlen; buf_T *buf; int valid = VALID_HEAD + VALID_PATH; /* assume valid result */ + int tilde_file = FALSE; int spec_idx; #ifdef FEAT_MODIFY_FNAME int skip_mod = FALSE; @@ -10720,7 +10721,10 @@ eval_vars( valid = 0; /* Must have ":p:h" to be valid */ } else + { result = curbuf->b_fname; + tilde_file = STRCMP(result, "~") == 0; + } break; case SPEC_HASH: /* '#' or "#99": alternate file */ @@ -10784,7 +10788,10 @@ eval_vars( valid = 0; /* Must have ":p:h" to be valid */ } else + { result = buf->b_fname; + tilde_file = STRCMP(result, "~") == 0; + } } break; @@ -10877,7 +10884,7 @@ eval_vars( #ifdef FEAT_MODIFY_FNAME else if (!skip_mod) { - valid |= modify_fname(src, usedlen, &result, &resultbuf, + valid |= modify_fname(src, tilde_file, usedlen, &result, &resultbuf, &resultlen); if (result == NULL) { diff --git a/src/if_cscope.c b/src/if_cscope.c --- a/src/if_cscope.c +++ b/src/if_cscope.c @@ -519,7 +519,7 @@ cs_add_common( #ifdef FEAT_MODIFY_FNAME len = (int)STRLEN(fname); fbuf = (char_u *)fname; - (void)modify_fname((char_u *)":p", &usedlen, + (void)modify_fname((char_u *)":p", FALSE, &usedlen, (char_u **)&fname, &fbuf, &len); if (fname == NULL) goto add_err; diff --git a/src/misc1.c b/src/misc1.c --- a/src/misc1.c +++ b/src/misc1.c @@ -4908,7 +4908,7 @@ home_replace( char_u *fbuf = NULL; flen = (int)STRLEN(homedir_env); - (void)modify_fname((char_u *)":p", &usedlen, + (void)modify_fname((char_u *)":p", FALSE, &usedlen, &homedir_env, &fbuf, &flen); flen = (int)STRLEN(homedir_env); if (flen > 0 && vim_ispathsep(homedir_env[flen - 1])) diff --git a/src/proto/eval.pro b/src/proto/eval.pro --- a/src/proto/eval.pro +++ b/src/proto/eval.pro @@ -136,7 +136,7 @@ void fill_assert_error(garray_T *gap, ty int typval_compare(typval_T *typ1, typval_T *typ2, exptype_T type, int type_is, int ic); char_u *typval_tostring(typval_T *arg); int var_exists(char_u *var); -int modify_fname(char_u *src, int *usedlen, char_u **fnamep, char_u **bufp, int *fnamelen); +int modify_fname(char_u *src, int tilde_file, int *usedlen, char_u **fnamep, char_u **bufp, int *fnamelen); char_u *do_string_sub(char_u *str, char_u *pat, char_u *sub, typval_T *expr, char_u *flags); void filter_map(typval_T *argvars, typval_T *rettv, int map); /* vim: set ft=c : */ diff --git a/src/testdir/test_expand.vim b/src/testdir/test_expand.vim --- a/src/testdir/test_expand.vim +++ b/src/testdir/test_expand.vim @@ -39,3 +39,11 @@ func Test_with_tilde() call delete('Xdir ~ dir', 'd') call assert_false(isdirectory('Xdir ~ dir')) endfunc + +func Test_expand_tilde_filename() + split ~ + call assert_equal('~', expand('%')) + call assert_notequal(expand('%:p'), expand('~/')) + call assert_match('\~', expand('%:p')) + bwipe! +endfunc diff --git a/src/version.c b/src/version.c --- a/src/version.c +++ b/src/version.c @@ -794,6 +794,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 211, +/**/ 210, /**/ 209,