mirror of
https://github.com/neovim/neovim.git
synced 2025-10-08 02:46:31 +00:00
vim-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.6f14da15ac
vim-patch:8.2.3742: dec mouse test fails without gnome terminfo entry Problem: Dec mouse test fails without gnome terminfo entry. Solution: Check if there is a gnome entry. Also fix 'acd' test on MS-Windows. (Dominique Pellé, closes vim/vim#9282)f589fd3e10
Cherry-pick test_autochdir.vim changes from patch 9.0.0313. Cherry-pick test_autocmd.vim changes from patch 9.0.0323. Co-authored-by: Bram Moolenaar <Bram@vim.org>
This commit is contained in:
@@ -4892,6 +4892,9 @@ static void f_mkdir(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
|
||||
*path_tail_with_sep((char *)dir) = NUL;
|
||||
}
|
||||
|
||||
bool defer = false;
|
||||
bool defer_recurse = false;
|
||||
char *created = NULL;
|
||||
if (argvars[1].v_type != VAR_UNKNOWN) {
|
||||
if (argvars[2].v_type != VAR_UNKNOWN) {
|
||||
prot = (int)tv_get_number_chk(&argvars[2], NULL);
|
||||
@@ -4899,9 +4902,17 @@ static void f_mkdir(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (strcmp(tv_get_string(&argvars[1]), "p") == 0) {
|
||||
const char *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) {
|
||||
char *failed_dir;
|
||||
int ret = os_mkdir_recurse(dir, prot, &failed_dir);
|
||||
int ret = os_mkdir_recurse(dir, prot, &failed_dir,
|
||||
defer || defer_recurse ? &created : NULL);
|
||||
if (ret != 0) {
|
||||
semsg(_(e_mkdir), failed_dir, os_strerror(ret));
|
||||
xfree(failed_dir);
|
||||
@@ -4909,10 +4920,27 @@ static void f_mkdir(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
|
||||
return;
|
||||
}
|
||||
rettv->vval.v_number = OK;
|
||||
return;
|
||||
}
|
||||
}
|
||||
rettv->vval.v_number = vim_mkdir_emsg(dir, prot);
|
||||
if (rettv->vval.v_number == FAIL) {
|
||||
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 = VAR_UNLOCKED;
|
||||
tv[0].vval.v_string = created;
|
||||
tv[1].v_type = VAR_STRING;
|
||||
tv[1].v_lock = VAR_UNLOCKED;
|
||||
tv[1].vval.v_string = xstrdup(defer_recurse ? "rf" : "d");
|
||||
add_defer("delete", 2, tv);
|
||||
}
|
||||
}
|
||||
|
||||
/// "mode()" function
|
||||
@@ -9332,8 +9360,7 @@ static void f_writefile(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
|
||||
return;
|
||||
}
|
||||
|
||||
if (defer && get_current_funccal() == NULL) {
|
||||
semsg(_(e_str_not_inside_function), "defer");
|
||||
if (defer && !can_add_defer()) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -9351,7 +9378,7 @@ static void f_writefile(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
|
||||
typval_T tv = {
|
||||
.v_type = VAR_STRING,
|
||||
.v_lock = VAR_UNLOCKED,
|
||||
.vval.v_string = xstrdup(fname),
|
||||
.vval.v_string = FullName_save(fname, false),
|
||||
};
|
||||
add_defer("delete", 1, &tv);
|
||||
}
|
||||
|
@@ -3153,6 +3153,17 @@ static int ex_defer_inner(char *name, char **arg, const partial_T *const partial
|
||||
return OK;
|
||||
}
|
||||
|
||||
/// Return true if currently inside a function call.
|
||||
/// Give an error message and return FALSE when not.
|
||||
bool can_add_defer(void)
|
||||
{
|
||||
if (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 current_funccal is not NULL.
|
||||
|
@@ -2536,7 +2536,7 @@ static int buf_write_make_backup(char *fname, bool append, FileInfo *file_info_o
|
||||
if (*dirp == NUL && !os_isdir(IObuff)) {
|
||||
int ret;
|
||||
char *failed_dir;
|
||||
if ((ret = os_mkdir_recurse(IObuff, 0755, &failed_dir)) != 0) {
|
||||
if ((ret = os_mkdir_recurse(IObuff, 0755, &failed_dir, NULL)) != 0) {
|
||||
semsg(_("E303: Unable to create directory \"%s\" for backup file: %s"),
|
||||
failed_dir, os_strerror(ret));
|
||||
xfree(failed_dir);
|
||||
@@ -2679,7 +2679,7 @@ nobackup:
|
||||
if (*dirp == NUL && !os_isdir(IObuff)) {
|
||||
int ret;
|
||||
char *failed_dir;
|
||||
if ((ret = os_mkdir_recurse(IObuff, 0755, &failed_dir)) != 0) {
|
||||
if ((ret = os_mkdir_recurse(IObuff, 0755, &failed_dir, NULL)) != 0) {
|
||||
semsg(_("E303: Unable to create directory \"%s\" for backup file: %s"),
|
||||
failed_dir, os_strerror(ret));
|
||||
xfree(failed_dir);
|
||||
|
@@ -76,7 +76,7 @@ static void log_path_init(void)
|
||||
char *failed_dir = NULL;
|
||||
bool log_dir_failure = false;
|
||||
if (!os_isdir(loghome)) {
|
||||
log_dir_failure = (os_mkdir_recurse(loghome, 0700, &failed_dir) != 0);
|
||||
log_dir_failure = (os_mkdir_recurse(loghome, 0700, &failed_dir, NULL) != 0);
|
||||
}
|
||||
XFREE_CLEAR(loghome);
|
||||
// Invalid $NVIM_LOG_FILE or failed to expand; fall back to default.
|
||||
|
@@ -3442,7 +3442,7 @@ static char *findswapname(buf_T *buf, char **dirp, char *old_fname, bool *found_
|
||||
} else if (!*found_existing_dir && **dirp == NUL) {
|
||||
int ret;
|
||||
char *failed_dir;
|
||||
if ((ret = os_mkdir_recurse(dir_name, 0755, &failed_dir)) != 0) {
|
||||
if ((ret = os_mkdir_recurse(dir_name, 0755, &failed_dir, NULL)) != 0) {
|
||||
semsg(_("E303: Unable to create directory \"%s\" for swap file, "
|
||||
"recovery impossible: %s"),
|
||||
failed_dir, os_strerror(ret));
|
||||
|
@@ -937,10 +937,13 @@ int os_mkdir(const char *path, int32_t mode)
|
||||
/// the name of the directory which os_mkdir_recurse
|
||||
/// failed to create. I.e. it will contain dir or any
|
||||
/// of the higher level directories.
|
||||
/// @param[out] created Set to the full name of the first created directory.
|
||||
/// It will be NULL until that happens.
|
||||
///
|
||||
/// @return `0` for success, libuv error code for failure.
|
||||
int os_mkdir_recurse(const char *const dir, int32_t mode, char **const failed_dir)
|
||||
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT
|
||||
int os_mkdir_recurse(const char *const dir, int32_t mode, char **const failed_dir,
|
||||
char **const created)
|
||||
FUNC_ATTR_NONNULL_ARG(1, 3) FUNC_ATTR_WARN_UNUSED_RESULT
|
||||
{
|
||||
// Get end of directory name in "dir".
|
||||
// We're done when it's "/" or "c:/".
|
||||
@@ -975,6 +978,8 @@ int os_mkdir_recurse(const char *const dir, int32_t mode, char **const failed_di
|
||||
if ((ret = os_mkdir(curdir, mode)) != 0) {
|
||||
*failed_dir = curdir;
|
||||
return ret;
|
||||
} else if (created != NULL && *created == NULL) {
|
||||
*created = FullName_save(curdir, false);
|
||||
}
|
||||
}
|
||||
xfree(curdir);
|
||||
@@ -1002,7 +1007,7 @@ int os_file_mkdir(char *fname, int32_t mode)
|
||||
*tail = NUL;
|
||||
int r;
|
||||
char *failed_dir;
|
||||
if (((r = os_mkdir_recurse(fname, mode, &failed_dir)) < 0)) {
|
||||
if (((r = os_mkdir_recurse(fname, mode, &failed_dir, NULL)) < 0)) {
|
||||
semsg(_(e_mkdir), failed_dir, os_strerror(r));
|
||||
xfree(failed_dir);
|
||||
}
|
||||
|
@@ -3042,7 +3042,7 @@ shada_write_file_nomerge: {}
|
||||
if (!os_isdir(fname)) {
|
||||
int ret;
|
||||
char *failed_dir;
|
||||
if ((ret = os_mkdir_recurse(fname, 0700, &failed_dir)) != 0) {
|
||||
if ((ret = os_mkdir_recurse(fname, 0700, &failed_dir, NULL)) != 0) {
|
||||
semsg(_(SERR "Failed to create directory %s "
|
||||
"for writing ShaDa file: %s"),
|
||||
failed_dir, os_strerror(ret));
|
||||
|
@@ -705,7 +705,7 @@ char *u_get_undo_file_name(const char *const buf_ffname, const bool reading)
|
||||
// Last directory in the list does not exist, create it.
|
||||
int ret;
|
||||
char *failed_dir;
|
||||
if ((ret = os_mkdir_recurse(dir_name, 0755, &failed_dir)) != 0) {
|
||||
if ((ret = os_mkdir_recurse(dir_name, 0755, &failed_dir, NULL)) != 0) {
|
||||
semsg(_("E5003: Unable to create directory \"%s\" for undo file: %s"),
|
||||
failed_dir, os_strerror(ret));
|
||||
xfree(failed_dir);
|
||||
|
Reference in New Issue
Block a user