summaryrefslogtreecommitdiff
path: root/src/ops.c
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2014-04-02 22:17:10 +0200
committerBram Moolenaar <Bram@vim.org>2014-04-02 22:17:10 +0200
commit5a50c2255c447838d08d3b4895a3be3a41cd8eda (patch)
treefcf0f3294276c6f7e7a27c252c1f7d521c691ba1 /src/ops.c
parentb7cb42bc3878fcb62ed407f47f0a2cc960aa7c1e (diff)
downloadvim-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.c224
1 files changed, 158 insertions, 66 deletions
diff --git a/src/ops.c b/src/ops.c
index acce2af42..3a7d84603 100644
--- a/src/ops.c
+++ b/src/ops.c
@@ -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;