summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--runtime/doc/eval.txt10
-rw-r--r--src/Makefile1
-rw-r--r--src/eval.c34
-rw-r--r--src/ops.c75
-rw-r--r--src/proto/ops.pro2
-rw-r--r--src/testdir/Make_amiga.mak2
-rw-r--r--src/testdir/Make_dos.mak1
-rw-r--r--src/testdir/Make_ming.mak1
-rw-r--r--src/testdir/Make_os2.mak1
-rw-r--r--src/testdir/Make_vms.mms1
-rw-r--r--src/testdir/test_eval.in21
-rw-r--r--src/testdir/test_eval.ok7
-rw-r--r--src/version.c2
-rw-r--r--src/vim.h5
14 files changed, 138 insertions, 25 deletions
diff --git a/runtime/doc/eval.txt b/runtime/doc/eval.txt
index cdf8d72bb..b09742df8 100644
--- a/runtime/doc/eval.txt
+++ b/runtime/doc/eval.txt
@@ -1819,7 +1819,8 @@ getmatches() List list of current matches
getpid() Number process ID of Vim
getpos( {expr}) List position of cursor, mark, etc.
getqflist() List list of quickfix items
-getreg( [{regname} [, 1]]) String contents of register
+getreg( [{regname} [, 1 [, {list}]]])
+ String or List contents of register
getregtype( [{regname}]) String type of register
gettabvar( {nr}, {varname} [, {def}])
any variable {varname} in tab {nr} or {def}
@@ -3467,7 +3468,7 @@ getqflist() *getqflist()*
:endfor
-getreg([{regname} [, 1]]) *getreg()*
+getreg([{regname} [, 1 [, {list}]]]) *getreg()*
The result is a String, which is the contents of register
{regname}. Example: >
:let cliptext = getreg('*')
@@ -3476,6 +3477,11 @@ getreg([{regname} [, 1]]) *getreg()*
getreg('=', 1) returns the expression itself, so that it can
be restored with |setreg()|. For other registers the extra
argument is ignored, thus you can always give it.
+ If {list} is present and non-zero result type is changed to
+ |List|. Each list item is one text line. Use it if you care
+ about zero bytes possibly present inside register: without
+ third argument both NLs and zero bytes are represented as NLs
+ (see |NL-used-for-Nul|).
If {regname} is not specified, |v:register| is used.
diff --git a/src/Makefile b/src/Makefile
index 55fa662fe..30545aac6 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -1880,6 +1880,7 @@ unittest unittests: $(UNITTEST_TARGETS)
# Run individual test, assuming that Vim was already compiled.
test1 test2 test3 test4 test5 test6 test7 test8 test9 \
+ test_eval \
test_options \
test10 test11 test12 test13 test14 test15 test16 test17 test18 test19 \
test20 test21 test22 test23 test24 test25 test26 test27 test28 test29 \
diff --git a/src/eval.c b/src/eval.c
index 7b682572c..0b2c32316 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -2458,7 +2458,7 @@ ex_let_one(arg, tv, copy, endchars, op)
p = get_tv_string_chk(tv);
if (p != NULL && op != NULL && *op == '.')
{
- s = get_reg_contents(*arg == '@' ? '"' : *arg, TRUE, TRUE);
+ s = get_reg_contents(*arg == '@' ? '"' : *arg, GREG_EXPR_SRC);
if (s != NULL)
{
p = ptofree = concat_str(s, p);
@@ -5121,7 +5121,8 @@ eval7(arg, rettv, evaluate, want_string)
if (evaluate)
{
rettv->v_type = VAR_STRING;
- rettv->vval.v_string = get_reg_contents(**arg, TRUE, TRUE);
+ rettv->vval.v_string = get_reg_contents(**arg,
+ GREG_EXPR_SRC);
}
if (**arg != NUL)
++*arg;
@@ -7970,7 +7971,7 @@ static struct fst
{"getpid", 0, 0, f_getpid},
{"getpos", 1, 1, f_getpos},
{"getqflist", 0, 0, f_getqflist},
- {"getreg", 0, 2, f_getreg},
+ {"getreg", 0, 3, f_getreg},
{"getregtype", 0, 1, f_getregtype},
{"gettabvar", 2, 3, f_gettabvar},
{"gettabwinvar", 3, 4, f_gettabwinvar},
@@ -11799,6 +11800,7 @@ f_getreg(argvars, rettv)
char_u *strregname;
int regname;
int arg2 = FALSE;
+ int return_list = FALSE;
int error = FALSE;
if (argvars[0].v_type != VAR_UNKNOWN)
@@ -11806,17 +11808,34 @@ f_getreg(argvars, rettv)
strregname = get_tv_string_chk(&argvars[0]);
error = strregname == NULL;
if (argvars[1].v_type != VAR_UNKNOWN)
+ {
arg2 = get_tv_number_chk(&argvars[1], &error);
+ if (!error && argvars[2].v_type != VAR_UNKNOWN)
+ return_list = get_tv_number_chk(&argvars[2], &error);
+ }
}
else
strregname = vimvars[VV_REG].vv_str;
+
+ if (error)
+ return;
+
regname = (strregname == NULL ? '"' : *strregname);
if (regname == 0)
regname = '"';
- rettv->v_type = VAR_STRING;
- rettv->vval.v_string = error ? NULL :
- get_reg_contents(regname, TRUE, arg2);
+ if (return_list)
+ {
+ rettv->v_type = VAR_LIST;
+ rettv->vval.v_list = (list_T *)get_reg_contents(regname,
+ (arg2 ? GREG_EXPR_SRC : 0) | GREG_LIST);
+ }
+ else
+ {
+ rettv->v_type = VAR_STRING;
+ rettv->vval.v_string = get_reg_contents(regname,
+ arg2 ? GREG_EXPR_SRC : 0);
+ }
}
/*
@@ -17891,9 +17910,6 @@ f_submatch(argvars, rettv)
typval_T *rettv;
{
int error = FALSE;
- char_u **match;
- char_u **s;
- listitem_T *li;
int no;
int retList = 0;
diff --git a/src/ops.c b/src/ops.c
index 1d9f644f9..acce2af42 100644
--- a/src/ops.c
+++ b/src/ops.c
@@ -6166,16 +6166,49 @@ get_reg_type(regname, reglen)
return MAUTO;
}
+static char_u *getreg_wrap_one_line __ARGS((char_u *s, int flags));
+
+/*
+ * When "flags" has GREG_LIST return a list with text "s".
+ * Otherwise just return "s".
+ */
+ static char_u *
+getreg_wrap_one_line(s, flags)
+ char_u *s;
+ int flags;
+{
+ if (flags & GREG_LIST)
+ {
+ list_T *list = list_alloc();
+
+ if (list != NULL)
+ {
+ if (list_append_string(list, NULL, -1) == FAIL)
+ {
+ list_free(list, TRUE);
+ return NULL;
+ }
+ list->lv_first->li_tv.vval.v_string = s;
+ }
+ return (char_u *)list;
+ }
+ return s;
+}
+
/*
* Return the contents of a register as a single allocated string.
* Used for "@r" in expressions and for getreg().
* Returns NULL for error.
+ * Flags:
+ * GREG_NO_EXPR Do not allow expression register
+ * GREG_EXPR_SRC For the expression register: return expression itself,
+ * not the result of its evaluation.
+ * GREG_LIST Return a list of lines in place of a single string.
*/
char_u *
-get_reg_contents(regname, allowexpr, expr_src)
+get_reg_contents(regname, flags)
int regname;
- int allowexpr; /* allow "=" register */
- int expr_src; /* get expression for "=" register */
+ int flags;
{
long i;
char_u *retval;
@@ -6185,13 +6218,11 @@ get_reg_contents(regname, allowexpr, expr_src)
/* Don't allow using an expression register inside an expression */
if (regname == '=')
{
- if (allowexpr)
- {
- if (expr_src)
- return get_expr_line_src();
- return get_expr_line();
- }
- return NULL;
+ if (flags & GREG_NO_EXPR)
+ return NULL;
+ if (flags & GREG_EXPR_SRC)
+ return getreg_wrap_one_line(get_expr_line_src(), flags);
+ return getreg_wrap_one_line(get_expr_line(), flags);
}
if (regname == '@') /* "@@" is used for unnamed register */
@@ -6209,15 +6240,33 @@ get_reg_contents(regname, allowexpr, expr_src)
{
if (retval == NULL)
return NULL;
- if (!allocated)
- retval = vim_strsave(retval);
- return retval;
+ if (allocated)
+ return getreg_wrap_one_line(retval, flags);
+ return getreg_wrap_one_line(vim_strsave(retval), flags);
}
get_yank_register(regname, FALSE);
if (y_current->y_array == NULL)
return NULL;
+ if (flags & GREG_LIST)
+ {
+ list_T *list = list_alloc();
+ int error = FALSE;
+
+ if (list == NULL)
+ return NULL;
+ for (i = 0; i < y_current->y_size; ++i)
+ if (list_append_string(list, y_current->y_array[i], -1) == FAIL)
+ error = TRUE;
+ if (error)
+ {
+ list_free(list, TRUE);
+ return NULL;
+ }
+ return (char_u *)list;
+ }
+
/*
* Compute length of resulting string.
*/
diff --git a/src/proto/ops.pro b/src/proto/ops.pro
index a8c144ea8..3631256a3 100644
--- a/src/proto/ops.pro
+++ b/src/proto/ops.pro
@@ -53,7 +53,7 @@ void clip_yank_selection __ARGS((int type, char_u *str, long len, VimClipboard *
int clip_convert_selection __ARGS((char_u **str, long_u *len, VimClipboard *cbd));
void dnd_yank_drag_data __ARGS((char_u *str, long len));
char_u get_reg_type __ARGS((int regname, long *reglen));
-char_u *get_reg_contents __ARGS((int regname, int allowexpr, int expr_src));
+char_u *get_reg_contents __ARGS((int regname, int flags));
void write_reg_contents __ARGS((int name, char_u *str, int maxlen, int must_append));
void write_reg_contents_ex __ARGS((int name, char_u *str, int maxlen, int must_append, int yank_type, long block_len));
void clear_oparg __ARGS((oparg_T *oap));
diff --git a/src/testdir/Make_amiga.mak b/src/testdir/Make_amiga.mak
index 7310ab57d..3492945eb 100644
--- a/src/testdir/Make_amiga.mak
+++ b/src/testdir/Make_amiga.mak
@@ -36,6 +36,7 @@ SCRIPTS = test1.out test3.out test4.out test5.out test6.out \
test94.out test95.out test96.out test97.out test98.out \
test99.out test100.out test101.out test102.out test103.out \
test104.out test105.out test106.out \
+ test_eval.out \
test_options.out
.SUFFIXES: .in .out
@@ -159,4 +160,5 @@ test103.out: test103.in
test104.out: test104.in
test105.out: test105.in
test106.out: test106.in
+test_eval.out: test_eval.in
test_options.out: test_options.in
diff --git a/src/testdir/Make_dos.mak b/src/testdir/Make_dos.mak
index 8f749b0df..a85980ea0 100644
--- a/src/testdir/Make_dos.mak
+++ b/src/testdir/Make_dos.mak
@@ -35,6 +35,7 @@ SCRIPTS = test3.out test4.out test5.out test6.out test7.out \
test94.out test95.out test96.out test98.out test99.out \
test100.out test101.out test102.out test103.out test104.out \
test105.out test106.out \
+ test_eval.out \
test_options.out
SCRIPTS32 = test50.out test70.out
diff --git a/src/testdir/Make_ming.mak b/src/testdir/Make_ming.mak
index 855885999..0bb22cb7b 100644
--- a/src/testdir/Make_ming.mak
+++ b/src/testdir/Make_ming.mak
@@ -55,6 +55,7 @@ SCRIPTS = test3.out test4.out test5.out test6.out test7.out \
test94.out test95.out test96.out test98.out test99.out \
test100.out test101.out test102.out test103.out test104.out \
test105.out test106.out \
+ test_eval.out \
test_options.out
SCRIPTS32 = test50.out test70.out
diff --git a/src/testdir/Make_os2.mak b/src/testdir/Make_os2.mak
index a6ba86a9a..a84ade6ff 100644
--- a/src/testdir/Make_os2.mak
+++ b/src/testdir/Make_os2.mak
@@ -37,6 +37,7 @@ SCRIPTS = test1.out test3.out test4.out test5.out test6.out \
test94.out test95.out test96.out test98.out test99.out \
test100.out test101.out test102.out test103.out test104.out \
test105.out test106.out \
+ test_eval.out \
test_options.out
.SUFFIXES: .in .out
diff --git a/src/testdir/Make_vms.mms b/src/testdir/Make_vms.mms
index e7cbf0927..89c4a84cc 100644
--- a/src/testdir/Make_vms.mms
+++ b/src/testdir/Make_vms.mms
@@ -96,6 +96,7 @@ SCRIPT = test1.out test2.out test3.out test4.out test5.out \
test95.out test96.out test98.out test99.out \
test100.out test101.out test103.out test104.out \
test105.out test106.out \
+ test_eval.out \
test_options.out
# Known problems:
diff --git a/src/testdir/test_eval.in b/src/testdir/test_eval.in
new file mode 100644
index 000000000..115d50dd9
--- /dev/null
+++ b/src/testdir/test_eval.in
@@ -0,0 +1,21 @@
+Test for various eval features.
+
+STARTTEST
+:so small.vim
+:"
+:" test getreg()
+/^one
+"ay3j:$put =string(getreg('a'))
+:$put =string(getreg('a', 1, 1))
+:"
+:/^result/,$w! test.out
+:qa!
+ENDTEST
+
+one
+two
+three
+four
+five
+
+result
diff --git a/src/testdir/test_eval.ok b/src/testdir/test_eval.ok
new file mode 100644
index 000000000..8e6c987bd
--- /dev/null
+++ b/src/testdir/test_eval.ok
@@ -0,0 +1,7 @@
+result
+'one
+two
+three
+four
+'
+['one', 'two', 'three', 'four']
diff --git a/src/version.c b/src/version.c
index fbfb5e66a..e8bbf853a 100644
--- a/src/version.c
+++ b/src/version.c
@@ -735,6 +735,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 242,
+/**/
241,
/**/
240,
diff --git a/src/vim.h b/src/vim.h
index e83ea4a6e..84e139c75 100644
--- a/src/vim.h
+++ b/src/vim.h
@@ -2259,6 +2259,11 @@ typedef int VimClipboard; /* This is required for the prototypes. */
#define SREQ_WIN 1 /* Request window-local option */
#define SREQ_BUF 2 /* Request buffer-local option */
+/* Flags for get_reg_contents */
+#define GREG_NO_EXPR 1 /* Do not allow expression register */
+#define GREG_EXPR_SRC 2 /* Return expression itself for "=" register */
+#define GREG_LIST 4 /* Return list */
+
/* Character used as separated in autoload function/variable names. */
#define AUTOLOAD_CHAR '#'