Patch 7.4.1988
Problem: When updating viminfo with file marks there is no time order.
Solution: Remember the time when a buffer was last used, store marks for
the most recently used buffers.
Files: src/buffer.c, src/structs.h, src/mark.c, src/main.c,
src/ex_cmds.c, src/proto/mark.pro, src/testdir/test_viminfo.vim
*** ../vim-7.4.1987/src/buffer.c 2016-07-01 17:17:13.270267053 +0200
--- src/buffer.c 2016-07-03 14:43:54.434420824 +0200
***************
*** 1619,1624 ****
--- 1619,1627 ----
if (!curbuf->b_help && curwin->w_p_spell && *curwin->w_s->b_p_spl != NUL)
(void)did_set_spelllang(curwin);
#endif
+ #ifdef FEAT_VIMINFO
+ curbuf->b_last_used = vim_time();
+ #endif
redraw_later(NOT_VALID);
}
*** ../vim-7.4.1987/src/structs.h 2016-07-01 18:16:47.497936191 +0200
--- src/structs.h 2016-07-03 14:43:52.018456420 +0200
***************
*** 1771,1776 ****
--- 1771,1780 ----
long b_mtime_read; /* last change time when reading */
off_T b_orig_size; /* size of original file in bytes */
int b_orig_mode; /* mode of original file */
+ #ifdef FEAT_VIMINFO
+ time_T b_last_used; /* time when the buffer was last used; used
+ * for viminfo */
+ #endif
pos_T b_namedm[NMARKS]; /* current named marks (mark.c) */
*** ../vim-7.4.1987/src/mark.c 2016-07-02 19:20:02.152849060 +0200
--- src/mark.c 2016-07-03 17:27:43.520476505 +0200
***************
*** 1799,1814 ****
return retval;
}
! static void write_one_mark(FILE *fp_out, int c, pos_T *pos);
/*
* Write all the named marks for all buffers.
! * Return the number of buffers for which marks have been written.
*/
! int
! write_viminfo_marks(FILE *fp_out)
{
- int count;
buf_T *buf;
int is_mark_set;
int i;
--- 1799,1852 ----
return retval;
}
! static void
! write_one_mark(FILE *fp_out, int c, pos_T *pos)
! {
! if (pos->lnum != 0)
! fprintf(fp_out, "\t%c\t%ld\t%d\n", c, (long)pos->lnum, (int)pos->col);
! }
!
!
! static void
! write_buffer_marks(buf_T *buf, FILE *fp_out)
! {
! int i;
! pos_T pos;
!
! home_replace(NULL, buf->b_ffname, IObuff, IOSIZE, TRUE);
! fprintf(fp_out, "\n> ");
! viminfo_writestring(fp_out, IObuff);
!
! /* Write the last used timestamp as the lnum of the non-existing mark '*'.
! * Older Vims will ignore it and/or copy it. */
! pos.lnum = (linenr_T)buf->b_last_used;
! pos.col = 0;
! write_one_mark(fp_out, '*', &pos);
!
! write_one_mark(fp_out, '"', &buf->b_last_cursor);
! write_one_mark(fp_out, '^', &buf->b_last_insert);
! write_one_mark(fp_out, '.', &buf->b_last_change);
! #ifdef FEAT_JUMPLIST
! /* changelist positions are stored oldest first */
! for (i = 0; i < buf->b_changelistlen; ++i)
! {
! /* skip duplicates */
! if (i == 0 || !equalpos(buf->b_changelist[i - 1], buf->b_changelist[i]))
! write_one_mark(fp_out, '+', &buf->b_changelist[i]);
! }
! #endif
! for (i = 0; i < NMARKS; i++)
! write_one_mark(fp_out, 'a' + i, &buf->b_namedm[i]);
! }
/*
* Write all the named marks for all buffers.
! * When "buflist" is not NULL fill it with the buffers for which marks are to
! * be written.
*/
! void
! write_viminfo_marks(FILE *fp_out, garray_T *buflist)
{
buf_T *buf;
int is_mark_set;
int i;
***************
*** 1826,1832 ****
#endif
fputs(_("\n# History of marks within files (newest to oldest):\n"),
fp_out);
- count = 0;
for (buf = firstbuf; buf != NULL; buf = buf->b_next)
{
/*
--- 1864,1869 ----
***************
*** 1850,1891 ****
if (is_mark_set && buf->b_ffname != NULL
&& buf->b_ffname[0] != NUL && !removable(buf->b_ffname))
{
! home_replace(NULL, buf->b_ffname, IObuff, IOSIZE, TRUE);
! fprintf(fp_out, "\n> ");
! viminfo_writestring(fp_out, IObuff);
! write_one_mark(fp_out, '"', &buf->b_last_cursor);
! write_one_mark(fp_out, '^', &buf->b_last_insert);
! write_one_mark(fp_out, '.', &buf->b_last_change);
! #ifdef FEAT_JUMPLIST
! /* changelist positions are stored oldest first */
! for (i = 0; i < buf->b_changelistlen; ++i)
! {
! /* skip duplicates */
! if (i == 0 || !equalpos(buf->b_changelist[i - 1],
! buf->b_changelist[i]))
! write_one_mark(fp_out, '+', &buf->b_changelist[i]);
! }
! #endif
! for (i = 0; i < NMARKS; i++)
! write_one_mark(fp_out, 'a' + i, &buf->b_namedm[i]);
! count++;
}
}
}
-
- return count;
}
! static void
! write_one_mark(FILE *fp_out, int c, pos_T *pos)
{
! if (pos->lnum != 0)
! fprintf(fp_out, "\t%c\t%ld\t%d\n", c, (long)pos->lnum, (int)pos->col);
}
/*
* Handle marks in the viminfo file:
! * fp_out != NULL: copy marks for buffers not in buffer list
* fp_out == NULL && (flags & VIF_WANT_MARKS): read marks for curbuf only
* fp_out == NULL && (flags & VIF_GET_OLDFILES | VIF_FORCEIT): fill v:oldfiles
*/
--- 1887,1921 ----
if (is_mark_set && buf->b_ffname != NULL
&& buf->b_ffname[0] != NUL && !removable(buf->b_ffname))
{
! if (buflist == NULL)
! write_buffer_marks(buf, fp_out);
! else if (ga_grow(buflist, 1) == OK)
! ((buf_T **)buflist->ga_data)[buflist->ga_len++] = buf;
}
}
}
}
! /*
! * Compare functions for qsort() below, that compares b_last_used.
! */
! static int
! #ifdef __BORLANDC__
! _RTLENTRYF
! #endif
! buf_compare(const void *s1, const void *s2)
{
! buf_T *buf1 = *(buf_T **)s1;
! buf_T *buf2 = *(buf_T **)s2;
!
! if (buf1->b_last_used == buf2->b_last_used)
! return 0;
! return buf1->b_last_used > buf2->b_last_used ? -1 : 1;
}
/*
* Handle marks in the viminfo file:
! * fp_out != NULL: copy marks, in time order with buffers in "buflist".
* fp_out == NULL && (flags & VIF_WANT_MARKS): read marks for curbuf only
* fp_out == NULL && (flags & VIF_GET_OLDFILES | VIF_FORCEIT): fill v:oldfiles
*/
***************
*** 1893,1899 ****
copy_viminfo_marks(
vir_T *virp,
FILE *fp_out,
! int count,
int eof,
int flags)
{
--- 1923,1929 ----
copy_viminfo_marks(
vir_T *virp,
FILE *fp_out,
! garray_T *buflist,
int eof,
int flags)
{
***************
*** 1910,1920 ****
--- 1940,1961 ----
#ifdef FEAT_EVAL
list_T *list = NULL;
#endif
+ int count = 0;
+ int buflist_used = 0;
+ buf_T *buflist_buf = NULL;
if ((name_buf = alloc(LSIZE)) == NULL)
return;
*name_buf = NUL;
+ if (fp_out != NULL && buflist->ga_len > 0)
+ {
+ /* Sort the list of buffers on b_last_used. */
+ qsort(buflist->ga_data, (size_t)buflist->ga_len,
+ sizeof(buf_T *), buf_compare);
+ buflist_buf = ((buf_T **)buflist->ga_data)[0];
+ }
+
#ifdef FEAT_EVAL
if (fp_out == NULL && (flags & (VIF_GET_OLDFILES | VIF_FORCEIT)))
{
***************
*** 1986,1999 ****
}
/*
! * copy marks if the buffer has not been loaded
*/
if (buf == NULL || !buf->b_marks_read)
{
! copy_marks_out = TRUE;
fputs("\n> ", fp_out);
viminfo_writestring(fp_out, str);
count++;
}
}
vim_free(str);
--- 2027,2096 ----
}
/*
! * Copy marks if the buffer has not been loaded.
*/
if (buf == NULL || !buf->b_marks_read)
{
! int did_read_line = FALSE;
!
! if (buflist_buf != NULL)
! {
! /* Read the next line. If it has the "*" mark compare the
! * time stamps. Write entries from "buflist" that are
! * newer. */
! if (!(eof = viminfo_readline(virp)) && line[0] == TAB)
! {
! did_read_line = TRUE;
! if (line[1] == '*')
! {
! long ltime;
!
! sscanf((char *)line + 2, "%ld ", <ime);
! while ((time_T)ltime < buflist_buf->b_last_used)
! {
! write_buffer_marks(buflist_buf, fp_out);
! if (++count >= num_marked_files)
! break;
! if (++buflist_used == buflist->ga_len)
! {
! buflist_buf = NULL;
! break;
! }
! buflist_buf =
! ((buf_T **)buflist->ga_data)[buflist_used];
! }
! }
! else
! {
! /* No timestamp, must be written by an older Vim.
! * Assume all remaining buffers are older then
! * ours. */
! while (count < num_marked_files
! && buflist_used < buflist->ga_len)
! {
! buflist_buf = ((buf_T **)buflist->ga_data)
! [buflist_used++];
! write_buffer_marks(buflist_buf, fp_out);
! ++count;
! }
! buflist_buf = NULL;
! }
!
! if (count >= num_marked_files)
! {
! vim_free(str);
! break;
! }
! }
! }
!
fputs("\n> ", fp_out);
viminfo_writestring(fp_out, str);
+ if (did_read_line)
+ fputs((char *)line, fp_out);
+
count++;
+ copy_marks_out = TRUE;
}
}
vim_free(str);
***************
*** 2031,2036 ****
--- 2128,2138 ----
curbuf->b_changelistlen - 1] = pos;
#endif
break;
+
+ /* Using the line number for the last-used
+ * timestamp. */
+ case '*': curbuf->b_last_used = pos.lnum; break;
+
default: if ((i = line[1] - 'a') >= 0 && i < NMARKS)
curbuf->b_namedm[i] = pos;
}
***************
*** 2039,2044 ****
--- 2141,2147 ----
else if (copy_marks_out)
fputs((char *)line, fp_out);
}
+
if (load_marks)
{
#ifdef FEAT_JUMPLIST
***************
*** 2053,2058 ****
--- 2156,2171 ----
break;
}
}
+
+ if (fp_out != NULL)
+ /* Write any remaining entries from buflist. */
+ while (count < num_marked_files && buflist_used < buflist->ga_len)
+ {
+ buflist_buf = ((buf_T **)buflist->ga_data)[buflist_used++];
+ write_buffer_marks(buflist_buf, fp_out);
+ ++count;
+ }
+
vim_free(name_buf);
}
#endif /* FEAT_VIMINFO */
*** ../vim-7.4.1987/src/main.c 2016-07-02 20:27:29.953436359 +0200
--- src/main.c 2016-07-03 14:45:57.640605919 +0200
***************
*** 1273,1278 ****
--- 1273,1281 ----
if (need_maketitle)
maketitle();
#endif
+ #ifdef FEAT_VIMINFO
+ curbuf->b_last_used = vim_time();
+ #endif
/* display message after redraw */
if (keep_msg != NULL)
{
*** ../vim-7.4.1987/src/ex_cmds.c 2016-07-02 22:33:42.697309329 +0200
--- src/ex_cmds.c 2016-07-03 17:21:27.574130345 +0200
***************
*** 2148,2157 ****
static void
do_viminfo(FILE *fp_in, FILE *fp_out, int flags)
{
- int count = 0;
int eof = FALSE;
vir_T vir;
int merge = FALSE;
if ((vir.vir_line = alloc(LSIZE)) == NULL)
return;
--- 2148,2158 ----
static void
do_viminfo(FILE *fp_in, FILE *fp_out, int flags)
{
int eof = FALSE;
vir_T vir;
int merge = FALSE;
+ int do_copy_marks = FALSE;
+ garray_T buflist;
if ((vir.vir_line = alloc(LSIZE)) == NULL)
return;
***************
*** 2183,2189 ****
--- 2184,2194 ----
while (!(eof = viminfo_readline(&vir))
&& vir.vir_line[0] != '>')
;
+
+ do_copy_marks = (flags &
+ (VIF_WANT_MARKS | VIF_GET_OLDFILES | VIF_FORCEIT));
}
+
if (fp_out != NULL)
{
/* Write the info: */
***************
*** 2209,2219 ****
finish_viminfo_marks();
write_viminfo_bufferlist(fp_out);
write_viminfo_barlines(&vir, fp_out);
! count = write_viminfo_marks(fp_out);
}
- if (fp_in != NULL
- && (flags & (VIF_WANT_MARKS | VIF_GET_OLDFILES | VIF_FORCEIT)))
- copy_viminfo_marks(&vir, fp_out, count, eof, flags);
vim_free(vir.vir_line);
#ifdef FEAT_MBYTE
--- 2214,2231 ----
finish_viminfo_marks();
write_viminfo_bufferlist(fp_out);
write_viminfo_barlines(&vir, fp_out);
!
! if (do_copy_marks)
! ga_init2(&buflist, sizeof(buf_T *), 50);
! write_viminfo_marks(fp_out, do_copy_marks ? &buflist : NULL);
! }
!
! if (do_copy_marks)
! {
! copy_viminfo_marks(&vir, fp_out, &buflist, eof, flags);
! if (fp_out != NULL)
! ga_clear(&buflist);
}
vim_free(vir.vir_line);
#ifdef FEAT_MBYTE
***************
*** 4287,4292 ****
--- 4299,4308 ----
msg_scrolled_ign = FALSE;
}
+ #ifdef FEAT_VIMINFO
+ curbuf->b_last_used = vim_time();
+ #endif
+
if (command != NULL)
do_cmdline(command, NULL, NULL, DOCMD_VERBOSE);
*** ../vim-7.4.1987/src/proto/mark.pro 2016-06-12 21:20:50.941837428 +0200
--- src/proto/mark.pro 2016-07-03 15:56:55.001566461 +0200
***************
*** 30,35 ****
void handle_viminfo_mark(garray_T *values, int force);
void write_viminfo_filemarks(FILE *fp);
int removable(char_u *name);
! int write_viminfo_marks(FILE *fp_out);
! void copy_viminfo_marks(vir_T *virp, FILE *fp_out, int count, int eof, int
flags);
/* vim: set ft=c : */
--- 30,35 ----
void handle_viminfo_mark(garray_T *values, int force);
void write_viminfo_filemarks(FILE *fp);
int removable(char_u *name);
! void write_viminfo_marks(FILE *fp_out, garray_T *buflist);
! void copy_viminfo_marks(vir_T *virp, FILE *fp_out, garray_T *buflist, int
eof, int flags);
/* vim: set ft=c : */
*** ../vim-7.4.1987/src/testdir/test_viminfo.vim 2016-06-15
21:44:47.645388277 +0200
--- src/testdir/test_viminfo.vim 2016-07-03 17:32:49.739875626 +0200
***************
*** 395,397 ****
--- 395,427 ----
call delete('Xviminfo')
endfunc
+ func Test_viminfo_file_marks()
+ silent! bwipe test_viminfo.vim
+ silent! bwipe Xviminfo
+
+ call test_settime(10)
+ edit ten
+ call test_settime(25)
+ edit again
+ call test_settime(30)
+ edit thirty
+ wviminfo Xviminfo
+
+ call test_settime(20)
+ edit twenty
+ call test_settime(35)
+ edit again
+ call test_settime(40)
+ edit fourty
+ wviminfo Xviminfo
+
+ sp Xviminfo
+ 1
+ for name in ['fourty', 'again', 'thirty', 'twenty', 'ten']
+ /^>
+ call assert_equal(name, substitute(getline('.'), '.*/', '', ''))
+ endfor
+ close
+
+ call delete('Xviminfo')
+ endfunc
*** ../vim-7.4.1987/src/version.c 2016-07-02 22:33:42.697309329 +0200
--- src/version.c 2016-07-03 14:45:03.829398486 +0200
***************
*** 760,761 ****
--- 760,763 ----
{ /* Add new patch number below this line */
+ /**/
+ 1988,
/**/
--
hundred-and-one symptoms of being an internet addict:
192. Your boss asks you to "go fer" coffee and you come up with 235 FTP sites.
/// 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.