Mercurial > vim
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(®match, hisptr->hisstr, (colnr_T)0)) | 5759 if (vim_regexec(®match, 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; |