| To: vim_dev@googlegroups.com |
| Subject: Patch 7.4.242 |
| Fcc: outbox |
| From: Bram Moolenaar <Bram@moolenaar.net> |
| Mime-Version: 1.0 |
| Content-Type: text/plain; charset=UTF-8 |
| Content-Transfer-Encoding: 8bit |
| |
| |
| Patch 7.4.242 |
| Problem: getreg() does not distinguish between a NL used for a line break |
| and a NL used for a NUL character. |
| Solution: Add another argument to return a list. (ZyX) |
| Files: runtime/doc/eval.txt, src/eval.c src/ops.c, src/proto/ops.pro, |
| src/vim.h, src/Makefile, src/testdir/test_eval.in, |
| src/testdir/test_eval.ok, src/testdir/Make_amiga.mak, |
| src/testdir/Make_dos.mak, src/testdir/Make_ming.mak, |
| src/testdir/Make_os2.mak, src/testdir/Make_vms.mms |
| |
| |
| |
| |
| |
| *** 1818,1824 **** |
| 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 |
| getregtype( [{regname}]) String type of register |
| gettabvar( {nr}, {varname} [, {def}]) |
| any variable {varname} in tab {nr} or {def} |
| --- 1819,1826 ---- |
| getpid() Number process ID of Vim |
| getpos( {expr}) List position of cursor, mark, etc. |
| getqflist() List list of quickfix items |
| ! 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} |
| |
| *** 3466,3472 **** |
| :endfor |
| |
| |
| ! getreg([{regname} [, 1]]) *getreg()* |
| The result is a String, which is the contents of register |
| {regname}. Example: > |
| :let cliptext = getreg('*') |
| --- 3468,3474 ---- |
| :endfor |
| |
| |
| ! getreg([{regname} [, 1 [, {list}]]]) *getreg()* |
| The result is a String, which is the contents of register |
| {regname}. Example: > |
| :let cliptext = getreg('*') |
| |
| *** 3475,3480 **** |
| --- 3477,3487 ---- |
| 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. |
| |
| |
| |
| |
| |
| *** 2458,2464 **** |
| p = get_tv_string_chk(tv); |
| if (p != NULL && op != NULL && *op == '.') |
| { |
| ! s = get_reg_contents(*arg == '@' ? '"' : *arg, TRUE, TRUE); |
| if (s != NULL) |
| { |
| p = ptofree = concat_str(s, p); |
| --- 2458,2464 ---- |
| p = get_tv_string_chk(tv); |
| if (p != NULL && op != NULL && *op == '.') |
| { |
| ! s = get_reg_contents(*arg == '@' ? '"' : *arg, GREG_EXPR_SRC); |
| if (s != NULL) |
| { |
| p = ptofree = concat_str(s, p); |
| |
| *** 5121,5127 **** |
| if (evaluate) |
| { |
| rettv->v_type = VAR_STRING; |
| ! rettv->vval.v_string = get_reg_contents(**arg, TRUE, TRUE); |
| } |
| if (**arg != NUL) |
| ++*arg; |
| --- 5121,5128 ---- |
| if (evaluate) |
| { |
| rettv->v_type = VAR_STRING; |
| ! rettv->vval.v_string = get_reg_contents(**arg, |
| ! GREG_EXPR_SRC); |
| } |
| if (**arg != NUL) |
| ++*arg; |
| |
| *** 7970,7976 **** |
| {"getpid", 0, 0, f_getpid}, |
| {"getpos", 1, 1, f_getpos}, |
| {"getqflist", 0, 0, f_getqflist}, |
| ! {"getreg", 0, 2, f_getreg}, |
| {"getregtype", 0, 1, f_getregtype}, |
| {"gettabvar", 2, 3, f_gettabvar}, |
| {"gettabwinvar", 3, 4, f_gettabwinvar}, |
| --- 7971,7977 ---- |
| {"getpid", 0, 0, f_getpid}, |
| {"getpos", 1, 1, f_getpos}, |
| {"getqflist", 0, 0, f_getqflist}, |
| ! {"getreg", 0, 3, f_getreg}, |
| {"getregtype", 0, 1, f_getregtype}, |
| {"gettabvar", 2, 3, f_gettabvar}, |
| {"gettabwinvar", 3, 4, f_gettabwinvar}, |
| |
| *** 11799,11804 **** |
| --- 11800,11806 ---- |
| char_u *strregname; |
| int regname; |
| int arg2 = FALSE; |
| + int return_list = FALSE; |
| int error = FALSE; |
| |
| if (argvars[0].v_type != VAR_UNKNOWN) |
| |
| *** 11806,11822 **** |
| 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); |
| } |
| else |
| strregname = vimvars[VV_REG].vv_str; |
| 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); |
| } |
| |
| /* |
| --- 11808,11841 ---- |
| 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 = '"'; |
| |
| ! 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,17899 **** |
| typval_T *rettv; |
| { |
| int error = FALSE; |
| - char_u **match; |
| - char_u **s; |
| - listitem_T *li; |
| int no; |
| int retList = 0; |
| |
| --- 17910,17915 ---- |
| |
| |
| |
| *** 6166,6181 **** |
| return MAUTO; |
| } |
| |
| /* |
| * Return the contents of a register as a single allocated string. |
| * Used for "@r" in expressions and for getreg(). |
| * Returns NULL for error. |
| */ |
| char_u * |
| ! get_reg_contents(regname, allowexpr, expr_src) |
| int regname; |
| ! int allowexpr; /* allow "=" register */ |
| ! int expr_src; /* get expression for "=" register */ |
| { |
| long i; |
| char_u *retval; |
| --- 6166,6214 ---- |
| 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, flags) |
| int regname; |
| ! int flags; |
| { |
| long i; |
| char_u *retval; |
| |
| *** 6185,6197 **** |
| /* 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 (regname == '@') /* "@@" is used for unnamed register */ |
| --- 6218,6228 ---- |
| /* Don't allow using an expression register inside an expression */ |
| if (regname == '=') |
| { |
| ! 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,6223 **** |
| { |
| if (retval == NULL) |
| return NULL; |
| ! if (!allocated) |
| ! retval = vim_strsave(retval); |
| ! return retval; |
| } |
| |
| get_yank_register(regname, FALSE); |
| if (y_current->y_array == NULL) |
| return NULL; |
| |
| /* |
| * Compute length of resulting string. |
| */ |
| --- 6240,6272 ---- |
| { |
| if (retval == NULL) |
| return NULL; |
| ! 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. |
| */ |
| |
| |
| |
| *** 53,59 **** |
| 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)); |
| 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)); |
| --- 53,59 ---- |
| 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 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)); |
| |
| |
| |
| *** 2259,2264 **** |
| --- 2259,2269 ---- |
| #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 '#' |
| |
| |
| |
| |
| *** 1880,1885 **** |
| --- 1880,1886 ---- |
| |
| # 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 \ |
| |
| |
| |
| |
| --- 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 |
| |
| |
| |
| |
| --- 1,7 ---- |
| + result |
| + 'one |
| + two |
| + three |
| + four |
| + ' |
| + ['one', 'two', 'three', 'four'] |
| |
| |
| |
| *** 36,41 **** |
| --- 36,42 ---- |
| 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,162 **** |
| --- 160,164 ---- |
| test104.out: test104.in |
| test105.out: test105.in |
| test106.out: test106.in |
| + test_eval.out: test_eval.in |
| test_options.out: test_options.in |
| |
| |
| |
| *** 35,40 **** |
| --- 35,41 ---- |
| 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 |
| |
| |
| |
| *** 55,60 **** |
| --- 55,61 ---- |
| 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 |
| |
| |
| |
| *** 37,42 **** |
| --- 37,43 ---- |
| 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 |
| |
| |
| |
| *** 96,101 **** |
| --- 96,102 ---- |
| 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: |
| |
| |
| |
| *** 736,737 **** |
| --- 736,739 ---- |
| { /* Add new patch number below this line */ |
| + /**/ |
| + 242, |
| /**/ |
| |
| -- |
| Don't Panic! |
| -- The Hitchhiker's Guide to the Galaxy |
| |
| /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ |
| /// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\ |
| \\\ an exciting new programming language -- http://www.Zimbu.org /// |
| \\\ help me help AIDS victims -- http://ICCF-Holland.org /// |