Mercurial > vim
comparison src/buffer.c @ 17823:7e6b7a4f13bc v8.1.1908
patch 8.1.1908: every popup window consumes a buffer number
Commit: https://github.com/vim/vim/commit/00b0d6d8dc2c04b3cb26ea3c3d58527939f01af6
Author: Bram Moolenaar <Bram@vim.org>
Date: Wed Aug 21 22:25:30 2019 +0200
patch 8.1.1908: every popup window consumes a buffer number
Problem: Every popup window consumes a buffer number.
Solution: Recycle buffers only used for popup windows. Do not list popup
window buffers.
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Wed, 21 Aug 2019 22:30:04 +0200 |
parents | 59f8948b7590 |
children | bb0e25a8b5d7 |
comparison
equal
deleted
inserted
replaced
17822:cde49c54b3f0 | 17823:7e6b7a4f13bc |
---|---|
60 static char *msg_loclist = N_("[Location List]"); | 60 static char *msg_loclist = N_("[Location List]"); |
61 static char *msg_qflist = N_("[Quickfix List]"); | 61 static char *msg_qflist = N_("[Quickfix List]"); |
62 #endif | 62 #endif |
63 static char *e_auabort = N_("E855: Autocommands caused command to abort"); | 63 static char *e_auabort = N_("E855: Autocommands caused command to abort"); |
64 | 64 |
65 /* Number of times free_buffer() was called. */ | 65 // Number of times free_buffer() was called. |
66 static int buf_free_count = 0; | 66 static int buf_free_count = 0; |
67 | |
68 static int top_file_num = 1; // highest file number | |
69 static garray_T buf_reuse = GA_EMPTY; // file numbers to recycle | |
70 | |
71 /* | |
72 * Return the highest possible buffer number. | |
73 */ | |
74 int | |
75 get_highest_fnum(void) | |
76 { | |
77 return top_file_num - 1; | |
78 } | |
67 | 79 |
68 /* | 80 /* |
69 * Read data from buffer for retrying. | 81 * Read data from buffer for retrying. |
70 */ | 82 */ |
71 static int | 83 static int |
468 * It can be: | 480 * It can be: |
469 * 0 buffer becomes hidden | 481 * 0 buffer becomes hidden |
470 * DOBUF_UNLOAD buffer is unloaded | 482 * DOBUF_UNLOAD buffer is unloaded |
471 * DOBUF_DELETE buffer is unloaded and removed from buffer list | 483 * DOBUF_DELETE buffer is unloaded and removed from buffer list |
472 * DOBUF_WIPE buffer is unloaded and really deleted | 484 * DOBUF_WIPE buffer is unloaded and really deleted |
485 * DOBUF_WIPE_REUSE idem, and add to buf_reuse list | |
473 * When doing all but the first one on the current buffer, the caller should | 486 * When doing all but the first one on the current buffer, the caller should |
474 * get a new buffer very soon! | 487 * get a new buffer very soon! |
475 * | 488 * |
476 * The 'bufhidden' option can force freeing and deleting. | 489 * The 'bufhidden' option can force freeing and deleting. |
477 * | 490 * |
491 bufref_T bufref; | 504 bufref_T bufref; |
492 int is_curwin = (curwin != NULL && curwin->w_buffer == buf); | 505 int is_curwin = (curwin != NULL && curwin->w_buffer == buf); |
493 win_T *the_curwin = curwin; | 506 win_T *the_curwin = curwin; |
494 tabpage_T *the_curtab = curtab; | 507 tabpage_T *the_curtab = curtab; |
495 int unload_buf = (action != 0); | 508 int unload_buf = (action != 0); |
496 int del_buf = (action == DOBUF_DEL || action == DOBUF_WIPE); | 509 int wipe_buf = (action == DOBUF_WIPE || action == DOBUF_WIPE_REUSE); |
497 int wipe_buf = (action == DOBUF_WIPE); | 510 int del_buf = (action == DOBUF_DEL || wipe_buf); |
498 | 511 |
499 /* | 512 /* |
500 * Force unloading or deleting when 'bufhidden' says so. | 513 * Force unloading or deleting when 'bufhidden' says so. |
501 * The caller must take care of NOT deleting/freeing when 'bufhidden' is | 514 * The caller must take care of NOT deleting/freeing when 'bufhidden' is |
502 * "hide" (otherwise we could never free or delete a buffer). | 515 * "hide" (otherwise we could never free or delete a buffer). |
684 /* | 697 /* |
685 * Remove the buffer from the list. | 698 * Remove the buffer from the list. |
686 */ | 699 */ |
687 if (wipe_buf) | 700 if (wipe_buf) |
688 { | 701 { |
702 if (action == DOBUF_WIPE_REUSE) | |
703 { | |
704 // we can re-use this buffer number, store it | |
705 if (buf_reuse.ga_itemsize == 0) | |
706 ga_init2(&buf_reuse, sizeof(int), 50); | |
707 if (ga_grow(&buf_reuse, 1) == OK) | |
708 ((int *)buf_reuse.ga_data)[buf_reuse.ga_len++] = buf->b_fnum; | |
709 } | |
689 if (buf->b_sfname != buf->b_ffname) | 710 if (buf->b_sfname != buf->b_ffname) |
690 VIM_CLEAR(buf->b_sfname); | 711 VIM_CLEAR(buf->b_sfname); |
691 else | 712 else |
692 buf->b_sfname = NULL; | 713 buf->b_sfname = NULL; |
693 VIM_CLEAR(buf->b_ffname); | 714 VIM_CLEAR(buf->b_ffname); |
1182 if (*arg == NUL) | 1203 if (*arg == NUL) |
1183 break; | 1204 break; |
1184 if (!VIM_ISDIGIT(*arg)) | 1205 if (!VIM_ISDIGIT(*arg)) |
1185 { | 1206 { |
1186 p = skiptowhite_esc(arg); | 1207 p = skiptowhite_esc(arg); |
1187 bnr = buflist_findpat(arg, p, command == DOBUF_WIPE, | 1208 bnr = buflist_findpat(arg, p, |
1209 command == DOBUF_WIPE || command == DOBUF_WIPE_REUSE, | |
1188 FALSE, FALSE); | 1210 FALSE, FALSE); |
1189 if (bnr < 0) /* failed */ | 1211 if (bnr < 0) /* failed */ |
1190 break; | 1212 break; |
1191 arg = p; | 1213 arg = p; |
1192 } | 1214 } |
1273 * action == DOBUF_GOTO go to specified buffer | 1295 * action == DOBUF_GOTO go to specified buffer |
1274 * action == DOBUF_SPLIT split window and go to specified buffer | 1296 * action == DOBUF_SPLIT split window and go to specified buffer |
1275 * action == DOBUF_UNLOAD unload specified buffer(s) | 1297 * action == DOBUF_UNLOAD unload specified buffer(s) |
1276 * action == DOBUF_DEL delete specified buffer(s) from buffer list | 1298 * action == DOBUF_DEL delete specified buffer(s) from buffer list |
1277 * action == DOBUF_WIPE delete specified buffer(s) really | 1299 * action == DOBUF_WIPE delete specified buffer(s) really |
1300 * action == DOBUF_WIPE_REUSE idem, and add number to "buf_reuse" | |
1278 * | 1301 * |
1279 * start == DOBUF_CURRENT go to "count" buffer from current buffer | 1302 * start == DOBUF_CURRENT go to "count" buffer from current buffer |
1280 * start == DOBUF_FIRST go to "count" buffer from first buffer | 1303 * start == DOBUF_FIRST go to "count" buffer from first buffer |
1281 * start == DOBUF_LAST go to "count" buffer from last buffer | 1304 * start == DOBUF_LAST go to "count" buffer from last buffer |
1282 * start == DOBUF_MOD go to "count" modified buffer from current buffer | 1305 * start == DOBUF_MOD go to "count" modified buffer from current buffer |
1292 int forceit) /* TRUE for :...! */ | 1315 int forceit) /* TRUE for :...! */ |
1293 { | 1316 { |
1294 buf_T *buf; | 1317 buf_T *buf; |
1295 buf_T *bp; | 1318 buf_T *bp; |
1296 int unload = (action == DOBUF_UNLOAD || action == DOBUF_DEL | 1319 int unload = (action == DOBUF_UNLOAD || action == DOBUF_DEL |
1297 || action == DOBUF_WIPE); | 1320 || action == DOBUF_WIPE || action == DOBUF_WIPE_REUSE); |
1298 | 1321 |
1299 switch (start) | 1322 switch (start) |
1300 { | 1323 { |
1301 case DOBUF_FIRST: buf = firstbuf; break; | 1324 case DOBUF_FIRST: buf = firstbuf; break; |
1302 case DOBUF_LAST: buf = lastbuf; break; | 1325 case DOBUF_LAST: buf = lastbuf; break; |
1393 | 1416 |
1394 set_bufref(&bufref, buf); | 1417 set_bufref(&bufref, buf); |
1395 | 1418 |
1396 /* When unloading or deleting a buffer that's already unloaded and | 1419 /* When unloading or deleting a buffer that's already unloaded and |
1397 * unlisted: fail silently. */ | 1420 * unlisted: fail silently. */ |
1398 if (action != DOBUF_WIPE && buf->b_ml.ml_mfp == NULL && !buf->b_p_bl) | 1421 if (action != DOBUF_WIPE && action != DOBUF_WIPE_REUSE |
1422 && buf->b_ml.ml_mfp == NULL && !buf->b_p_bl) | |
1399 return FAIL; | 1423 return FAIL; |
1400 | 1424 |
1401 if (!forceit && bufIsChanged(buf)) | 1425 if (!forceit && bufIsChanged(buf)) |
1402 { | 1426 { |
1403 #if defined(FEAT_GUI_DIALOG) || defined(FEAT_CON_DIALOG) | 1427 #if defined(FEAT_GUI_DIALOG) || defined(FEAT_CON_DIALOG) |
1629 * DOBUF_GOTO free or hide it | 1653 * DOBUF_GOTO free or hide it |
1630 * DOBUF_SPLIT nothing | 1654 * DOBUF_SPLIT nothing |
1631 * DOBUF_UNLOAD unload it | 1655 * DOBUF_UNLOAD unload it |
1632 * DOBUF_DEL delete it | 1656 * DOBUF_DEL delete it |
1633 * DOBUF_WIPE wipe it out | 1657 * DOBUF_WIPE wipe it out |
1658 * DOBUF_WIPE_REUSE wipe it out and add to "buf_reuse" | |
1634 */ | 1659 */ |
1635 void | 1660 void |
1636 set_curbuf(buf_T *buf, int action) | 1661 set_curbuf(buf_T *buf, int action) |
1637 { | 1662 { |
1638 buf_T *prevbuf; | 1663 buf_T *prevbuf; |
1639 int unload = (action == DOBUF_UNLOAD || action == DOBUF_DEL | 1664 int unload = (action == DOBUF_UNLOAD || action == DOBUF_DEL |
1640 || action == DOBUF_WIPE); | 1665 || action == DOBUF_WIPE || action == DOBUF_WIPE_REUSE); |
1641 #ifdef FEAT_SYN_HL | 1666 #ifdef FEAT_SYN_HL |
1642 long old_tw = curbuf->b_p_tw; | 1667 long old_tw = curbuf->b_p_tw; |
1643 #endif | 1668 #endif |
1644 bufref_T newbufref; | 1669 bufref_T newbufref; |
1645 bufref_T prevbufref; | 1670 bufref_T prevbufref; |
1859 | 1884 |
1860 /* | 1885 /* |
1861 * functions for dealing with the buffer list | 1886 * functions for dealing with the buffer list |
1862 */ | 1887 */ |
1863 | 1888 |
1864 static int top_file_num = 1; /* highest file number */ | |
1865 | |
1866 /* | 1889 /* |
1867 * Return TRUE if the current buffer is empty, unnamed, unmodified and used in | 1890 * Return TRUE if the current buffer is empty, unnamed, unmodified and used in |
1868 * only one window. That means it can be re-used. | 1891 * only one window. That means it can be re-used. |
1869 */ | 1892 */ |
1870 int | 1893 int |
1888 * If (flags & BLN_LISTED) is TRUE, add new buffer to buffer list. | 1911 * If (flags & BLN_LISTED) is TRUE, add new buffer to buffer list. |
1889 * If (flags & BLN_DUMMY) is TRUE, don't count it as a real buffer. | 1912 * If (flags & BLN_DUMMY) is TRUE, don't count it as a real buffer. |
1890 * If (flags & BLN_NEW) is TRUE, don't use an existing buffer. | 1913 * If (flags & BLN_NEW) is TRUE, don't use an existing buffer. |
1891 * If (flags & BLN_NOOPT) is TRUE, don't copy options from the current buffer | 1914 * If (flags & BLN_NOOPT) is TRUE, don't copy options from the current buffer |
1892 * if the buffer already exists. | 1915 * if the buffer already exists. |
1916 * If (flags & BLN_REUSE) is TRUE, may use buffer number from "buf_reuse". | |
1893 * This is the ONLY way to create a new buffer. | 1917 * This is the ONLY way to create a new buffer. |
1894 */ | 1918 */ |
1895 buf_T * | 1919 buf_T * |
1896 buflist_new( | 1920 buflist_new( |
1897 char_u *ffname_arg, // full path of fname or relative | 1921 char_u *ffname_arg, // full path of fname or relative |
2063 lastbuf->b_next = buf; | 2087 lastbuf->b_next = buf; |
2064 buf->b_prev = lastbuf; | 2088 buf->b_prev = lastbuf; |
2065 } | 2089 } |
2066 lastbuf = buf; | 2090 lastbuf = buf; |
2067 | 2091 |
2068 buf->b_fnum = top_file_num++; | 2092 if ((flags & BLN_REUSE) && buf_reuse.ga_len > 0) |
2093 { | |
2094 // Recycle a previously used buffer number. Used for buffers which | |
2095 // are normally hidden, e.g. in a popup window. Avoids that the | |
2096 // buffer number grows rapidly. | |
2097 --buf_reuse.ga_len; | |
2098 buf->b_fnum = ((int *)buf_reuse.ga_data)[buf_reuse.ga_len]; | |
2099 } | |
2100 else | |
2101 buf->b_fnum = top_file_num++; | |
2069 if (top_file_num < 0) /* wrap around (may cause duplicates) */ | 2102 if (top_file_num < 0) /* wrap around (may cause duplicates) */ |
2070 { | 2103 { |
2071 emsg(_("W14: Warning: List of file names overflow")); | 2104 emsg(_("W14: Warning: List of file names overflow")); |
2072 if (emsg_silent == 0) | 2105 if (emsg_silent == 0) |
2073 { | 2106 { |