comparison src/ex_getln.c @ 4258:9945fe0536a3 v7.3.880

updated for version 7.3.880 Problem: When writing viminfo, old history lines may replace lines written more recently by another Vim instance. Solution: Mark history entries that were read from viminfo and overwrite them when merging with the current viminfo.
author Bram Moolenaar <bram@vim.org>
date Fri, 05 Apr 2013 18:58:47 +0200
parents edd0bc1f26bd
children 76aa34cef80f
comparison
equal deleted inserted replaced
4257:2ffb43ae7849 4258:9945fe0536a3
54 54
55 #ifdef FEAT_CMDHIST 55 #ifdef FEAT_CMDHIST
56 typedef struct hist_entry 56 typedef struct hist_entry
57 { 57 {
58 int hisnum; /* identifying number */ 58 int hisnum; /* identifying number */
59 int viminfo; /* when TRUE hisstr comes from viminfo */
59 char_u *hisstr; /* actual entry, separator char after the NUL */ 60 char_u *hisstr; /* actual entry, separator char after the NUL */
60 } histentry_T; 61 } histentry_T;
61 62
62 static histentry_T *(history[HIST_COUNT]) = {NULL, NULL, NULL, NULL, NULL}; 63 static histentry_T *(history[HIST_COUNT]) = {NULL, NULL, NULL, NULL, NULL};
63 static int hisidx[HIST_COUNT] = {-1, -1, -1, -1, -1}; /* lastused entry */ 64 static int hisidx[HIST_COUNT] = {-1, -1, -1, -1, -1}; /* lastused entry */
111 #ifdef FEAT_CMDL_COMPL 112 #ifdef FEAT_CMDL_COMPL
112 static int expand_shellcmd __ARGS((char_u *filepat, int *num_file, char_u ***file, int flagsarg)); 113 static int expand_shellcmd __ARGS((char_u *filepat, int *num_file, char_u ***file, int flagsarg));
113 static int ExpandRTDir __ARGS((char_u *pat, int *num_file, char_u ***file, char *dirname[])); 114 static int ExpandRTDir __ARGS((char_u *pat, int *num_file, char_u ***file, char *dirname[]));
114 # ifdef FEAT_CMDHIST 115 # ifdef FEAT_CMDHIST
115 static char_u *get_history_arg __ARGS((expand_T *xp, int idx)); 116 static char_u *get_history_arg __ARGS((expand_T *xp, int idx));
117 static void clear_hist_entry __ARGS((histentry_T *hisptr));
116 # endif 118 # endif
117 # if defined(FEAT_USR_CMDS) && defined(FEAT_EVAL) 119 # if defined(FEAT_USR_CMDS) && defined(FEAT_EVAL)
118 static int ExpandUserDefined __ARGS((expand_T *xp, regmatch_T *regmatch, int *num_file, char_u ***file)); 120 static int ExpandUserDefined __ARGS((expand_T *xp, regmatch_T *regmatch, int *num_file, char_u ***file));
119 static int ExpandUserList __ARGS((expand_T *xp, int *num_file, char_u ***file)); 121 static int ExpandUserList __ARGS((expand_T *xp, int *num_file, char_u ***file));
120 # endif 122 # endif
5341 if (newlen == 0 || temp != NULL) 5343 if (newlen == 0 || temp != NULL)
5342 { 5344 {
5343 if (hisidx[type] < 0) /* there are no entries yet */ 5345 if (hisidx[type] < 0) /* there are no entries yet */
5344 { 5346 {
5345 for (i = 0; i < newlen; ++i) 5347 for (i = 0; i < newlen; ++i)
5346 { 5348 clear_hist_entry(&temp[i]);
5347 temp[i].hisnum = 0;
5348 temp[i].hisstr = NULL;
5349 }
5350 } 5349 }
5351 else if (newlen > hislen) /* array becomes bigger */ 5350 else if (newlen > hislen) /* array becomes bigger */
5352 { 5351 {
5353 for (i = 0; i <= hisidx[type]; ++i) 5352 for (i = 0; i <= hisidx[type]; ++i)
5354 temp[i] = history[type][i]; 5353 temp[i] = history[type][i];
5355 j = i; 5354 j = i;
5356 for ( ; i <= newlen - (hislen - hisidx[type]); ++i) 5355 for ( ; i <= newlen - (hislen - hisidx[type]); ++i)
5357 { 5356 clear_hist_entry(&temp[i]);
5358 temp[i].hisnum = 0;
5359 temp[i].hisstr = NULL;
5360 }
5361 for ( ; j < hislen; ++i, ++j) 5357 for ( ; j < hislen; ++i, ++j)
5362 temp[i] = history[type][j]; 5358 temp[i] = history[type][j];
5363 } 5359 }
5364 else /* array becomes smaller or 0 */ 5360 else /* array becomes smaller or 0 */
5365 { 5361 {
5383 } 5379 }
5384 hislen = newlen; 5380 hislen = newlen;
5385 } 5381 }
5386 } 5382 }
5387 5383
5384 static void
5385 clear_hist_entry(hisptr)
5386 histentry_T *hisptr;
5387 {
5388 hisptr->hisnum = 0;
5389 hisptr->viminfo = FALSE;
5390 hisptr->hisstr = NULL;
5391 }
5392
5388 /* 5393 /*
5389 * Check if command line 'str' is already in history. 5394 * Check if command line 'str' is already in history.
5390 * If 'move_to_front' is TRUE, matching entry is moved to end of history. 5395 * If 'move_to_front' is TRUE, matching entry is moved to end of history.
5391 */ 5396 */
5392 static int 5397 static int
5431 if (++i >= hislen) 5436 if (++i >= hislen)
5432 i = 0; 5437 i = 0;
5433 history[type][last_i] = history[type][i]; 5438 history[type][last_i] = history[type][i];
5434 last_i = i; 5439 last_i = i;
5435 } 5440 }
5441 history[type][i].hisnum = ++hisnum[type];
5442 history[type][i].viminfo = FALSE;
5436 history[type][i].hisstr = str; 5443 history[type][i].hisstr = str;
5437 history[type][i].hisnum = ++hisnum[type];
5438 return TRUE; 5444 return TRUE;
5439 } 5445 }
5440 return FALSE; 5446 return FALSE;
5441 } 5447 }
5442 5448
5496 if (maptick == last_maptick) 5502 if (maptick == last_maptick)
5497 { 5503 {
5498 /* Current line is from the same mapping, remove it */ 5504 /* Current line is from the same mapping, remove it */
5499 hisptr = &history[HIST_SEARCH][hisidx[HIST_SEARCH]]; 5505 hisptr = &history[HIST_SEARCH][hisidx[HIST_SEARCH]];
5500 vim_free(hisptr->hisstr); 5506 vim_free(hisptr->hisstr);
5501 hisptr->hisstr = NULL; 5507 clear_hist_entry(hisptr);
5502 hisptr->hisnum = 0;
5503 --hisnum[histype]; 5508 --hisnum[histype];
5504 if (--hisidx[HIST_SEARCH] < 0) 5509 if (--hisidx[HIST_SEARCH] < 0)
5505 hisidx[HIST_SEARCH] = hislen - 1; 5510 hisidx[HIST_SEARCH] = hislen - 1;
5506 } 5511 }
5507 last_maptick = -1; 5512 last_maptick = -1;
5518 hisptr->hisstr = vim_strnsave(new_entry, len + 2); 5523 hisptr->hisstr = vim_strnsave(new_entry, len + 2);
5519 if (hisptr->hisstr != NULL) 5524 if (hisptr->hisstr != NULL)
5520 hisptr->hisstr[len + 1] = sep; 5525 hisptr->hisstr[len + 1] = sep;
5521 5526
5522 hisptr->hisnum = ++hisnum[histype]; 5527 hisptr->hisnum = ++hisnum[histype];
5528 hisptr->viminfo = FALSE;
5523 if (histype == HIST_SEARCH && in_map) 5529 if (histype == HIST_SEARCH && in_map)
5524 last_maptick = maptick; 5530 last_maptick = maptick;
5525 } 5531 }
5526 } 5532 }
5527 5533
5707 { 5713 {
5708 hisptr = history[histype]; 5714 hisptr = history[histype];
5709 for (i = hislen; i--;) 5715 for (i = hislen; i--;)
5710 { 5716 {
5711 vim_free(hisptr->hisstr); 5717 vim_free(hisptr->hisstr);
5712 hisptr->hisnum = 0; 5718 clear_hist_entry(hisptr);
5713 hisptr++->hisstr = NULL;
5714 } 5719 }
5715 hisidx[histype] = -1; /* mark history as cleared */ 5720 hisidx[histype] = -1; /* mark history as cleared */
5716 hisnum[histype] = 0; /* reset identifier counter */ 5721 hisnum[histype] = 0; /* reset identifier counter */
5717 return OK; 5722 return OK;
5718 } 5723 }
5753 break; 5758 break;
5754 if (vim_regexec(&regmatch, hisptr->hisstr, (colnr_T)0)) 5759 if (vim_regexec(&regmatch, hisptr->hisstr, (colnr_T)0))
5755 { 5760 {
5756 found = TRUE; 5761 found = TRUE;
5757 vim_free(hisptr->hisstr); 5762 vim_free(hisptr->hisstr);
5758 hisptr->hisstr = NULL; 5763 clear_hist_entry(hisptr);
5759 hisptr->hisnum = 0;
5760 } 5764 }
5761 else 5765 else
5762 { 5766 {
5763 if (i != last) 5767 if (i != last)
5764 { 5768 {
5765 history[histype][last] = *hisptr; 5769 history[histype][last] = *hisptr;
5766 hisptr->hisstr = NULL; 5770 clear_hist_entry(hisptr);
5767 hisptr->hisnum = 0;
5768 } 5771 }
5769 if (--last < 0) 5772 if (--last < 0)
5770 last += hislen; 5773 last += hislen;
5771 } 5774 }
5772 if (--i < 0) 5775 if (--i < 0)
5806 { 5809 {
5807 j = (i + 1) % hislen; 5810 j = (i + 1) % hislen;
5808 history[histype][i] = history[histype][j]; 5811 history[histype][i] = history[histype][j];
5809 i = j; 5812 i = j;
5810 } 5813 }
5811 history[histype][i].hisstr = NULL; 5814 clear_hist_entry(&history[histype][i]);
5812 history[histype][i].hisnum = 0;
5813 if (--i < 0) 5815 if (--i < 0)
5814 i += hislen; 5816 i += hislen;
5815 hisidx[histype] = i; 5817 hisidx[histype] = i;
5816 return TRUE; 5818 return TRUE;
5817 } 5819 }
6041 if (asklen > hislen) 6043 if (asklen > hislen)
6042 asklen = hislen; 6044 asklen = hislen;
6043 6045
6044 for (type = 0; type < HIST_COUNT; ++type) 6046 for (type = 0; type < HIST_COUNT; ++type)
6045 { 6047 {
6046 /* 6048 /* Count the number of empty spaces in the history list. Entries read
6047 * Count the number of empty spaces in the history list. If there are 6049 * from viminfo previously are also considered empty. If there are
6048 * more spaces available than we request, then fill them up. 6050 * more spaces available than we request, then fill them up. */
6049 */
6050 for (i = 0, num = 0; i < hislen; i++) 6051 for (i = 0, num = 0; i < hislen; i++)
6051 if (history[type][i].hisstr == NULL) 6052 if (history[type][i].hisstr == NULL || history[type][i].viminfo)
6052 num++; 6053 num++;
6053 len = asklen; 6054 len = asklen;
6054 if (num > len) 6055 if (num > len)
6055 len = num; 6056 len = num;
6056 if (len <= 0) 6057 if (len <= 0)
6139 { 6140 {
6140 if (hisidx[type] == -1) 6141 if (hisidx[type] == -1)
6141 hisidx[type] = hislen - 1; 6142 hisidx[type] = hislen - 1;
6142 do 6143 do
6143 { 6144 {
6144 if (history[type][idx].hisstr != NULL) 6145 if (history[type][idx].hisstr != NULL
6146 || history[type][idx].viminfo)
6145 break; 6147 break;
6146 if (++idx == hislen) 6148 if (++idx == hislen)
6147 idx = 0; 6149 idx = 0;
6148 } while (idx != hisidx[type]); 6150 } while (idx != hisidx[type]);
6149 if (idx != hisidx[type] && --idx < 0) 6151 if (idx != hisidx[type] && --idx < 0)
6151 } 6153 }
6152 for (i = 0; i < viminfo_hisidx[type]; i++) 6154 for (i = 0; i < viminfo_hisidx[type]; i++)
6153 { 6155 {
6154 vim_free(history[type][idx].hisstr); 6156 vim_free(history[type][idx].hisstr);
6155 history[type][idx].hisstr = viminfo_history[type][i]; 6157 history[type][idx].hisstr = viminfo_history[type][i];
6158 history[type][idx].viminfo = TRUE;
6156 if (--idx < 0) 6159 if (--idx < 0)
6157 idx = hislen - 1; 6160 idx = hislen - 1;
6158 } 6161 }
6159 idx += 1; 6162 idx += 1;
6160 idx %= hislen; 6163 idx %= hislen;