diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/nvim/quickfix.c | 77 | ||||
-rw-r--r-- | src/nvim/testdir/test_quickfix.vim | 46 |
2 files changed, 92 insertions, 31 deletions
diff --git a/src/nvim/quickfix.c b/src/nvim/quickfix.c index fc2e1a4295..da7e02ff54 100644 --- a/src/nvim/quickfix.c +++ b/src/nvim/quickfix.c @@ -2453,12 +2453,13 @@ static void win_set_loclist(win_T *wp, qf_info_T *qi) qi->qf_refcount++; } -/// Find a help window or open one. -static int jump_to_help_window(qf_info_T *qi, int *opened_window) +/// Find a help window or open one. If 'newwin' is true, then open a new help +/// window. +static int jump_to_help_window(qf_info_T *qi, bool newwin, int *opened_window) { win_T *wp = NULL; - if (cmdmod.tab != 0) { + if (cmdmod.tab != 0 || newwin) { wp = NULL; } else { wp = qf_find_help_win(); @@ -2476,8 +2477,10 @@ static int jump_to_help_window(qf_info_T *qi, int *opened_window) flags |= WSP_TOP; } - if (IS_LL_STACK(qi)) { - flags |= WSP_NEWLOC; // don't copy the location list + // If the user asks to open a new window, then 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) { @@ -2490,8 +2493,10 @@ static int jump_to_help_window(qf_info_T *qi, int *opened_window) win_setheight((int)p_hh); } - if (IS_LL_STACK(qi)) { // not a quickfix list - // The new window should use the supplied location 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) { win_set_loclist(curwin, qi); } } @@ -2652,14 +2657,19 @@ static void qf_goto_win_with_qfl_file(int qf_fnum) // 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 -// window, jump to it. Otherwise open a new window to display the file. This is -// called from either a quickfix or a location list window. -static int qf_jump_to_usable_window(int qf_fnum, int *opened_window) +// window, jump to it. Otherwise open a new window to display the file. If +// 'newwin' is true, then always open a new window. This is called from either +// a quickfix or a location list window. +static int qf_jump_to_usable_window(int qf_fnum, bool newwin, + int *opened_window) { win_T *usable_win_ptr = NULL; bool usable_win = false; - qf_info_T *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. + qf_info_T *ll_ref = newwin ? NULL : curwin->w_llist_ref; if (ll_ref != NULL) { // Find a non-quickfix window with this location list usable_win_ptr = qf_find_win_with_loclist(ll_ref); @@ -2684,7 +2694,7 @@ static int 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 // 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) { return FAIL; } @@ -2823,11 +2833,12 @@ static void qf_jump_print_msg(qf_info_T *qi, int qf_index, qfline_T *qf_ptr, } /// 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 /// able to jump/open a window. Returns NOTDONE if a file is not associated /// with the entry. -static int qf_jump_open_window(qf_info_T *qi, qfline_T *qf_ptr, +static int qf_jump_open_window(qf_info_T *qi, qfline_T *qf_ptr, bool newwin, int *opened_window) { qf_list_T *qfl = qf_get_curlist(qi); @@ -2837,7 +2848,7 @@ static int qf_jump_open_window(qf_info_T *qi, qfline_T *qf_ptr, // For ":helpgrep" find a help window or open one. 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; } } @@ -2861,7 +2872,8 @@ static int qf_jump_open_window(qf_info_T *qi, qfline_T *qf_ptr, 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; } } @@ -2924,15 +2936,23 @@ static int qf_jump_to_buffer(qf_info_T *qi, int qf_index, qfline_T *qf_ptr, return retval; } -/// jump to a quickfix ltne -/// if dir == FORWARD go "errornr" valid entries forward -/// if dir == BACKWARD go "errornr" valid entries backward -/// if dir == FORWARD_FILE go "errornr" valid entries files backward -/// if dir == BACKWARD_FILE go "errornr" valid entries files backward +/// Jump to a quickfix line. +/// If dir == FORWARD go "errornr" valid entries forward. +/// If dir == BACKWARD go "errornr" valid entries backward. +/// If dir == FORWARD_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 go to entry "errornr" +/// else go to entry "errornr". void qf_jump(qf_info_T *qi, int dir, int errornr, 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. +static void qf_jump_newwin(qf_info_T *qi, int dir, int errornr, int forceit, + bool newwin) +{ qf_list_T *qfl; qfline_T *qf_ptr; qfline_T *old_qf_ptr; @@ -2975,7 +2995,7 @@ void qf_jump(qf_info_T *qi, int dir, int errornr, int forceit) 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) { goto failed; } @@ -3445,14 +3465,9 @@ void qf_view_result(bool split) } if (split) { - char cmd[32]; - - snprintf(cmd, sizeof(cmd), "split +%" PRId64 "%s", - (int64_t)curwin->w_cursor.lnum, - IS_LL_WINDOW(curwin) ? "ll" : "cc"); - if (do_cmdline_cmd(cmd) == OK) { - do_cmdline_cmd("clearjumps"); - } + // Open the selected entry in a new window + qf_jump_newwin(qi, 0, (int)curwin->w_cursor.lnum, false, true); + do_cmdline_cmd("clearjumps"); return; } diff --git a/src/nvim/testdir/test_quickfix.vim b/src/nvim/testdir/test_quickfix.vim index 4090db2874..4e04ea161f 100644 --- a/src/nvim/testdir/test_quickfix.vim +++ b/src/nvim/testdir/test_quickfix.vim @@ -3869,6 +3869,52 @@ func Test_curswant() cclose | helpclose 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 + " Test for parsing entries using visual screen column func Test_viscol() enew |