Skip to content

Commit 5fa7ca5

Browse files
committed
Merge remote-tracking branch 'vim/master'
2 parents c66ee27 + 42c9cfa commit 5fa7ca5

29 files changed

+404
-72
lines changed

runtime/doc/eval.txt

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
*eval.txt* For Vim version 7.4. Last change: 2016 Jan 15
1+
*eval.txt* For Vim version 7.4. Last change: 2016 Jan 16
22

33

44
VIM REFERENCE MANUAL by Bram Moolenaar
@@ -919,6 +919,11 @@ just above, except that indexes out of range cause an error. Examples: >
919919
Using expr8[expr1] or expr8[expr1a : expr1b] on a |Funcref| results in an
920920
error.
921921

922+
Watch out for confusion between a namespace and a variable followed by a colon
923+
for a sublist: >
924+
mylist[n:] " uses variable n
925+
mylist[s:] " uses namespace s:, error!
926+
922927
923928
expr8.name entry in a |Dictionary| *expr-entry*
924929

@@ -1794,7 +1799,7 @@ cursor( {lnum}, {col} [, {off}])
17941799
Number move cursor to {lnum}, {col}, {off}
17951800
cursor( {list}) Number move cursor to position in {list}
17961801
deepcopy( {expr} [, {noref}]) any make a full copy of {expr}
1797-
delete( {fname}) Number delete file {fname}
1802+
delete( {fname} [, {flags}]) Number delete the file or directory {fname}
17981803
did_filetype() Number TRUE if FileType autocommand event used
17991804
diff_filler( {lnum}) Number diff filler lines about {lnum}
18001805
diff_hlID( {lnum}, {col}) Number diff highlighting at {lnum}/{col}
@@ -2748,10 +2753,20 @@ deepcopy({expr}[, {noref}]) *deepcopy()* *E698*
27482753
{noref} set to 1 will fail.
27492754
Also see |copy()|.
27502755

2751-
delete({fname}) *delete()*
2752-
Deletes the file by the name {fname}. The result is a Number,
2753-
which is 0 if the file was deleted successfully, and non-zero
2754-
when the deletion failed.
2756+
delete({fname} [, {flags}]) *delete()*
2757+
Without {flags} or with {flags} empty: Deletes the file by the
2758+
name {fname}. This also works when {fname} is a symbolic link.
2759+
2760+
When {flags} is "d": Deletes the directory by the name
2761+
{fname}. This fails when directory {fname} is not empty.
2762+
2763+
When {flags} is "rf": Deletes the directory by the name
2764+
{fname} and everything in it, recursively. BE CAREFUL!
2765+
A symbolic link itself is deleted, not what it points to.
2766+
2767+
The result is a Number, which is 0 if the delete operation was
2768+
successful and -1 when the deletion failed or partly failed.
2769+
27552770
Use |remove()| to delete an item from a |List|.
27562771
To delete a line from the buffer use |:delete|. Use |:exe|
27572772
when the line number is in a variable.

src/Makefile

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1992,12 +1992,15 @@ test1 \
19921992
test70 test71 test72 test73 test74 test75 test76 test77 test78 test79 \
19931993
test80 test81 test82 test83 test84 test85 test86 test87 test88 test89 \
19941994
test90 test91 test92 test93 test94 test95 test96 test97 test98 test99 \
1995-
test100 test101 test102 test103 test104 test105 test106 test107:
1995+
test100 test101 test102 test103 test104 test105 test106 test107 test108:
19961996
cd testdir; rm -f $@.out; $(MAKE) -f Makefile $@.out VIMPROG=../$(VIMTARGET) $(GUI_TESTARG) SCRIPTSOURCE=../$(SCRIPTSOURCE)
19971997

19981998
test_assert \
19991999
test_backspace_opt \
20002000
test_cdo \
2001+
test_cursor_func \
2002+
test_delete \
2003+
test_expand \
20012004
test_hardcopy \
20022005
test_increment \
20032006
test_lispwords \

src/eval.c

Lines changed: 32 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8132,7 +8132,7 @@ static struct fst
81328132
{"cscope_connection",0,3, f_cscope_connection},
81338133
{"cursor", 1, 3, f_cursor},
81348134
{"deepcopy", 1, 2, f_deepcopy},
8135-
{"delete", 1, 1, f_delete},
8135+
{"delete", 1, 2, f_delete},
81368136
{"did_filetype", 0, 0, f_did_filetype},
81378137
{"diff_filler", 1, 1, f_diff_filler},
81388138
{"diff_hlID", 2, 2, f_diff_hlID},
@@ -10392,10 +10392,37 @@ f_delete(argvars, rettv)
1039210392
typval_T *argvars;
1039310393
typval_T *rettv;
1039410394
{
10395+
char_u nbuf[NUMBUFLEN];
10396+
char_u *name;
10397+
char_u *flags;
10398+
10399+
rettv->vval.v_number = -1;
1039510400
if (check_restricted() || check_secure())
10396-
rettv->vval.v_number = -1;
10401+
return;
10402+
10403+
name = get_tv_string(&argvars[0]);
10404+
if (name == NULL || *name == NUL)
10405+
{
10406+
EMSG(_(e_invarg));
10407+
return;
10408+
}
10409+
10410+
if (argvars[1].v_type != VAR_UNKNOWN)
10411+
flags = get_tv_string_buf(&argvars[1], nbuf);
1039710412
else
10398-
rettv->vval.v_number = mch_remove(get_tv_string(&argvars[0]));
10413+
flags = (char_u *)"";
10414+
10415+
if (*flags == NUL)
10416+
/* delete a file */
10417+
rettv->vval.v_number = mch_remove(name) == 0 ? 0 : -1;
10418+
else if (STRCMP(flags, "d") == 0)
10419+
/* delete an empty directory */
10420+
rettv->vval.v_number = mch_rmdir(name) == 0 ? 0 : -1;
10421+
else if (STRCMP(flags, "rf") == 0)
10422+
/* delete a directory recursively */
10423+
rettv->vval.v_number = delete_recursive(name);
10424+
else
10425+
EMSG2(_(e_invexpr2), flags);
1039910426
}
1040010427

1040110428
/*
@@ -20845,10 +20872,10 @@ find_name_end(arg, expr_start, expr_end, flags)
2084520872
else if (br_nest == 0 && mb_nest == 0 && *p == ':')
2084620873
{
2084720874
/* "s:" is start of "s:var", but "n:" is not and can be used in
20848-
* slice "[n:]". Also "xx:" is not a namespace. */
20875+
* slice "[n:]". Also "xx:" is not a namespace. But {ns}: is. */
2084920876
len = (int)(p - arg);
2085020877
if ((len == 1 && vim_strchr(NAMESPACE_CHAR, *arg) == NULL)
20851-
|| len > 1)
20878+
|| (len > 1 && p[-1] != '}'))
2085220879
break;
2085320880
}
2085420881

src/ex_cmds2.c

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2220,9 +2220,7 @@ do_arglist(str, what, after)
22202220
i = expand_wildcards(new_ga.ga_len, (char_u **)new_ga.ga_data,
22212221
&exp_count, &exp_files, EW_DIR|EW_FILE|EW_ADDSLASH|EW_NOTFOUND);
22222222
ga_clear(&new_ga);
2223-
if (i == FAIL)
2224-
return FAIL;
2225-
if (exp_count == 0)
2223+
if (i == FAIL || exp_count == 0)
22262224
{
22272225
EMSG(_(e_nomatch));
22282226
return FAIL;
@@ -2637,6 +2635,10 @@ ex_argdelete(eap)
26372635
curwin->w_arg_idx -= n;
26382636
else if (curwin->w_arg_idx > eap->line1)
26392637
curwin->w_arg_idx = eap->line1;
2638+
if (ARGCOUNT == 0)
2639+
curwin->w_arg_idx = 0;
2640+
else if (curwin->w_arg_idx >= ARGCOUNT)
2641+
curwin->w_arg_idx = ARGCOUNT - 1;
26402642
}
26412643
}
26422644
else if (*eap->arg == NUL)

src/fileio.c

Lines changed: 53 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -7318,39 +7318,77 @@ write_lnum_adjust(offset)
73187318
curbuf->b_no_eol_lnum += offset;
73197319
}
73207320

7321-
#if defined(TEMPDIRNAMES) || defined(PROTO)
7322-
static long temp_count = 0; /* Temp filename counter. */
7323-
7321+
#if defined(TEMPDIRNAMES) || defined(FEAT_EVAL) || defined(PROTO)
73247322
/*
7325-
* Delete the temp directory and all files it contains.
7323+
* Delete "name" and everything in it, recursively.
7324+
* return 0 for succes, -1 if some file was not deleted.
73267325
*/
7327-
void
7328-
vim_deltempdir()
7326+
int
7327+
delete_recursive(char_u *name)
73297328
{
7329+
int result = 0;
73307330
char_u **files;
73317331
int file_count;
73327332
int i;
7333+
char_u *exp;
73337334

7334-
if (vim_tempdir != NULL)
7335+
/* A symbolic link to a directory itself is deleted, not the directory it
7336+
* points to. */
7337+
if (
7338+
# if defined(WIN32)
7339+
mch_isdir(name) && !mch_is_symbolic_link(name)
7340+
# else
7341+
# ifdef UNIX
7342+
mch_isrealdir(name)
7343+
# else
7344+
mch_isdir(name)
7345+
# endif
7346+
# endif
7347+
)
73357348
{
7336-
sprintf((char *)NameBuff, "%s*", vim_tempdir);
7337-
if (gen_expand_wildcards(1, &NameBuff, &file_count, &files,
7338-
EW_DIR|EW_FILE|EW_SILENT) == OK)
7349+
vim_snprintf((char *)NameBuff, MAXPATHL, "%s/*", name);
7350+
exp = vim_strsave(NameBuff);
7351+
if (exp == NULL)
7352+
return -1;
7353+
if (gen_expand_wildcards(1, &exp, &file_count, &files,
7354+
EW_DIR|EW_FILE|EW_SILENT|EW_ALLLINKS|EW_DODOT|EW_EMPTYOK) == OK)
73397355
{
73407356
for (i = 0; i < file_count; ++i)
7341-
mch_remove(files[i]);
7357+
if (delete_recursive(files[i]) != 0)
7358+
result = -1;
73427359
FreeWild(file_count, files);
73437360
}
7344-
gettail(NameBuff)[-1] = NUL;
7345-
(void)mch_rmdir(NameBuff);
7361+
else
7362+
result = -1;
7363+
vim_free(exp);
7364+
(void)mch_rmdir(name);
7365+
}
7366+
else
7367+
result = mch_remove(name) == 0 ? 0 : -1;
73467368

7369+
return result;
7370+
}
7371+
#endif
7372+
7373+
#if defined(TEMPDIRNAMES) || defined(PROTO)
7374+
static long temp_count = 0; /* Temp filename counter. */
7375+
7376+
/*
7377+
* Delete the temp directory and all files it contains.
7378+
*/
7379+
void
7380+
vim_deltempdir()
7381+
{
7382+
if (vim_tempdir != NULL)
7383+
{
7384+
/* remove the trailing path separator */
7385+
gettail(vim_tempdir)[-1] = NUL;
7386+
delete_recursive(vim_tempdir);
73477387
vim_free(vim_tempdir);
73487388
vim_tempdir = NULL;
73497389
}
73507390
}
7351-
#endif
73527391

7353-
#ifdef TEMPDIRNAMES
73547392
/*
73557393
* Directory "tempdir" was created. Expand this name to a full path and put
73567394
* it in "vim_tempdir". This avoids that using ":cd" would confuse us.

src/misc1.c

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10019,7 +10019,7 @@ dos_expandpath(
1001910019
if (p[0] == '*' && p[1] == '*')
1002010020
starstar = TRUE;
1002110021

10022-
starts_with_dot = (*s == '.');
10022+
starts_with_dot = *s == '.';
1002310023
pat = file_pat_to_reg_pat(s, e, NULL, FALSE);
1002410024
if (pat == NULL)
1002510025
{
@@ -10102,7 +10102,9 @@ dos_expandpath(
1010210102
#endif
1010310103
/* Ignore entries starting with a dot, unless when asked for. Accept
1010410104
* all entries found with "matchname". */
10105-
if ((p[0] != '.' || starts_with_dot)
10105+
if ((p[0] != '.' || starts_with_dot
10106+
|| ((flags & EW_DODOT)
10107+
&& p[1] != NUL && (p[1] != '.' || p[2] != NUL)))
1010610108
&& (matchname == NULL
1010710109
|| (regmatch.regprog != NULL
1010810110
&& vim_regexec(&regmatch, p, (colnr_T)0))
@@ -10331,7 +10333,7 @@ unix_expandpath(gap, path, wildoff, flags, didstar)
1033110333
starstar = TRUE;
1033210334

1033310335
/* convert the file pattern to a regexp pattern */
10334-
starts_with_dot = (*s == '.');
10336+
starts_with_dot = *s == '.';
1033510337
pat = file_pat_to_reg_pat(s, e, NULL, FALSE);
1033610338
if (pat == NULL)
1033710339
{
@@ -10380,7 +10382,10 @@ unix_expandpath(gap, path, wildoff, flags, didstar)
1038010382
dp = readdir(dirp);
1038110383
if (dp == NULL)
1038210384
break;
10383-
if ((dp->d_name[0] != '.' || starts_with_dot)
10385+
if ((dp->d_name[0] != '.' || starts_with_dot
10386+
|| ((flags & EW_DODOT)
10387+
&& dp->d_name[1] != NUL
10388+
&& (dp->d_name[1] != '.' || dp->d_name[2] != NUL)))
1038410389
&& ((regmatch.regprog != NULL && vim_regexec(&regmatch,
1038510390
(char_u *)dp->d_name, (colnr_T)0))
1038610391
|| ((flags & EW_NOTWILD)
@@ -11088,7 +11093,7 @@ gen_expand_wildcards(num_pat, pat, num_file, file, flags)
1108811093

1108911094
recursive = FALSE;
1109011095

11091-
return (ga.ga_data != NULL) ? retval : FAIL;
11096+
return ((flags & EW_EMPTYOK) || ga.ga_data != NULL) ? retval : FAIL;
1109211097
}
1109311098

1109411099
# ifdef VIM_BACKTICK

src/misc2.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5549,7 +5549,7 @@ find_file_in_path_option(ptr, len, options, first, path_option,
55495549
/* copy file name into NameBuff, expanding environment variables */
55505550
save_char = ptr[len];
55515551
ptr[len] = NUL;
5552-
expand_env(ptr, NameBuff, MAXPATHL);
5552+
expand_env_esc(ptr, NameBuff, MAXPATHL, FALSE, TRUE, NULL);
55535553
ptr[len] = save_char;
55545554

55555555
vim_free(ff_file_to_find);

src/os_unix.c

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2996,7 +2996,7 @@ mch_hide(name)
29962996
}
29972997

29982998
/*
2999-
* return TRUE if "name" is a directory
2999+
* return TRUE if "name" is a directory or a symlink to a directory
30003000
* return FALSE if "name" is not a directory
30013001
* return FALSE for error
30023002
*/
@@ -3017,6 +3017,28 @@ mch_isdir(name)
30173017
#endif
30183018
}
30193019

3020+
/*
3021+
* return TRUE if "name" is a directory, NOT a symlink to a directory
3022+
* return FALSE if "name" is not a directory
3023+
* return FALSE for error
3024+
*/
3025+
int
3026+
mch_isrealdir(name)
3027+
char_u *name;
3028+
{
3029+
struct stat statb;
3030+
3031+
if (*name == NUL) /* Some stat()s don't flag "" as an error. */
3032+
return FALSE;
3033+
if (lstat((char *)name, &statb))
3034+
return FALSE;
3035+
#ifdef _POSIX_SOURCE
3036+
return (S_ISDIR(statb.st_mode) ? TRUE : FALSE);
3037+
#else
3038+
return ((statb.st_mode & S_IFMT) == S_IFDIR ? TRUE : FALSE);
3039+
#endif
3040+
}
3041+
30203042
static int executable_file __ARGS((char_u *name));
30213043

30223044
/*

src/os_win32.c

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3153,6 +3153,30 @@ mch_mkdir(char_u *name)
31533153
return _mkdir(name);
31543154
}
31553155

3156+
/*
3157+
* Delete directory "name".
3158+
* Return 0 on success, -1 on error.
3159+
*/
3160+
int
3161+
mch_rmdir(char_u *name)
3162+
{
3163+
#ifdef FEAT_MBYTE
3164+
if (enc_codepage >= 0 && (int)GetACP() != enc_codepage)
3165+
{
3166+
WCHAR *p;
3167+
int retval;
3168+
3169+
p = enc_to_utf16(name, NULL);
3170+
if (p == NULL)
3171+
return -1;
3172+
retval = _wrmdir(p);
3173+
vim_free(p);
3174+
return retval;
3175+
}
3176+
#endif
3177+
return _rmdir(name);
3178+
}
3179+
31563180
/*
31573181
* Return TRUE if file "fname" has more than one link.
31583182
*/

src/proto/fileio.pro

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ int buf_check_timestamp __ARGS((buf_T *buf, int focus));
2222
void buf_reload __ARGS((buf_T *buf, int orig_mode));
2323
void buf_store_time __ARGS((buf_T *buf, struct stat *st, char_u *fname));
2424
void write_lnum_adjust __ARGS((linenr_T offset));
25+
int delete_recursive __ARGS((char_u *name));
2526
void vim_deltempdir __ARGS((void));
2627
char_u *vim_tempname __ARGS((int extra_char, int keep));
2728
void forward_slash __ARGS((char_u *fname));

0 commit comments

Comments
 (0)