aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--runtime/doc/eval.txt24
-rw-r--r--src/nvim/diff.c1
-rw-r--r--src/nvim/eval.c44
-rw-r--r--src/nvim/ex_cmds.c1
-rw-r--r--src/nvim/fileio.c142
-rw-r--r--src/nvim/hardcopy.c1
-rw-r--r--src/nvim/if_cscope.c1
-rw-r--r--src/nvim/memline.c1
-rw-r--r--src/nvim/misc1.c1
-rw-r--r--src/nvim/msgpack_rpc/server.c2
-rw-r--r--src/nvim/os/fs.c17
-rw-r--r--src/nvim/os_unix.c1
-rw-r--r--src/nvim/path.c13
-rw-r--r--src/nvim/path.h2
-rw-r--r--src/nvim/quickfix.c1
-rw-r--r--src/nvim/spell.c1
-rw-r--r--src/nvim/tempfile.c139
-rw-r--r--src/nvim/tempfile.h8
-rw-r--r--src/nvim/version.c10
-rw-r--r--test/functional/legacy/delete_spec.lua99
-rw-r--r--test/unit/formatc.lua2
-rw-r--r--test/unit/tempfile_spec.lua2
22 files changed, 325 insertions, 188 deletions
diff --git a/runtime/doc/eval.txt b/runtime/doc/eval.txt
index 0fdf905bd3..148ac7732a 100644
--- a/runtime/doc/eval.txt
+++ b/runtime/doc/eval.txt
@@ -1,4 +1,4 @@
-*eval.txt* For Vim version 7.4. Last change: 2015 Sep 19
+*eval.txt* For Vim version 7.4. Last change: 2016 Jan 16
VIM REFERENCE MANUAL by Bram Moolenaar
@@ -1830,7 +1830,7 @@ cursor( {lnum}, {col} [, {off}])
Number move cursor to {lnum}, {col}, {off}
cursor( {list}) Number move cursor to position in {list}
deepcopy( {expr} [, {noref}]) any make a full copy of {expr}
-delete( {fname}) Number delete file {fname}
+delete( {fname} [, {flags}]) Number delete the file or directory {fname}
dictwatcheradd( {dict}, {pattern}, {callback})
Start watching a dictionary
dictwatcherdel( {dict}, {pattern}, {callback})
@@ -2770,13 +2770,19 @@ deepcopy({expr}[, {noref}]) *deepcopy()* *E698*
{noref} set to 1 will fail.
Also see |copy()|.
-delete({fname}) *delete()*
- Deletes the file by the name {fname}. The result is a Number,
- which is 0 if the file was deleted successfully, and non-zero
- when the deletion failed.
- Use |remove()| to delete an item from a |List|.
- To delete a line from the buffer use |:delete|. Use |:exe|
- when the line number is in a variable.
+delete({fname} [, {flags}]) *delete()*
+ Without {flags} or with {flags} empty: Deletes the file by the
+ name {fname}. This also works when {fname} is a symbolic link.
+ A symbolic link itself is deleted, not what it points to.
+
+ When {flags} is "d": Deletes the directory by the name
+ {fname}. This fails when directory {fname} is not empty.
+
+ When {flags} is "rf": Deletes the directory by the name
+ {fname} and everything in it, recursively. BE CAREFUL!
+
+ The result is a Number, which is 0 if the delete operation was
+ successful and -1 when the deletion failed or partly failed.
dictwatcheradd({dict}, {pattern}, {callback}) *dictwatcheradd()*
Adds a watcher to a dictionary. A dictionary watcher is
diff --git a/src/nvim/diff.c b/src/nvim/diff.c
index a3063de869..4826e70727 100644
--- a/src/nvim/diff.c
+++ b/src/nvim/diff.c
@@ -29,7 +29,6 @@
#include "nvim/path.h"
#include "nvim/screen.h"
#include "nvim/strings.h"
-#include "nvim/tempfile.h"
#include "nvim/undo.h"
#include "nvim/window.h"
#include "nvim/os/os.h"
diff --git a/src/nvim/eval.c b/src/nvim/eval.c
index 300e1c677e..31b264395b 100644
--- a/src/nvim/eval.c
+++ b/src/nvim/eval.c
@@ -66,7 +66,6 @@
#include "nvim/strings.h"
#include "nvim/syntax.h"
#include "nvim/tag.h"
-#include "nvim/tempfile.h"
#include "nvim/ui.h"
#include "nvim/mouse.h"
#include "nvim/terminal.h"
@@ -6702,7 +6701,7 @@ static struct fst {
{ "cscope_connection", 0, 3, f_cscope_connection },
{ "cursor", 1, 3, f_cursor },
{ "deepcopy", 1, 2, f_deepcopy },
- { "delete", 1, 1, f_delete },
+ { "delete", 1, 2, f_delete },
{ "dictwatcheradd", 3, 3, f_dictwatcheradd },
{ "dictwatcherdel", 3, 3, f_dictwatcherdel },
{ "did_filetype", 0, 0, f_did_filetype },
@@ -8374,15 +8373,42 @@ static void f_deepcopy(typval_T *argvars, typval_T *rettv)
}
}
-/*
- * "delete()" function
- */
+// "delete()" function
static void f_delete(typval_T *argvars, typval_T *rettv)
{
- if (check_restricted() || check_secure())
- rettv->vval.v_number = -1;
- else
- rettv->vval.v_number = os_remove((char *)get_tv_string(&argvars[0]));
+ char_u nbuf[NUMBUFLEN];
+ char_u *name;
+ char_u *flags;
+
+ rettv->vval.v_number = -1;
+ if (check_restricted() || check_secure()) {
+ return;
+ }
+
+ name = get_tv_string(&argvars[0]);
+ if (name == NULL || *name == NUL) {
+ EMSG(_(e_invarg));
+ return;
+ }
+
+ if (argvars[1].v_type != VAR_UNKNOWN) {
+ flags = get_tv_string_buf(&argvars[1], nbuf);
+ } else {
+ flags = (char_u *)"";
+ }
+
+ if (*flags == NUL) {
+ // delete a file
+ rettv->vval.v_number = os_remove((char *)name) == 0 ? 0 : -1;
+ } else if (STRCMP(flags, "d") == 0) {
+ // delete an empty directory
+ rettv->vval.v_number = os_rmdir((char *)name) == 0 ? 0 : -1;
+ } else if (STRCMP(flags, "rf") == 0) {
+ // delete a directory recursively
+ rettv->vval.v_number = delete_recursive(name);
+ } else {
+ EMSG2(_(e_invexpr2), flags);
+ }
}
// dictwatcheradd(dict, key, funcref) function
diff --git a/src/nvim/ex_cmds.c b/src/nvim/ex_cmds.c
index d344daed11..69bf7abe6e 100644
--- a/src/nvim/ex_cmds.c
+++ b/src/nvim/ex_cmds.c
@@ -50,7 +50,6 @@
#include "nvim/strings.h"
#include "nvim/syntax.h"
#include "nvim/tag.h"
-#include "nvim/tempfile.h"
#include "nvim/ui.h"
#include "nvim/undo.h"
#include "nvim/window.h"
diff --git a/src/nvim/fileio.c b/src/nvim/fileio.c
index 32e1b645d0..c7870b9f69 100644
--- a/src/nvim/fileio.c
+++ b/src/nvim/fileio.c
@@ -45,7 +45,6 @@
#include "nvim/search.h"
#include "nvim/sha256.h"
#include "nvim/strings.h"
-#include "nvim/tempfile.h"
#include "nvim/ui.h"
#include "nvim/types.h"
#include "nvim/undo.h"
@@ -5116,6 +5115,147 @@ void forward_slash(char_u *fname)
}
#endif
+/// Name of Vim's own temp dir. Ends in a slash.
+static char_u *vim_tempdir = NULL;
+
+/// Create a directory for private use by this instance of Neovim.
+/// This is done once, and the same directory is used for all temp files.
+/// This method avoids security problems because of symlink attacks et al.
+/// It's also a bit faster, because we only need to check for an existing
+/// file when creating the directory and not for each temp file.
+static void vim_maketempdir(void)
+{
+ static const char *temp_dirs[] = TEMP_DIR_NAMES;
+ // Try the entries in `TEMP_DIR_NAMES` to create the temp directory.
+ char_u template[TEMP_FILE_PATH_MAXLEN];
+ char_u path[TEMP_FILE_PATH_MAXLEN];
+ for (size_t i = 0; i < ARRAY_SIZE(temp_dirs); i++) {
+ // Expand environment variables, leave room for "/nvimXXXXXX/999999999"
+ expand_env((char_u *)temp_dirs[i], template, TEMP_FILE_PATH_MAXLEN - 22);
+ if (!os_isdir(template)) { // directory doesn't exist
+ continue;
+ }
+
+ add_pathsep((char *)template);
+ // Concatenate with temporary directory name pattern
+ STRCAT(template, "nvimXXXXXX");
+
+ if (os_mkdtemp((const char *)template, (char *)path) != 0) {
+ continue;
+ }
+
+ if (vim_settempdir((char *)path)) {
+ // Successfully created and set temporary directory so stop trying.
+ break;
+ } else {
+ // Couldn't set `vim_tempdir` to `path` so remove created directory.
+ os_rmdir((char *)path);
+ }
+ }
+}
+
+/// Delete "name" and everything in it, recursively.
+/// @param name The path which should be deleted.
+/// @return 0 for success, -1 if some file was not deleted.
+int delete_recursive(char_u *name)
+{
+ int result = 0;
+
+ if (os_isrealdir(name)) {
+ snprintf((char *)NameBuff, MAXPATHL, "%s/*", name); // NOLINT
+
+ char_u **files;
+ int file_count;
+ char_u *exp = vim_strsave(NameBuff);
+ if (gen_expand_wildcards(1, &exp, &file_count, &files,
+ EW_DIR | EW_FILE | EW_SILENT | EW_ALLLINKS
+ | EW_DODOT | EW_EMPTYOK) == OK) {
+ for (int i = 0; i < file_count; i++) {
+ if (delete_recursive(files[i]) != 0) {
+ result = -1;
+ }
+ }
+ FreeWild(file_count, files);
+ } else {
+ result = -1;
+ }
+
+ xfree(exp);
+ os_rmdir((char *)name);
+ } else {
+ result = os_remove((char *)name) == 0 ? 0 : -1;
+ }
+
+ return result;
+}
+
+/// Delete the temp directory and all files it contains.
+void vim_deltempdir(void)
+{
+ if (vim_tempdir != NULL) {
+ // remove the trailing path separator
+ path_tail(vim_tempdir)[-1] = NUL;
+ delete_recursive(vim_tempdir);
+ xfree(vim_tempdir);
+ vim_tempdir = NULL;
+ }
+}
+
+/// Get the name of temp directory. This directory would be created on the first
+/// call to this function.
+char_u *vim_gettempdir(void)
+{
+ if (vim_tempdir == NULL) {
+ vim_maketempdir();
+ }
+
+ return vim_tempdir;
+}
+
+/// Set Neovim own temporary directory name to `tempdir`. This directory should
+/// be already created. Expand this name to a full path and put it in
+/// `vim_tempdir`. This avoids that using `:cd` would confuse us.
+///
+/// @param tempdir must be no longer than MAXPATHL.
+///
+/// @return false if we run out of memory.
+static bool vim_settempdir(char *tempdir)
+{
+ char *buf = verbose_try_malloc(MAXPATHL + 2);
+ if (!buf) {
+ return false;
+ }
+ vim_FullName(tempdir, buf, MAXPATHL, false);
+ add_pathsep(buf);
+ vim_tempdir = (char_u *)xstrdup(buf);
+ xfree(buf);
+ return true;
+}
+
+/// Return a unique name that can be used for a temp file.
+///
+/// @note The temp file is NOT created.
+///
+/// @return pointer to the temp file name or NULL if Neovim can't create
+/// temporary directory for its own temporary files.
+char_u *vim_tempname(void)
+{
+ // Temp filename counter.
+ static uint32_t temp_count;
+
+ char_u *tempdir = vim_gettempdir();
+ if (!tempdir) {
+ return NULL;
+ }
+
+ // There is no need to check if the file exists, because we own the directory
+ // and nobody else creates a file in it.
+ char_u template[TEMP_FILE_PATH_MAXLEN];
+ snprintf((char *)template, TEMP_FILE_PATH_MAXLEN,
+ "%s%" PRIu32, tempdir, temp_count++);
+ return vim_strsave(template);
+}
+
/*
* Code for automatic commands.
diff --git a/src/nvim/hardcopy.c b/src/nvim/hardcopy.c
index cc49bcd074..6ce8954fef 100644
--- a/src/nvim/hardcopy.c
+++ b/src/nvim/hardcopy.c
@@ -32,7 +32,6 @@
#include "nvim/syntax.h"
#include "nvim/ui.h"
#include "nvim/version.h"
-#include "nvim/tempfile.h"
#include "nvim/os/os.h"
#include "nvim/os/input.h"
diff --git a/src/nvim/if_cscope.c b/src/nvim/if_cscope.c
index a143490356..daddd7cee4 100644
--- a/src/nvim/if_cscope.c
+++ b/src/nvim/if_cscope.c
@@ -27,7 +27,6 @@
#include "nvim/quickfix.h"
#include "nvim/strings.h"
#include "nvim/tag.h"
-#include "nvim/tempfile.h"
#include "nvim/window.h"
#include "nvim/os/os.h"
#include "nvim/os/input.h"
diff --git a/src/nvim/memline.c b/src/nvim/memline.c
index 10176752d5..f82f88a88f 100644
--- a/src/nvim/memline.c
+++ b/src/nvim/memline.c
@@ -65,7 +65,6 @@
#include "nvim/strings.h"
#include "nvim/ui.h"
#include "nvim/version.h"
-#include "nvim/tempfile.h"
#include "nvim/undo.h"
#include "nvim/window.h"
#include "nvim/os/os.h"
diff --git a/src/nvim/misc1.c b/src/nvim/misc1.c
index a20ee562fa..43e0dd0c1a 100644
--- a/src/nvim/misc1.c
+++ b/src/nvim/misc1.c
@@ -43,7 +43,6 @@
#include "nvim/search.h"
#include "nvim/strings.h"
#include "nvim/tag.h"
-#include "nvim/tempfile.h"
#include "nvim/ui.h"
#include "nvim/undo.h"
#include "nvim/window.h"
diff --git a/src/nvim/msgpack_rpc/server.c b/src/nvim/msgpack_rpc/server.c
index bf384e3379..6cc56ba3dd 100644
--- a/src/nvim/msgpack_rpc/server.c
+++ b/src/nvim/msgpack_rpc/server.c
@@ -14,7 +14,7 @@
#include "nvim/vim.h"
#include "nvim/memory.h"
#include "nvim/log.h"
-#include "nvim/tempfile.h"
+#include "nvim/fileio.h"
#include "nvim/path.h"
#include "nvim/strings.h"
diff --git a/src/nvim/os/fs.c b/src/nvim/os/fs.c
index 34d8fde4f1..bc2d37764d 100644
--- a/src/nvim/os/fs.c
+++ b/src/nvim/os/fs.c
@@ -59,6 +59,23 @@ int os_dirname(char_u *buf, size_t len)
return OK;
}
+/// Check if the given path is a directory and not a symlink to a directory.
+/// @return `true` if `name` is a directory and NOT a symlink to a directory.
+/// `false` if `name` is not a directory or if an error occurred.
+bool os_isrealdir(const char_u *name)
+ FUNC_ATTR_NONNULL_ALL
+{
+ uv_fs_t request;
+ if (uv_fs_lstat(&fs_loop, &request, (char *)name, NULL) != kLibuvSuccess) {
+ return false;
+ }
+ if (S_ISLNK(request.statbuf.st_mode)) {
+ return false;
+ } else {
+ return S_ISDIR(request.statbuf.st_mode);
+ }
+}
+
/// Check if the given path is a directory or not.
///
/// @return `true` if `fname` is a directory.
diff --git a/src/nvim/os_unix.c b/src/nvim/os_unix.c
index cb9a58cc77..2a859a0f7a 100644
--- a/src/nvim/os_unix.c
+++ b/src/nvim/os_unix.c
@@ -34,7 +34,6 @@
#include "nvim/screen.h"
#include "nvim/strings.h"
#include "nvim/syntax.h"
-#include "nvim/tempfile.h"
#include "nvim/ui.h"
#include "nvim/types.h"
#include "nvim/os/os.h"
diff --git a/src/nvim/path.c b/src/nvim/path.c
index aaf54bc5b4..d3df9bc059 100644
--- a/src/nvim/path.c
+++ b/src/nvim/path.c
@@ -604,7 +604,7 @@ static size_t do_path_expand(garray_T *gap, const char_u *path,
starstar = true;
// convert the file pattern to a regexp pattern
- int starts_with_dot = (*s == '.');
+ int starts_with_dot = *s == '.';
char_u *pat = file_pat_to_reg_pat(s, e, NULL, false);
if (pat == NULL) {
xfree(buf);
@@ -647,9 +647,12 @@ static size_t do_path_expand(garray_T *gap, const char_u *path,
if (os_file_is_readable(dirpath) && os_scandir(&dir, dirpath)) {
// Find all matching entries.
char_u *name;
- scandir_next_with_dots(NULL /* initialize */);
- while((name = (char_u *) scandir_next_with_dots(&dir)) && name != NULL) {
- if ((name[0] != '.' || starts_with_dot)
+ scandir_next_with_dots(NULL); // initialize
+ while ((name = (char_u *) scandir_next_with_dots(&dir)) && name != NULL) {
+ if ((name[0] != '.'
+ || starts_with_dot
+ || ((flags & EW_DODOT)
+ && name[1] != NUL && (name[1] != '.' || name[2] != NUL)))
&& ((regmatch.regprog != NULL && vim_regexec(&regmatch, name, 0))
|| ((flags & EW_NOTWILD)
&& fnamencmp(path + (s - buf), name, e - s) == 0))) {
@@ -1220,7 +1223,7 @@ int gen_expand_wildcards(int num_pat, char_u **pat, int *num_file,
recursive = false;
- return (ga.ga_data != NULL) ? OK : FAIL;
+ return ((flags & EW_EMPTYOK) || ga.ga_data != NULL) ? OK : FAIL;
}
diff --git a/src/nvim/path.h b/src/nvim/path.h
index eac367d0ac..88e5935c24 100644
--- a/src/nvim/path.h
+++ b/src/nvim/path.h
@@ -21,6 +21,8 @@
/* Note: mostly EW_NOTFOUND and EW_SILENT are mutually exclusive: EW_NOTFOUND
* is used when executing commands and EW_SILENT for interactive expanding. */
#define EW_ALLLINKS 0x1000 // also links not pointing to existing file
+#define EW_DODOT 0x4000 // also files starting with a dot
+#define EW_EMPTYOK 0x8000 // no matches is not an error
/// Return value for the comparison of two files. Also @see path_full_compare.
typedef enum file_comparison {
diff --git a/src/nvim/quickfix.c b/src/nvim/quickfix.c
index 28c0425e2c..97db69d3f3 100644
--- a/src/nvim/quickfix.c
+++ b/src/nvim/quickfix.c
@@ -39,7 +39,6 @@
#include "nvim/search.h"
#include "nvim/strings.h"
#include "nvim/ui.h"
-#include "nvim/tempfile.h"
#include "nvim/window.h"
#include "nvim/os/os.h"
#include "nvim/os/input.h"
diff --git a/src/nvim/spell.c b/src/nvim/spell.c
index fdae89b84c..0acaa9ae2b 100644
--- a/src/nvim/spell.c
+++ b/src/nvim/spell.c
@@ -319,7 +319,6 @@
#include "nvim/strings.h"
#include "nvim/syntax.h"
#include "nvim/ui.h"
-#include "nvim/tempfile.h"
#include "nvim/undo.h"
#include "nvim/os/os.h"
#include "nvim/os/input.h"
diff --git a/src/nvim/tempfile.c b/src/nvim/tempfile.c
deleted file mode 100644
index afe926b2ef..0000000000
--- a/src/nvim/tempfile.c
+++ /dev/null
@@ -1,139 +0,0 @@
-#include <inttypes.h>
-#include <stdbool.h>
-#include <stdlib.h>
-#include <stdio.h>
-
-#include "nvim/ascii.h"
-#include "nvim/memory.h"
-#include "nvim/misc1.h"
-#include "nvim/os/os.h"
-#include "nvim/os/os_defs.h"
-#include "nvim/path.h"
-#include "nvim/strings.h"
-#include "nvim/tempfile.h"
-
-#ifdef INCLUDE_GENERATED_DECLARATIONS
-# include "tempfile.c.generated.h"
-#endif
-
-/// Name of Vim's own temp dir. Ends in a slash.
-static char_u *vim_tempdir = NULL;
-
-/// Create a directory for private use by this instance of Neovim.
-/// This is done once, and the same directory is used for all temp files.
-/// This method avoids security problems because of symlink attacks et al.
-/// It's also a bit faster, because we only need to check for an existing
-/// file when creating the directory and not for each temp file.
-static void vim_maketempdir(void)
-{
- static const char *temp_dirs[] = TEMP_DIR_NAMES;
- // Try the entries in `TEMP_DIR_NAMES` to create the temp directory.
- char_u template[TEMP_FILE_PATH_MAXLEN];
- char_u path[TEMP_FILE_PATH_MAXLEN];
- for (size_t i = 0; i < ARRAY_SIZE(temp_dirs); ++i) {
- // Expand environment variables, leave room for "/nvimXXXXXX/999999999"
- // Skip the directory check if the expansion fails.
- expand_env((char_u *)temp_dirs[i], template, TEMP_FILE_PATH_MAXLEN - 22);
- if (template[0] == '$' || !os_isdir(template)) {
- continue;
- }
-
- add_pathsep((char *)template);
- // Concatenate with temporary directory name pattern
- STRCAT(template, "nvimXXXXXX");
-
- if (os_mkdtemp((const char *)template, (char *)path) != 0) {
- continue;
- }
-
- if (vim_settempdir((char *)path)) {
- // Successfully created and set temporary directory so stop trying.
- break;
- } else {
- // Couldn't set `vim_tempdir` to `path` so remove created directory.
- os_rmdir((char *)path);
- }
- }
-}
-
-/// Delete the temp directory and all files it contains.
-void vim_deltempdir(void)
-{
- if (vim_tempdir != NULL) {
- snprintf((char *)NameBuff, MAXPATHL, "%s*", vim_tempdir);
-
- char_u **files;
- int file_count;
-
- // Note: We cannot just do `&NameBuff` because it is a statically
- // sized array so `NameBuff == &NameBuff` according to C semantics.
- char_u *buff_list[1] = {NameBuff};
- if (gen_expand_wildcards(1, buff_list, &file_count, &files,
- EW_DIR|EW_FILE|EW_SILENT) == OK) {
- for (int i = 0; i < file_count; ++i) {
- os_remove((char *)files[i]);
- }
- FreeWild(file_count, files);
- }
- path_tail(NameBuff)[-1] = NUL;
- os_rmdir((char *)NameBuff);
-
- xfree(vim_tempdir);
- vim_tempdir = NULL;
- }
-}
-
-/// Get the name of temp directory. This directory would be created on the first
-/// call to this function.
-char_u *vim_gettempdir(void)
-{
- if (vim_tempdir == NULL) {
- vim_maketempdir();
- }
-
- return vim_tempdir;
-}
-
-/// Set Neovim own temporary directory name to `tempdir`. This directory should
-/// be already created. Expand this name to a full path and put it in
-/// `vim_tempdir`. This avoids that using `:cd` would confuse us.
-///
-/// @param tempdir must be no longer than MAXPATHL.
-///
-/// @return false if we run out of memory.
-static bool vim_settempdir(char *tempdir)
-{
- char *buf = verbose_try_malloc(MAXPATHL + 2);
- if (!buf) {
- return false;
- }
- vim_FullName(tempdir, buf, MAXPATHL, false);
- add_pathsep(buf);
- vim_tempdir = (char_u *)xstrdup(buf);
- xfree(buf);
- return true;
-}
-
-/// Return a unique name that can be used for a temp file.
-///
-/// @note The temp file is NOT created.
-///
-/// @return pointer to the temp file name or NULL if Neovim can't create
-/// temporary directory for its own temporary files.
-char_u *vim_tempname(void)
-{
- // Temp filename counter.
- static uint32_t temp_count;
-
- char_u *tempdir = vim_gettempdir();
- if (!tempdir) {
- return NULL;
- }
-
- // There is no need to check if the file exists, because we own the directory
- // and nobody else creates a file in it.
- char_u template[TEMP_FILE_PATH_MAXLEN];
- snprintf((char *)template, TEMP_FILE_PATH_MAXLEN,
- "%s%" PRIu32, tempdir, temp_count++);
- return vim_strsave(template);
-}
diff --git a/src/nvim/tempfile.h b/src/nvim/tempfile.h
deleted file mode 100644
index c030a70eeb..0000000000
--- a/src/nvim/tempfile.h
+++ /dev/null
@@ -1,8 +0,0 @@
-#ifndef NVIM_TEMPFILE_H
-#define NVIM_TEMPFILE_H
-
-#ifdef INCLUDE_GENERATED_DECLARATIONS
-# include "tempfile.h.generated.h"
-#endif
-
-#endif // NVIM_TEMPFILE_H
diff --git a/src/nvim/version.c b/src/nvim/version.c
index 4b5216760e..ca6b66f220 100644
--- a/src/nvim/version.c
+++ b/src/nvim/version.c
@@ -557,20 +557,20 @@ static int included_patches[] = {
// 1123,
// 1122 NA
// 1121,
- // 1120,
+ 1120,
// 1119,
// 1118,
- // 1117,
- // 1116,
+ 1117,
+ 1116,
// 1115 NA
- // 1114,
+ 1114,
1113,
1112,
// 1111,
// 1110,
// 1109 NA
// 1108,
- // 1107,
+ 1107,
// 1106 NA
1105,
// 1104 NA
diff --git a/test/functional/legacy/delete_spec.lua b/test/functional/legacy/delete_spec.lua
new file mode 100644
index 0000000000..cd18a8f750
--- /dev/null
+++ b/test/functional/legacy/delete_spec.lua
@@ -0,0 +1,99 @@
+local helpers = require('test.functional.helpers')
+local clear, source = helpers.clear, helpers.source
+local eq, eval, execute = helpers.eq, helpers.eval, helpers.execute
+
+describe('Test for delete()', function()
+ before_each(clear)
+
+ it('file delete', function()
+ execute('split Xfile')
+ execute("call setline(1, ['a', 'b'])")
+ execute('wq')
+ eq(eval("['a', 'b']"), eval("readfile('Xfile')"))
+ eq(0, eval("delete('Xfile')"))
+ eq(-1, eval("delete('Xfile')"))
+ end)
+
+ it('directory delete', function()
+ execute("call mkdir('Xdir1')")
+ eq(1, eval("isdirectory('Xdir1')"))
+ eq(0, eval("delete('Xdir1', 'd')"))
+ eq(0, eval("isdirectory('Xdir1')"))
+ eq(-1, eval("delete('Xdir1', 'd')"))
+ end)
+ it('recursive delete', function()
+ execute("call mkdir('Xdir1')")
+ execute("call mkdir('Xdir1/subdir')")
+ execute("call mkdir('Xdir1/empty')")
+ execute('split Xdir1/Xfile')
+ execute("call setline(1, ['a', 'b'])")
+ execute('w')
+ execute('w Xdir1/subdir/Xfile')
+ execute('close')
+
+ eq(1, eval("isdirectory('Xdir1')"))
+ eq(eval("['a', 'b']"), eval("readfile('Xdir1/Xfile')"))
+ eq(1, eval("isdirectory('Xdir1/subdir')"))
+ eq(eval("['a', 'b']"), eval("readfile('Xdir1/subdir/Xfile')"))
+ eq(1, eval("isdirectory('Xdir1/empty')"))
+ eq(0, eval("delete('Xdir1', 'rf')"))
+ eq(0, eval("isdirectory('Xdir1')"))
+ eq(-1, eval("delete('Xdir1', 'd')"))
+ end)
+
+ it('symlink delete', function()
+ source([[
+ split Xfile
+ call setline(1, ['a', 'b'])
+ wq
+ silent !ln -s Xfile Xlink
+ ]])
+ -- Delete the link, not the file
+ eq(0, eval("delete('Xlink')"))
+ eq(-1, eval("delete('Xlink')"))
+ eq(0, eval("delete('Xfile')"))
+ end)
+
+ it('symlink directory delete', function()
+ execute("call mkdir('Xdir1')")
+ execute("silent !ln -s Xdir1 Xlink")
+ eq(1, eval("isdirectory('Xdir1')"))
+ eq(1, eval("isdirectory('Xlink')"))
+ -- Delete the link, not the directory
+ eq(0, eval("delete('Xlink')"))
+ eq(-1, eval("delete('Xlink')"))
+ eq(0, eval("delete('Xdir1', 'd')"))
+ end)
+
+ it('symlink recursive delete', function()
+ source([[
+ call mkdir('Xdir3')
+ call mkdir('Xdir3/subdir')
+ call mkdir('Xdir4')
+ split Xdir3/Xfile
+ call setline(1, ['a', 'b'])
+ w
+ w Xdir3/subdir/Xfile
+ w Xdir4/Xfile
+ close
+ silent !ln -s ../Xdir4 Xdir3/Xlink
+ ]])
+
+ eq(1, eval("isdirectory('Xdir3')"))
+ eq(eval("['a', 'b']"), eval("readfile('Xdir3/Xfile')"))
+ eq(1, eval("isdirectory('Xdir3/subdir')"))
+ eq(eval("['a', 'b']"), eval("readfile('Xdir3/subdir/Xfile')"))
+ eq(1, eval("isdirectory('Xdir4')"))
+ eq(1, eval("isdirectory('Xdir3/Xlink')"))
+ eq(eval("['a', 'b']"), eval("readfile('Xdir4/Xfile')"))
+
+ eq(0, eval("delete('Xdir3', 'rf')"))
+ eq(0, eval("isdirectory('Xdir3')"))
+ eq(-1, eval("delete('Xdir3', 'd')"))
+ -- symlink is deleted, not the directory it points to
+ eq(1, eval("isdirectory('Xdir4')"))
+ eq(eval("['a', 'b']"), eval("readfile('Xdir4/Xfile')"))
+ eq(0, eval("delete('Xdir4/Xfile')"))
+ eq(0, eval("delete('Xdir4', 'd')"))
+ end)
+end)
diff --git a/test/unit/formatc.lua b/test/unit/formatc.lua
index 3f86c5f1b1..00637e0b8d 100644
--- a/test/unit/formatc.lua
+++ b/test/unit/formatc.lua
@@ -238,7 +238,7 @@ local function standalone(...) -- luacheck: ignore
end
-- uncomment this line (and comment the `return`) for standalone debugging
-- example usage:
--- ../../.deps/usr/bin/luajit formatc.lua ../../include/tempfile.h.generated.h
+-- ../../.deps/usr/bin/luajit formatc.lua ../../include/fileio.h.generated.h
-- ../../.deps/usr/bin/luajit formatc.lua /usr/include/malloc.h
-- standalone(...)
return formatc
diff --git a/test/unit/tempfile_spec.lua b/test/unit/tempfile_spec.lua
index e558ff04c8..b3e84db132 100644
--- a/test/unit/tempfile_spec.lua
+++ b/test/unit/tempfile_spec.lua
@@ -2,7 +2,7 @@ local lfs = require 'lfs'
local helpers = require 'test.unit.helpers'
local os = helpers.cimport './src/nvim/os/os.h'
-local tempfile = helpers.cimport './src/nvim/tempfile.h'
+local tempfile = helpers.cimport './src/nvim/fileio.h'
describe('tempfile related functions', function()
after_each(function()