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 ", &ltime);
!                           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.

Raspunde prin e-mail lui