Patch 7.4.1919
Problem: Register contents is not merged when writing viminfo.
Solution: Use timestamps for register contents.
Files: src/ops.c, src/ex_getln.c, src/ex_cmds.c, src/proto/ex_cmds.pro,
src/proto/ex_getln.pro, src/proto/ops.pro, src/vim.h
*** ../vim-7.4.1918/src/ops.c 2016-06-04 20:14:00.302000092 +0200
--- src/ops.c 2016-06-11 20:45:08.396494246 +0200
***************
*** 50,68 ****
#endif
/*
! * Each yank register is an array of pointers to lines.
*/
! static struct yankreg
{
char_u **y_array; /* pointer to array of line pointers */
linenr_T y_size; /* number of lines in y_array */
char_u y_type; /* MLINE, MCHAR or MBLOCK */
colnr_T y_width; /* only set if y_type == MBLOCK */
! } y_regs[NUM_REGISTERS];
! static struct yankreg *y_current; /* ptr to current yankreg */
static int y_append; /* TRUE when appending */
! static struct yankreg *y_previous = NULL; /* ptr to last written yankreg */
/*
* structure used by block_prep, op_delete and op_yank for blockwise operators
--- 50,73 ----
#endif
/*
! * Each yank register has an array of pointers to lines.
*/
! typedef struct
{
char_u **y_array; /* pointer to array of line pointers */
linenr_T y_size; /* number of lines in y_array */
char_u y_type; /* MLINE, MCHAR or MBLOCK */
colnr_T y_width; /* only set if y_type == MBLOCK */
! #ifdef FEAT_VIMINFO
! time_t y_time_set;
! #endif
! } yankreg_T;
!
! static yankreg_T y_regs[NUM_REGISTERS];
! static yankreg_T *y_current; /* ptr to current yankreg */
static int y_append; /* TRUE when appending */
! static yankreg_T *y_previous = NULL; /* ptr to last written yankreg */
/*
* structure used by block_prep, op_delete and op_yank for blockwise operators
***************
*** 104,110 ****
static void free_yank_all(void);
static int yank_copy_line(struct block_def *bd, long y_idx);
#ifdef FEAT_CLIPBOARD
! static void copy_yank_reg(struct yankreg *reg);
static void may_set_selection(void);
#endif
static void dis_msg(char_u *p, int skip_esc);
--- 109,115 ----
static void free_yank_all(void);
static int yank_copy_line(struct block_def *bd, long y_idx);
#ifdef FEAT_CLIPBOARD
! static void copy_yank_reg(yankreg_T *reg);
static void may_set_selection(void);
#endif
static void dis_msg(char_u *p, int skip_esc);
***************
*** 114,120 ****
static void block_prep(oparg_T *oap, struct block_def *, linenr_T, int);
static int do_addsub(int op_type, pos_T *pos, int length, linenr_T
Prenum1);
#if defined(FEAT_CLIPBOARD) || defined(FEAT_EVAL)
! static void str_to_reg(struct yankreg *y_ptr, int yank_type, char_u *str,
long len, long blocklen, int str_list);
#endif
static int ends_in_white(linenr_T lnum);
#ifdef FEAT_COMMENTS
--- 119,125 ----
static void block_prep(oparg_T *oap, struct block_def *, linenr_T, int);
static int do_addsub(int op_type, pos_T *pos, int length, linenr_T
Prenum1);
#if defined(FEAT_CLIPBOARD) || defined(FEAT_EVAL)
! static void str_to_reg(yankreg_T *y_ptr, int yank_type, char_u *str, long
len, long blocklen, int str_list);
#endif
static int ends_in_white(linenr_T lnum);
#ifdef FEAT_COMMENTS
***************
*** 964,971 ****
int name,
int copy) /* make a copy, if FALSE make register empty. */
{
! struct yankreg *reg;
! int i;
#ifdef FEAT_CLIPBOARD
/* When Visual area changed, may have to update selection. Obtain the
--- 969,976 ----
int name,
int copy) /* make a copy, if FALSE make register empty. */
{
! yankreg_T *reg;
! int i;
#ifdef FEAT_CLIPBOARD
/* When Visual area changed, may have to update selection. Obtain the
***************
*** 985,991 ****
#endif
get_yank_register(name, 0);
! reg = (struct yankreg *)alloc((unsigned)sizeof(struct yankreg));
if (reg != NULL)
{
*reg = *y_current;
--- 990,996 ----
#endif
get_yank_register(name, 0);
! reg = (yankreg_T *)alloc((unsigned)sizeof(yankreg_T));
if (reg != NULL)
{
*reg = *y_current;
***************
*** 1017,1023 ****
{
get_yank_register(name, 0);
free_yank_all();
! *y_current = *(struct yankreg *)reg;
vim_free(reg);
#ifdef FEAT_CLIPBOARD
--- 1022,1028 ----
{
get_yank_register(name, 0);
free_yank_all();
! *y_current = *(yankreg_T *)reg;
vim_free(reg);
#ifdef FEAT_CLIPBOARD
***************
*** 1029,1038 ****
void
free_register(void *reg)
{
! struct yankreg tmp;
tmp = *y_current;
! *y_current = *(struct yankreg *)reg;
free_yank_all();
vim_free(reg);
*y_current = tmp;
--- 1034,1043 ----
void
free_register(void *reg)
{
! yankreg_T tmp;
tmp = *y_current;
! *y_current = *(yankreg_T *)reg;
free_yank_all();
vim_free(reg);
*y_current = tmp;
***************
*** 1064,1070 ****
{
char_u *p;
static int regname;
! struct yankreg *old_y_previous, *old_y_current;
int retval;
if (Recording == FALSE) /* start recording */
--- 1069,1075 ----
{
char_u *p;
static int regname;
! yankreg_T *old_y_previous, *old_y_current;
int retval;
if (Recording == FALSE) /* start recording */
***************
*** 1164,1169 ****
--- 1169,1177 ----
y_current->y_array[0] = p;
y_current->y_size = 1;
y_current->y_type = MCHAR; /* used to be MLINE, why? */
+ #ifdef FEAT_VIMINFO
+ y_current->y_time_set = vim_time();
+ #endif
}
return OK;
}
***************
*** 2907,2914 ****
op_yank(oparg_T *oap, int deleting, int mess)
{
long y_idx; /* index in y_array[] */
! struct yankreg *curr; /* copy of y_current */
! struct yankreg newreg; /* new yank register when appending */
char_u **new_ptr;
linenr_T lnum; /* current line number */
long j;
--- 2915,2922 ----
op_yank(oparg_T *oap, int deleting, int mess)
{
long y_idx; /* index in y_array[] */
! yankreg_T *curr; /* copy of y_current */
! yankreg_T newreg; /* new yank register when appending */
char_u **new_ptr;
linenr_T lnum; /* current line number */
long j;
***************
*** 2970,2981 ****
y_current->y_width = 0;
y_current->y_array = (char_u **)lalloc_clear((long_u)(sizeof(char_u *) *
yanklines), TRUE);
-
if (y_current->y_array == NULL)
{
y_current = curr;
return FAIL;
}
y_idx = 0;
lnum = oap->start.lnum;
--- 2978,2991 ----
y_current->y_width = 0;
y_current->y_array = (char_u **)lalloc_clear((long_u)(sizeof(char_u *) *
yanklines), TRUE);
if (y_current->y_array == NULL)
{
y_current = curr;
return FAIL;
}
+ #ifdef FEAT_VIMINFO
+ y_current->y_time_set = vim_time();
+ #endif
y_idx = 0;
lnum = oap->start.lnum;
***************
*** 3102,3107 ****
--- 3112,3120 ----
new_ptr[j] = curr->y_array[j];
vim_free(curr->y_array);
curr->y_array = new_ptr;
+ #ifdef FEAT_VIMINFO
+ curr->y_time_set = vim_time();
+ #endif
if (yanktype == MLINE) /* MLINE overrides MCHAR and MBLOCK */
curr->y_type = MLINE;
***************
*** 3252,3261 ****
* Make a copy of the y_current register to register "reg".
*/
static void
! copy_yank_reg(struct yankreg *reg)
{
! struct yankreg *curr = y_current;
! long j;
y_current = reg;
free_yank_all();
--- 3265,3274 ----
* Make a copy of the y_current register to register "reg".
*/
static void
! copy_yank_reg(yankreg_T *reg)
{
! yankreg_T *curr = y_current;
! long j;
y_current = reg;
free_yank_all();
***************
*** 4013,4019 ****
}
#endif
! /* Return the character name of the register with the given number */
int
get_register_name(int num)
{
--- 4026,4034 ----
}
#endif
! /*
! * Return the character name of the register with the given number.
! */
int
get_register_name(int num)
{
***************
*** 4053,4067 ****
void
ex_display(exarg_T *eap)
{
! int i, n;
! long j;
! char_u *p;
! struct yankreg *yb;
! int name;
! int attr;
! char_u *arg = eap->arg;
#ifdef FEAT_MBYTE
! int clen;
#else
# define clen 1
#endif
--- 4068,4082 ----
void
ex_display(exarg_T *eap)
{
! int i, n;
! long j;
! char_u *p;
! yankreg_T *yb;
! int name;
! int attr;
! char_u *arg = eap->arg;
#ifdef FEAT_MBYTE
! int clen;
#else
# define clen 1
#endif
***************
*** 5794,5799 ****
--- 5809,5850 ----
}
#ifdef FEAT_VIMINFO
+
+ static yankreg_T *y_read_regs = NULL;
+
+ #define REG_PREVIOUS 1
+ #define REG_EXEC 2
+
+ /*
+ * Prepare for reading viminfo registers when writing viminfo later.
+ */
+ void
+ prepare_viminfo_registers()
+ {
+ y_read_regs = (yankreg_T *)alloc_clear(NUM_REGISTERS
+ * (int)sizeof(yankreg_T));
+ }
+
+ void
+ finish_viminfo_registers()
+ {
+ int i;
+ int j;
+
+ if (y_read_regs != NULL)
+ {
+ for (i = 0; i < NUM_REGISTERS; ++i)
+ if (y_read_regs[i].y_array != NULL)
+ {
+ for (j = 0; j < y_read_regs[i].y_size; j++)
+ vim_free(y_read_regs[i].y_array[j]);
+ vim_free(y_read_regs[i].y_array);
+ }
+ vim_free(y_read_regs);
+ y_read_regs = NULL;
+ }
+ }
+
int
read_viminfo_register(vir_T *virp, int force)
{
***************
*** 5900,5905 ****
--- 5951,5957 ----
y_current->y_type = new_type;
y_current->y_width = new_width;
y_current->y_size = size;
+ y_current->y_time_set = 0;
if (size == 0)
{
y_current->y_array = NULL;
***************
*** 5929,5944 ****
return eof;
}
void
write_viminfo_registers(FILE *fp)
{
! int i, j;
! char_u *type;
! char_u c;
! int num_lines;
! int max_num_lines;
! int max_kbyte;
! long len;
fputs(_("\n# Registers:\n"), fp);
--- 5981,6086 ----
return eof;
}
+ /*
+ * Accept a new style register line from the viminfo, store it when it's new.
+ */
+ void
+ handle_viminfo_register(garray_T *values, int force)
+ {
+ bval_T *vp = (bval_T *)values->ga_data;
+ int flags;
+ int name;
+ int type;
+ int linecount;
+ int width;
+ time_t timestamp;
+ yankreg_T *y_ptr;
+ int i;
+
+ /* Check the format:
+ * |{bartype},{flags},{name},{type},
+ * {linecount},{width},{timestamp},"line1","line2"
+ */
+ if (values->ga_len < 6
+ || vp[0].bv_type != BVAL_NR
+ || vp[1].bv_type != BVAL_NR
+ || vp[2].bv_type != BVAL_NR
+ || vp[3].bv_type != BVAL_NR
+ || vp[4].bv_type != BVAL_NR
+ || vp[5].bv_type != BVAL_NR)
+ return;
+ flags = vp[0].bv_nr;
+ name = vp[1].bv_nr;
+ if (name < 0 || name > NUM_REGISTERS)
+ return;
+ type = vp[2].bv_nr;
+ if (type != MCHAR && type != MLINE && type != MBLOCK)
+ return;
+ linecount = vp[3].bv_nr;
+ if (values->ga_len < 6 + linecount)
+ return;
+ width = vp[4].bv_nr;
+ if (width < 0)
+ return;
+
+ if (y_read_regs != NULL)
+ /* Reading viminfo for merging and writing. Store the register
+ * content, don't update the current registers. */
+ y_ptr = &y_read_regs[name];
+ else
+ y_ptr = &y_regs[name];
+
+ /* Do not overwrite unless forced or the timestamp is newer. */
+ timestamp = (time_t)vp[5].bv_nr;
+ if (y_ptr->y_array != NULL && !force
+ && (timestamp == 0 || y_ptr->y_time_set > timestamp))
+ return;
+
+ for (i = 0; i < y_ptr->y_size; i++)
+ vim_free(y_ptr->y_array[i]);
+ vim_free(y_ptr->y_array);
+
+ if (y_read_regs == NULL)
+ {
+ if (flags & REG_PREVIOUS)
+ y_previous = y_ptr;
+ if ((flags & REG_EXEC) && (force || execreg_lastc == NUL))
+ execreg_lastc = get_register_name(name);
+ }
+ y_ptr->y_type = type;
+ y_ptr->y_width = width;
+ y_ptr->y_size = linecount;
+ y_ptr->y_time_set = timestamp;
+ if (linecount == 0)
+ y_ptr->y_array = NULL;
+ else
+ {
+ y_ptr->y_array =
+ (char_u **)alloc((unsigned)(linecount * sizeof(char_u *)));
+ for (i = 0; i < linecount; i++)
+ {
+ if (vp[i + 6].bv_allocated)
+ {
+ y_ptr->y_array[i] = vp[i + 6].bv_string;
+ vp[i + 6].bv_string = NULL;
+ }
+ else
+ y_ptr->y_array[i] = vim_strsave(vp[i + 6].bv_string);
+ }
+ }
+ }
+
void
write_viminfo_registers(FILE *fp)
{
! int i, j;
! char_u *type;
! char_u c;
! int num_lines;
! int max_num_lines;
! int max_kbyte;
! long len;
! yankreg_T *y_ptr;
fputs(_("\n# Registers:\n"), fp);
***************
*** 5954,5961 ****
for (i = 0; i < NUM_REGISTERS; i++)
{
- if (y_regs[i].y_array == NULL)
- continue;
#ifdef FEAT_CLIPBOARD
/* Skip '*'/'+' register, we don't want them back next time */
if (i == STAR_REGISTER || i == PLUS_REGISTER)
--- 6096,6101 ----
***************
*** 5966,5976 ****
if (i == TILDE_REGISTER)
continue;
#endif
/* Skip empty registers. */
! num_lines = y_regs[i].y_size;
if (num_lines == 0
! || (num_lines == 1 && y_regs[i].y_type == MCHAR
! && *y_regs[i].y_array[0] == NUL))
continue;
if (max_kbyte > 0)
--- 6106,6128 ----
if (i == TILDE_REGISTER)
continue;
#endif
+ /* When reading viminfo for merging and writing: Use the register from
+ * viminfo if it's newer. */
+ if (y_read_regs != NULL
+ && y_read_regs[i].y_array != NULL
+ && (y_regs[i].y_array == NULL ||
+ y_read_regs[i].y_time_set > y_regs[i].y_time_set))
+ y_ptr = &y_read_regs[i];
+ else if (y_regs[i].y_array == NULL)
+ continue;
+ else
+ y_ptr = &y_regs[i];
+
/* Skip empty registers. */
! num_lines = y_ptr->y_size;
if (num_lines == 0
! || (num_lines == 1 && y_ptr->y_type == MCHAR
! && *y_ptr->y_array[0] == NUL))
continue;
if (max_kbyte > 0)
***************
*** 5978,5989 ****
/* Skip register if there is more text than the maximum size. */
len = 0;
for (j = 0; j < num_lines; j++)
! len += (long)STRLEN(y_regs[i].y_array[j]) + 1L;
if (len > (long)max_kbyte * 1024L)
continue;
}
! switch (y_regs[i].y_type)
{
case MLINE:
type = (char_u *)"LINE";
--- 6130,6141 ----
/* Skip register if there is more text than the maximum size. */
len = 0;
for (j = 0; j < num_lines; j++)
! len += (long)STRLEN(y_ptr->y_array[j]) + 1L;
if (len > (long)max_kbyte * 1024L)
continue;
}
! switch (y_ptr->y_type)
{
case MLINE:
type = (char_u *)"LINE";
***************
*** 5996,6002 ****
break;
default:
sprintf((char *)IObuff, _("E574: Unknown register type %d"),
! y_regs[i].y_type);
emsg(IObuff);
type = (char_u *)"LINE";
break;
--- 6148,6154 ----
break;
default:
sprintf((char *)IObuff, _("E574: Unknown register type %d"),
! y_ptr->y_type);
emsg(IObuff);
type = (char_u *)"LINE";
break;
***************
*** 6007,6013 ****
fprintf(fp, "\"%c", c);
if (c == execreg_lastc)
fprintf(fp, "@");
! fprintf(fp, "\t%s\t%d\n", type, (int)y_regs[i].y_width);
/* If max_num_lines < 0, then we save ALL the lines in the register */
if (max_num_lines > 0 && num_lines > max_num_lines)
--- 6159,6165 ----
fprintf(fp, "\"%c", c);
if (c == execreg_lastc)
fprintf(fp, "@");
! fprintf(fp, "\t%s\t%d\n", type, (int)y_ptr->y_width);
/* If max_num_lines < 0, then we save ALL the lines in the register */
if (max_num_lines > 0 && num_lines > max_num_lines)
***************
*** 6015,6021 ****
for (j = 0; j < num_lines; j++)
{
putc('\t', fp);
! viminfo_writestring(fp, y_regs[i].y_array[j]);
}
}
}
--- 6167,6202 ----
for (j = 0; j < num_lines; j++)
{
putc('\t', fp);
! viminfo_writestring(fp, y_ptr->y_array[j]);
! }
!
! {
! int flags = 0;
! int remaining;
!
! /* New style with a bar line. Format:
! * |{bartype},{flags},{name},{type},
! * {linecount},{width},{timestamp},"line1","line2"
! * flags: REG_PREVIOUS - register is y_previous
! * REG_EXEC - used for @@
! */
! if (y_previous == &y_regs[i])
! flags |= REG_PREVIOUS;
! if (c == execreg_lastc)
! flags |= REG_EXEC;
! fprintf(fp, "|%d,%d,%d,%d,%d,%d,%ld", BARTYPE_REGISTER, flags,
! i, y_ptr->y_type, num_lines, (int)y_ptr->y_width,
! (long)y_ptr->y_time_set);
! /* 11 chars for type/flags/name/type, 3 * 20 for numbers */
! remaining = LSIZE - 71;
! for (j = 0; j < num_lines; j++)
! {
! putc(',', fp);
! --remaining;
! remaining = barline_writestring(fp, y_ptr->y_array[j],
! remaining);
! }
! putc('\n', fp);
}
}
}
***************
*** 6133,6139 ****
void
clip_free_selection(VimClipboard *cbd)
{
! struct yankreg *y_ptr = y_current;
if (cbd == &clip_plus)
y_current = &y_regs[PLUS_REGISTER];
--- 6314,6320 ----
void
clip_free_selection(VimClipboard *cbd)
{
! yankreg_T *y_ptr = y_current;
if (cbd == &clip_plus)
y_current = &y_regs[PLUS_REGISTER];
***************
*** 6150,6156 ****
void
clip_get_selection(VimClipboard *cbd)
{
! struct yankreg *old_y_previous, *old_y_current;
pos_T old_cursor;
pos_T old_visual;
int old_visual_mode;
--- 6331,6337 ----
void
clip_get_selection(VimClipboard *cbd)
{
! yankreg_T *old_y_previous, *old_y_current;
pos_T old_cursor;
pos_T old_visual;
int old_visual_mode;
***************
*** 6215,6221 ****
long len,
VimClipboard *cbd)
{
! struct yankreg *y_ptr;
if (cbd == &clip_plus)
y_ptr = &y_regs[PLUS_REGISTER];
--- 6396,6402 ----
long len,
VimClipboard *cbd)
{
! yankreg_T *y_ptr;
if (cbd == &clip_plus)
y_ptr = &y_regs[PLUS_REGISTER];
***************
*** 6239,6245 ****
int lnum;
int i, j;
int_u eolsize;
! struct yankreg *y_ptr;
if (cbd == &clip_plus)
y_ptr = &y_regs[PLUS_REGISTER];
--- 6420,6426 ----
int lnum;
int i, j;
int_u eolsize;
! yankreg_T *y_ptr;
if (cbd == &clip_plus)
y_ptr = &y_regs[PLUS_REGISTER];
***************
*** 6322,6328 ****
void
dnd_yank_drag_data(char_u *str, long len)
{
! struct yankreg *curr;
curr = y_current;
y_current = &y_regs[TILDE_REGISTER];
--- 6503,6509 ----
void
dnd_yank_drag_data(char_u *str, long len)
{
! yankreg_T *curr;
curr = y_current;
y_current = &y_regs[TILDE_REGISTER];
***************
*** 6518,6528 ****
static int
init_write_reg(
! 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 */
{
--- 6699,6709 ----
static int
init_write_reg(
! int name,
! yankreg_T **old_y_previous,
! yankreg_T **old_y_current,
! int must_append,
! int *yank_type UNUSED)
{
if (!valid_yank_reg(name, TRUE)) /* check for valid reg name */
{
***************
*** 6542,6550 ****
static void
finish_write_reg(
! int name,
! struct yankreg *old_y_previous,
! struct yankreg *old_y_current)
{
# ifdef FEAT_CLIPBOARD
/* Send text of clipboard register to the clipboard. */
--- 6723,6731 ----
static void
finish_write_reg(
! int name,
! yankreg_T *old_y_previous,
! yankreg_T *old_y_current)
{
# ifdef FEAT_CLIPBOARD
/* Send text of clipboard register to the clipboard. */
***************
*** 6585,6591 ****
int yank_type,
long block_len)
{
! struct yankreg *old_y_previous, *old_y_current;
if (name == '/'
#ifdef FEAT_EVAL
--- 6766,6772 ----
int yank_type,
long block_len)
{
! yankreg_T *old_y_previous, *old_y_current;
if (name == '/'
#ifdef FEAT_EVAL
***************
*** 6630,6637 ****
int yank_type,
long block_len)
{
! struct yankreg *old_y_previous, *old_y_current;
! long len;
if (maxlen >= 0)
len = maxlen;
--- 6811,6818 ----
int yank_type,
long block_len)
{
! yankreg_T *old_y_previous, *old_y_current;
! long len;
if (maxlen >= 0)
len = maxlen;
***************
*** 6705,6716 ****
*/
static void
str_to_reg(
! 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;
--- 6886,6897 ----
*/
static void
str_to_reg(
! yankreg_T *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;
***************
*** 6840,6845 ****
--- 7021,7029 ----
y_ptr->y_width = (blocklen < 0 ? maxlen - 1 : blocklen);
else
y_ptr->y_width = 0;
+ #ifdef FEAT_VIMINFO
+ y_ptr->y_time_set = vim_time();
+ #endif
}
#endif /* FEAT_CLIPBOARD || FEAT_EVAL || PROTO */
*** ../vim-7.4.1918/src/ex_getln.c 2016-06-11 15:31:44.079937578 +0200
--- src/ex_getln.c 2016-06-11 16:56:44.496230647 +0200
***************
*** 5408,5427 ****
NULL
};
- /*
- * Return the current time in seconds. Calls time(), unless test_settime()
- * was used.
- */
- static time_t
- vim_time(void)
- {
- #ifdef FEAT_EVAL
- return time_for_testing == 0 ? time(NULL) : time_for_testing;
- #else
- return time(NULL);
- #endif
- }
-
#if defined(FEAT_CMDL_COMPL) || defined(PROTO)
/*
* Function given to ExpandGeneric() to obtain the possible first
--- 5408,5413 ----
***************
*** 6280,6313 ****
*/
void
handle_viminfo_history(
! bval_T *values,
! int count,
! int writing)
{
int type;
long_u len;
char_u *val;
char_u *p;
/* Check the format:
* |{bartype},{histtype},{timestamp},{separator},"text" */
! if (count < 4
! || values[0].bv_type != BVAL_NR
! || values[1].bv_type != BVAL_NR
! || (values[2].bv_type != BVAL_NR && values[2].bv_type != BVAL_EMPTY)
! || values[3].bv_type != BVAL_STRING)
return;
! type = values[0].bv_nr;
if (type >= HIST_COUNT)
return;
if (viminfo_hisidx[type] < viminfo_hislen[type])
{
! val = values[3].bv_string;
if (val != NULL && *val != NUL)
{
! int sep = type == HIST_SEARCH && values[2].bv_type == BVAL_NR
! ? values[2].bv_nr : NUL;
int idx;
int overwrite = FALSE;
--- 6266,6299 ----
*/
void
handle_viminfo_history(
! garray_T *values,
! int writing)
{
int type;
long_u len;
char_u *val;
char_u *p;
+ bval_T *vp = (bval_T *)values->ga_data;
/* Check the format:
* |{bartype},{histtype},{timestamp},{separator},"text" */
! if (values->ga_len < 4
! || vp[0].bv_type != BVAL_NR
! || vp[1].bv_type != BVAL_NR
! || (vp[2].bv_type != BVAL_NR && vp[2].bv_type != BVAL_EMPTY)
! || vp[3].bv_type != BVAL_STRING)
return;
! type = vp[0].bv_nr;
if (type >= HIST_COUNT)
return;
if (viminfo_hisidx[type] < viminfo_hislen[type])
{
! val = vp[3].bv_string;
if (val != NULL && *val != NUL)
{
! int sep = type == HIST_SEARCH && vp[2].bv_type == BVAL_NR
! ? vp[2].bv_nr : NUL;
int idx;
int overwrite = FALSE;
***************
*** 6329,6340 ****
if (!overwrite)
{
/* Need to re-allocate to append the separator byte. */
! len = values[3].bv_len;
p = lalloc(len + 2, TRUE);
}
if (p != NULL)
{
! viminfo_history[type][idx].time_set = values[1].bv_nr;
if (!overwrite)
{
mch_memmove(p, val, (size_t)len + 1);
--- 6315,6326 ----
if (!overwrite)
{
/* Need to re-allocate to append the separator byte. */
! len = vp[3].bv_len;
p = lalloc(len + 2, TRUE);
}
if (p != NULL)
{
! viminfo_history[type][idx].time_set = vp[1].bv_nr;
if (!overwrite)
{
mch_memmove(p, val, (size_t)len + 1);
*** ../vim-7.4.1918/src/ex_cmds.c 2016-06-11 15:31:44.075937621 +0200
--- src/ex_cmds.c 2016-06-11 21:04:08.932042575 +0200
***************
*** 1750,1756 ****
#if defined(FEAT_VIMINFO) || defined(PROTO)
static int no_viminfo(void);
! static int read_viminfo_barline(vir_T *virp, int got_encoding, int writing);
static void write_viminfo_version(FILE *fp_out);
static void write_viminfo_barlines(vir_T *virp, FILE *fp_out);
static int viminfo_errcnt;
--- 1750,1756 ----
#if defined(FEAT_VIMINFO) || defined(PROTO)
static int no_viminfo(void);
! static int read_viminfo_barline(vir_T *virp, int got_encoding, int force, int
writing);
static void write_viminfo_version(FILE *fp_out);
static void write_viminfo_barlines(vir_T *virp, FILE *fp_out);
static int viminfo_errcnt;
***************
*** 2164,2169 ****
--- 2164,2173 ----
{
if (flags & VIF_WANT_INFO)
{
+ /* Registers are read and newer ones are used when writing. */
+ if (fp_out != NULL)
+ prepare_viminfo_registers();
+
eof = read_viminfo_up_to_marks(&vir,
flags & VIF_FORCEIT, fp_out != NULL);
merge = TRUE;
***************
*** 2191,2196 ****
--- 2195,2201 ----
write_viminfo_history(fp_out, merge);
#endif
write_viminfo_registers(fp_out);
+ finish_viminfo_registers();
#ifdef FEAT_EVAL
write_viminfo_varlist(fp_out);
#endif
***************
*** 2229,2234 ****
--- 2234,2240 ----
#ifdef FEAT_CMDHIST
prepare_viminfo_history(forceit ? 9999 : 0, writing);
#endif
+
eof = viminfo_readline(virp);
while (!eof && virp->vir_line[0] != '>')
{
***************
*** 2246,2252 ****
eof = viminfo_readline(virp);
break;
case '|':
! eof = read_viminfo_barline(virp, got_encoding, writing);
break;
case '*': /* "*encoding=value" */
got_encoding = TRUE;
--- 2252,2259 ----
eof = viminfo_readline(virp);
break;
case '|':
! eof = read_viminfo_barline(virp, got_encoding,
! forceit, writing);
break;
case '*': /* "*encoding=value" */
got_encoding = TRUE;
***************
*** 2263,2269 ****
eof = read_viminfo_bufferlist(virp, writing);
break;
case '"':
! eof = read_viminfo_register(virp, forceit);
break;
case '/': /* Search string */
case '&': /* Substitute search string */
--- 2270,2284 ----
eof = read_viminfo_bufferlist(virp, writing);
break;
case '"':
! /* When registers are in bar lines skip the old style register
! * lines. */
! if (virp->vir_version < VIMINFO_VERSION_WITH_REGISTERS)
! eof = read_viminfo_register(virp, forceit);
! else
! do {
! eof = viminfo_readline(virp);
! } while (!eof && (virp->vir_line[0] == TAB
! || virp->vir_line[0] == '<'));
break;
case '/': /* Search string */
case '&': /* Substitute search string */
***************
*** 2527,2546 ****
}
}
putc('"', fd);
! return remaining;
}
/*
* Parse a viminfo line starting with '|'.
! * Put each decoded value in "values" and return the number of values found.
*/
! static int
! barline_parse(vir_T *virp, char_u *text, bval_T *values)
{
char_u *p = text;
char_u *nextp = NULL;
char_u *buf = NULL;
! int count = 0;
int i;
int allocated = FALSE;
#ifdef FEAT_MBYTE
--- 2542,2561 ----
}
}
putc('"', fd);
! return remaining - 2;
}
/*
* Parse a viminfo line starting with '|'.
! * Add each decoded value to "values".
*/
! static void
! barline_parse(vir_T *virp, char_u *text, garray_T *values)
{
char_u *p = text;
char_u *nextp = NULL;
char_u *buf = NULL;
! bval_T *value;
int i;
int allocated = FALSE;
#ifdef FEAT_MBYTE
***************
*** 2550,2576 ****
while (*p == ',')
{
- if (count == BVAL_MAX)
- {
- EMSG2(e_intern2, "barline_parse()");
- break;
- }
++p;
if (*p == '>')
{
! /* Need to read a continuation line. Need to put strings in
! * allocated memory, because virp->vir_line is overwritten. */
if (!allocated)
{
! for (i = 0; i < count; ++i)
! if (values[i].bv_type == BVAL_STRING
! && !values[i].bv_allocated)
{
! values[i].bv_string = vim_strnsave(
! values[i].bv_string, values[i].bv_len);
! values[i].bv_allocated = TRUE;
}
allocated = TRUE;
}
--- 2565,2591 ----
while (*p == ',')
{
++p;
+ if (ga_grow(values, 1) == FAIL)
+ break;
+ value = (bval_T *)(values->ga_data) + values->ga_len;
if (*p == '>')
{
! /* Need to read a continuation line. Put strings in allocated
! * memory, because virp->vir_line is overwritten. */
if (!allocated)
{
! for (i = 0; i < values->ga_len; ++i)
! {
! bval_T *vp = (bval_T *)(values->ga_data) + i;
!
! if (vp->bv_type == BVAL_STRING && !vp->bv_allocated)
{
! vp->bv_string = vim_strnsave(vp->bv_string, vp->bv_len);
! vp->bv_allocated = TRUE;
}
+ }
allocated = TRUE;
}
***************
*** 2590,2596 ****
len = getdigits(&p);
buf = alloc((int)(len + 1));
if (buf == NULL)
! return count;
p = buf;
for (todo = len; todo > 0; todo -= n)
{
--- 2605,2611 ----
len = getdigits(&p);
buf = alloc((int)(len + 1));
if (buf == NULL)
! return;
p = buf;
for (todo = len; todo > 0; todo -= n)
{
***************
*** 2599,2605 ****
{
/* file was truncated or garbled */
vim_free(buf);
! return count;
}
/* Get length of text, excluding |< and NL chars. */
n = STRLEN(virp->vir_line);
--- 2614,2620 ----
{
/* file was truncated or garbled */
vim_free(buf);
! return;
}
/* Get length of text, excluding |< and NL chars. */
n = STRLEN(virp->vir_line);
***************
*** 2628,2643 ****
if (viminfo_readline(virp) || virp->vir_line[0] != '|'
|| virp->vir_line[1] != '<')
/* file was truncated or garbled */
! return count;
p = virp->vir_line + 2;
}
}
if (isdigit(*p))
{
! values[count].bv_type = BVAL_NR;
! values[count].bv_nr = getdigits(&p);
! ++count;
}
else if (*p == '"')
{
--- 2643,2658 ----
if (viminfo_readline(virp) || virp->vir_line[0] != '|'
|| virp->vir_line[1] != '<')
/* file was truncated or garbled */
! return;
p = virp->vir_line + 2;
}
}
if (isdigit(*p))
{
! value->bv_type = BVAL_NR;
! value->bv_nr = getdigits(&p);
! ++values->ga_len;
}
else if (*p == '"')
{
***************
*** 2649,2655 ****
while (*p != '"')
{
if (*p == NL || *p == NUL)
! return count; /* syntax error, drop the value */
if (*p == '\\')
{
++p;
--- 2664,2670 ----
while (*p != '"')
{
if (*p == NL || *p == NUL)
! return; /* syntax error, drop the value */
if (*p == '\\')
{
++p;
***************
*** 2662,2667 ****
--- 2677,2683 ----
else
s[len++] = *p++;
}
+ ++p;
s[len] = NUL;
#ifdef FEAT_MBYTE
***************
*** 2683,2697 ****
* above and we did allocate before, thus vir_line may change. */
if (s != buf && allocated)
s = vim_strsave(s);
! values[count].bv_string = s;
! values[count].bv_type = BVAL_STRING;
! values[count].bv_len = len;
! values[count].bv_allocated = allocated
#ifdef FEAT_MBYTE
|| converted
#endif
;
! ++count;
if (nextp != NULL)
{
/* values following a long string */
--- 2699,2713 ----
* above and we did allocate before, thus vir_line may change. */
if (s != buf && allocated)
s = vim_strsave(s);
! value->bv_string = s;
! value->bv_type = BVAL_STRING;
! value->bv_len = len;
! value->bv_allocated = allocated
#ifdef FEAT_MBYTE
|| converted
#endif
;
! ++values->ga_len;
if (nextp != NULL)
{
/* values following a long string */
***************
*** 2701,2723 ****
}
else if (*p == ',')
{
! values[count].bv_type = BVAL_EMPTY;
! ++count;
}
else
break;
}
-
- return count;
}
static int
! read_viminfo_barline(vir_T *virp, int got_encoding, int writing)
{
char_u *p = virp->vir_line + 1;
int bartype;
! bval_T values[BVAL_MAX];
! int count = 0;
int i;
/* The format is: |{bartype},{value},...
--- 2717,2737 ----
}
else if (*p == ',')
{
! value->bv_type = BVAL_EMPTY;
! ++values->ga_len;
}
else
break;
}
}
static int
! read_viminfo_barline(vir_T *virp, int got_encoding, int force, int writing)
{
char_u *p = virp->vir_line + 1;
int bartype;
! garray_T values;
! bval_T *vp;
int i;
/* The format is: |{bartype},{value},...
***************
*** 2737,2742 ****
--- 2751,2757 ----
}
else
{
+ ga_init2(&values, sizeof(bval_T), 20);
bartype = getdigits(&p);
switch (bartype)
{
***************
*** 2746,2760 ****
* doesn't understand the version. */
if (!got_encoding)
{
! count = barline_parse(virp, p, values);
! if (count > 0 && values[0].bv_type == BVAL_NR)
! virp->vir_version = values[0].bv_nr;
}
break;
case BARTYPE_HISTORY:
! count = barline_parse(virp, p, values);
! handle_viminfo_history(values, count, writing);
break;
default:
--- 2761,2781 ----
* doesn't understand the version. */
if (!got_encoding)
{
! barline_parse(virp, p, &values);
! vp = (bval_T *)values.ga_data;
! if (values.ga_len > 0 && vp->bv_type == BVAL_NR)
! virp->vir_version = vp->bv_nr;
}
break;
case BARTYPE_HISTORY:
! barline_parse(virp, p, &values);
! handle_viminfo_history(&values, writing);
! break;
!
! case BARTYPE_REGISTER:
! barline_parse(virp, p, &values);
! handle_viminfo_register(&values, force);
break;
default:
***************
*** 2762,2773 ****
if (writing)
ga_add_string(&virp->vir_barlines, virp->vir_line);
}
}
- for (i = 0; i < count; ++i)
- if (values[i].bv_type == BVAL_STRING && values[i].bv_allocated)
- vim_free(values[i].bv_string);
-
return viminfo_readline(virp);
}
--- 2783,2797 ----
if (writing)
ga_add_string(&virp->vir_barlines, virp->vir_line);
}
+ for (i = 0; i < values.ga_len; ++i)
+ {
+ vp = (bval_T *)values.ga_data + i;
+ if (vp->bv_type == BVAL_STRING && vp->bv_allocated)
+ vim_free(vp->bv_string);
+ }
+ ga_clear(&values);
}
return viminfo_readline(virp);
}
***************
*** 2794,2799 ****
--- 2818,2839 ----
}
#endif /* FEAT_VIMINFO */
+ #if defined(FEAT_VIMINFO) || defined(PROTO)
+ /*
+ * Return the current time in seconds. Calls time(), unless test_settime()
+ * was used.
+ */
+ time_t
+ vim_time(void)
+ {
+ # ifdef FEAT_EVAL
+ return time_for_testing == 0 ? time(NULL) : time_for_testing;
+ # else
+ return time(NULL);
+ # endif
+ }
+ #endif
+
/*
* Implementation of ":fixdel", also used by get_stty().
* <BS> resulting <Del>
*** ../vim-7.4.1918/src/proto/ex_cmds.pro 2016-06-06 21:07:48.387578685
+0200
--- src/proto/ex_cmds.pro 2016-06-11 15:58:10.398859944 +0200
***************
*** 17,22 ****
--- 17,23 ----
char_u *viminfo_readstring(vir_T *virp, int off, int convert);
void viminfo_writestring(FILE *fd, char_u *p);
int barline_writestring(FILE *fd, char_u *s, int remaining_start);
+ time_t vim_time(void);
void do_fixdel(exarg_T *eap);
void print_line_no_prefix(linenr_T lnum, int use_number, int list);
void print_line(linenr_T lnum, int use_number, int list);
*** ../vim-7.4.1918/src/proto/ex_getln.pro 2016-06-09 20:24:24.312049004
+0200
--- src/proto/ex_getln.pro 2016-06-11 16:56:49.496175792 +0200
***************
*** 50,56 ****
void ex_history(exarg_T *eap);
void prepare_viminfo_history(int asklen, int writing);
int read_viminfo_history(vir_T *virp, int writing);
! void handle_viminfo_history(bval_T *values, int count, int writing);
void finish_viminfo_history(vir_T *virp);
void write_viminfo_history(FILE *fp, int merge);
void cmd_pchar(int c, int offset);
--- 50,56 ----
void ex_history(exarg_T *eap);
void prepare_viminfo_history(int asklen, int writing);
int read_viminfo_history(vir_T *virp, int writing);
! void handle_viminfo_history(garray_T *values, int writing);
void finish_viminfo_history(vir_T *virp);
void write_viminfo_history(FILE *fp, int merge);
void cmd_pchar(int c, int offset);
*** ../vim-7.4.1918/src/proto/ops.pro 2016-01-19 13:21:55.845334290 +0100
--- src/proto/ops.pro 2016-06-11 17:29:22.775506503 +0200
***************
*** 44,50 ****
--- 44,53 ----
void format_lines(linenr_T line_count, int avoid_fex);
int paragraph_start(linenr_T lnum);
void op_addsub(oparg_T *oap, linenr_T Prenum1, int g_cmd);
+ void prepare_viminfo_registers(void);
+ void finish_viminfo_registers(void);
int read_viminfo_register(vir_T *virp, int force);
+ void handle_viminfo_register(garray_T *values, int writing);
void write_viminfo_registers(FILE *fp);
void x11_export_final_selection(void);
void clip_free_selection(VimClipboard *cbd);
*** ../vim-7.4.1918/src/vim.h 2016-06-09 20:24:24.312049004 +0200
--- src/vim.h 2016-06-11 20:59:19.275176065 +0200
***************
*** 1075,1083 ****
/* The type numbers are fixed for backwards compatibility. */
#define BARTYPE_VERSION 1
#define BARTYPE_HISTORY 2
! #define VIMINFO_VERSION 2
#define VIMINFO_VERSION_WITH_HISTORY 2
typedef enum {
BVAL_NR,
--- 1075,1085 ----
/* The type numbers are fixed for backwards compatibility. */
#define BARTYPE_VERSION 1
#define BARTYPE_HISTORY 2
+ #define BARTYPE_REGISTER 3
! #define VIMINFO_VERSION 3
#define VIMINFO_VERSION_WITH_HISTORY 2
+ #define VIMINFO_VERSION_WITH_REGISTERS 3
typedef enum {
BVAL_NR,
***************
*** 1085,1092 ****
BVAL_EMPTY
} btype_T;
- #define BVAL_MAX 4 /* Maximum number of fields in a barline. */
-
typedef struct {
btype_T bv_type;
long bv_nr;
--- 1087,1092 ----
*** ../vim-7.4.1918/src/version.c 2016-06-11 15:31:44.083937535 +0200
--- src/version.c 2016-06-11 20:54:32.610282009 +0200
***************
*** 755,756 ****
--- 755,758 ----
{ /* Add new patch number below this line */
+ /**/
+ 1919,
/**/
--
>From "know your smileys":
O:-) Saint
/// Bram Moolenaar -- [email protected] -- 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 ///
--
--
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php
---
You received this message because you are subscribed to the Google Groups
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.