To: vim_dev@googlegroups.com Subject: Patch 8.1.0877 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 8.1.0877 Problem: New buffer used every time the quickfix window is opened. Solution: Reuse the buffer. (Yegappan Lakshmanan, closes #3902) Files: src/buffer.c, src/proto/quickfix.pro, src/quickfix.c, src/testdir/test_quickfix.vim *** ../vim-8.1.0876/src/buffer.c 2019-01-26 17:28:22.220599167 +0100 --- src/buffer.c 2019-02-05 20:49:04.364708960 +0100 *************** *** 5753,5769 **** #if defined(FEAT_QUICKFIX) if (bt_quickfix(buf)) { - win_T *win; - tabpage_T *tp; - /* ! * For location list window, w_llist_ref points to the location list. ! * For quickfix window, w_llist_ref is NULL. */ ! if (find_win_for_buf(buf, &win, &tp) == OK && win->w_llist_ref != NULL) ! return (char_u *)_(msg_loclist); ! else return (char_u *)_(msg_qflist); } #endif --- 5753,5766 ---- #if defined(FEAT_QUICKFIX) if (bt_quickfix(buf)) { /* ! * Differentiate between the quickfix and location list buffers using ! * the buffer number stored in the global quickfix stack. */ ! if (buf->b_fnum == qf_stack_get_bufnr()) return (char_u *)_(msg_qflist); + else + return (char_u *)_(msg_loclist); } #endif *** ../vim-8.1.0876/src/proto/quickfix.pro 2018-11-11 22:50:20.806297851 +0100 --- src/proto/quickfix.pro 2019-02-05 20:49:04.364708960 +0100 *************** *** 1,5 **** --- 1,6 ---- /* quickfix.c */ int qf_init(win_T *wp, char_u *efile, char_u *errorformat, int newlist, char_u *qf_title, char_u *enc); + int qf_stack_get_bufnr(void); void qf_free_all(win_T *wp); void check_quickfix_busy(void); void copy_loclist_stack(win_T *from, win_T *to); *** ../vim-8.1.0876/src/quickfix.c 2019-01-31 14:27:01.238142723 +0100 --- src/quickfix.c 2019-02-05 20:49:04.364708960 +0100 *************** *** 48,53 **** --- 48,54 ---- */ #define LISTCOUNT 10 #define INVALID_QFIDX (-1) + #define INVALID_QFBUFNR (0) /* * Quickfix list type. *************** *** 107,112 **** --- 108,114 ---- int qf_curlist; // current error list qf_list_T qf_lists[LISTCOUNT]; qfltype_T qfl_type; // type of list + int qf_bufnr; // quickfix window buffer number }; static qf_info_T ql_info; // global quickfix list *************** *** 1853,1858 **** --- 1855,1891 ---- } /* + * Return the global quickfix stack window buffer number. + */ + int + qf_stack_get_bufnr(void) + { + return ql_info.qf_bufnr; + } + + /* + * Wipe the quickfix window buffer (if present) for the specified + * quickfix/location list. + */ + static void + wipe_qf_buffer(qf_info_T *qi) + { + buf_T *qfbuf; + + if (qi->qf_bufnr != INVALID_QFBUFNR) + { + qfbuf = buflist_findnr(qi->qf_bufnr); + if (qfbuf != NULL && qfbuf->b_nwindows == 0) + { + // If the quickfix buffer is not loaded in any window, then + // wipe the buffer. + close_buffer(NULL, qfbuf, DOBUF_WIPE, FALSE); + qi->qf_bufnr = INVALID_QFBUFNR; + } + } + } + + /* * Free a location list stack */ static void *************** *** 1876,1881 **** --- 1909,1917 ---- locstack_queue_delreq(qi); else { + // If the quickfix window buffer is loaded, then wipe it + wipe_qf_buffer(qi); + for (i = 0; i < qi->qf_listcount; ++i) qf_free(&qi->qf_lists[i]); vim_free(qi); *************** *** 2066,2071 **** --- 2102,2108 ---- { qi->qf_refcount++; qi->qfl_type = qfltype; + qi->qf_bufnr = INVALID_QFBUFNR; } return qi; } *************** *** 2741,2747 **** } /* ! * Find a non-quickfix window using the given location list. * Returns NULL if a matching window is not found. */ static win_T * --- 2778,2785 ---- } /* ! * Find a non-quickfix window in the current tabpage using the given location ! * list stack. * Returns NULL if a matching window is not found. */ static win_T * *************** *** 3988,3994 **** set_option_value((char_u *)"swf", 0L, NULL, OPT_LOCAL); set_option_value((char_u *)"bt", 0L, (char_u *)"quickfix", OPT_LOCAL); ! set_option_value((char_u *)"bh", 0L, (char_u *)"wipe", OPT_LOCAL); RESET_BINDING(curwin); #ifdef FEAT_DIFF curwin->w_p_diff = FALSE; --- 4026,4032 ---- set_option_value((char_u *)"swf", 0L, NULL, OPT_LOCAL); set_option_value((char_u *)"bt", 0L, (char_u *)"quickfix", OPT_LOCAL); ! set_option_value((char_u *)"bh", 0L, (char_u *)"hide", OPT_LOCAL); RESET_BINDING(curwin); #ifdef FEAT_DIFF curwin->w_p_diff = FALSE; *************** *** 3997,4002 **** --- 4035,4042 ---- set_option_value((char_u *)"fdm", 0L, (char_u *)"manual", OPT_LOCAL); #endif + // save the number of the new buffer + qi->qf_bufnr = curbuf->b_fnum; } // Only set the height when still in the same tab page and there is no *************** *** 4212,4217 **** --- 4252,4267 ---- tabpage_T *tp; win_T *win; + if (qi->qf_bufnr != INVALID_QFBUFNR) + { + buf_T *qfbuf; + qfbuf = buflist_findnr(qi->qf_bufnr); + if (qfbuf != NULL) + return qfbuf; + // buffer is no longer present + qi->qf_bufnr = INVALID_QFBUFNR; + } + FOR_ALL_TAB_WINDOWS(tp, win) if (is_qf_win(win, qi)) return win->w_buffer; *************** *** 6581,6602 **** } /* - * Find the non-location list window with the specified location list stack in - * the current tabpage. - */ - static win_T * - find_win_with_ll(qf_info_T *qi) - { - win_T *wp = NULL; - - FOR_ALL_WINDOWS(wp) - if ((wp->w_llist == qi) && !bt_quickfix(wp->w_buffer)) - return wp; - - return NULL; - } - - /* * Free the entire quickfix/location list stack. * If the quickfix/location list window is open, then clear it. */ --- 6631,6636 ---- *************** *** 6605,6611 **** { win_T *qfwin = qf_find_win(qi); win_T *llwin = NULL; - win_T *orig_wp = wp; if (qfwin != NULL) { --- 6639,6644 ---- *************** *** 6619,6625 **** { // If in the location list window, then use the non-location list // window with this location list (if present) ! llwin = find_win_with_ll(qi); if (llwin != NULL) wp = llwin; } --- 6652,6658 ---- { // If in the location list window, then use the non-location list // window with this location list (if present) ! llwin = qf_find_win_with_loclist(qi); if (llwin != NULL) wp = llwin; } *************** *** 6631,6649 **** qi->qf_curlist = 0; qi->qf_listcount = 0; } ! else if (IS_LL_WINDOW(orig_wp)) { // If the location list window is open, then create a new empty // location list qf_info_T *new_ll = qf_alloc_stack(QFLT_LOCATION); // first free the list reference in the location list window ! ll_free_all(&orig_wp->w_llist_ref); ! orig_wp->w_llist_ref = new_ll; ! if (llwin != NULL) { ! llwin->w_llist = new_ll; new_ll->qf_refcount++; } } --- 6664,6683 ---- qi->qf_curlist = 0; qi->qf_listcount = 0; } ! else if (qfwin != NULL) { // If the location list window is open, then create a new empty // location list qf_info_T *new_ll = qf_alloc_stack(QFLT_LOCATION); + new_ll->qf_bufnr = qfwin->w_buffer->b_fnum; // first free the list reference in the location list window ! ll_free_all(&qfwin->w_llist_ref); ! qfwin->w_llist_ref = new_ll; ! if (wp != qfwin) { ! wp->w_llist = new_ll; new_ll->qf_refcount++; } } *** ../vim-8.1.0876/src/testdir/test_quickfix.vim 2019-01-31 14:27:01.238142723 +0100 --- src/testdir/test_quickfix.vim 2019-02-05 20:49:04.364708960 +0100 *************** *** 3899,3901 **** --- 3899,3944 ---- set efm& call delete('Xfile1') endfunc + + " Test for the quickfix window buffer + func Xqfbuf_test(cchar) + call s:setup_commands(a:cchar) + + " Quickfix buffer should be reused across closing and opening a quickfix + " window + Xexpr "F1:10:Line10" + Xopen + let qfbnum = bufnr('') + Xclose + " Even after the quickfix window is closed, the buffer should be loaded + call assert_true(bufloaded(qfbnum)) + Xopen + " Buffer should be reused when opening the window again + call assert_equal(qfbnum, bufnr('')) + Xclose + + if a:cchar == 'l' + %bwipe + " For a location list, when both the file window and the location list + " window for the list are closed, then the buffer should be freed. + new | only + lexpr "F1:10:Line10" + let wid = win_getid() + lopen + let qfbnum = bufnr('') + call assert_match(qfbnum . ' %a- "\[Location List]"', execute('ls')) + close + " When the location list window is closed, the buffer name should not + " change to 'Quickfix List' + call assert_match(qfbnum . ' h- "\[Location List]"', execute('ls')) + call assert_true(bufloaded(qfbnum)) + + new | only + call assert_false(bufloaded(qfbnum)) + endif + endfunc + + func Test_qfbuf() + call Xqfbuf_test('c') + call Xqfbuf_test('l') + endfunc *** ../vim-8.1.0876/src/version.c 2019-02-05 20:11:57.355368329 +0100 --- src/version.c 2019-02-05 20:45:38.242078612 +0100 *************** *** 785,786 **** --- 785,788 ---- { /* Add new patch number below this line */ + /**/ + 877, /**/ -- To the optimist, the glass is half full. To the pessimist, the glass is half empty. To the engineer, the glass is twice as big as it needs to be. /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ /// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\ \\\ an exciting new programming language -- http://www.Zimbu.org /// \\\ help me help AIDS victims -- http://ICCF-Holland.org ///