Skip to content

Commit d3ced67

Browse files
committed
Merge remote-tracking branch 'vim/master'
2 parents 3d0d9f9 + e5a420f commit d3ced67

29 files changed

Lines changed: 379 additions & 71 deletions

runtime/doc/builtin.txt

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6239,8 +6239,26 @@ min({expr}) Return the minimum value of all items in {expr}. Example: >
62396239
mkdir({name} [, {path} [, {prot}]])
62406240
Create directory {name}.
62416241

6242-
If {path} is "p" then intermediate directories are created as
6243-
necessary. Otherwise it must be "".
6242+
If {path} contains "p" then intermediate directories are
6243+
created as necessary. Otherwise it must be "".
6244+
6245+
If {path} contains "D" then {name} is deleted at the end of
6246+
the current function, as with: >
6247+
defer delete({name}, 'd')
6248+
<
6249+
If {path} contains "R" then {name} is deleted recursively at
6250+
the end of the current function, as with: >
6251+
defer delete({name}, 'rf')
6252+
< Note that when {name} has more than one part and "p" is used
6253+
some directories may already exist. Only the first one that
6254+
is created and what it contains is scheduled to be deleted.
6255+
E.g. when using: >
6256+
call mkdir('subdir/tmp/autoload', 'pR')
6257+
< and "subdir" already exists then "subdir/tmp" will be
6258+
scheduled for deletion, like with: >
6259+
defer delete('subdir/tmp', 'rf')
6260+
< Note that if scheduling the defer fails the directory is not
6261+
deleted. This should only happen when out of memory.
62446262

62456263
If {prot} is given it is used to set the protection bits of
62466264
the new directory. The default is 0o755 (rwxr-xr-x: r/w for

runtime/filetype.vim

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -940,7 +940,7 @@ au BufNewFile,BufRead *.java,*.jav setf java
940940
au BufNewFile,BufRead *.jj,*.jjt setf javacc
941941

942942
" JavaScript, ECMAScript, ES module script, CommonJS script
943-
au BufNewFile,BufRead *.js,*.javascript,*.es,*.mjs,*.cjs setf javascript
943+
au BufNewFile,BufRead *.js,*.jsm,*.javascript,*.es,*.mjs,*.cjs setf javascript
944944

945945
" JavaScript with React
946946
au BufNewFile,BufRead *.jsx setf javascriptreact

src/charset.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -943,14 +943,13 @@ vim_isprintc_strict(int c)
943943
init_chartabsize_arg(
944944
chartabsize_T *cts,
945945
win_T *wp,
946-
linenr_T lnum,
946+
linenr_T lnum UNUSED,
947947
colnr_T col,
948948
char_u *line,
949949
char_u *ptr)
950950
{
951951
CLEAR_POINTER(cts);
952952
cts->cts_win = wp;
953-
cts->cts_lnum = lnum;
954953
cts->cts_vcol = col;
955954
cts->cts_line = line;
956955
cts->cts_ptr = ptr;

src/dict.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -911,13 +911,15 @@ eval_dict(char_u **arg, typval_T *rettv, evalarg_T *evalarg, int literal)
911911
int vim9script = in_vim9script();
912912
int had_comma;
913913

914-
// First check if it's not a curly-braces thing: {expr}.
914+
// First check if it's not a curly-braces expression: {expr}.
915915
// Must do this without evaluating, otherwise a function may be called
916916
// twice. Unfortunately this means we need to call eval1() twice for the
917917
// first item.
918-
// But {} is an empty Dictionary.
918+
// "{}" is an empty Dictionary.
919+
// "#{abc}" is never a curly-braces expression.
919920
if (!vim9script
920921
&& *curly_expr != '}'
922+
&& !literal
921923
&& eval1(&curly_expr, &tv, NULL) == OK
922924
&& *skipwhite(curly_expr) == '}')
923925
return NOTDONE;

src/eval.c

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -263,9 +263,17 @@ eval_expr_typval(typval_T *expr, typval_T *argv, int argc, typval_T *rettv)
263263
if (partial->pt_func != NULL
264264
&& partial->pt_func->uf_def_status != UF_NOT_COMPILED)
265265
{
266-
// FIXME: should create a funccal and link it in current_funccal.
267-
if (call_def_function(partial->pt_func, argc, argv,
268-
partial, NULL, rettv) == FAIL)
266+
funccall_T *fc = create_funccal(partial->pt_func, rettv);
267+
int r;
268+
269+
if (fc == NULL)
270+
return FAIL;
271+
272+
// Shortcut to call a compiled function without overhead.
273+
r = call_def_function(partial->pt_func, argc, argv,
274+
DEF_USE_PT_ARGV, partial, fc, rettv);
275+
remove_funccal();
276+
if (r == FAIL)
269277
return FAIL;
270278
}
271279
else

src/filepath.c

Lines changed: 46 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1428,10 +1428,12 @@ f_isabsolutepath(typval_T *argvars, typval_T *rettv)
14281428
/*
14291429
* Create the directory in which "dir" is located, and higher levels when
14301430
* needed.
1431+
* Set "created" to the full name of the first created directory. It will be
1432+
* NULL until that happens.
14311433
* Return OK or FAIL.
14321434
*/
14331435
static int
1434-
mkdir_recurse(char_u *dir, int prot)
1436+
mkdir_recurse(char_u *dir, int prot, char_u **created)
14351437
{
14361438
char_u *p;
14371439
char_u *updir;
@@ -1449,8 +1451,12 @@ mkdir_recurse(char_u *dir, int prot)
14491451
return FAIL;
14501452
if (mch_isdir(updir))
14511453
r = OK;
1452-
else if (mkdir_recurse(updir, prot) == OK)
1454+
else if (mkdir_recurse(updir, prot, created) == OK)
1455+
{
14531456
r = vim_mkdir_emsg(updir, prot);
1457+
if (r == OK && created != NULL && *created == NULL)
1458+
*created = FullName_save(updir, FALSE);
1459+
}
14541460
vim_free(updir);
14551461
return r;
14561462
}
@@ -1464,6 +1470,9 @@ f_mkdir(typval_T *argvars, typval_T *rettv)
14641470
char_u *dir;
14651471
char_u buf[NUMBUFLEN];
14661472
int prot = 0755;
1473+
int defer = FALSE;
1474+
int defer_recurse = FALSE;
1475+
char_u *created = NULL;
14671476

14681477
rettv->vval.v_number = FAIL;
14691478
if (check_restricted() || check_secure())
@@ -1486,24 +1495,55 @@ f_mkdir(typval_T *argvars, typval_T *rettv)
14861495

14871496
if (argvars[1].v_type != VAR_UNKNOWN)
14881497
{
1498+
char_u *arg2;
1499+
14891500
if (argvars[2].v_type != VAR_UNKNOWN)
14901501
{
14911502
prot = (int)tv_get_number_chk(&argvars[2], NULL);
14921503
if (prot == -1)
14931504
return;
14941505
}
1495-
if (STRCMP(tv_get_string(&argvars[1]), "p") == 0)
1506+
arg2 = tv_get_string(&argvars[1]);
1507+
defer = vim_strchr(arg2, 'D') != NULL;
1508+
defer_recurse = vim_strchr(arg2, 'R') != NULL;
1509+
if ((defer || defer_recurse) && !can_add_defer())
1510+
return;
1511+
1512+
if (vim_strchr(arg2, 'p') != NULL)
14961513
{
14971514
if (mch_isdir(dir))
14981515
{
14991516
// With the "p" flag it's OK if the dir already exists.
15001517
rettv->vval.v_number = OK;
15011518
return;
15021519
}
1503-
mkdir_recurse(dir, prot);
1520+
mkdir_recurse(dir, prot, defer || defer_recurse ? &created : NULL);
15041521
}
15051522
}
15061523
rettv->vval.v_number = vim_mkdir_emsg(dir, prot);
1524+
1525+
// Handle "D" and "R": deferred deletion of the created directory.
1526+
if (rettv->vval.v_number == OK
1527+
&& created == NULL && (defer || defer_recurse))
1528+
created = FullName_save(dir, FALSE);
1529+
if (created != NULL)
1530+
{
1531+
typval_T tv[2];
1532+
1533+
tv[0].v_type = VAR_STRING;
1534+
tv[0].v_lock = 0;
1535+
tv[0].vval.v_string = created;
1536+
tv[1].v_type = VAR_STRING;
1537+
tv[1].v_lock = 0;
1538+
tv[1].vval.v_string = vim_strsave(
1539+
(char_u *)(defer_recurse ? "rf" : "d"));
1540+
if (tv[0].vval.v_string == NULL || tv[1].vval.v_string == NULL
1541+
|| add_defer((char_u *)"delete", 2, tv) == FAIL)
1542+
{
1543+
vim_free(tv[0].vval.v_string);
1544+
vim_free(tv[1].vval.v_string);
1545+
}
1546+
}
15071547
}
15081548

15091549
/*
@@ -2300,11 +2340,8 @@ f_writefile(typval_T *argvars, typval_T *rettv)
23002340
if (fname == NULL)
23012341
return;
23022342

2303-
if (defer && !in_def_function() && get_current_funccal() == NULL)
2304-
{
2305-
semsg(_(e_str_not_inside_function), "defer");
2343+
if (defer && !can_add_defer())
23062344
return;
2307-
}
23082345

23092346
// Always open the file in binary mode, library functions have a mind of
23102347
// their own about CR-LF conversion.
@@ -2323,7 +2360,7 @@ f_writefile(typval_T *argvars, typval_T *rettv)
23232360

23242361
tv.v_type = VAR_STRING;
23252362
tv.v_lock = 0;
2326-
tv.vval.v_string = vim_strsave(fname);
2363+
tv.vval.v_string = FullName_save(fname, FALSE);
23272364
if (tv.vval.v_string == NULL
23282365
|| add_defer((char_u *)"delete", 1, &tv) == FAIL)
23292366
{

src/gui_w32.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8649,6 +8649,7 @@ test_gui_w32_sendevent(dict_T *args)
86498649
inputs[0].ki.wVk = vkCode;
86508650
if (STRICMP(event, "keyup") == 0)
86518651
inputs[0].ki.dwFlags = KEYEVENTF_KEYUP;
8652+
(void)SetForegroundWindow(s_hwnd);
86528653
SendInput(ARRAYSIZE(inputs), inputs, sizeof(INPUT));
86538654
}
86548655
else

src/proto/userfunc.pro

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ int funcdepth_increment(void);
2121
void funcdepth_decrement(void);
2222
int funcdepth_get(void);
2323
void funcdepth_restore(int depth);
24+
funccall_T *create_funccal(ufunc_T *fp, typval_T *rettv);
25+
void remove_funccal(void);
2426
int check_user_func_argcount(ufunc_T *fp, int argcount);
2527
int call_user_func_check(ufunc_T *fp, int argcount, typval_T *argvars, typval_T *rettv, funcexe_T *funcexe, dict_T *selfdict);
2628
void save_funccal(funccal_entry_T *entry);
@@ -58,6 +60,7 @@ void func_ptr_unref(ufunc_T *fp);
5860
void func_ref(char_u *name);
5961
void func_ptr_ref(ufunc_T *fp);
6062
void ex_return(exarg_T *eap);
63+
int can_add_defer(void);
6164
int add_defer(char_u *name, int argcount_arg, typval_T *argvars);
6265
void invoke_all_defer(void);
6366
void ex_call(exarg_T *eap);

src/proto/vim9execute.pro

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ typval_T *lookup_debug_var(char_u *name);
1515
int may_break_in_function(ufunc_T *ufunc);
1616
int exe_typval_instr(typval_T *tv, typval_T *rettv);
1717
char_u *exe_substitute_instr(void);
18-
int call_def_function(ufunc_T *ufunc, int argc_arg, typval_T *argv, partial_T *partial, funccall_T *funccal, typval_T *rettv);
18+
int call_def_function(ufunc_T *ufunc, int argc_arg, typval_T *argv, int flags, partial_T *partial, funccall_T *funccal, typval_T *rettv);
1919
void unwind_def_callstack(ectx_T *ectx);
2020
void may_invoke_defer_funcs(ectx_T *ectx);
2121
void set_context_in_disassemble_cmd(expand_T *xp, char_u *arg);

src/regexp_bt.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3444,7 +3444,7 @@ regmatch(
34443444
linenr_T lnum = rex.reg_firstlnum + rex.lnum;
34453445
long_u vcol = 0;
34463446

3447-
if (lnum > 0 && lnum <= wp->w_buffer->b_ml.ml_line_count)
3447+
if (lnum >= 0 && lnum <= wp->w_buffer->b_ml.ml_line_count)
34483448
vcol = (long_u)win_linetabsize(wp, lnum, rex.line,
34493449
(colnr_T)(rex.input - rex.line));
34503450
if (!re_num_cmp(vcol + 1, scan))

0 commit comments

Comments
 (0)