comparison src/viminfo.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 e43f0c0c491c
children 15de78cb9f39
comparison
equal deleted inserted replaced
17463:16f01738068b 17464:3e708b5c0509
1906 else 1906 else
1907 write_viminfo(eap->arg, eap->forceit); 1907 write_viminfo(eap->arg, eap->forceit);
1908 p_viminfo = save_viminfo; 1908 p_viminfo = save_viminfo;
1909 } 1909 }
1910 1910
1911 int
1912 read_viminfo_filemark(vir_T *virp, int force)
1913 {
1914 char_u *str;
1915 xfmark_T *namedfm_p = get_namedfm();
1916 xfmark_T *fm;
1917 int i;
1918
1919 // We only get here if line[0] == '\'' or '-'.
1920 // Illegal mark names are ignored (for future expansion).
1921 str = virp->vir_line + 1;
1922 if (
1923 #ifndef EBCDIC
1924 *str <= 127 &&
1925 #endif
1926 ((*virp->vir_line == '\'' && (VIM_ISDIGIT(*str) || isupper(*str)))
1927 || (*virp->vir_line == '-' && *str == '\'')))
1928 {
1929 if (*str == '\'')
1930 {
1931 #ifdef FEAT_JUMPLIST
1932 // If the jumplist isn't full insert fmark as oldest entry
1933 if (curwin->w_jumplistlen == JUMPLISTSIZE)
1934 fm = NULL;
1935 else
1936 {
1937 for (i = curwin->w_jumplistlen; i > 0; --i)
1938 curwin->w_jumplist[i] = curwin->w_jumplist[i - 1];
1939 ++curwin->w_jumplistidx;
1940 ++curwin->w_jumplistlen;
1941 fm = &curwin->w_jumplist[0];
1942 fm->fmark.mark.lnum = 0;
1943 fm->fname = NULL;
1944 }
1945 #else
1946 fm = NULL;
1947 #endif
1948 }
1949 else if (VIM_ISDIGIT(*str))
1950 fm = &namedfm_p[*str - '0' + NMARKS];
1951 else
1952 fm = &namedfm_p[*str - 'A'];
1953 if (fm != NULL && (fm->fmark.mark.lnum == 0 || force))
1954 {
1955 str = skipwhite(str + 1);
1956 fm->fmark.mark.lnum = getdigits(&str);
1957 str = skipwhite(str);
1958 fm->fmark.mark.col = getdigits(&str);
1959 fm->fmark.mark.coladd = 0;
1960 fm->fmark.fnum = 0;
1961 str = skipwhite(str);
1962 vim_free(fm->fname);
1963 fm->fname = viminfo_readstring(virp, (int)(str - virp->vir_line),
1964 FALSE);
1965 fm->time_set = 0;
1966 }
1967 }
1968 return vim_fgets(virp->vir_line, LSIZE, virp->vir_fd);
1969 }
1970
1971 static xfmark_T *vi_namedfm = NULL;
1972 #ifdef FEAT_JUMPLIST
1973 static xfmark_T *vi_jumplist = NULL;
1974 static int vi_jumplist_len = 0;
1975 #endif
1976
1977 /*
1978 * Prepare for reading viminfo marks when writing viminfo later.
1979 */
1980 void
1981 prepare_viminfo_marks(void)
1982 {
1983 vi_namedfm = ALLOC_CLEAR_MULT(xfmark_T, NMARKS + EXTRA_MARKS);
1984 #ifdef FEAT_JUMPLIST
1985 vi_jumplist = ALLOC_CLEAR_MULT(xfmark_T, JUMPLISTSIZE);
1986 vi_jumplist_len = 0;
1987 #endif
1988 }
1989
1990 void
1991 finish_viminfo_marks(void)
1992 {
1993 int i;
1994
1995 if (vi_namedfm != NULL)
1996 {
1997 for (i = 0; i < NMARKS + EXTRA_MARKS; ++i)
1998 vim_free(vi_namedfm[i].fname);
1999 VIM_CLEAR(vi_namedfm);
2000 }
2001 #ifdef FEAT_JUMPLIST
2002 if (vi_jumplist != NULL)
2003 {
2004 for (i = 0; i < vi_jumplist_len; ++i)
2005 vim_free(vi_jumplist[i].fname);
2006 VIM_CLEAR(vi_jumplist);
2007 }
2008 #endif
2009 }
2010
2011 /*
2012 * Accept a new style mark line from the viminfo, store it when it's new.
2013 */
2014 void
2015 handle_viminfo_mark(garray_T *values, int force)
2016 {
2017 bval_T *vp = (bval_T *)values->ga_data;
2018 int name;
2019 linenr_T lnum;
2020 colnr_T col;
2021 time_t timestamp;
2022 xfmark_T *fm = NULL;
2023
2024 // Check the format:
2025 // |{bartype},{name},{lnum},{col},{timestamp},{filename}
2026 if (values->ga_len < 5
2027 || vp[0].bv_type != BVAL_NR
2028 || vp[1].bv_type != BVAL_NR
2029 || vp[2].bv_type != BVAL_NR
2030 || vp[3].bv_type != BVAL_NR
2031 || vp[4].bv_type != BVAL_STRING)
2032 return;
2033
2034 name = vp[0].bv_nr;
2035 if (name != '\'' && !VIM_ISDIGIT(name) && !ASCII_ISUPPER(name))
2036 return;
2037 lnum = vp[1].bv_nr;
2038 col = vp[2].bv_nr;
2039 if (lnum <= 0 || col < 0)
2040 return;
2041 timestamp = (time_t)vp[3].bv_nr;
2042
2043 if (name == '\'')
2044 {
2045 #ifdef FEAT_JUMPLIST
2046 if (vi_jumplist != NULL)
2047 {
2048 if (vi_jumplist_len < JUMPLISTSIZE)
2049 fm = &vi_jumplist[vi_jumplist_len++];
2050 }
2051 else
2052 {
2053 int idx;
2054 int i;
2055
2056 // If we have a timestamp insert it in the right place.
2057 if (timestamp != 0)
2058 {
2059 for (idx = curwin->w_jumplistlen - 1; idx >= 0; --idx)
2060 if (curwin->w_jumplist[idx].time_set < timestamp)
2061 {
2062 ++idx;
2063 break;
2064 }
2065 // idx cannot be zero now
2066 if (idx < 0 && curwin->w_jumplistlen < JUMPLISTSIZE)
2067 // insert as the oldest entry
2068 idx = 0;
2069 }
2070 else if (curwin->w_jumplistlen < JUMPLISTSIZE)
2071 // insert as oldest entry
2072 idx = 0;
2073 else
2074 idx = -1;
2075
2076 if (idx >= 0)
2077 {
2078 if (curwin->w_jumplistlen == JUMPLISTSIZE)
2079 {
2080 // Drop the oldest entry.
2081 --idx;
2082 vim_free(curwin->w_jumplist[0].fname);
2083 for (i = 0; i < idx; ++i)
2084 curwin->w_jumplist[i] = curwin->w_jumplist[i + 1];
2085 }
2086 else
2087 {
2088 // Move newer entries forward.
2089 for (i = curwin->w_jumplistlen; i > idx; --i)
2090 curwin->w_jumplist[i] = curwin->w_jumplist[i - 1];
2091 ++curwin->w_jumplistidx;
2092 ++curwin->w_jumplistlen;
2093 }
2094 fm = &curwin->w_jumplist[idx];
2095 fm->fmark.mark.lnum = 0;
2096 fm->fname = NULL;
2097 fm->time_set = 0;
2098 }
2099 }
2100 #endif
2101 }
2102 else
2103 {
2104 int idx;
2105 xfmark_T *namedfm_p = get_namedfm();
2106
2107 if (VIM_ISDIGIT(name))
2108 {
2109 if (vi_namedfm != NULL)
2110 idx = name - '0' + NMARKS;
2111 else
2112 {
2113 int i;
2114
2115 // Do not use the name from the viminfo file, insert in time
2116 // order.
2117 for (idx = NMARKS; idx < NMARKS + EXTRA_MARKS; ++idx)
2118 if (namedfm_p[idx].time_set < timestamp)
2119 break;
2120 if (idx == NMARKS + EXTRA_MARKS)
2121 // All existing entries are newer.
2122 return;
2123 i = NMARKS + EXTRA_MARKS - 1;
2124
2125 vim_free(namedfm_p[i].fname);
2126 for ( ; i > idx; --i)
2127 namedfm_p[i] = namedfm_p[i - 1];
2128 namedfm_p[idx].fname = NULL;
2129 }
2130 }
2131 else
2132 idx = name - 'A';
2133 if (vi_namedfm != NULL)
2134 fm = &vi_namedfm[idx];
2135 else
2136 fm = &namedfm_p[idx];
2137 }
2138
2139 if (fm != NULL)
2140 {
2141 if (vi_namedfm != NULL || fm->fmark.mark.lnum == 0
2142 || fm->time_set < timestamp || force)
2143 {
2144 fm->fmark.mark.lnum = lnum;
2145 fm->fmark.mark.col = col;
2146 fm->fmark.mark.coladd = 0;
2147 fm->fmark.fnum = 0;
2148 vim_free(fm->fname);
2149 if (vp[4].bv_allocated)
2150 {
2151 fm->fname = vp[4].bv_string;
2152 vp[4].bv_string = NULL;
2153 }
2154 else
2155 fm->fname = vim_strsave(vp[4].bv_string);
2156 fm->time_set = timestamp;
2157 }
2158 }
2159 }
2160
2161 /*
2162 * Return TRUE if marks for "buf" should not be written.
2163 */
2164 static int
2165 skip_for_viminfo(buf_T *buf)
2166 {
2167 return
2168 #ifdef FEAT_TERMINAL
2169 bt_terminal(buf) ||
2170 #endif
2171 removable(buf->b_ffname);
2172 }
2173
2174 static void
2175 write_one_filemark(
2176 FILE *fp,
2177 xfmark_T *fm,
2178 int c1,
2179 int c2)
2180 {
2181 char_u *name;
2182
2183 if (fm->fmark.mark.lnum == 0) // not set
2184 return;
2185
2186 if (fm->fmark.fnum != 0) // there is a buffer
2187 name = buflist_nr2name(fm->fmark.fnum, TRUE, FALSE);
2188 else
2189 name = fm->fname; // use name from .viminfo
2190 if (name != NULL && *name != NUL)
2191 {
2192 fprintf(fp, "%c%c %ld %ld ", c1, c2, (long)fm->fmark.mark.lnum,
2193 (long)fm->fmark.mark.col);
2194 viminfo_writestring(fp, name);
2195
2196 // Barline: |{bartype},{name},{lnum},{col},{timestamp},{filename}
2197 // size up to filename: 8 + 3 * 20
2198 fprintf(fp, "|%d,%d,%ld,%ld,%ld,", BARTYPE_MARK, c2,
2199 (long)fm->fmark.mark.lnum, (long)fm->fmark.mark.col,
2200 (long)fm->time_set);
2201 barline_writestring(fp, name, LSIZE - 70);
2202 putc('\n', fp);
2203 }
2204
2205 if (fm->fmark.fnum != 0)
2206 vim_free(name);
2207 }
2208
2209 void
2210 write_viminfo_filemarks(FILE *fp)
2211 {
2212 int i;
2213 char_u *name;
2214 buf_T *buf;
2215 xfmark_T *namedfm_p = get_namedfm();
2216 xfmark_T *fm;
2217 int vi_idx;
2218 int idx;
2219
2220 if (get_viminfo_parameter('f') == 0)
2221 return;
2222
2223 fputs(_("\n# File marks:\n"), fp);
2224
2225 // Write the filemarks 'A - 'Z
2226 for (i = 0; i < NMARKS; i++)
2227 {
2228 if (vi_namedfm != NULL
2229 && (vi_namedfm[i].time_set > namedfm_p[i].time_set
2230 || namedfm_p[i].fmark.mark.lnum == 0))
2231 fm = &vi_namedfm[i];
2232 else
2233 fm = &namedfm_p[i];
2234 write_one_filemark(fp, fm, '\'', i + 'A');
2235 }
2236
2237 // Find a mark that is the same file and position as the cursor.
2238 // That one, or else the last one is deleted.
2239 // Move '0 to '1, '1 to '2, etc. until the matching one or '9
2240 // Set the '0 mark to current cursor position.
2241 if (curbuf->b_ffname != NULL && !skip_for_viminfo(curbuf))
2242 {
2243 name = buflist_nr2name(curbuf->b_fnum, TRUE, FALSE);
2244 for (i = NMARKS; i < NMARKS + EXTRA_MARKS - 1; ++i)
2245 if (namedfm_p[i].fmark.mark.lnum == curwin->w_cursor.lnum
2246 && (namedfm_p[i].fname == NULL
2247 ? namedfm_p[i].fmark.fnum == curbuf->b_fnum
2248 : (name != NULL
2249 && STRCMP(name, namedfm_p[i].fname) == 0)))
2250 break;
2251 vim_free(name);
2252
2253 vim_free(namedfm_p[i].fname);
2254 for ( ; i > NMARKS; --i)
2255 namedfm_p[i] = namedfm_p[i - 1];
2256 namedfm_p[NMARKS].fmark.mark = curwin->w_cursor;
2257 namedfm_p[NMARKS].fmark.fnum = curbuf->b_fnum;
2258 namedfm_p[NMARKS].fname = NULL;
2259 namedfm_p[NMARKS].time_set = vim_time();
2260 }
2261
2262 // Write the filemarks '0 - '9. Newest (highest timestamp) first.
2263 vi_idx = NMARKS;
2264 idx = NMARKS;
2265 for (i = NMARKS; i < NMARKS + EXTRA_MARKS; i++)
2266 {
2267 xfmark_T *vi_fm = vi_namedfm != NULL ? &vi_namedfm[vi_idx] : NULL;
2268
2269 if (vi_fm != NULL
2270 && vi_fm->fmark.mark.lnum != 0
2271 && (vi_fm->time_set > namedfm_p[idx].time_set
2272 || namedfm_p[idx].fmark.mark.lnum == 0))
2273 {
2274 fm = vi_fm;
2275 ++vi_idx;
2276 }
2277 else
2278 {
2279 fm = &namedfm_p[idx++];
2280 if (vi_fm != NULL
2281 && vi_fm->fmark.mark.lnum == fm->fmark.mark.lnum
2282 && vi_fm->time_set == fm->time_set
2283 && ((vi_fm->fmark.fnum != 0
2284 && vi_fm->fmark.fnum == fm->fmark.fnum)
2285 || (vi_fm->fname != NULL
2286 && fm->fname != NULL
2287 && STRCMP(vi_fm->fname, fm->fname) == 0)))
2288 ++vi_idx; // skip duplicate
2289 }
2290 write_one_filemark(fp, fm, '\'', i - NMARKS + '0');
2291 }
2292
2293 #ifdef FEAT_JUMPLIST
2294 // Write the jumplist with -'
2295 fputs(_("\n# Jumplist (newest first):\n"), fp);
2296 setpcmark(); // add current cursor position
2297 cleanup_jumplist(curwin, FALSE);
2298 vi_idx = 0;
2299 idx = curwin->w_jumplistlen - 1;
2300 for (i = 0; i < JUMPLISTSIZE; ++i)
2301 {
2302 xfmark_T *vi_fm;
2303
2304 fm = idx >= 0 ? &curwin->w_jumplist[idx] : NULL;
2305 vi_fm = vi_idx < vi_jumplist_len ? &vi_jumplist[vi_idx] : NULL;
2306 if (fm == NULL && vi_fm == NULL)
2307 break;
2308 if (fm == NULL || (vi_fm != NULL && fm->time_set < vi_fm->time_set))
2309 {
2310 fm = vi_fm;
2311 ++vi_idx;
2312 }
2313 else
2314 --idx;
2315 if (fm->fmark.fnum == 0
2316 || ((buf = buflist_findnr(fm->fmark.fnum)) != NULL
2317 && !skip_for_viminfo(buf)))
2318 write_one_filemark(fp, fm, '-', '\'');
2319 }
2320 #endif
2321 }
2322
2323 /*
2324 * Return TRUE if "name" is on removable media (depending on 'viminfo').
2325 */
2326 int
2327 removable(char_u *name)
2328 {
2329 char_u *p;
2330 char_u part[51];
2331 int retval = FALSE;
2332 size_t n;
2333
2334 name = home_replace_save(NULL, name);
2335 if (name != NULL)
2336 {
2337 for (p = p_viminfo; *p; )
2338 {
2339 copy_option_part(&p, part, 51, ", ");
2340 if (part[0] == 'r')
2341 {
2342 n = STRLEN(part + 1);
2343 if (MB_STRNICMP(part + 1, name, n) == 0)
2344 {
2345 retval = TRUE;
2346 break;
2347 }
2348 }
2349 }
2350 vim_free(name);
2351 }
2352 return retval;
2353 }
2354
2355 static void
2356 write_one_mark(FILE *fp_out, int c, pos_T *pos)
2357 {
2358 if (pos->lnum != 0)
2359 fprintf(fp_out, "\t%c\t%ld\t%d\n", c, (long)pos->lnum, (int)pos->col);
2360 }
2361
2362
2363 static void
2364 write_buffer_marks(buf_T *buf, FILE *fp_out)
2365 {
2366 int i;
2367 pos_T pos;
2368
2369 home_replace(NULL, buf->b_ffname, IObuff, IOSIZE, TRUE);
2370 fprintf(fp_out, "\n> ");
2371 viminfo_writestring(fp_out, IObuff);
2372
2373 // Write the last used timestamp as the lnum of the non-existing mark '*'.
2374 // Older Vims will ignore it and/or copy it.
2375 pos.lnum = (linenr_T)buf->b_last_used;
2376 pos.col = 0;
2377 write_one_mark(fp_out, '*', &pos);
2378
2379 write_one_mark(fp_out, '"', &buf->b_last_cursor);
2380 write_one_mark(fp_out, '^', &buf->b_last_insert);
2381 write_one_mark(fp_out, '.', &buf->b_last_change);
2382 #ifdef FEAT_JUMPLIST
2383 // changelist positions are stored oldest first
2384 for (i = 0; i < buf->b_changelistlen; ++i)
2385 {
2386 // skip duplicates
2387 if (i == 0 || !EQUAL_POS(buf->b_changelist[i - 1],
2388 buf->b_changelist[i]))
2389 write_one_mark(fp_out, '+', &buf->b_changelist[i]);
2390 }
2391 #endif
2392 for (i = 0; i < NMARKS; i++)
2393 write_one_mark(fp_out, 'a' + i, &buf->b_namedm[i]);
2394 }
2395
2396 /*
2397 * Write all the named marks for all buffers.
2398 * When "buflist" is not NULL fill it with the buffers for which marks are to
2399 * be written.
2400 */
2401 void
2402 write_viminfo_marks(FILE *fp_out, garray_T *buflist)
2403 {
2404 buf_T *buf;
2405 int is_mark_set;
2406 int i;
2407 win_T *win;
2408 tabpage_T *tp;
2409
2410 // Set b_last_cursor for the all buffers that have a window.
2411 FOR_ALL_TAB_WINDOWS(tp, win)
2412 set_last_cursor(win);
2413
2414 fputs(_("\n# History of marks within files (newest to oldest):\n"), fp_out);
2415 FOR_ALL_BUFFERS(buf)
2416 {
2417 // Only write something if buffer has been loaded and at least one
2418 // mark is set.
2419 if (buf->b_marks_read)
2420 {
2421 if (buf->b_last_cursor.lnum != 0)
2422 is_mark_set = TRUE;
2423 else
2424 {
2425 is_mark_set = FALSE;
2426 for (i = 0; i < NMARKS; i++)
2427 if (buf->b_namedm[i].lnum != 0)
2428 {
2429 is_mark_set = TRUE;
2430 break;
2431 }
2432 }
2433 if (is_mark_set && buf->b_ffname != NULL
2434 && buf->b_ffname[0] != NUL
2435 && !skip_for_viminfo(buf))
2436 {
2437 if (buflist == NULL)
2438 write_buffer_marks(buf, fp_out);
2439 else if (ga_grow(buflist, 1) == OK)
2440 ((buf_T **)buflist->ga_data)[buflist->ga_len++] = buf;
2441 }
2442 }
2443 }
2444 }
2445
2446 /*
2447 * Compare functions for qsort() below, that compares b_last_used.
2448 */
2449 static int
2450 buf_compare(const void *s1, const void *s2)
2451 {
2452 buf_T *buf1 = *(buf_T **)s1;
2453 buf_T *buf2 = *(buf_T **)s2;
2454
2455 if (buf1->b_last_used == buf2->b_last_used)
2456 return 0;
2457 return buf1->b_last_used > buf2->b_last_used ? -1 : 1;
2458 }
2459
2460 /*
2461 * Handle marks in the viminfo file:
2462 * fp_out != NULL: copy marks, in time order with buffers in "buflist".
2463 * fp_out == NULL && (flags & VIF_WANT_MARKS): read marks for curbuf only
2464 * fp_out == NULL && (flags & VIF_GET_OLDFILES | VIF_FORCEIT): fill v:oldfiles
2465 */
2466 void
2467 copy_viminfo_marks(
2468 vir_T *virp,
2469 FILE *fp_out,
2470 garray_T *buflist,
2471 int eof,
2472 int flags)
2473 {
2474 char_u *line = virp->vir_line;
2475 buf_T *buf;
2476 int num_marked_files;
2477 int load_marks;
2478 int copy_marks_out;
2479 char_u *str;
2480 int i;
2481 char_u *p;
2482 char_u *name_buf;
2483 pos_T pos;
2484 #ifdef FEAT_EVAL
2485 list_T *list = NULL;
2486 #endif
2487 int count = 0;
2488 int buflist_used = 0;
2489 buf_T *buflist_buf = NULL;
2490
2491 if ((name_buf = alloc(LSIZE)) == NULL)
2492 return;
2493 *name_buf = NUL;
2494
2495 if (fp_out != NULL && buflist->ga_len > 0)
2496 {
2497 // Sort the list of buffers on b_last_used.
2498 qsort(buflist->ga_data, (size_t)buflist->ga_len,
2499 sizeof(buf_T *), buf_compare);
2500 buflist_buf = ((buf_T **)buflist->ga_data)[0];
2501 }
2502
2503 #ifdef FEAT_EVAL
2504 if (fp_out == NULL && (flags & (VIF_GET_OLDFILES | VIF_FORCEIT)))
2505 {
2506 list = list_alloc();
2507 if (list != NULL)
2508 set_vim_var_list(VV_OLDFILES, list);
2509 }
2510 #endif
2511
2512 num_marked_files = get_viminfo_parameter('\'');
2513 while (!eof && (count < num_marked_files || fp_out == NULL))
2514 {
2515 if (line[0] != '>')
2516 {
2517 if (line[0] != '\n' && line[0] != '\r' && line[0] != '#')
2518 {
2519 if (viminfo_error("E576: ", _("Missing '>'"), line))
2520 break; // too many errors, return now
2521 }
2522 eof = vim_fgets(line, LSIZE, virp->vir_fd);
2523 continue; // Skip this dud line
2524 }
2525
2526 // Handle long line and translate escaped characters.
2527 // Find file name, set str to start.
2528 // Ignore leading and trailing white space.
2529 str = skipwhite(line + 1);
2530 str = viminfo_readstring(virp, (int)(str - virp->vir_line), FALSE);
2531 if (str == NULL)
2532 continue;
2533 p = str + STRLEN(str);
2534 while (p != str && (*p == NUL || vim_isspace(*p)))
2535 p--;
2536 if (*p)
2537 p++;
2538 *p = NUL;
2539
2540 #ifdef FEAT_EVAL
2541 if (list != NULL)
2542 list_append_string(list, str, -1);
2543 #endif
2544
2545 // If fp_out == NULL, load marks for current buffer.
2546 // If fp_out != NULL, copy marks for buffers not in buflist.
2547 load_marks = copy_marks_out = FALSE;
2548 if (fp_out == NULL)
2549 {
2550 if ((flags & VIF_WANT_MARKS) && curbuf->b_ffname != NULL)
2551 {
2552 if (*name_buf == NUL) // only need to do this once
2553 home_replace(NULL, curbuf->b_ffname, name_buf, LSIZE, TRUE);
2554 if (fnamecmp(str, name_buf) == 0)
2555 load_marks = TRUE;
2556 }
2557 }
2558 else // fp_out != NULL
2559 {
2560 // This is slow if there are many buffers!!
2561 FOR_ALL_BUFFERS(buf)
2562 if (buf->b_ffname != NULL)
2563 {
2564 home_replace(NULL, buf->b_ffname, name_buf, LSIZE, TRUE);
2565 if (fnamecmp(str, name_buf) == 0)
2566 break;
2567 }
2568
2569 // Copy marks if the buffer has not been loaded.
2570 if (buf == NULL || !buf->b_marks_read)
2571 {
2572 int did_read_line = FALSE;
2573
2574 if (buflist_buf != NULL)
2575 {
2576 // Read the next line. If it has the "*" mark compare the
2577 // time stamps. Write entries from "buflist" that are
2578 // newer.
2579 if (!(eof = viminfo_readline(virp)) && line[0] == TAB)
2580 {
2581 did_read_line = TRUE;
2582 if (line[1] == '*')
2583 {
2584 long ltime;
2585
2586 sscanf((char *)line + 2, "%ld ", &ltime);
2587 while ((time_T)ltime < buflist_buf->b_last_used)
2588 {
2589 write_buffer_marks(buflist_buf, fp_out);
2590 if (++count >= num_marked_files)
2591 break;
2592 if (++buflist_used == buflist->ga_len)
2593 {
2594 buflist_buf = NULL;
2595 break;
2596 }
2597 buflist_buf =
2598 ((buf_T **)buflist->ga_data)[buflist_used];
2599 }
2600 }
2601 else
2602 {
2603 // No timestamp, must be written by an older Vim.
2604 // Assume all remaining buffers are older then
2605 // ours.
2606 while (count < num_marked_files
2607 && buflist_used < buflist->ga_len)
2608 {
2609 buflist_buf = ((buf_T **)buflist->ga_data)
2610 [buflist_used++];
2611 write_buffer_marks(buflist_buf, fp_out);
2612 ++count;
2613 }
2614 buflist_buf = NULL;
2615 }
2616
2617 if (count >= num_marked_files)
2618 {
2619 vim_free(str);
2620 break;
2621 }
2622 }
2623 }
2624
2625 fputs("\n> ", fp_out);
2626 viminfo_writestring(fp_out, str);
2627 if (did_read_line)
2628 fputs((char *)line, fp_out);
2629
2630 count++;
2631 copy_marks_out = TRUE;
2632 }
2633 }
2634 vim_free(str);
2635
2636 pos.coladd = 0;
2637 while (!(eof = viminfo_readline(virp)) && line[0] == TAB)
2638 {
2639 if (load_marks)
2640 {
2641 if (line[1] != NUL)
2642 {
2643 unsigned u;
2644
2645 sscanf((char *)line + 2, "%ld %u", &pos.lnum, &u);
2646 pos.col = u;
2647 switch (line[1])
2648 {
2649 case '"': curbuf->b_last_cursor = pos; break;
2650 case '^': curbuf->b_last_insert = pos; break;
2651 case '.': curbuf->b_last_change = pos; break;
2652 case '+':
2653 #ifdef FEAT_JUMPLIST
2654 // changelist positions are stored oldest
2655 // first
2656 if (curbuf->b_changelistlen == JUMPLISTSIZE)
2657 // list is full, remove oldest entry
2658 mch_memmove(curbuf->b_changelist,
2659 curbuf->b_changelist + 1,
2660 sizeof(pos_T) * (JUMPLISTSIZE - 1));
2661 else
2662 ++curbuf->b_changelistlen;
2663 curbuf->b_changelist[
2664 curbuf->b_changelistlen - 1] = pos;
2665 #endif
2666 break;
2667
2668 // Using the line number for the last-used
2669 // timestamp.
2670 case '*': curbuf->b_last_used = pos.lnum; break;
2671
2672 default: if ((i = line[1] - 'a') >= 0 && i < NMARKS)
2673 curbuf->b_namedm[i] = pos;
2674 }
2675 }
2676 }
2677 else if (copy_marks_out)
2678 fputs((char *)line, fp_out);
2679 }
2680
2681 if (load_marks)
2682 {
2683 #ifdef FEAT_JUMPLIST
2684 win_T *wp;
2685
2686 FOR_ALL_WINDOWS(wp)
2687 {
2688 if (wp->w_buffer == curbuf)
2689 wp->w_changelistidx = curbuf->b_changelistlen;
2690 }
2691 #endif
2692 break;
2693 }
2694 }
2695
2696 if (fp_out != NULL)
2697 // Write any remaining entries from buflist.
2698 while (count < num_marked_files && buflist_used < buflist->ga_len)
2699 {
2700 buflist_buf = ((buf_T **)buflist->ga_data)[buflist_used++];
2701 write_buffer_marks(buflist_buf, fp_out);
2702 ++count;
2703 }
2704
2705 vim_free(name_buf);
2706 }
1911 #endif // FEAT_VIMINFO 2707 #endif // FEAT_VIMINFO