diff options
author | Bram Moolenaar <Bram@vim.org> | 2014-04-02 22:17:10 +0200 |
---|---|---|
committer | Bram Moolenaar <Bram@vim.org> | 2014-04-02 22:17:10 +0200 |
commit | 5a50c2255c447838d08d3b4895a3be3a41cd8eda (patch) | |
tree | fcf0f3294276c6f7e7a27c252c1f7d521c691ba1 /src/ops.c | |
parent | b7cb42bc3878fcb62ed407f47f0a2cc960aa7c1e (diff) | |
download | vim-git-5a50c2255c447838d08d3b4895a3be3a41cd8eda.tar.gz |
updated for version 7.4.243v7.4.243
Problem: Cannot use setreg() to add text that includes a NUL.
Solution: Make setreg() accept a list.
Diffstat (limited to 'src/ops.c')
-rw-r--r-- | src/ops.c | 224 |
1 files changed, 158 insertions, 66 deletions
@@ -113,7 +113,7 @@ static char_u *skip_comment __ARGS((char_u *line, int process, int include_space #endif static void block_prep __ARGS((oparg_T *oap, struct block_def *, linenr_T, int)); #if defined(FEAT_CLIPBOARD) || defined(FEAT_EVAL) -static void str_to_reg __ARGS((struct yankreg *y_ptr, int type, char_u *str, long len, long blocklen)); +static void str_to_reg __ARGS((struct yankreg *y_ptr, int type, char_u *str, long len, long blocklen, int str_list)); #endif static int ends_in_white __ARGS((linenr_T lnum)); #ifdef FEAT_COMMENTS @@ -6005,7 +6005,7 @@ clip_yank_selection(type, str, len, cbd) clip_free_selection(cbd); - str_to_reg(y_ptr, type, str, len, 0L); + str_to_reg(y_ptr, type, str, len, 0L, FALSE); } /* @@ -6113,7 +6113,7 @@ dnd_yank_drag_data(str, len) curr = y_current; y_current = &y_regs[TILDE_REGISTER]; free_yank_all(); - str_to_reg(y_current, MCHAR, str, len, 0L); + str_to_reg(y_current, MCHAR, str, len, 0L, FALSE); y_current = curr; } #endif @@ -6308,6 +6308,47 @@ get_reg_contents(regname, flags) return retval; } + static int +init_write_reg(name, old_y_previous, old_y_current, must_append, yank_type) + int name; + struct yankreg **old_y_previous; + struct yankreg **old_y_current; + int must_append; + int *yank_type UNUSED; +{ + if (!valid_yank_reg(name, TRUE)) /* check for valid reg name */ + { + emsg_invreg(name); + return FAIL; + } + + /* Don't want to change the current (unnamed) register */ + *old_y_previous = y_previous; + *old_y_current = y_current; + + get_yank_register(name, TRUE); + if (!y_append && !must_append) + free_yank_all(); + return OK; +} + + static void +finish_write_reg(name, old_y_previous, old_y_current) + int name; + struct yankreg *old_y_previous; + struct yankreg *old_y_current; +{ +# ifdef FEAT_CLIPBOARD + /* Send text of clipboard register to the clipboard. */ + may_set_selection(); +# endif + + /* ':let @" = "val"' should change the meaning of the "" register */ + if (name != '"') + y_previous = old_y_previous; + y_current = old_y_current; +} + /* * Store string "str" in register "name". * "maxlen" is the maximum number of bytes to use, -1 for all bytes. @@ -6328,6 +6369,51 @@ write_reg_contents(name, str, maxlen, must_append) } void +write_reg_contents_lst(name, strings, maxlen, must_append, yank_type, block_len) + int name; + char_u **strings; + int maxlen UNUSED; + int must_append; + int yank_type; + long block_len; +{ + struct yankreg *old_y_previous, *old_y_current; + + if (name == '/' +#ifdef FEAT_EVAL + || name == '=' +#endif + ) + { + char_u *s; + + if (strings[0] == NULL) + s = (char_u *)""; + else if (strings[1] != NULL) + { + EMSG(_("E883: search pattern and expression register may not " + "contain two or more lines")); + return; + } + else + s = strings[0]; + write_reg_contents_ex(name, s, -1, must_append, yank_type, block_len); + return; + } + + if (name == '_') /* black hole: nothing to do */ + return; + + if (init_write_reg(name, &old_y_previous, &old_y_current, must_append, + &yank_type) == FAIL) + return; + + str_to_reg(y_current, yank_type, (char_u *) strings, -1, block_len, TRUE); + + finish_write_reg(name, old_y_previous, old_y_current); +} + + void write_reg_contents_ex(name, str, maxlen, must_append, yank_type, block_len) int name; char_u *str; @@ -6364,40 +6450,22 @@ write_reg_contents_ex(name, str, maxlen, must_append, yank_type, block_len) s = concat_str(get_expr_line_src(), p); vim_free(p); p = s; - } set_expr_line(p); return; } #endif - if (!valid_yank_reg(name, TRUE)) /* check for valid reg name */ - { - emsg_invreg(name); - return; - } - if (name == '_') /* black hole: nothing to do */ return; - /* Don't want to change the current (unnamed) register */ - old_y_previous = y_previous; - old_y_current = y_current; - - get_yank_register(name, TRUE); - if (!y_append && !must_append) - free_yank_all(); - str_to_reg(y_current, yank_type, str, len, block_len); + if (init_write_reg(name, &old_y_previous, &old_y_current, must_append, + &yank_type) == FAIL) + return; -# ifdef FEAT_CLIPBOARD - /* Send text of clipboard register to the clipboard. */ - may_set_selection(); -# endif + str_to_reg(y_current, yank_type, str, len, block_len, FALSE); - /* ':let @" = "val"' should change the meaning of the "" register */ - if (name != '"') - y_previous = old_y_previous; - y_current = old_y_current; + finish_write_reg(name, old_y_previous, old_y_current); } #endif /* FEAT_EVAL */ @@ -6407,12 +6475,13 @@ write_reg_contents_ex(name, str, maxlen, must_append, yank_type, block_len) * is appended. */ static void -str_to_reg(y_ptr, yank_type, str, len, blocklen) +str_to_reg(y_ptr, yank_type, str, len, blocklen, str_list) struct yankreg *y_ptr; /* pointer to yank register */ int yank_type; /* MCHAR, MLINE, MBLOCK, MAUTO */ char_u *str; /* string to put in register */ long len; /* length of string */ long blocklen; /* width of Visual block */ + int str_list; /* TRUE if str is char_u ** */ { int type; /* MCHAR, MLINE or MBLOCK */ int lnum; @@ -6423,6 +6492,7 @@ str_to_reg(y_ptr, yank_type, str, len, blocklen) int extraline = 0; /* extra line at the end */ int append = FALSE; /* append to last line in register */ char_u *s; + char_u **ss; char_u **pp; long maxlen; @@ -6430,7 +6500,8 @@ str_to_reg(y_ptr, yank_type, str, len, blocklen) y_ptr->y_size = 0; if (yank_type == MAUTO) - type = ((len > 0 && (str[len - 1] == NL || str[len - 1] == CAR)) + type = ((str_list || (len > 0 && (str[len - 1] == NL + || str[len - 1] == CAR))) ? MLINE : MCHAR); else type = yank_type; @@ -6439,18 +6510,26 @@ str_to_reg(y_ptr, yank_type, str, len, blocklen) * Count the number of lines within the string */ newlines = 0; - for (i = 0; i < len; i++) - if (str[i] == '\n') - ++newlines; - if (type == MCHAR || len == 0 || str[len - 1] != '\n') + if (str_list) { - extraline = 1; - ++newlines; /* count extra newline at the end */ + for (ss = (char_u **) str; *ss != NULL; ++ss) + ++newlines; } - if (y_ptr->y_size > 0 && y_ptr->y_type == MCHAR) + else { - append = TRUE; - --newlines; /* uncount newline when appending first line */ + for (i = 0; i < len; i++) + if (str[i] == '\n') + ++newlines; + if (type == MCHAR || len == 0 || str[len - 1] != '\n') + { + extraline = 1; + ++newlines; /* count extra newline at the end */ + } + if (y_ptr->y_size > 0 && y_ptr->y_type == MCHAR) + { + append = TRUE; + --newlines; /* uncount newline when appending first line */ + } } /* @@ -6470,40 +6549,53 @@ str_to_reg(y_ptr, yank_type, str, len, blocklen) /* * Find the end of each line and save it into the array. */ - for (start = 0; start < len + extraline; start += i + 1) + if (str_list) { - for (i = start; i < len; ++i) /* find the end of the line */ - if (str[i] == '\n') - break; - i -= start; /* i is now length of line */ - if (i > maxlen) - maxlen = i; - if (append) + for (ss = (char_u **) str; *ss != NULL; ++ss, ++lnum) { - --lnum; - extra = (int)STRLEN(y_ptr->y_array[lnum]); + i = STRLEN(*ss); + pp[lnum] = vim_strnsave(*ss, i); + if (i > maxlen) + maxlen = i; } - else - extra = 0; - s = alloc((unsigned)(i + extra + 1)); - if (s == NULL) - break; - if (extra) - mch_memmove(s, y_ptr->y_array[lnum], (size_t)extra); - if (append) - vim_free(y_ptr->y_array[lnum]); - if (i) - mch_memmove(s + extra, str + start, (size_t)i); - extra += i; - s[extra] = NUL; - y_ptr->y_array[lnum++] = s; - while (--extra >= 0) + } + else + { + for (start = 0; start < len + extraline; start += i + 1) { - if (*s == NUL) - *s = '\n'; /* replace NUL with newline */ - ++s; + for (i = start; i < len; ++i) /* find the end of the line */ + if (str[i] == '\n') + break; + i -= start; /* i is now length of line */ + if (i > maxlen) + maxlen = i; + if (append) + { + --lnum; + extra = (int)STRLEN(y_ptr->y_array[lnum]); + } + else + extra = 0; + s = alloc((unsigned)(i + extra + 1)); + if (s == NULL) + break; + if (extra) + mch_memmove(s, y_ptr->y_array[lnum], (size_t)extra); + if (append) + vim_free(y_ptr->y_array[lnum]); + if (i) + mch_memmove(s + extra, str + start, (size_t)i); + extra += i; + s[extra] = NUL; + y_ptr->y_array[lnum++] = s; + while (--extra >= 0) + { + if (*s == NUL) + *s = '\n'; /* replace NUL with newline */ + ++s; + } + append = FALSE; /* only first line is appended */ } - append = FALSE; /* only first line is appended */ } y_ptr->y_type = type; y_ptr->y_size = lnum; |