Mercurial > vim
changeset 30150:0fe61fa4e5d1 v9.0.0411
patch 9.0.0411: only created files can be cleaned up with one call
Commit: https://github.com/vim/vim/commit/6f14da15ac900589f2f413d77898b9bff3b31ece
Author: Bram Moolenaar <Bram@vim.org>
Date: Wed Sep 7 21:30:44 2022 +0100
patch 9.0.0411: only created files can be cleaned up with one call
Problem: Only created files can be cleaned up with one call.
Solution: Add flags to mkdir() to delete with a deferred function.
Expand the writefile() name to a full path to handle changing
directory.
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Wed, 07 Sep 2022 22:45:04 +0200 |
parents | 58dd17222e56 |
children | c51f0fe92cf5 |
files | runtime/doc/builtin.txt src/filepath.c src/proto/userfunc.pro src/testdir/test_autochdir.vim src/testdir/test_autocmd.vim src/testdir/test_eval_stuff.vim src/testdir/test_writefile.vim src/userfunc.c src/version.c |
diffstat | 9 files changed, 105 insertions(+), 27 deletions(-) [+] |
line wrap: on
line diff
--- a/runtime/doc/builtin.txt +++ b/runtime/doc/builtin.txt @@ -6239,8 +6239,26 @@ min({expr}) Return the minimum value of mkdir({name} [, {path} [, {prot}]]) Create directory {name}. - If {path} is "p" then intermediate directories are created as - necessary. Otherwise it must be "". + If {path} contains "p" then intermediate directories are + created as necessary. Otherwise it must be "". + + If {path} contains "D" then {name} is deleted at the end of + the current function, as with: > + defer delete({name}, 'd') +< + If {path} contains "R" then {name} is deleted recursively at + the end of the current function, as with: > + defer delete({name}, 'rf') +< Note that when {name} has more than one part and "p" is used + some directories may already exist. Only the first one that + is created and what it contains is scheduled to be deleted. + E.g. when using: > + call mkdir('subdir/tmp/autoload', 'pR') +< and "subdir" already exists then "subdir/tmp" will be + scheduled for deletion, like with: > + defer delete('subdir/tmp', 'rf') +< Note that if scheduling the defer fails the directory is not + deleted. This should only happen when out of memory. If {prot} is given it is used to set the protection bits of the new directory. The default is 0o755 (rwxr-xr-x: r/w for
--- a/src/filepath.c +++ b/src/filepath.c @@ -1428,10 +1428,12 @@ f_isabsolutepath(typval_T *argvars, typv /* * Create the directory in which "dir" is located, and higher levels when * needed. + * Set "created" to the full name of the first created directory. It will be + * NULL until that happens. * Return OK or FAIL. */ static int -mkdir_recurse(char_u *dir, int prot) +mkdir_recurse(char_u *dir, int prot, char_u **created) { char_u *p; char_u *updir; @@ -1449,8 +1451,12 @@ mkdir_recurse(char_u *dir, int prot) return FAIL; if (mch_isdir(updir)) r = OK; - else if (mkdir_recurse(updir, prot) == OK) + else if (mkdir_recurse(updir, prot, created) == OK) + { r = vim_mkdir_emsg(updir, prot); + if (r == OK && created != NULL && *created == NULL) + *created = FullName_save(updir, FALSE); + } vim_free(updir); return r; } @@ -1464,6 +1470,9 @@ f_mkdir(typval_T *argvars, typval_T *ret char_u *dir; char_u buf[NUMBUFLEN]; int prot = 0755; + int defer = FALSE; + int defer_recurse = FALSE; + char_u *created = NULL; rettv->vval.v_number = FAIL; if (check_restricted() || check_secure()) @@ -1486,13 +1495,21 @@ f_mkdir(typval_T *argvars, typval_T *ret if (argvars[1].v_type != VAR_UNKNOWN) { + char_u *arg2; + if (argvars[2].v_type != VAR_UNKNOWN) { prot = (int)tv_get_number_chk(&argvars[2], NULL); if (prot == -1) return; } - if (STRCMP(tv_get_string(&argvars[1]), "p") == 0) + arg2 = tv_get_string(&argvars[1]); + defer = vim_strchr(arg2, 'D') != NULL; + defer_recurse = vim_strchr(arg2, 'R') != NULL; + if ((defer || defer_recurse) && !can_add_defer()) + return; + + if (vim_strchr(arg2, 'p') != NULL) { if (mch_isdir(dir)) { @@ -1500,10 +1517,33 @@ f_mkdir(typval_T *argvars, typval_T *ret rettv->vval.v_number = OK; return; } - mkdir_recurse(dir, prot); + mkdir_recurse(dir, prot, defer || defer_recurse ? &created : NULL); } } rettv->vval.v_number = vim_mkdir_emsg(dir, prot); + + // Handle "D" and "R": deferred deletion of the created directory. + if (rettv->vval.v_number == OK + && created == NULL && (defer || defer_recurse)) + created = FullName_save(dir, FALSE); + if (created != NULL) + { + typval_T tv[2]; + + tv[0].v_type = VAR_STRING; + tv[0].v_lock = 0; + tv[0].vval.v_string = created; + tv[1].v_type = VAR_STRING; + tv[1].v_lock = 0; + tv[1].vval.v_string = vim_strsave( + (char_u *)(defer_recurse ? "rf" : "d")); + if (tv[0].vval.v_string == NULL || tv[1].vval.v_string == NULL + || add_defer((char_u *)"delete", 2, tv) == FAIL) + { + vim_free(tv[0].vval.v_string); + vim_free(tv[1].vval.v_string); + } + } } /* @@ -2300,11 +2340,8 @@ f_writefile(typval_T *argvars, typval_T if (fname == NULL) return; - if (defer && !in_def_function() && get_current_funccal() == NULL) - { - semsg(_(e_str_not_inside_function), "defer"); + if (defer && !can_add_defer()) return; - } // Always open the file in binary mode, library functions have a mind of // their own about CR-LF conversion. @@ -2323,7 +2360,7 @@ f_writefile(typval_T *argvars, typval_T tv.v_type = VAR_STRING; tv.v_lock = 0; - tv.vval.v_string = vim_strsave(fname); + tv.vval.v_string = FullName_save(fname, FALSE); if (tv.vval.v_string == NULL || add_defer((char_u *)"delete", 1, &tv) == FAIL) {
--- a/src/proto/userfunc.pro +++ b/src/proto/userfunc.pro @@ -60,6 +60,7 @@ void func_ptr_unref(ufunc_T *fp); void func_ref(char_u *name); void func_ptr_ref(ufunc_T *fp); void ex_return(exarg_T *eap); +int can_add_defer(void); int add_defer(char_u *name, int argcount_arg, typval_T *argvars); void invoke_all_defer(void); void ex_call(exarg_T *eap);
--- a/src/testdir/test_autochdir.vim +++ b/src/testdir/test_autochdir.vim @@ -28,9 +28,9 @@ endfunc func Test_set_filename_other_window() let cwd = getcwd() call test_autochdir() - call mkdir('Xa') - call mkdir('Xb') - call mkdir('Xc') + call mkdir('Xa', 'R') + call mkdir('Xb', 'R') + call mkdir('Xc', 'R') try args Xa/aaa.txt Xb/bbb.txt set acd @@ -45,9 +45,6 @@ func Test_set_filename_other_window() bwipe! aaa.txt bwipe! bbb.txt bwipe! ccc.txt - call delete('Xa', 'rf') - call delete('Xb', 'rf') - call delete('Xc', 'rf') endtry endfunc @@ -56,7 +53,7 @@ func Test_acd_win_execute() set acd call test_autochdir() - call mkdir('XacdDir') + call mkdir('XacdDir', 'R') let winid = win_getid() new XacdDir/file call assert_match('testdir.XacdDir$', getcwd()) @@ -68,7 +65,6 @@ func Test_acd_win_execute() bwipe! set noacd call chdir(cwd) - call delete('XacdDir', 'rf') endfunc func Test_verbose_pwd() @@ -78,7 +74,7 @@ func Test_verbose_pwd() edit global.txt call assert_match('\[global\].*testdir$', execute('verbose pwd')) - call mkdir('Xautodir') + call mkdir('Xautodir', 'R') split Xautodir/local.txt lcd Xautodir call assert_match('\[window\].*testdir[/\\]Xautodir', execute('verbose pwd')) @@ -112,7 +108,6 @@ func Test_verbose_pwd() bwipe! call chdir(cwd) - call delete('Xautodir', 'rf') endfunc func Test_multibyte()
--- a/src/testdir/test_autocmd.vim +++ b/src/testdir/test_autocmd.vim @@ -707,14 +707,13 @@ func Test_BufEnter() call assert_equal('++', g:val) " Also get BufEnter when editing a directory - call mkdir('Xbufenterdir') + call mkdir('Xbufenterdir', 'D') split Xbufenterdir call assert_equal('+++', g:val) " On MS-Windows we can't edit the directory, make sure we wipe the right " buffer. bwipe! Xbufenterdir - call delete('Xbufenterdir', 'd') au! BufEnter " Editing a "nofile" buffer doesn't read the file but does trigger BufEnter @@ -1902,11 +1901,10 @@ func Test_BufWriteCmd() new file Xbufwritecmd set buftype=acwrite - call mkdir('Xbufwritecmd') + call mkdir('Xbufwritecmd', 'D') write " BufWriteCmd should be triggered even if a directory has the same name call assert_equal(1, g:written) - call delete('Xbufwritecmd', 'd') unlet g:written au! BufWriteCmd bwipe! @@ -2710,7 +2708,7 @@ func Test_throw_in_BufWritePre() endfunc func Test_autocmd_in_try_block() - call mkdir('Xintrydir') + call mkdir('Xintrydir', 'R') au BufEnter * let g:fname = expand('%') try edit Xintrydir/ @@ -2719,7 +2717,6 @@ func Test_autocmd_in_try_block() unlet g:fname au! BufEnter - call delete('Xintrydir', 'rf') endfunc func Test_autocmd_SafeState()
index 3669cfd40b24aad092ae59b3cf49bd8aef15d5fb..0081d89a52a488d644f570d314bce2336251c0b0 GIT binary patch literal 26019 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
--- a/src/testdir/test_writefile.vim +++ b/src/testdir/test_writefile.vim @@ -950,6 +950,19 @@ func Test_write_with_deferred_delete() call assert_equal('', glob('XdefdeferDelete')) endfunc +func DoWriteFile() + call writefile(['text'], 'Xthefile', 'D') + cd .. +endfunc + +func Test_write_defer_delete_chdir() + let dir = getcwd() + call DoWriteFile() + call assert_notequal(dir, getcwd()) + call chdir(dir) + call assert_equal('', glob('Xthefile')) +endfunc + " Check that buffer is written before triggering QuitPre func Test_wq_quitpre_autocommand() edit Xsomefile
--- a/src/userfunc.c +++ b/src/userfunc.c @@ -5650,6 +5650,21 @@ ex_defer_inner( } /* + * Return TRUE if currently inside a function call. + * Give an error message and return FALSE when not. + */ + int +can_add_defer(void) +{ + if (!in_def_function() && get_current_funccal() == NULL) + { + semsg(_(e_str_not_inside_function), "defer"); + return FALSE; + } + return TRUE; +} + +/* * Add a deferred call for "name" with arguments "argvars[argcount]". * Consumes "argvars[]". * Caller must check that in_def_function() returns TRUE or current_funccal is