0
0
mirror of https://github.com/vim/vim.git synced 2025-09-23 03:43:49 -04:00

patch 8.1.0523: opening window from quickfix leaves empty buffer behind

Problem:    Opening window from quickfix leaves empty buffer behind.
Solution:   Add qf_jump_newwin(). (Yegappan Lakshmanan, closes #2574)
This commit is contained in:
Bram Moolenaar
2018-11-11 22:50:27 +01:00
parent f3aea59afa
commit b244373bec
4 changed files with 107 additions and 31 deletions

View File

@@ -4,6 +4,7 @@ void qf_free_all(win_T *wp);
void check_quickfix_busy(void); void check_quickfix_busy(void);
void copy_loclist_stack(win_T *from, win_T *to); void copy_loclist_stack(win_T *from, win_T *to);
void qf_jump(qf_info_T *qi, int dir, int errornr, int forceit); void qf_jump(qf_info_T *qi, int dir, int errornr, int forceit);
void qf_jump_newwin(qf_info_T *qi, int dir, int errornr, int forceit, int newwin);
void qf_list(exarg_T *eap); void qf_list(exarg_T *eap);
void qf_age(exarg_T *eap); void qf_age(exarg_T *eap);
void qf_history(exarg_T *eap); void qf_history(exarg_T *eap);

View File

@@ -2699,15 +2699,16 @@ qf_find_help_win(void)
} }
/* /*
* Find a help window or open one. * Find a help window or open one. If 'newwin' is TRUE, then open a new help
* window.
*/ */
static int static int
jump_to_help_window(qf_info_T *qi, int *opened_window) jump_to_help_window(qf_info_T *qi, int newwin, int *opened_window)
{ {
win_T *wp; win_T *wp;
int flags; int flags;
if (cmdmod.tab != 0) if (cmdmod.tab != 0 || newwin)
wp = NULL; wp = NULL;
else else
wp = qf_find_help_win(); wp = qf_find_help_win();
@@ -2721,8 +2722,10 @@ jump_to_help_window(qf_info_T *qi, int *opened_window)
if (cmdmod.split == 0 && curwin->w_width != Columns if (cmdmod.split == 0 && curwin->w_width != Columns
&& curwin->w_width < 80) && curwin->w_width < 80)
flags |= WSP_TOP; flags |= WSP_TOP;
if (IS_LL_STACK(qi)) // If the user asks to open a new window, then copy the location list.
flags |= WSP_NEWLOC; // don't copy the location list // Otherwise, don't copy the location list.
if (IS_LL_STACK(qi) && !newwin)
flags |= WSP_NEWLOC;
if (win_split(0, flags) == FAIL) if (win_split(0, flags) == FAIL)
return FAIL; return FAIL;
@@ -2732,9 +2735,11 @@ jump_to_help_window(qf_info_T *qi, int *opened_window)
if (curwin->w_height < p_hh) if (curwin->w_height < p_hh)
win_setheight((int)p_hh); win_setheight((int)p_hh);
if (IS_LL_STACK(qi)) // not a quickfix list // When using location list, the new window should use the supplied
// location list. If the user asks to open a new window, then the new
// window will get a copy of the location list.
if (IS_LL_STACK(qi) && !newwin)
{ {
// The new window should use the supplied location list
curwin->w_llist = qi; curwin->w_llist = qi;
qi->qf_refcount++; qi->qf_refcount++;
} }
@@ -2915,20 +2920,26 @@ qf_goto_win_with_qfl_file(int qf_fnum)
/* /*
* Find a suitable window for opening a file (qf_fnum) from the * Find a suitable window for opening a file (qf_fnum) from the
* quickfix/location list and jump to it. If the file is already opened in a * quickfix/location list and jump to it. If the file is already opened in a
* window, jump to it. Otherwise open a new window to display the file. This is * window, jump to it. Otherwise open a new window to display the file. If
* called from either a quickfix or a location list window. * 'newwin' is TRUE, then always open a new window. This is called from either
* a quickfix or a location list window.
*/ */
static int static int
qf_jump_to_usable_window(int qf_fnum, int *opened_window) qf_jump_to_usable_window(int qf_fnum, int newwin, int *opened_window)
{ {
win_T *usable_win_ptr = NULL; win_T *usable_win_ptr = NULL;
int usable_win; int usable_win;
qf_info_T *ll_ref; qf_info_T *ll_ref = NULL;
win_T *win; win_T *win;
usable_win = 0; usable_win = 0;
ll_ref = curwin->w_llist_ref; // If opening a new window, then don't use the location list referred by
// the current window. Otherwise two windows will refer to the same
// location list.
if (!newwin)
ll_ref = curwin->w_llist_ref;
if (ll_ref != NULL) if (ll_ref != NULL)
{ {
// Find a non-quickfix window with this location list // Find a non-quickfix window with this location list
@@ -2952,7 +2963,7 @@ qf_jump_to_usable_window(int qf_fnum, int *opened_window)
// If there is only one window and it is the quickfix window, create a // If there is only one window and it is the quickfix window, create a
// new one above the quickfix window. // new one above the quickfix window.
if ((ONE_WINDOW && bt_quickfix(curbuf)) || !usable_win) if ((ONE_WINDOW && bt_quickfix(curbuf)) || !usable_win || newwin)
{ {
if (qf_open_new_file_win(ll_ref) != OK) if (qf_open_new_file_win(ll_ref) != OK)
return FAIL; return FAIL;
@@ -3146,17 +3157,22 @@ qf_jump_print_msg(
/* /*
* Find a usable window for opening a file from the quickfix/location list. If * Find a usable window for opening a file from the quickfix/location list. If
* a window is not found then open a new window. * a window is not found then open a new window. If 'newwin' is TRUE, then open
* a new window.
* Returns OK if successfully jumped or opened a window. Returns FAIL if not * Returns OK if successfully jumped or opened a window. Returns FAIL if not
* able to jump/open a window. Returns NOTDONE if a file is not associated * able to jump/open a window. Returns NOTDONE if a file is not associated
* with the entry. * with the entry.
*/ */
static int static int
qf_jump_open_window(qf_info_T *qi, qfline_T *qf_ptr, int *opened_window) qf_jump_open_window(
qf_info_T *qi,
qfline_T *qf_ptr,
int newwin,
int *opened_window)
{ {
// For ":helpgrep" find a help window or open one. // For ":helpgrep" find a help window or open one.
if (qf_ptr->qf_type == 1 && (!bt_help(curwin->w_buffer) || cmdmod.tab != 0)) if (qf_ptr->qf_type == 1 && (!bt_help(curwin->w_buffer) || cmdmod.tab != 0))
if (jump_to_help_window(qi, opened_window) == FAIL) if (jump_to_help_window(qi, newwin, opened_window) == FAIL)
return FAIL; return FAIL;
// If currently in the quickfix window, find another window to show the // If currently in the quickfix window, find another window to show the
@@ -3168,7 +3184,8 @@ qf_jump_open_window(qf_info_T *qi, qfline_T *qf_ptr, int *opened_window)
if (qf_ptr->qf_fnum == 0) if (qf_ptr->qf_fnum == 0)
return NOTDONE; return NOTDONE;
if (qf_jump_to_usable_window(qf_ptr->qf_fnum, opened_window) == FAIL) if (qf_jump_to_usable_window(qf_ptr->qf_fnum, newwin,
opened_window) == FAIL)
return FAIL; return FAIL;
} }
@@ -3229,19 +3246,33 @@ qf_jump_to_buffer(
} }
/* /*
* jump to a quickfix line * Jump to a quickfix line.
* if dir == FORWARD go "errornr" valid entries forward * If dir == FORWARD go "errornr" valid entries forward.
* if dir == BACKWARD go "errornr" valid entries backward * If dir == BACKWARD go "errornr" valid entries backward.
* if dir == FORWARD_FILE go "errornr" valid entries files backward * If dir == FORWARD_FILE go "errornr" valid entries files backward.
* if dir == BACKWARD_FILE go "errornr" valid entries files backward * If dir == BACKWARD_FILE go "errornr" valid entries files backward
* else if "errornr" is zero, redisplay the same line * else if "errornr" is zero, redisplay the same line
* else go to entry "errornr" * else go to entry "errornr".
*/ */
void void
qf_jump(qf_info_T *qi, qf_jump(qf_info_T *qi,
int dir, int dir,
int errornr, int errornr,
int forceit) int forceit)
{
qf_jump_newwin(qi, dir, errornr, forceit, FALSE);
}
/*
* As qf_info().
* If 'newwin' is TRUE, then open the file in a new window.
*/
void
qf_jump_newwin(qf_info_T *qi,
int dir,
int errornr,
int forceit,
int newwin)
{ {
qf_list_T *qfl; qf_list_T *qfl;
qfline_T *qf_ptr; qfline_T *qf_ptr;
@@ -3288,7 +3319,7 @@ qf_jump(qf_info_T *qi,
// window // window
print_message = FALSE; print_message = FALSE;
retval = qf_jump_open_window(qi, qf_ptr, &opened_window); retval = qf_jump_open_window(qi, qf_ptr, newwin, &opened_window);
if (retval == FAIL) if (retval == FAIL)
goto failed; goto failed;
if (retval == NOTDONE) if (retval == NOTDONE)
@@ -3824,13 +3855,9 @@ qf_view_result(int split)
if (split) if (split)
{ {
char_u cmd[32]; // Open the selected entry in a new window
qf_jump_newwin(qi, 0, (long)curwin->w_cursor.lnum, FALSE, TRUE);
vim_snprintf((char *)cmd, sizeof(cmd), "split +%ld%s", do_cmdline_cmd((char_u *) "clearjumps");
(long)curwin->w_cursor.lnum,
IS_LL_WINDOW(curwin) ? "ll" : "cc");
if (do_cmdline_cmd(cmd) == OK)
do_cmdline_cmd((char_u *) "clearjumps");
return; return;
} }

View File

@@ -3718,3 +3718,49 @@ func Test_curswant()
call assert_equal(getcurpos()[4], virtcol('.')) call assert_equal(getcurpos()[4], virtcol('.'))
cclose | helpclose cclose | helpclose
endfunc endfunc
" Test for opening a file from the quickfix window using CTRL-W <Enter>
" doesn't leave an empty buffer around.
func Test_splitview()
call s:create_test_file('Xtestfile1')
call s:create_test_file('Xtestfile2')
new | only
let last_bufnr = bufnr('Test_sv_1', 1)
let l = ['Xtestfile1:2:Line2', 'Xtestfile2:4:Line4']
cgetexpr l
copen
let numbufs = len(getbufinfo())
exe "normal \<C-W>\<CR>"
copen
exe "normal j\<C-W>\<CR>"
" Make sure new empty buffers are not created
call assert_equal(numbufs, len(getbufinfo()))
" Creating a new buffer should use the next available buffer number
call assert_equal(last_bufnr + 4, bufnr("Test_sv_2", 1))
bwipe Test_sv_1
bwipe Test_sv_2
new | only
" When split opening files from location list window, make sure that two
" windows doesn't refer to the same location list
lgetexpr l
let locid = getloclist(0, {'id' : 0}).id
lopen
exe "normal \<C-W>\<CR>"
call assert_notequal(locid, getloclist(0, {'id' : 0}).id)
call assert_equal(0, getloclist(0, {'winid' : 0}).winid)
new | only
" When split opening files from a helpgrep location list window, a new help
" window should be opend with a copy of the location list.
lhelpgrep window
let locid = getloclist(0, {'id' : 0}).id
lwindow
exe "normal j\<C-W>\<CR>"
call assert_notequal(locid, getloclist(0, {'id' : 0}).id)
call assert_equal(0, getloclist(0, {'winid' : 0}).winid)
new | only
call delete('Xtestfile1')
call delete('Xtestfile2')
endfunc

View File

@@ -792,6 +792,8 @@ static char *(features[]) =
static int included_patches[] = static int included_patches[] =
{ /* Add new patch number below this line */ { /* Add new patch number below this line */
/**/
523,
/**/ /**/
522, 522,
/**/ /**/