comparison src/mark.c @ 17464:3e708b5c0509 v8.1.1730

patch 8.1.1730: wrong place for mark viminfo support commit https://github.com/vim/vim/commit/1e78e69680a5f52970d9b1ef60710e556b09b8c2 Author: Bram Moolenaar <Bram@vim.org> Date: Mon Jul 22 20:18:27 2019 +0200 patch 8.1.1730: wrong place for mark viminfo support Problem: Wrong place for mark viminfo support. Solution: Move it to viminfo.c. (Yegappan Lakshmanan, closes https://github.com/vim/vim/issues/4716)
author Bram Moolenaar <Bram@vim.org>
date Mon, 22 Jul 2019 20:30:05 +0200
parents ce04ebdf26b8
children 0f7ae8010787
comparison
equal deleted inserted replaced
17463:16f01738068b 17464:3e708b5c0509
22 * If a named file mark's fnum is non-zero, it is for an existing buffer, 22 * If a named file mark's fnum is non-zero, it is for an existing buffer,
23 * otherwise it is from .viminfo and namedfm[n].fname is the file name. 23 * otherwise it is from .viminfo and namedfm[n].fname is the file name.
24 * There are marks 'A - 'Z (set by user) and '0 to '9 (set when writing 24 * There are marks 'A - 'Z (set by user) and '0 to '9 (set when writing
25 * viminfo). 25 * viminfo).
26 */ 26 */
27 #define EXTRA_MARKS 10 /* marks 0-9 */
28 static xfmark_T namedfm[NMARKS + EXTRA_MARKS]; /* marks with file nr */ 27 static xfmark_T namedfm[NMARKS + EXTRA_MARKS]; /* marks with file nr */
29 28
30 static void fmarks_check_one(xfmark_T *fm, char_u *name, buf_T *buf); 29 static void fmarks_check_one(xfmark_T *fm, char_u *name, buf_T *buf);
31 static char_u *mark_line(pos_T *mp, int lead_len); 30 static char_u *mark_line(pos_T *mp, int lead_len);
32 static void show_one_mark(int, char_u *, pos_T *, char_u *, int current); 31 static void show_one_mark(int, char_u *, pos_T *, char_u *, int current);
33 #ifdef FEAT_VIMINFO
34 static void write_one_filemark(FILE *fp, xfmark_T *fm, int c1, int c2);
35 #endif
36 static void mark_adjust_internal(linenr_T line1, linenr_T line2, long amount, 32 static void mark_adjust_internal(linenr_T line1, linenr_T line2, long amount,
37 long amount_after, int adjust_folds); 33 long amount_after, int adjust_folds);
38 34
39 /* 35 /*
40 * Set named mark "c" at current cursor position. 36 * Set named mark "c" at current cursor position.
1404 if (namedfm[i].fmark.mark.lnum != 0) 1400 if (namedfm[i].fmark.mark.lnum != 0)
1405 vim_free(namedfm[i].fname); 1401 vim_free(namedfm[i].fname);
1406 } 1402 }
1407 #endif 1403 #endif
1408 1404
1409 #if defined(FEAT_VIMINFO) || defined(PROTO) 1405 /*
1410 int 1406 * Return a pointer to the named file marks.
1411 read_viminfo_filemark(vir_T *virp, int force) 1407 */
1412 { 1408 xfmark_T *
1413 char_u *str; 1409 get_namedfm(void)
1414 xfmark_T *fm; 1410 {
1415 int i; 1411 return namedfm;
1416 1412 }
1417 /* We only get here if line[0] == '\'' or '-'.
1418 * Illegal mark names are ignored (for future expansion). */
1419 str = virp->vir_line + 1;
1420 if (
1421 #ifndef EBCDIC
1422 *str <= 127 &&
1423 #endif
1424 ((*virp->vir_line == '\'' && (VIM_ISDIGIT(*str) || isupper(*str)))
1425 || (*virp->vir_line == '-' && *str == '\'')))
1426 {
1427 if (*str == '\'')
1428 {
1429 #ifdef FEAT_JUMPLIST
1430 /* If the jumplist isn't full insert fmark as oldest entry */
1431 if (curwin->w_jumplistlen == JUMPLISTSIZE)
1432 fm = NULL;
1433 else
1434 {
1435 for (i = curwin->w_jumplistlen; i > 0; --i)
1436 curwin->w_jumplist[i] = curwin->w_jumplist[i - 1];
1437 ++curwin->w_jumplistidx;
1438 ++curwin->w_jumplistlen;
1439 fm = &curwin->w_jumplist[0];
1440 fm->fmark.mark.lnum = 0;
1441 fm->fname = NULL;
1442 }
1443 #else
1444 fm = NULL;
1445 #endif
1446 }
1447 else if (VIM_ISDIGIT(*str))
1448 fm = &namedfm[*str - '0' + NMARKS];
1449 else
1450 fm = &namedfm[*str - 'A'];
1451 if (fm != NULL && (fm->fmark.mark.lnum == 0 || force))
1452 {
1453 str = skipwhite(str + 1);
1454 fm->fmark.mark.lnum = getdigits(&str);
1455 str = skipwhite(str);
1456 fm->fmark.mark.col = getdigits(&str);
1457 fm->fmark.mark.coladd = 0;
1458 fm->fmark.fnum = 0;
1459 str = skipwhite(str);
1460 vim_free(fm->fname);
1461 fm->fname = viminfo_readstring(virp, (int)(str - virp->vir_line),
1462 FALSE);
1463 fm->time_set = 0;
1464 }
1465 }
1466 return vim_fgets(virp->vir_line, LSIZE, virp->vir_fd);
1467 }
1468
1469 static xfmark_T *vi_namedfm = NULL;
1470 #ifdef FEAT_JUMPLIST
1471 static xfmark_T *vi_jumplist = NULL;
1472 static int vi_jumplist_len = 0;
1473 #endif
1474
1475 /*
1476 * Prepare for reading viminfo marks when writing viminfo later.
1477 */
1478 void
1479 prepare_viminfo_marks(void)
1480 {
1481 vi_namedfm = ALLOC_CLEAR_MULT(xfmark_T, NMARKS + EXTRA_MARKS);
1482 #ifdef FEAT_JUMPLIST
1483 vi_jumplist = ALLOC_CLEAR_MULT(xfmark_T, JUMPLISTSIZE);
1484 vi_jumplist_len = 0;
1485 #endif
1486 }
1487
1488 void
1489 finish_viminfo_marks(void)
1490 {
1491 int i;
1492
1493 if (vi_namedfm != NULL)
1494 {
1495 for (i = 0; i < NMARKS + EXTRA_MARKS; ++i)
1496 vim_free(vi_namedfm[i].fname);
1497 VIM_CLEAR(vi_namedfm);
1498 }
1499 #ifdef FEAT_JUMPLIST
1500 if (vi_jumplist != NULL)
1501 {
1502 for (i = 0; i < vi_jumplist_len; ++i)
1503 vim_free(vi_jumplist[i].fname);
1504 VIM_CLEAR(vi_jumplist);
1505 }
1506 #endif
1507 }
1508
1509 /*
1510 * Accept a new style mark line from the viminfo, store it when it's new.
1511 */
1512 void
1513 handle_viminfo_mark(garray_T *values, int force)
1514 {
1515 bval_T *vp = (bval_T *)values->ga_data;
1516 int name;
1517 linenr_T lnum;
1518 colnr_T col;
1519 time_t timestamp;
1520 xfmark_T *fm = NULL;
1521
1522 /* Check the format:
1523 * |{bartype},{name},{lnum},{col},{timestamp},{filename} */
1524 if (values->ga_len < 5
1525 || vp[0].bv_type != BVAL_NR
1526 || vp[1].bv_type != BVAL_NR
1527 || vp[2].bv_type != BVAL_NR
1528 || vp[3].bv_type != BVAL_NR
1529 || vp[4].bv_type != BVAL_STRING)
1530 return;
1531
1532 name = vp[0].bv_nr;
1533 if (name != '\'' && !VIM_ISDIGIT(name) && !ASCII_ISUPPER(name))
1534 return;
1535 lnum = vp[1].bv_nr;
1536 col = vp[2].bv_nr;
1537 if (lnum <= 0 || col < 0)
1538 return;
1539 timestamp = (time_t)vp[3].bv_nr;
1540
1541 if (name == '\'')
1542 {
1543 #ifdef FEAT_JUMPLIST
1544 if (vi_jumplist != NULL)
1545 {
1546 if (vi_jumplist_len < JUMPLISTSIZE)
1547 fm = &vi_jumplist[vi_jumplist_len++];
1548 }
1549 else
1550 {
1551 int idx;
1552 int i;
1553
1554 /* If we have a timestamp insert it in the right place. */
1555 if (timestamp != 0)
1556 {
1557 for (idx = curwin->w_jumplistlen - 1; idx >= 0; --idx)
1558 if (curwin->w_jumplist[idx].time_set < timestamp)
1559 {
1560 ++idx;
1561 break;
1562 }
1563 /* idx cannot be zero now */
1564 if (idx < 0 && curwin->w_jumplistlen < JUMPLISTSIZE)
1565 /* insert as the oldest entry */
1566 idx = 0;
1567 }
1568 else if (curwin->w_jumplistlen < JUMPLISTSIZE)
1569 /* insert as oldest entry */
1570 idx = 0;
1571 else
1572 idx = -1;
1573
1574 if (idx >= 0)
1575 {
1576 if (curwin->w_jumplistlen == JUMPLISTSIZE)
1577 {
1578 /* Drop the oldest entry. */
1579 --idx;
1580 vim_free(curwin->w_jumplist[0].fname);
1581 for (i = 0; i < idx; ++i)
1582 curwin->w_jumplist[i] = curwin->w_jumplist[i + 1];
1583 }
1584 else
1585 {
1586 /* Move newer entries forward. */
1587 for (i = curwin->w_jumplistlen; i > idx; --i)
1588 curwin->w_jumplist[i] = curwin->w_jumplist[i - 1];
1589 ++curwin->w_jumplistidx;
1590 ++curwin->w_jumplistlen;
1591 }
1592 fm = &curwin->w_jumplist[idx];
1593 fm->fmark.mark.lnum = 0;
1594 fm->fname = NULL;
1595 fm->time_set = 0;
1596 }
1597 }
1598 #endif
1599 }
1600 else
1601 {
1602 int idx;
1603
1604 if (VIM_ISDIGIT(name))
1605 {
1606 if (vi_namedfm != NULL)
1607 idx = name - '0' + NMARKS;
1608 else
1609 {
1610 int i;
1611
1612 /* Do not use the name from the viminfo file, insert in time
1613 * order. */
1614 for (idx = NMARKS; idx < NMARKS + EXTRA_MARKS; ++idx)
1615 if (namedfm[idx].time_set < timestamp)
1616 break;
1617 if (idx == NMARKS + EXTRA_MARKS)
1618 /* All existing entries are newer. */
1619 return;
1620 i = NMARKS + EXTRA_MARKS - 1;
1621
1622 vim_free(namedfm[i].fname);
1623 for ( ; i > idx; --i)
1624 namedfm[i] = namedfm[i - 1];
1625 namedfm[idx].fname = NULL;
1626 }
1627 }
1628 else
1629 idx = name - 'A';
1630 if (vi_namedfm != NULL)
1631 fm = &vi_namedfm[idx];
1632 else
1633 fm = &namedfm[idx];
1634 }
1635
1636 if (fm != NULL)
1637 {
1638 if (vi_namedfm != NULL || fm->fmark.mark.lnum == 0
1639 || fm->time_set < timestamp || force)
1640 {
1641 fm->fmark.mark.lnum = lnum;
1642 fm->fmark.mark.col = col;
1643 fm->fmark.mark.coladd = 0;
1644 fm->fmark.fnum = 0;
1645 vim_free(fm->fname);
1646 if (vp[4].bv_allocated)
1647 {
1648 fm->fname = vp[4].bv_string;
1649 vp[4].bv_string = NULL;
1650 }
1651 else
1652 fm->fname = vim_strsave(vp[4].bv_string);
1653 fm->time_set = timestamp;
1654 }
1655 }
1656 }
1657
1658 /*
1659 * Return TRUE if marks for "buf" should not be written.
1660 */
1661 static int
1662 skip_for_viminfo(buf_T *buf)
1663 {
1664 return
1665 #ifdef FEAT_TERMINAL
1666 bt_terminal(buf) ||
1667 #endif
1668 removable(buf->b_ffname);
1669 }
1670
1671 void
1672 write_viminfo_filemarks(FILE *fp)
1673 {
1674 int i;
1675 char_u *name;
1676 buf_T *buf;
1677 xfmark_T *fm;
1678 int vi_idx;
1679 int idx;
1680
1681 if (get_viminfo_parameter('f') == 0)
1682 return;
1683
1684 fputs(_("\n# File marks:\n"), fp);
1685
1686 /* Write the filemarks 'A - 'Z */
1687 for (i = 0; i < NMARKS; i++)
1688 {
1689 if (vi_namedfm != NULL && (vi_namedfm[i].time_set > namedfm[i].time_set
1690 || namedfm[i].fmark.mark.lnum == 0))
1691 fm = &vi_namedfm[i];
1692 else
1693 fm = &namedfm[i];
1694 write_one_filemark(fp, fm, '\'', i + 'A');
1695 }
1696
1697 /*
1698 * Find a mark that is the same file and position as the cursor.
1699 * That one, or else the last one is deleted.
1700 * Move '0 to '1, '1 to '2, etc. until the matching one or '9
1701 * Set the '0 mark to current cursor position.
1702 */
1703 if (curbuf->b_ffname != NULL && !skip_for_viminfo(curbuf))
1704 {
1705 name = buflist_nr2name(curbuf->b_fnum, TRUE, FALSE);
1706 for (i = NMARKS; i < NMARKS + EXTRA_MARKS - 1; ++i)
1707 if (namedfm[i].fmark.mark.lnum == curwin->w_cursor.lnum
1708 && (namedfm[i].fname == NULL
1709 ? namedfm[i].fmark.fnum == curbuf->b_fnum
1710 : (name != NULL
1711 && STRCMP(name, namedfm[i].fname) == 0)))
1712 break;
1713 vim_free(name);
1714
1715 vim_free(namedfm[i].fname);
1716 for ( ; i > NMARKS; --i)
1717 namedfm[i] = namedfm[i - 1];
1718 namedfm[NMARKS].fmark.mark = curwin->w_cursor;
1719 namedfm[NMARKS].fmark.fnum = curbuf->b_fnum;
1720 namedfm[NMARKS].fname = NULL;
1721 namedfm[NMARKS].time_set = vim_time();
1722 }
1723
1724 /* Write the filemarks '0 - '9. Newest (highest timestamp) first. */
1725 vi_idx = NMARKS;
1726 idx = NMARKS;
1727 for (i = NMARKS; i < NMARKS + EXTRA_MARKS; i++)
1728 {
1729 xfmark_T *vi_fm = vi_namedfm != NULL ? &vi_namedfm[vi_idx] : NULL;
1730
1731 if (vi_fm != NULL
1732 && vi_fm->fmark.mark.lnum != 0
1733 && (vi_fm->time_set > namedfm[idx].time_set
1734 || namedfm[idx].fmark.mark.lnum == 0))
1735 {
1736 fm = vi_fm;
1737 ++vi_idx;
1738 }
1739 else
1740 {
1741 fm = &namedfm[idx++];
1742 if (vi_fm != NULL
1743 && vi_fm->fmark.mark.lnum == fm->fmark.mark.lnum
1744 && vi_fm->time_set == fm->time_set
1745 && ((vi_fm->fmark.fnum != 0
1746 && vi_fm->fmark.fnum == fm->fmark.fnum)
1747 || (vi_fm->fname != NULL
1748 && fm->fname != NULL
1749 && STRCMP(vi_fm->fname, fm->fname) == 0)))
1750 ++vi_idx; /* skip duplicate */
1751 }
1752 write_one_filemark(fp, fm, '\'', i - NMARKS + '0');
1753 }
1754
1755 #ifdef FEAT_JUMPLIST
1756 /* Write the jumplist with -' */
1757 fputs(_("\n# Jumplist (newest first):\n"), fp);
1758 setpcmark(); /* add current cursor position */
1759 cleanup_jumplist(curwin, FALSE);
1760 vi_idx = 0;
1761 idx = curwin->w_jumplistlen - 1;
1762 for (i = 0; i < JUMPLISTSIZE; ++i)
1763 {
1764 xfmark_T *vi_fm;
1765
1766 fm = idx >= 0 ? &curwin->w_jumplist[idx] : NULL;
1767 vi_fm = vi_idx < vi_jumplist_len ? &vi_jumplist[vi_idx] : NULL;
1768 if (fm == NULL && vi_fm == NULL)
1769 break;
1770 if (fm == NULL || (vi_fm != NULL && fm->time_set < vi_fm->time_set))
1771 {
1772 fm = vi_fm;
1773 ++vi_idx;
1774 }
1775 else
1776 --idx;
1777 if (fm->fmark.fnum == 0
1778 || ((buf = buflist_findnr(fm->fmark.fnum)) != NULL
1779 && !skip_for_viminfo(buf)))
1780 write_one_filemark(fp, fm, '-', '\'');
1781 }
1782 #endif
1783 }
1784
1785 static void
1786 write_one_filemark(
1787 FILE *fp,
1788 xfmark_T *fm,
1789 int c1,
1790 int c2)
1791 {
1792 char_u *name;
1793
1794 if (fm->fmark.mark.lnum == 0) /* not set */
1795 return;
1796
1797 if (fm->fmark.fnum != 0) /* there is a buffer */
1798 name = buflist_nr2name(fm->fmark.fnum, TRUE, FALSE);
1799 else
1800 name = fm->fname; /* use name from .viminfo */
1801 if (name != NULL && *name != NUL)
1802 {
1803 fprintf(fp, "%c%c %ld %ld ", c1, c2, (long)fm->fmark.mark.lnum,
1804 (long)fm->fmark.mark.col);
1805 viminfo_writestring(fp, name);
1806
1807 /* Barline: |{bartype},{name},{lnum},{col},{timestamp},{filename}
1808 * size up to filename: 8 + 3 * 20 */
1809 fprintf(fp, "|%d,%d,%ld,%ld,%ld,", BARTYPE_MARK, c2,
1810 (long)fm->fmark.mark.lnum, (long)fm->fmark.mark.col,
1811 (long)fm->time_set);
1812 barline_writestring(fp, name, LSIZE - 70);
1813 putc('\n', fp);
1814 }
1815
1816 if (fm->fmark.fnum != 0)
1817 vim_free(name);
1818 }
1819
1820 /*
1821 * Return TRUE if "name" is on removable media (depending on 'viminfo').
1822 */
1823 int
1824 removable(char_u *name)
1825 {
1826 char_u *p;
1827 char_u part[51];
1828 int retval = FALSE;
1829 size_t n;
1830
1831 name = home_replace_save(NULL, name);
1832 if (name != NULL)
1833 {
1834 for (p = p_viminfo; *p; )
1835 {
1836 copy_option_part(&p, part, 51, ", ");
1837 if (part[0] == 'r')
1838 {
1839 n = STRLEN(part + 1);
1840 if (MB_STRNICMP(part + 1, name, n) == 0)
1841 {
1842 retval = TRUE;
1843 break;
1844 }
1845 }
1846 }
1847 vim_free(name);
1848 }
1849 return retval;
1850 }
1851
1852 static void
1853 write_one_mark(FILE *fp_out, int c, pos_T *pos)
1854 {
1855 if (pos->lnum != 0)
1856 fprintf(fp_out, "\t%c\t%ld\t%d\n", c, (long)pos->lnum, (int)pos->col);
1857 }
1858
1859
1860 static void
1861 write_buffer_marks(buf_T *buf, FILE *fp_out)
1862 {
1863 int i;
1864 pos_T pos;
1865
1866 home_replace(NULL, buf->b_ffname, IObuff, IOSIZE, TRUE);
1867 fprintf(fp_out, "\n> ");
1868 viminfo_writestring(fp_out, IObuff);
1869
1870 /* Write the last used timestamp as the lnum of the non-existing mark '*'.
1871 * Older Vims will ignore it and/or copy it. */
1872 pos.lnum = (linenr_T)buf->b_last_used;
1873 pos.col = 0;
1874 write_one_mark(fp_out, '*', &pos);
1875
1876 write_one_mark(fp_out, '"', &buf->b_last_cursor);
1877 write_one_mark(fp_out, '^', &buf->b_last_insert);
1878 write_one_mark(fp_out, '.', &buf->b_last_change);
1879 #ifdef FEAT_JUMPLIST
1880 /* changelist positions are stored oldest first */
1881 for (i = 0; i < buf->b_changelistlen; ++i)
1882 {
1883 /* skip duplicates */
1884 if (i == 0 || !EQUAL_POS(buf->b_changelist[i - 1],
1885 buf->b_changelist[i]))
1886 write_one_mark(fp_out, '+', &buf->b_changelist[i]);
1887 }
1888 #endif
1889 for (i = 0; i < NMARKS; i++)
1890 write_one_mark(fp_out, 'a' + i, &buf->b_namedm[i]);
1891 }
1892
1893 /*
1894 * Write all the named marks for all buffers.
1895 * When "buflist" is not NULL fill it with the buffers for which marks are to
1896 * be written.
1897 */
1898 void
1899 write_viminfo_marks(FILE *fp_out, garray_T *buflist)
1900 {
1901 buf_T *buf;
1902 int is_mark_set;
1903 int i;
1904 win_T *win;
1905 tabpage_T *tp;
1906
1907 /*
1908 * Set b_last_cursor for the all buffers that have a window.
1909 */
1910 FOR_ALL_TAB_WINDOWS(tp, win)
1911 set_last_cursor(win);
1912
1913 fputs(_("\n# History of marks within files (newest to oldest):\n"), fp_out);
1914 FOR_ALL_BUFFERS(buf)
1915 {
1916 /*
1917 * Only write something if buffer has been loaded and at least one
1918 * mark is set.
1919 */
1920 if (buf->b_marks_read)
1921 {
1922 if (buf->b_last_cursor.lnum != 0)
1923 is_mark_set = TRUE;
1924 else
1925 {
1926 is_mark_set = FALSE;
1927 for (i = 0; i < NMARKS; i++)
1928 if (buf->b_namedm[i].lnum != 0)
1929 {
1930 is_mark_set = TRUE;
1931 break;
1932 }
1933 }
1934 if (is_mark_set && buf->b_ffname != NULL
1935 && buf->b_ffname[0] != NUL
1936 && !skip_for_viminfo(buf))
1937 {
1938 if (buflist == NULL)
1939 write_buffer_marks(buf, fp_out);
1940 else if (ga_grow(buflist, 1) == OK)
1941 ((buf_T **)buflist->ga_data)[buflist->ga_len++] = buf;
1942 }
1943 }
1944 }
1945 }
1946
1947 /*
1948 * Compare functions for qsort() below, that compares b_last_used.
1949 */
1950 static int
1951 buf_compare(const void *s1, const void *s2)
1952 {
1953 buf_T *buf1 = *(buf_T **)s1;
1954 buf_T *buf2 = *(buf_T **)s2;
1955
1956 if (buf1->b_last_used == buf2->b_last_used)
1957 return 0;
1958 return buf1->b_last_used > buf2->b_last_used ? -1 : 1;
1959 }
1960
1961 /*
1962 * Handle marks in the viminfo file:
1963 * fp_out != NULL: copy marks, in time order with buffers in "buflist".
1964 * fp_out == NULL && (flags & VIF_WANT_MARKS): read marks for curbuf only
1965 * fp_out == NULL && (flags & VIF_GET_OLDFILES | VIF_FORCEIT): fill v:oldfiles
1966 */
1967 void
1968 copy_viminfo_marks(
1969 vir_T *virp,
1970 FILE *fp_out,
1971 garray_T *buflist,
1972 int eof,
1973 int flags)
1974 {
1975 char_u *line = virp->vir_line;
1976 buf_T *buf;
1977 int num_marked_files;
1978 int load_marks;
1979 int copy_marks_out;
1980 char_u *str;
1981 int i;
1982 char_u *p;
1983 char_u *name_buf;
1984 pos_T pos;
1985 #ifdef FEAT_EVAL
1986 list_T *list = NULL;
1987 #endif
1988 int count = 0;
1989 int buflist_used = 0;
1990 buf_T *buflist_buf = NULL;
1991
1992 if ((name_buf = alloc(LSIZE)) == NULL)
1993 return;
1994 *name_buf = NUL;
1995
1996 if (fp_out != NULL && buflist->ga_len > 0)
1997 {
1998 /* Sort the list of buffers on b_last_used. */
1999 qsort(buflist->ga_data, (size_t)buflist->ga_len,
2000 sizeof(buf_T *), buf_compare);
2001 buflist_buf = ((buf_T **)buflist->ga_data)[0];
2002 }
2003
2004 #ifdef FEAT_EVAL
2005 if (fp_out == NULL && (flags & (VIF_GET_OLDFILES | VIF_FORCEIT)))
2006 {
2007 list = list_alloc();
2008 if (list != NULL)
2009 set_vim_var_list(VV_OLDFILES, list);
2010 }
2011 #endif
2012
2013 num_marked_files = get_viminfo_parameter('\'');
2014 while (!eof && (count < num_marked_files || fp_out == NULL))
2015 {
2016 if (line[0] != '>')
2017 {
2018 if (line[0] != '\n' && line[0] != '\r' && line[0] != '#')
2019 {
2020 if (viminfo_error("E576: ", _("Missing '>'"), line))
2021 break; /* too many errors, return now */
2022 }
2023 eof = vim_fgets(line, LSIZE, virp->vir_fd);
2024 continue; /* Skip this dud line */
2025 }
2026
2027 /*
2028 * Handle long line and translate escaped characters.
2029 * Find file name, set str to start.
2030 * Ignore leading and trailing white space.
2031 */
2032 str = skipwhite(line + 1);
2033 str = viminfo_readstring(virp, (int)(str - virp->vir_line), FALSE);
2034 if (str == NULL)
2035 continue;
2036 p = str + STRLEN(str);
2037 while (p != str && (*p == NUL || vim_isspace(*p)))
2038 p--;
2039 if (*p)
2040 p++;
2041 *p = NUL;
2042
2043 #ifdef FEAT_EVAL
2044 if (list != NULL)
2045 list_append_string(list, str, -1);
2046 #endif
2047
2048 /*
2049 * If fp_out == NULL, load marks for current buffer.
2050 * If fp_out != NULL, copy marks for buffers not in buflist.
2051 */
2052 load_marks = copy_marks_out = FALSE;
2053 if (fp_out == NULL)
2054 {
2055 if ((flags & VIF_WANT_MARKS) && curbuf->b_ffname != NULL)
2056 {
2057 if (*name_buf == NUL) /* only need to do this once */
2058 home_replace(NULL, curbuf->b_ffname, name_buf, LSIZE, TRUE);
2059 if (fnamecmp(str, name_buf) == 0)
2060 load_marks = TRUE;
2061 }
2062 }
2063 else /* fp_out != NULL */
2064 {
2065 /* This is slow if there are many buffers!! */
2066 FOR_ALL_BUFFERS(buf)
2067 if (buf->b_ffname != NULL)
2068 {
2069 home_replace(NULL, buf->b_ffname, name_buf, LSIZE, TRUE);
2070 if (fnamecmp(str, name_buf) == 0)
2071 break;
2072 }
2073
2074 /*
2075 * Copy marks if the buffer has not been loaded.
2076 */
2077 if (buf == NULL || !buf->b_marks_read)
2078 {
2079 int did_read_line = FALSE;
2080
2081 if (buflist_buf != NULL)
2082 {
2083 /* Read the next line. If it has the "*" mark compare the
2084 * time stamps. Write entries from "buflist" that are
2085 * newer. */
2086 if (!(eof = viminfo_readline(virp)) && line[0] == TAB)
2087 {
2088 did_read_line = TRUE;
2089 if (line[1] == '*')
2090 {
2091 long ltime;
2092
2093 sscanf((char *)line + 2, "%ld ", &ltime);
2094 while ((time_T)ltime < buflist_buf->b_last_used)
2095 {
2096 write_buffer_marks(buflist_buf, fp_out);
2097 if (++count >= num_marked_files)
2098 break;
2099 if (++buflist_used == buflist->ga_len)
2100 {
2101 buflist_buf = NULL;
2102 break;
2103 }
2104 buflist_buf =
2105 ((buf_T **)buflist->ga_data)[buflist_used];
2106 }
2107 }
2108 else
2109 {
2110 /* No timestamp, must be written by an older Vim.
2111 * Assume all remaining buffers are older then
2112 * ours. */
2113 while (count < num_marked_files
2114 && buflist_used < buflist->ga_len)
2115 {
2116 buflist_buf = ((buf_T **)buflist->ga_data)
2117 [buflist_used++];
2118 write_buffer_marks(buflist_buf, fp_out);
2119 ++count;
2120 }
2121 buflist_buf = NULL;
2122 }
2123
2124 if (count >= num_marked_files)
2125 {
2126 vim_free(str);
2127 break;
2128 }
2129 }
2130 }
2131
2132 fputs("\n> ", fp_out);
2133 viminfo_writestring(fp_out, str);
2134 if (did_read_line)
2135 fputs((char *)line, fp_out);
2136
2137 count++;
2138 copy_marks_out = TRUE;
2139 }
2140 }
2141 vim_free(str);
2142
2143 pos.coladd = 0;
2144 while (!(eof = viminfo_readline(virp)) && line[0] == TAB)
2145 {
2146 if (load_marks)
2147 {
2148 if (line[1] != NUL)
2149 {
2150 unsigned u;
2151
2152 sscanf((char *)line + 2, "%ld %u", &pos.lnum, &u);
2153 pos.col = u;
2154 switch (line[1])
2155 {
2156 case '"': curbuf->b_last_cursor = pos; break;
2157 case '^': curbuf->b_last_insert = pos; break;
2158 case '.': curbuf->b_last_change = pos; break;
2159 case '+':
2160 #ifdef FEAT_JUMPLIST
2161 /* changelist positions are stored oldest
2162 * first */
2163 if (curbuf->b_changelistlen == JUMPLISTSIZE)
2164 /* list is full, remove oldest entry */
2165 mch_memmove(curbuf->b_changelist,
2166 curbuf->b_changelist + 1,
2167 sizeof(pos_T) * (JUMPLISTSIZE - 1));
2168 else
2169 ++curbuf->b_changelistlen;
2170 curbuf->b_changelist[
2171 curbuf->b_changelistlen - 1] = pos;
2172 #endif
2173 break;
2174
2175 /* Using the line number for the last-used
2176 * timestamp. */
2177 case '*': curbuf->b_last_used = pos.lnum; break;
2178
2179 default: if ((i = line[1] - 'a') >= 0 && i < NMARKS)
2180 curbuf->b_namedm[i] = pos;
2181 }
2182 }
2183 }
2184 else if (copy_marks_out)
2185 fputs((char *)line, fp_out);
2186 }
2187
2188 if (load_marks)
2189 {
2190 #ifdef FEAT_JUMPLIST
2191 win_T *wp;
2192
2193 FOR_ALL_WINDOWS(wp)
2194 {
2195 if (wp->w_buffer == curbuf)
2196 wp->w_changelistidx = curbuf->b_changelistlen;
2197 }
2198 #endif
2199 break;
2200 }
2201 }
2202
2203 if (fp_out != NULL)
2204 /* Write any remaining entries from buflist. */
2205 while (count < num_marked_files && buflist_used < buflist->ga_len)
2206 {
2207 buflist_buf = ((buf_T **)buflist->ga_data)[buflist_used++];
2208 write_buffer_marks(buflist_buf, fp_out);
2209 ++count;
2210 }
2211
2212 vim_free(name_buf);
2213 }
2214 #endif /* FEAT_VIMINFO */