@@ -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 {
0 commit comments