summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2021-01-13 20:38:03 +0100
committerBram Moolenaar <Bram@vim.org>2021-01-13 20:38:03 +0100
commitc423ad77ed763c11ba67729bbf63c1cf0915231f (patch)
treed50a83a06633e84412413b5b6c8fcbe58a4acf75
parent9145846b6aa411e3ab5c0d145b37808654352877 (diff)
downloadvim-git-c423ad77ed763c11ba67729bbf63c1cf0915231f.tar.gz
patch 8.2.2343: Vim9: return type of readfile() is anyv8.2.2343
Problem: Vim9: return type of readfile() is any. Solution: Add readblob() so that readfile() can be expected to always return a list of strings. (closes #7671)
-rw-r--r--runtime/doc/eval.txt21
-rw-r--r--runtime/doc/usr_41.txt1
-rw-r--r--src/evalfunc.c4
-rw-r--r--src/filepath.c27
-rw-r--r--src/proto/filepath.pro3
-rw-r--r--src/testdir/test_vim9_builtin.vim26
-rw-r--r--src/version.c2
7 files changed, 74 insertions, 10 deletions
diff --git a/runtime/doc/eval.txt b/runtime/doc/eval.txt
index 76c554853..01a123565 100644
--- a/runtime/doc/eval.txt
+++ b/runtime/doc/eval.txt
@@ -1,4 +1,4 @@
-*eval.txt* For Vim version 8.2. Last change: 2021 Jan 10
+*eval.txt* For Vim version 8.2. Last change: 2021 Jan 13
VIM REFERENCE MANUAL by Bram Moolenaar
@@ -2775,6 +2775,7 @@ pyxeval({expr}) any evaluate |python_x| expression
rand([{expr}]) Number get pseudo-random number
range({expr} [, {max} [, {stride}]])
List items from {expr} to {max}
+readblob({fname}) Blob read a |Blob| from {fname}
readdir({dir} [, {expr} [, {dict}]])
List file names in {dir} selected by {expr}
readdirex({dir} [, {expr} [, {dict}]])
@@ -8265,6 +8266,14 @@ rand([{expr}]) *rand()* *random*
:echo rand(seed)
:echo rand(seed) % 16 " random number 0 - 15
<
+
+readblob({fname}) *readblob()*
+ Read file {fname} in binary mode and return a |Blob|.
+ When the file can't be opened an error message is given and
+ the result is an empty |Blob|.
+ Also see |readfile()| and |writefile()|.
+
+
readdir({directory} [, {expr} [, {dict}]]) *readdir()*
Return a list with file and directory names in {directory}.
You can also use |glob()| if you don't need to do complicated
@@ -8379,6 +8388,7 @@ readdirex({directory} [, {expr} [, {dict}]]) *readdirex()*
Can also be used as a |method|: >
GetDirName()->readdirex()
<
+
*readfile()*
readfile({fname} [, {type} [, {max}]])
Read file {fname} and return a |List|, each line of the file
@@ -8390,8 +8400,6 @@ readfile({fname} [, {type} [, {max}]])
- When the last line ends in a NL an extra empty list item is
added.
- No CR characters are removed.
- When {type} contains "B" a |Blob| is returned with the binary
- data of the file unmodified.
Otherwise:
- CR characters that appear before a NL are removed.
- Whether the last line ends in a NL or not does not matter.
@@ -8409,6 +8417,9 @@ readfile({fname} [, {type} [, {max}]])
Note that without {max} the whole file is read into memory.
Also note that there is no recognition of encoding. Read a
file into a buffer if you need to.
+ Deprecated (use |readblob()| instead): When {type} contains
+ "B" a |Blob| is returned with the binary data of the file
+ unmodified.
When the file can't be opened an error message is given and
the result is an empty list.
Also see |writefile()|.
@@ -11295,9 +11306,11 @@ win_execute({id}, {command} [, {silent}]) *win_execute()*
call win_execute(winid, 'set syntax=python')
< Doing the same with `setwinvar()` would not trigger
autocommands and not actually show syntax highlighting.
+
*E994*
Not all commands are allowed in popup windows.
- When window {id} does not exist then no error is given.
+ When window {id} does not exist then no error is given and
+ an empty string is returned.
Can also be used as a |method|, the base is passed as the
second argument: >
diff --git a/runtime/doc/usr_41.txt b/runtime/doc/usr_41.txt
index 5f9c8e1bd..bac064cf7 100644
--- a/runtime/doc/usr_41.txt
+++ b/runtime/doc/usr_41.txt
@@ -820,6 +820,7 @@ System functions and manipulation of files:
setenv() set an environment variable
hostname() name of the system
readfile() read a file into a List of lines
+ readblob() read a file into a Blob
readdir() get a List of file names in a directory
readdirex() get a List of file information in a directory
writefile() write a List of lines or Blob into a file
diff --git a/src/evalfunc.c b/src/evalfunc.c
index 59fa2b1cf..a891378ee 100644
--- a/src/evalfunc.c
+++ b/src/evalfunc.c
@@ -1344,12 +1344,14 @@ static funcentry_T global_functions[] =
ret_number, f_rand},
{"range", 1, 3, FEARG_1, NULL,
ret_list_number, f_range},
+ {"readblob", 1, 1, FEARG_1, NULL,
+ ret_blob, f_readblob},
{"readdir", 1, 3, FEARG_1, NULL,
ret_list_string, f_readdir},
{"readdirex", 1, 3, FEARG_1, NULL,
ret_list_dict_any, f_readdirex},
{"readfile", 1, 3, FEARG_1, NULL,
- ret_any, f_readfile},
+ ret_list_string, f_readfile},
{"reduce", 2, 3, FEARG_1, NULL,
ret_any, f_reduce},
{"reg_executing", 0, 0, 0, NULL,
diff --git a/src/filepath.c b/src/filepath.c
index 0db0dcfb1..81fe74924 100644
--- a/src/filepath.c
+++ b/src/filepath.c
@@ -1640,11 +1640,11 @@ f_readdirex(typval_T *argvars, typval_T *rettv)
/*
* "readfile()" function
*/
- void
-f_readfile(typval_T *argvars, typval_T *rettv)
+ static void
+read_file_or_blob(typval_T *argvars, typval_T *rettv, int always_blob)
{
int binary = FALSE;
- int blob = FALSE;
+ int blob = always_blob;
int failed = FALSE;
char_u *fname;
FILE *fd;
@@ -1796,7 +1796,8 @@ f_readfile(typval_T *argvars, typval_T *rettv)
if (dest < buf)
{
- adjust_prevlen = (int)(buf - dest); // must be 1 or 2
+ // must be 1 or 2
+ adjust_prevlen = (int)(buf - dest);
dest = buf;
}
if (readlen > p - buf + 1)
@@ -1867,6 +1868,24 @@ f_readfile(typval_T *argvars, typval_T *rettv)
}
/*
+ * "readblob()" function
+ */
+ void
+f_readblob(typval_T *argvars, typval_T *rettv)
+{
+ read_file_or_blob(argvars, rettv, TRUE);
+}
+
+/*
+ * "readfile()" function
+ */
+ void
+f_readfile(typval_T *argvars, typval_T *rettv)
+{
+ read_file_or_blob(argvars, rettv, FALSE);
+}
+
+/*
* "resolve()" function
*/
void
diff --git a/src/proto/filepath.pro b/src/proto/filepath.pro
index b502b8e49..62612117d 100644
--- a/src/proto/filepath.pro
+++ b/src/proto/filepath.pro
@@ -1,5 +1,6 @@
/* filepath.c */
int modify_fname(char_u *src, int tilde_file, int *usedlen, char_u **fnamep, char_u **bufp, int *fnamelen);
+void shorten_dir(char_u *str);
void f_chdir(typval_T *argvars, typval_T *rettv);
void f_delete(typval_T *argvars, typval_T *rettv);
void f_executable(typval_T *argvars, typval_T *rettv);
@@ -21,10 +22,10 @@ void f_glob2regpat(typval_T *argvars, typval_T *rettv);
void f_globpath(typval_T *argvars, typval_T *rettv);
void f_isdirectory(typval_T *argvars, typval_T *rettv);
void f_mkdir(typval_T *argvars, typval_T *rettv);
-void shorten_dir(char_u *str);
void f_pathshorten(typval_T *argvars, typval_T *rettv);
void f_readdir(typval_T *argvars, typval_T *rettv);
void f_readdirex(typval_T *argvars, typval_T *rettv);
+void f_readblob(typval_T *argvars, typval_T *rettv);
void f_readfile(typval_T *argvars, typval_T *rettv);
void f_resolve(typval_T *argvars, typval_T *rettv);
void f_tempname(typval_T *argvars, typval_T *rettv);
diff --git a/src/testdir/test_vim9_builtin.vim b/src/testdir/test_vim9_builtin.vim
index 40cfdcbb1..3d474f3ed 100644
--- a/src/testdir/test_vim9_builtin.vim
+++ b/src/testdir/test_vim9_builtin.vim
@@ -623,6 +623,32 @@ def Test_readdir()
eval expand('sautest')->readdirex((e) => e.name[0] !=# '.')
enddef
+def Test_readblob()
+ var blob = 0z12341234
+ writefile(blob, 'Xreadblob')
+ var read: blob = readblob('Xreadblob')
+ assert_equal(blob, read)
+
+ var lines =<< trim END
+ var read: list<string> = readblob('Xreadblob')
+ END
+ CheckDefAndScriptFailure(lines, 'E1012: Type mismatch; expected list<string> but got blob', 1)
+ delete('Xreadblob')
+enddef
+
+def Test_readfile()
+ var text = ['aaa', 'bbb', 'ccc']
+ writefile(text, 'Xreadfile')
+ var read: list<string> = readfile('Xreadfile')
+ assert_equal(text, read)
+
+ var lines =<< trim END
+ var read: dict<string> = readfile('Xreadfile')
+ END
+ CheckDefAndScriptFailure(lines, 'E1012: Type mismatch; expected dict<string> but got list<string>', 1)
+ delete('Xreadfile')
+enddef
+
def Test_remove_return_type()
var l = remove({one: [1, 2], two: [3, 4]}, 'one')
var res = 0
diff --git a/src/version.c b/src/version.c
index aae7bf58d..07df2f30b 100644
--- a/src/version.c
+++ b/src/version.c
@@ -751,6 +751,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 2343,
+/**/
2342,
/**/
2341,