mirror of
https://github.com/vim/vim.git
synced 2025-07-26 11:04:33 -04:00
patch 7.4.1903
Problem: When writing viminfo merging current history with history in viminfo may drop recent history entries. Solution: Add new format for viminfo lines, use it for history entries. Use a timestamp for ordering the entries. Add test_settime(). Add the viminfo version. Does not do merging on timestamp yet.
This commit is contained in:
parent
bbe8d91e69
commit
45d2eeaad6
26
src/eval.c
26
src/eval.c
@ -820,6 +820,7 @@ static void f_test_null_job(typval_T *argvars, typval_T *rettv);
|
|||||||
static void f_test_null_list(typval_T *argvars, typval_T *rettv);
|
static void f_test_null_list(typval_T *argvars, typval_T *rettv);
|
||||||
static void f_test_null_partial(typval_T *argvars, typval_T *rettv);
|
static void f_test_null_partial(typval_T *argvars, typval_T *rettv);
|
||||||
static void f_test_null_string(typval_T *argvars, typval_T *rettv);
|
static void f_test_null_string(typval_T *argvars, typval_T *rettv);
|
||||||
|
static void f_test_settime(typval_T *argvars, typval_T *rettv);
|
||||||
#ifdef FEAT_FLOAT
|
#ifdef FEAT_FLOAT
|
||||||
static void f_tan(typval_T *argvars, typval_T *rettv);
|
static void f_tan(typval_T *argvars, typval_T *rettv);
|
||||||
static void f_tanh(typval_T *argvars, typval_T *rettv);
|
static void f_tanh(typval_T *argvars, typval_T *rettv);
|
||||||
@ -8809,13 +8810,14 @@ static struct fst
|
|||||||
#ifdef FEAT_JOB_CHANNEL
|
#ifdef FEAT_JOB_CHANNEL
|
||||||
{"test_null_channel", 0, 0, f_test_null_channel},
|
{"test_null_channel", 0, 0, f_test_null_channel},
|
||||||
#endif
|
#endif
|
||||||
{"test_null_dict", 0, 0, f_test_null_dict},
|
{"test_null_dict", 0, 0, f_test_null_dict},
|
||||||
#ifdef FEAT_JOB_CHANNEL
|
#ifdef FEAT_JOB_CHANNEL
|
||||||
{"test_null_job", 0, 0, f_test_null_job},
|
{"test_null_job", 0, 0, f_test_null_job},
|
||||||
#endif
|
#endif
|
||||||
{"test_null_list", 0, 0, f_test_null_list},
|
{"test_null_list", 0, 0, f_test_null_list},
|
||||||
{"test_null_partial", 0, 0, f_test_null_partial},
|
{"test_null_partial", 0, 0, f_test_null_partial},
|
||||||
{"test_null_string", 0, 0, f_test_null_string},
|
{"test_null_string", 0, 0, f_test_null_string},
|
||||||
|
{"test_settime", 1, 1, f_test_settime},
|
||||||
#ifdef FEAT_TIMERS
|
#ifdef FEAT_TIMERS
|
||||||
{"timer_start", 2, 3, f_timer_start},
|
{"timer_start", 2, 3, f_timer_start},
|
||||||
{"timer_stop", 1, 1, f_timer_stop},
|
{"timer_stop", 1, 1, f_timer_stop},
|
||||||
@ -20849,7 +20851,7 @@ f_test_garbagecollect_now(typval_T *argvars UNUSED, typval_T *rettv UNUSED)
|
|||||||
|
|
||||||
#ifdef FEAT_JOB_CHANNEL
|
#ifdef FEAT_JOB_CHANNEL
|
||||||
static void
|
static void
|
||||||
f_test_null_channel(typval_T *argvars UNUSED, typval_T *rettv UNUSED)
|
f_test_null_channel(typval_T *argvars UNUSED, typval_T *rettv)
|
||||||
{
|
{
|
||||||
rettv->v_type = VAR_CHANNEL;
|
rettv->v_type = VAR_CHANNEL;
|
||||||
rettv->vval.v_channel = NULL;
|
rettv->vval.v_channel = NULL;
|
||||||
@ -20857,7 +20859,7 @@ f_test_null_channel(typval_T *argvars UNUSED, typval_T *rettv UNUSED)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
static void
|
static void
|
||||||
f_test_null_dict(typval_T *argvars UNUSED, typval_T *rettv UNUSED)
|
f_test_null_dict(typval_T *argvars UNUSED, typval_T *rettv)
|
||||||
{
|
{
|
||||||
rettv->v_type = VAR_DICT;
|
rettv->v_type = VAR_DICT;
|
||||||
rettv->vval.v_dict = NULL;
|
rettv->vval.v_dict = NULL;
|
||||||
@ -20865,7 +20867,7 @@ f_test_null_dict(typval_T *argvars UNUSED, typval_T *rettv UNUSED)
|
|||||||
|
|
||||||
#ifdef FEAT_JOB_CHANNEL
|
#ifdef FEAT_JOB_CHANNEL
|
||||||
static void
|
static void
|
||||||
f_test_null_job(typval_T *argvars UNUSED, typval_T *rettv UNUSED)
|
f_test_null_job(typval_T *argvars UNUSED, typval_T *rettv)
|
||||||
{
|
{
|
||||||
rettv->v_type = VAR_JOB;
|
rettv->v_type = VAR_JOB;
|
||||||
rettv->vval.v_job = NULL;
|
rettv->vval.v_job = NULL;
|
||||||
@ -20873,26 +20875,32 @@ f_test_null_job(typval_T *argvars UNUSED, typval_T *rettv UNUSED)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
static void
|
static void
|
||||||
f_test_null_list(typval_T *argvars UNUSED, typval_T *rettv UNUSED)
|
f_test_null_list(typval_T *argvars UNUSED, typval_T *rettv)
|
||||||
{
|
{
|
||||||
rettv->v_type = VAR_LIST;
|
rettv->v_type = VAR_LIST;
|
||||||
rettv->vval.v_list = NULL;
|
rettv->vval.v_list = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
f_test_null_partial(typval_T *argvars UNUSED, typval_T *rettv UNUSED)
|
f_test_null_partial(typval_T *argvars UNUSED, typval_T *rettv)
|
||||||
{
|
{
|
||||||
rettv->v_type = VAR_PARTIAL;
|
rettv->v_type = VAR_PARTIAL;
|
||||||
rettv->vval.v_partial = NULL;
|
rettv->vval.v_partial = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
f_test_null_string(typval_T *argvars UNUSED, typval_T *rettv UNUSED)
|
f_test_null_string(typval_T *argvars UNUSED, typval_T *rettv)
|
||||||
{
|
{
|
||||||
rettv->v_type = VAR_STRING;
|
rettv->v_type = VAR_STRING;
|
||||||
rettv->vval.v_string = NULL;
|
rettv->vval.v_string = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
f_test_settime(typval_T *argvars, typval_T *rettv UNUSED)
|
||||||
|
{
|
||||||
|
time_for_testing = (time_t)get_tv_number(&argvars[0]);
|
||||||
|
}
|
||||||
|
|
||||||
#if defined(FEAT_JOB_CHANNEL) || defined(FEAT_TIMERS) || defined(PROTO)
|
#if defined(FEAT_JOB_CHANNEL) || defined(FEAT_TIMERS) || defined(PROTO)
|
||||||
/*
|
/*
|
||||||
* Get a callback from "arg". It can be a Funcref or a function name.
|
* Get a callback from "arg". It can be a Funcref or a function name.
|
||||||
|
305
src/ex_cmds.c
305
src/ex_cmds.c
@ -1750,9 +1750,14 @@ append_redir(
|
|||||||
#if defined(FEAT_VIMINFO) || defined(PROTO)
|
#if defined(FEAT_VIMINFO) || defined(PROTO)
|
||||||
|
|
||||||
static int no_viminfo(void);
|
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 void write_viminfo_barlines(vir_T *virp, FILE *fp_out);
|
||||||
static int viminfo_errcnt;
|
static int viminfo_errcnt;
|
||||||
|
|
||||||
|
#define VIMINFO_VERSION 2
|
||||||
|
#define VIMINFO_VERSION_WITH_HISTORY 2
|
||||||
|
|
||||||
static int
|
static int
|
||||||
no_viminfo(void)
|
no_viminfo(void)
|
||||||
{
|
{
|
||||||
@ -2156,6 +2161,7 @@ do_viminfo(FILE *fp_in, FILE *fp_out, int flags)
|
|||||||
vir.vir_conv.vc_type = CONV_NONE;
|
vir.vir_conv.vc_type = CONV_NONE;
|
||||||
#endif
|
#endif
|
||||||
ga_init2(&vir.vir_barlines, (int)sizeof(char_u *), 100);
|
ga_init2(&vir.vir_barlines, (int)sizeof(char_u *), 100);
|
||||||
|
vir.vir_version = -1;
|
||||||
|
|
||||||
if (fp_in != NULL)
|
if (fp_in != NULL)
|
||||||
{
|
{
|
||||||
@ -2177,6 +2183,7 @@ do_viminfo(FILE *fp_in, FILE *fp_out, int flags)
|
|||||||
fprintf(fp_out, _("# This viminfo file was generated by Vim %s.\n"),
|
fprintf(fp_out, _("# This viminfo file was generated by Vim %s.\n"),
|
||||||
VIM_VERSION_MEDIUM);
|
VIM_VERSION_MEDIUM);
|
||||||
fputs(_("# You may edit it if you're careful!\n\n"), fp_out);
|
fputs(_("# You may edit it if you're careful!\n\n"), fp_out);
|
||||||
|
write_viminfo_version(fp_out);
|
||||||
#ifdef FEAT_MBYTE
|
#ifdef FEAT_MBYTE
|
||||||
fputs(_("# Value of 'encoding' when this file was written\n"), fp_out);
|
fputs(_("# Value of 'encoding' when this file was written\n"), fp_out);
|
||||||
fprintf(fp_out, "*encoding=%s\n\n", p_enc);
|
fprintf(fp_out, "*encoding=%s\n\n", p_enc);
|
||||||
@ -2220,6 +2227,7 @@ read_viminfo_up_to_marks(
|
|||||||
{
|
{
|
||||||
int eof;
|
int eof;
|
||||||
buf_T *buf;
|
buf_T *buf;
|
||||||
|
int got_encoding = FALSE;
|
||||||
|
|
||||||
#ifdef FEAT_CMDHIST
|
#ifdef FEAT_CMDHIST
|
||||||
prepare_viminfo_history(forceit ? 9999 : 0, writing);
|
prepare_viminfo_history(forceit ? 9999 : 0, writing);
|
||||||
@ -2240,12 +2248,11 @@ read_viminfo_up_to_marks(
|
|||||||
case '#':
|
case '#':
|
||||||
eof = viminfo_readline(virp);
|
eof = viminfo_readline(virp);
|
||||||
break;
|
break;
|
||||||
case '|': /* copy line (for future use) */
|
case '|':
|
||||||
if (writing)
|
eof = read_viminfo_barline(virp, got_encoding, writing);
|
||||||
ga_add_string(&virp->vir_barlines, virp->vir_line);
|
|
||||||
eof = viminfo_readline(virp);
|
|
||||||
break;
|
break;
|
||||||
case '*': /* "*encoding=value" */
|
case '*': /* "*encoding=value" */
|
||||||
|
got_encoding = TRUE;
|
||||||
eof = viminfo_encoding(virp);
|
eof = viminfo_encoding(virp);
|
||||||
break;
|
break;
|
||||||
case '!': /* global variable */
|
case '!': /* global variable */
|
||||||
@ -2274,10 +2281,13 @@ read_viminfo_up_to_marks(
|
|||||||
case '=':
|
case '=':
|
||||||
case '@':
|
case '@':
|
||||||
#ifdef FEAT_CMDHIST
|
#ifdef FEAT_CMDHIST
|
||||||
eof = read_viminfo_history(virp, writing);
|
/* When history is in bar lines skip the old style history
|
||||||
#else
|
* lines. */
|
||||||
eof = viminfo_readline(virp);
|
if (virp->vir_version < VIMINFO_VERSION_WITH_HISTORY)
|
||||||
|
eof = read_viminfo_history(virp, writing);
|
||||||
|
else
|
||||||
#endif
|
#endif
|
||||||
|
eof = viminfo_readline(virp);
|
||||||
break;
|
break;
|
||||||
case '-':
|
case '-':
|
||||||
case '\'':
|
case '\'':
|
||||||
@ -2347,8 +2357,8 @@ viminfo_readline(vir_T *virp)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* check string read from viminfo file
|
* Check string read from viminfo file.
|
||||||
* remove '\n' at the end of the line
|
* Remove '\n' at the end of the line.
|
||||||
* - replace CTRL-V CTRL-V with CTRL-V
|
* - replace CTRL-V CTRL-V with CTRL-V
|
||||||
* - replace CTRL-V 'n' with '\n'
|
* - replace CTRL-V 'n' with '\n'
|
||||||
*
|
*
|
||||||
@ -2463,6 +2473,283 @@ viminfo_writestring(FILE *fd, char_u *p)
|
|||||||
putc('\n', fd);
|
putc('\n', fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Write a string in quotes that barline_parse() can read back.
|
||||||
|
* Breaks the line in less than LSIZE pieces when needed.
|
||||||
|
* Returns remaining characters in the line.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
barline_writestring(FILE *fd, char_u *s, int remaining_start)
|
||||||
|
{
|
||||||
|
char_u *p;
|
||||||
|
int remaining = remaining_start;
|
||||||
|
int len = 2;
|
||||||
|
|
||||||
|
/* Count the number of characters produced, including quotes. */
|
||||||
|
for (p = s; *p != NUL; ++p)
|
||||||
|
{
|
||||||
|
if (*p == NL)
|
||||||
|
len += 2;
|
||||||
|
else if (*p == '"' || *p == '\\')
|
||||||
|
len += 2;
|
||||||
|
else
|
||||||
|
++len;
|
||||||
|
}
|
||||||
|
if (len > remaining)
|
||||||
|
{
|
||||||
|
fprintf(fd, ">%d\n|<", len);
|
||||||
|
remaining = LSIZE - 20;
|
||||||
|
}
|
||||||
|
|
||||||
|
putc('"', fd);
|
||||||
|
for (p = s; *p != NUL; ++p)
|
||||||
|
{
|
||||||
|
if (*p == NL)
|
||||||
|
{
|
||||||
|
putc('\\', fd);
|
||||||
|
putc('n', fd);
|
||||||
|
--remaining;
|
||||||
|
}
|
||||||
|
else if (*p == '"' || *p == '\\')
|
||||||
|
{
|
||||||
|
putc('\\', fd);
|
||||||
|
putc(*p, fd);
|
||||||
|
--remaining;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
putc(*p, fd);
|
||||||
|
--remaining;
|
||||||
|
|
||||||
|
if (remaining < 3)
|
||||||
|
{
|
||||||
|
putc('\n', fd);
|
||||||
|
putc('|', fd);
|
||||||
|
putc('<', fd);
|
||||||
|
/* Leave enough space for another continuation. */
|
||||||
|
remaining = LSIZE - 20;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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;
|
||||||
|
|
||||||
|
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_string = vim_strnsave(
|
||||||
|
values[i].bv_string, values[i].bv_len);
|
||||||
|
values[i].bv_allocated = TRUE;
|
||||||
|
}
|
||||||
|
allocated = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (vim_isdigit(p[1]))
|
||||||
|
{
|
||||||
|
int len;
|
||||||
|
int todo;
|
||||||
|
int n;
|
||||||
|
|
||||||
|
/* String value was split into lines that are each shorter
|
||||||
|
* than LSIZE:
|
||||||
|
* |{bartype},>{length of "{text}{text2}"}
|
||||||
|
* |<"{text1}
|
||||||
|
* |<{text2}",{value}
|
||||||
|
*/
|
||||||
|
++p;
|
||||||
|
len = getdigits(&p);
|
||||||
|
buf = alloc(len + 1);
|
||||||
|
p = buf;
|
||||||
|
for (todo = len; todo > 0; todo -= n)
|
||||||
|
{
|
||||||
|
if (viminfo_readline(virp) || virp->vir_line[0] != '|'
|
||||||
|
|| virp->vir_line[1] != '<')
|
||||||
|
/* file was truncated or garbled */
|
||||||
|
return 0;
|
||||||
|
/* Get length of text, excluding |< and NL chars. */
|
||||||
|
n = STRLEN(virp->vir_line);
|
||||||
|
while (n > 0 && (virp->vir_line[n - 1] == NL
|
||||||
|
|| virp->vir_line[n - 1] == CAR))
|
||||||
|
--n;
|
||||||
|
n -= 2;
|
||||||
|
if (n > todo)
|
||||||
|
{
|
||||||
|
/* more values follow after the string */
|
||||||
|
nextp = virp->vir_line + 2 + todo;
|
||||||
|
n = todo;
|
||||||
|
}
|
||||||
|
mch_memmove(p, virp->vir_line + 2, n);
|
||||||
|
p += n;
|
||||||
|
}
|
||||||
|
*p = NUL;
|
||||||
|
p = buf;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Line ending in ">" continues in the next line:
|
||||||
|
* |{bartype},{lots of values},>
|
||||||
|
* |<{value},{value}
|
||||||
|
*/
|
||||||
|
if (viminfo_readline(virp) || virp->vir_line[0] != '|'
|
||||||
|
|| virp->vir_line[1] != '<')
|
||||||
|
/* file was truncated or garbled */
|
||||||
|
return 0;
|
||||||
|
p = virp->vir_line + 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isdigit(*p))
|
||||||
|
{
|
||||||
|
values[count].bv_type = BVAL_NR;
|
||||||
|
values[count].bv_nr = getdigits(&p);
|
||||||
|
++count;
|
||||||
|
}
|
||||||
|
else if (*p == '"')
|
||||||
|
{
|
||||||
|
int len = 0;
|
||||||
|
char_u *s = p;
|
||||||
|
|
||||||
|
/* Unescape special characters in-place. */
|
||||||
|
++p;
|
||||||
|
while (*p != '"')
|
||||||
|
{
|
||||||
|
if (*p == NL || *p == NUL)
|
||||||
|
return count; /* syntax error, drop the value */
|
||||||
|
if (*p == '\\')
|
||||||
|
{
|
||||||
|
++p;
|
||||||
|
if (*p == 'n')
|
||||||
|
s[len++] = '\n';
|
||||||
|
else
|
||||||
|
s[len++] = *p;
|
||||||
|
++p;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
s[len++] = *p++;
|
||||||
|
}
|
||||||
|
s[len] = NUL;
|
||||||
|
|
||||||
|
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;
|
||||||
|
++count;
|
||||||
|
if (nextp != NULL)
|
||||||
|
{
|
||||||
|
/* values following a long string */
|
||||||
|
p = nextp;
|
||||||
|
nextp = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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},...
|
||||||
|
* For a very long string:
|
||||||
|
* |{bartype},>{length of "{text}{text2}"}
|
||||||
|
* |<{text1}
|
||||||
|
* |<{text2},{value}
|
||||||
|
* For a long line not using a string
|
||||||
|
* |{bartype},{lots of values},>
|
||||||
|
* |<{value},{value}
|
||||||
|
*/
|
||||||
|
if (*p == '<')
|
||||||
|
{
|
||||||
|
/* Continuation line of an unrecognized item. */
|
||||||
|
if (writing)
|
||||||
|
ga_add_string(&virp->vir_barlines, virp->vir_line);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
bartype = getdigits(&p);
|
||||||
|
switch (bartype)
|
||||||
|
{
|
||||||
|
case BARTYPE_VERSION:
|
||||||
|
/* Only use the version when it comes before the encoding.
|
||||||
|
* If it comes later it was copied by a Vim version that
|
||||||
|
* 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:
|
||||||
|
/* copy unrecognized line (for future use) */
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
write_viminfo_version(FILE *fp_out)
|
||||||
|
{
|
||||||
|
fprintf(fp_out, "# Viminfo version\n|%d,%d\n\n",
|
||||||
|
BARTYPE_VERSION, VIMINFO_VERSION);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
write_viminfo_barlines(vir_T *virp, FILE *fp_out)
|
write_viminfo_barlines(vir_T *virp, FILE *fp_out)
|
||||||
{
|
{
|
||||||
|
158
src/ex_getln.c
158
src/ex_getln.c
@ -58,6 +58,7 @@ typedef struct hist_entry
|
|||||||
int hisnum; /* identifying number */
|
int hisnum; /* identifying number */
|
||||||
int viminfo; /* when TRUE hisstr comes from viminfo */
|
int viminfo; /* when TRUE hisstr comes from viminfo */
|
||||||
char_u *hisstr; /* actual entry, separator char after the NUL */
|
char_u *hisstr; /* actual entry, separator char after the NUL */
|
||||||
|
time_t time_set; /* when it was typed, zero if unknown */
|
||||||
} histentry_T;
|
} histentry_T;
|
||||||
|
|
||||||
static histentry_T *(history[HIST_COUNT]) = {NULL, NULL, NULL, NULL, NULL};
|
static histentry_T *(history[HIST_COUNT]) = {NULL, NULL, NULL, NULL, NULL};
|
||||||
@ -5407,6 +5408,20 @@ static char *(history_names[]) =
|
|||||||
NULL
|
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)
|
#if defined(FEAT_CMDL_COMPL) || defined(PROTO)
|
||||||
/*
|
/*
|
||||||
* Function given to ExpandGeneric() to obtain the possible first
|
* Function given to ExpandGeneric() to obtain the possible first
|
||||||
@ -5576,6 +5591,7 @@ in_history(
|
|||||||
history[type][i].hisnum = ++hisnum[type];
|
history[type][i].hisnum = ++hisnum[type];
|
||||||
history[type][i].viminfo = FALSE;
|
history[type][i].viminfo = FALSE;
|
||||||
history[type][i].hisstr = str;
|
history[type][i].hisstr = str;
|
||||||
|
history[type][i].time_set = vim_time();
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
return FALSE;
|
return FALSE;
|
||||||
@ -5663,6 +5679,7 @@ add_to_history(
|
|||||||
|
|
||||||
hisptr->hisnum = ++hisnum[histype];
|
hisptr->hisnum = ++hisnum[histype];
|
||||||
hisptr->viminfo = FALSE;
|
hisptr->viminfo = FALSE;
|
||||||
|
hisptr->time_set = vim_time();
|
||||||
if (histype == HIST_SEARCH && in_map)
|
if (histype == HIST_SEARCH && in_map)
|
||||||
last_maptick = maptick;
|
last_maptick = maptick;
|
||||||
}
|
}
|
||||||
@ -6131,9 +6148,10 @@ ex_history(exarg_T *eap)
|
|||||||
/*
|
/*
|
||||||
* Buffers for history read from a viminfo file. Only valid while reading.
|
* Buffers for history read from a viminfo file. Only valid while reading.
|
||||||
*/
|
*/
|
||||||
static char_u **viminfo_history[HIST_COUNT] = {NULL, NULL, NULL, NULL};
|
static histentry_T *viminfo_history[HIST_COUNT] =
|
||||||
static int viminfo_hisidx[HIST_COUNT] = {0, 0, 0, 0};
|
{NULL, NULL, NULL, NULL, NULL};
|
||||||
static int viminfo_hislen[HIST_COUNT] = {0, 0, 0, 0};
|
static int viminfo_hisidx[HIST_COUNT] = {0, 0, 0, 0, 0};
|
||||||
|
static int viminfo_hislen[HIST_COUNT] = {0, 0, 0, 0, 0};
|
||||||
static int viminfo_add_at_front = FALSE;
|
static int viminfo_add_at_front = FALSE;
|
||||||
|
|
||||||
static int hist_type2char(int type, int use_question);
|
static int hist_type2char(int type, int use_question);
|
||||||
@ -6191,8 +6209,8 @@ prepare_viminfo_history(int asklen, int writing)
|
|||||||
if (len <= 0)
|
if (len <= 0)
|
||||||
viminfo_history[type] = NULL;
|
viminfo_history[type] = NULL;
|
||||||
else
|
else
|
||||||
viminfo_history[type] =
|
viminfo_history[type] = (histentry_T *)lalloc(
|
||||||
(char_u **)lalloc((long_u)(len * sizeof(char_u *)), FALSE);
|
(long_u)(len * sizeof(histentry_T)), FALSE);
|
||||||
if (viminfo_history[type] == NULL)
|
if (viminfo_history[type] == NULL)
|
||||||
len = 0;
|
len = 0;
|
||||||
viminfo_hislen[type] = len;
|
viminfo_hislen[type] = len;
|
||||||
@ -6242,7 +6260,9 @@ read_viminfo_history(vir_T *virp, int writing)
|
|||||||
mch_memmove(p, val, (size_t)len + 1);
|
mch_memmove(p, val, (size_t)len + 1);
|
||||||
p[len + 1] = NUL;
|
p[len + 1] = NUL;
|
||||||
}
|
}
|
||||||
viminfo_history[type][viminfo_hisidx[type]++] = p;
|
viminfo_history[type][viminfo_hisidx[type]].hisstr = p;
|
||||||
|
viminfo_history[type][viminfo_hisidx[type]].time_set = 0;
|
||||||
|
viminfo_hisidx[type]++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -6251,6 +6271,81 @@ read_viminfo_history(vir_T *virp, int writing)
|
|||||||
return viminfo_readline(virp);
|
return viminfo_readline(virp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Accept a new style history line from the viminfo, store it in the history
|
||||||
|
* array when it's new.
|
||||||
|
*/
|
||||||
|
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;
|
||||||
|
|
||||||
|
if (!in_history(type, val, viminfo_add_at_front, sep, writing))
|
||||||
|
{
|
||||||
|
/* If lines were written by an older Vim we need to avoid
|
||||||
|
* getting duplicates. See if the entry already exists. */
|
||||||
|
for (idx = 0; idx < viminfo_hisidx[type]; ++idx)
|
||||||
|
{
|
||||||
|
p = viminfo_history[type][idx].hisstr;
|
||||||
|
if (STRCMP(val, p) == 0
|
||||||
|
&& (type != HIST_SEARCH || sep == p[STRLEN(p) + 1]))
|
||||||
|
{
|
||||||
|
overwrite = TRUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
/* Put the separator after the NUL. */
|
||||||
|
p[len + 1] = sep;
|
||||||
|
viminfo_history[type][idx].hisstr = p;
|
||||||
|
viminfo_hisidx[type]++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Finish reading history lines from viminfo. Not used when writing viminfo.
|
* Finish reading history lines from viminfo. Not used when writing viminfo.
|
||||||
*/
|
*/
|
||||||
@ -6290,8 +6385,9 @@ finish_viminfo_history(void)
|
|||||||
for (i = 0; i < viminfo_hisidx[type]; i++)
|
for (i = 0; i < viminfo_hisidx[type]; i++)
|
||||||
{
|
{
|
||||||
vim_free(history[type][idx].hisstr);
|
vim_free(history[type][idx].hisstr);
|
||||||
history[type][idx].hisstr = viminfo_history[type][i];
|
history[type][idx].hisstr = viminfo_history[type][i].hisstr;
|
||||||
history[type][idx].viminfo = TRUE;
|
history[type][idx].viminfo = TRUE;
|
||||||
|
history[type][idx].time_set = viminfo_history[type][i].time_set;
|
||||||
if (--idx < 0)
|
if (--idx < 0)
|
||||||
idx = hislen - 1;
|
idx = hislen - 1;
|
||||||
}
|
}
|
||||||
@ -6315,15 +6411,11 @@ finish_viminfo_history(void)
|
|||||||
* When "merge" is FALSE just write all history lines. Used for ":wviminfo!".
|
* When "merge" is FALSE just write all history lines. Used for ":wviminfo!".
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
write_viminfo_history(
|
write_viminfo_history(FILE *fp, int merge)
|
||||||
FILE *fp,
|
|
||||||
int merge)
|
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
int type;
|
int type;
|
||||||
int num_saved;
|
int num_saved;
|
||||||
char_u *p;
|
|
||||||
int c;
|
|
||||||
int round;
|
int round;
|
||||||
|
|
||||||
init_history();
|
init_history();
|
||||||
@ -6339,8 +6431,9 @@ write_viminfo_history(
|
|||||||
fprintf(fp, _("\n# %s History (newest to oldest):\n"),
|
fprintf(fp, _("\n# %s History (newest to oldest):\n"),
|
||||||
type == HIST_CMD ? _("Command Line") :
|
type == HIST_CMD ? _("Command Line") :
|
||||||
type == HIST_SEARCH ? _("Search String") :
|
type == HIST_SEARCH ? _("Search String") :
|
||||||
type == HIST_EXPR ? _("Expression") :
|
type == HIST_EXPR ? _("Expression") :
|
||||||
_("Input Line"));
|
type == HIST_INPUT ? _("Input Line") :
|
||||||
|
_("Debug Line"));
|
||||||
if (num_saved > hislen)
|
if (num_saved > hislen)
|
||||||
num_saved = hislen;
|
num_saved = hislen;
|
||||||
|
|
||||||
@ -6364,9 +6457,23 @@ write_viminfo_history(
|
|||||||
while (num_saved > 0
|
while (num_saved > 0
|
||||||
&& !(round == 2 && i >= viminfo_hisidx[type]))
|
&& !(round == 2 && i >= viminfo_hisidx[type]))
|
||||||
{
|
{
|
||||||
p = round == 1 ? history[type][i].hisstr
|
char_u *p;
|
||||||
: viminfo_history[type] == NULL ? NULL
|
time_t timestamp;
|
||||||
: viminfo_history[type][i];
|
int c = NUL;
|
||||||
|
|
||||||
|
if (round == 1)
|
||||||
|
{
|
||||||
|
p = history[type][i].hisstr;
|
||||||
|
timestamp = history[type][i].time_set;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
p = viminfo_history[type] == NULL ? NULL
|
||||||
|
: viminfo_history[type][i].hisstr;
|
||||||
|
timestamp = viminfo_history[type] == NULL ? 0
|
||||||
|
: viminfo_history[type][i].time_set;
|
||||||
|
}
|
||||||
|
|
||||||
if (p != NULL && (round == 2
|
if (p != NULL && (round == 2
|
||||||
|| !merge
|
|| !merge
|
||||||
|| !history[type][i].viminfo))
|
|| !history[type][i].viminfo))
|
||||||
@ -6381,6 +6488,21 @@ write_viminfo_history(
|
|||||||
putc(c == NUL ? ' ' : c, fp);
|
putc(c == NUL ? ' ' : c, fp);
|
||||||
}
|
}
|
||||||
viminfo_writestring(fp, p);
|
viminfo_writestring(fp, p);
|
||||||
|
|
||||||
|
{
|
||||||
|
char cbuf[NUMBUFLEN];
|
||||||
|
|
||||||
|
/* New style history with a bar line. Format:
|
||||||
|
* |{bartype},{histtype},{timestamp},{separator},"text" */
|
||||||
|
if (c == NUL)
|
||||||
|
cbuf[0] = NUL;
|
||||||
|
else
|
||||||
|
sprintf(cbuf, "%d", c);
|
||||||
|
fprintf(fp, "|%d,%d,%ld,%s,", BARTYPE_HISTORY,
|
||||||
|
type, (long)timestamp, cbuf);
|
||||||
|
barline_writestring(fp, p, LSIZE - 20);
|
||||||
|
putc('\n', fp);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (round == 1)
|
if (round == 1)
|
||||||
{
|
{
|
||||||
@ -6400,7 +6522,7 @@ write_viminfo_history(
|
|||||||
}
|
}
|
||||||
for (i = 0; i < viminfo_hisidx[type]; ++i)
|
for (i = 0; i < viminfo_hisidx[type]; ++i)
|
||||||
if (viminfo_history[type] != NULL)
|
if (viminfo_history[type] != NULL)
|
||||||
vim_free(viminfo_history[type][i]);
|
vim_free(viminfo_history[type][i].hisstr);
|
||||||
vim_free(viminfo_history[type]);
|
vim_free(viminfo_history[type]);
|
||||||
viminfo_history[type] = NULL;
|
viminfo_history[type] = NULL;
|
||||||
viminfo_hisidx[type] = 0;
|
viminfo_hisidx[type] = 0;
|
||||||
|
@ -1639,6 +1639,10 @@ EXTERN int in_free_unref_items INIT(= FALSE);
|
|||||||
EXTERN int did_add_timer INIT(= FALSE);
|
EXTERN int did_add_timer INIT(= FALSE);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef FEAT_EVAL
|
||||||
|
EXTERN time_t time_for_testing INIT(= 0);
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Optional Farsi support. Include it here, so EXTERN and INIT are defined.
|
* Optional Farsi support. Include it here, so EXTERN and INIT are defined.
|
||||||
*/
|
*/
|
||||||
|
@ -16,6 +16,7 @@ void write_viminfo(char_u *file, int forceit);
|
|||||||
int viminfo_readline(vir_T *virp);
|
int viminfo_readline(vir_T *virp);
|
||||||
char_u *viminfo_readstring(vir_T *virp, int off, int convert);
|
char_u *viminfo_readstring(vir_T *virp, int off, int convert);
|
||||||
void viminfo_writestring(FILE *fd, char_u *p);
|
void viminfo_writestring(FILE *fd, char_u *p);
|
||||||
|
int barline_writestring(FILE *fd, char_u *s, int remaining_start);
|
||||||
void do_fixdel(exarg_T *eap);
|
void do_fixdel(exarg_T *eap);
|
||||||
void print_line_no_prefix(linenr_T lnum, int use_number, int list);
|
void print_line_no_prefix(linenr_T lnum, int use_number, int list);
|
||||||
void print_line(linenr_T lnum, int use_number, int list);
|
void print_line(linenr_T lnum, int use_number, int list);
|
||||||
|
@ -37,19 +37,20 @@ void init_history(void);
|
|||||||
int get_histtype(char_u *name);
|
int get_histtype(char_u *name);
|
||||||
void add_to_history(int histype, char_u *new_entry, int in_map, int sep);
|
void add_to_history(int histype, char_u *new_entry, int in_map, int sep);
|
||||||
int get_history_idx(int histype);
|
int get_history_idx(int histype);
|
||||||
char_u *get_cmdline_str(void);
|
|
||||||
int get_cmdline_pos(void);
|
|
||||||
int set_cmdline_pos(int pos);
|
|
||||||
int get_cmdline_type(void);
|
|
||||||
char_u *get_history_entry(int histype, int idx);
|
char_u *get_history_entry(int histype, int idx);
|
||||||
int clr_history(int histype);
|
int clr_history(int histype);
|
||||||
int del_history_entry(int histype, char_u *str);
|
int del_history_entry(int histype, char_u *str);
|
||||||
int del_history_idx(int histype, int idx);
|
int del_history_idx(int histype, int idx);
|
||||||
void remove_key_from_history(void);
|
void remove_key_from_history(void);
|
||||||
|
char_u *get_cmdline_str(void);
|
||||||
|
int get_cmdline_pos(void);
|
||||||
|
int set_cmdline_pos(int pos);
|
||||||
|
int get_cmdline_type(void);
|
||||||
int get_list_range(char_u **str, int *num1, int *num2);
|
int get_list_range(char_u **str, int *num1, int *num2);
|
||||||
void ex_history(exarg_T *eap);
|
void ex_history(exarg_T *eap);
|
||||||
void prepare_viminfo_history(int asklen, int writing);
|
void prepare_viminfo_history(int asklen, int writing);
|
||||||
int read_viminfo_history(vir_T *virp, 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(void);
|
void finish_viminfo_history(void);
|
||||||
void write_viminfo_history(FILE *fp, int merge);
|
void write_viminfo_history(FILE *fp, int merge);
|
||||||
void cmd_pchar(int c, int offset);
|
void cmd_pchar(int c, int offset);
|
||||||
|
@ -1014,6 +1014,7 @@ typedef struct
|
|||||||
#ifdef FEAT_MBYTE
|
#ifdef FEAT_MBYTE
|
||||||
vimconv_T vir_conv; /* encoding conversion */
|
vimconv_T vir_conv; /* encoding conversion */
|
||||||
#endif
|
#endif
|
||||||
|
int vir_version; /* viminfo version detected or -1 */
|
||||||
garray_T vir_barlines; /* lines starting with | */
|
garray_T vir_barlines; /* lines starting with | */
|
||||||
} vir_T;
|
} vir_T;
|
||||||
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
" Test for reading and writing .viminfo
|
" Test for reading and writing .viminfo
|
||||||
|
|
||||||
function Test_read_and_write()
|
function Test_read_and_write()
|
||||||
|
call histdel(':')
|
||||||
let lines = [
|
let lines = [
|
||||||
\ '# comment line',
|
\ '# comment line',
|
||||||
\ '*encoding=utf-8',
|
\ '*encoding=utf-8',
|
||||||
@ -18,14 +19,16 @@ function Test_read_and_write()
|
|||||||
for line in lines
|
for line in lines
|
||||||
if line[0] == '|'
|
if line[0] == '|'
|
||||||
if done == 0
|
if done == 0
|
||||||
call assert_equal('|copied as-is', line)
|
call assert_equal('|1,2', line)
|
||||||
elseif done == 1
|
elseif done == 1
|
||||||
|
call assert_equal('|copied as-is', line)
|
||||||
|
elseif done == 2
|
||||||
call assert_equal('|and one more', line)
|
call assert_equal('|and one more', line)
|
||||||
endif
|
endif
|
||||||
let done += 1
|
let done += 1
|
||||||
endif
|
endif
|
||||||
endfor
|
endfor
|
||||||
call assert_equal(2, done)
|
call assert_equal(3, done)
|
||||||
|
|
||||||
call delete('Xviminfo')
|
call delete('Xviminfo')
|
||||||
endfunc
|
endfunc
|
||||||
@ -48,3 +51,68 @@ func Test_global_vars()
|
|||||||
call delete('Xviminfo')
|
call delete('Xviminfo')
|
||||||
set viminfo-=!
|
set viminfo-=!
|
||||||
endfunc
|
endfunc
|
||||||
|
|
||||||
|
func Test_cmdline_history()
|
||||||
|
call histdel(':')
|
||||||
|
call test_settime(11)
|
||||||
|
call histadd(':', "echo 'one'")
|
||||||
|
call test_settime(12)
|
||||||
|
" split into two lines
|
||||||
|
let long800 = repeat(" 'eight'", 100)
|
||||||
|
call histadd(':', "echo " . long800)
|
||||||
|
call test_settime(13)
|
||||||
|
" split into three lines
|
||||||
|
let long1400 = repeat(" 'fourteeeeen'", 100)
|
||||||
|
call histadd(':', "echo " . long1400)
|
||||||
|
wviminfo Xviminfo
|
||||||
|
let lines = readfile('Xviminfo')
|
||||||
|
let done_colon = 0
|
||||||
|
let done_bar = 0
|
||||||
|
let lnum = 0
|
||||||
|
while lnum < len(lines)
|
||||||
|
let line = lines[lnum] | let lnum += 1
|
||||||
|
if line[0] == ':'
|
||||||
|
if done_colon == 0
|
||||||
|
call assert_equal(":\x161408", line)
|
||||||
|
let line = lines[lnum] | let lnum += 1
|
||||||
|
call assert_equal('<echo ' . long1400, line)
|
||||||
|
elseif done_colon == 1
|
||||||
|
call assert_equal(":\x16808", line)
|
||||||
|
let line = lines[lnum] | let lnum += 1
|
||||||
|
call assert_equal("<echo " . long800, line)
|
||||||
|
elseif done_colon == 2
|
||||||
|
call assert_equal(":echo 'one'", line)
|
||||||
|
endif
|
||||||
|
let done_colon += 1
|
||||||
|
elseif line[0:4] == '|2,0,'
|
||||||
|
if done_bar == 0
|
||||||
|
call assert_equal("|2,0,13,,>1407", line)
|
||||||
|
let line = lines[lnum] | let lnum += 1
|
||||||
|
call assert_equal('|<"echo ' . long1400[0:484], line)
|
||||||
|
let line = lines[lnum] | let lnum += 1
|
||||||
|
call assert_equal('|<' . long1400[485:974], line)
|
||||||
|
let line = lines[lnum] | let lnum += 1
|
||||||
|
call assert_equal('|<' . long1400[975:] . '"', line)
|
||||||
|
elseif done_bar == 1
|
||||||
|
call assert_equal('|2,0,12,,>807', line)
|
||||||
|
let line = lines[lnum] | let lnum += 1
|
||||||
|
call assert_equal('|<"echo ' . long800[0:484], line)
|
||||||
|
let line = lines[lnum] | let lnum += 1
|
||||||
|
call assert_equal('|<' . long800[485:] . '"', line)
|
||||||
|
elseif done_bar == 2
|
||||||
|
call assert_equal("|2,0,11,,\"echo 'one'\"", line)
|
||||||
|
endif
|
||||||
|
let done_bar += 1
|
||||||
|
endif
|
||||||
|
endwhile
|
||||||
|
call assert_equal(3, done_colon)
|
||||||
|
call assert_equal(3, done_bar)
|
||||||
|
|
||||||
|
call histdel(':')
|
||||||
|
rviminfo Xviminfo
|
||||||
|
call assert_equal("echo " . long1400, histget(':', -1))
|
||||||
|
call assert_equal("echo " . long800, histget(':', -2))
|
||||||
|
call assert_equal("echo 'one'", histget(':', -3))
|
||||||
|
|
||||||
|
call delete('Xviminfo')
|
||||||
|
endfunc
|
||||||
|
@ -753,6 +753,8 @@ static char *(features[]) =
|
|||||||
|
|
||||||
static int included_patches[] =
|
static int included_patches[] =
|
||||||
{ /* Add new patch number below this line */
|
{ /* Add new patch number below this line */
|
||||||
|
/**/
|
||||||
|
1903,
|
||||||
/**/
|
/**/
|
||||||
1902,
|
1902,
|
||||||
/**/
|
/**/
|
||||||
|
Loading…
x
Reference in New Issue
Block a user