aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/nvim/buffer.c8
-rw-r--r--src/nvim/ex_cmds.c6
-rw-r--r--src/nvim/quickfix.c28
-rw-r--r--src/nvim/testdir/test_quickfix.vim14
-rw-r--r--src/nvim/window.c8
5 files changed, 47 insertions, 17 deletions
diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c
index 64569c294b..9815063633 100644
--- a/src/nvim/buffer.c
+++ b/src/nvim/buffer.c
@@ -252,7 +252,7 @@ open_buffer (
msg_silent = old_msg_silent;
// Help buffer is filtered.
- if (curbuf->b_help) {
+ if (bt_help(curbuf)) {
fix_help_buffer();
}
} else if (read_stdin) {
@@ -4930,6 +4930,12 @@ chk_modeline (
return retval;
}
+// Return true if "buf" is a help buffer.
+bool bt_help(const buf_T *const buf)
+{
+ return buf != NULL && buf->b_help;
+}
+
/*
* Return special buffer name.
* Returns NULL when the buffer has a normal file name.
diff --git a/src/nvim/ex_cmds.c b/src/nvim/ex_cmds.c
index a9e9364dc3..4d32b76eb0 100644
--- a/src/nvim/ex_cmds.c
+++ b/src/nvim/ex_cmds.c
@@ -4514,7 +4514,7 @@ void ex_help(exarg_T *eap)
* Re-use an existing help window or open a new one.
* Always open a new one for ":tab help".
*/
- if (!curwin->w_buffer->b_help
+ if (!bt_help(curwin->w_buffer)
|| cmdmod.tab != 0
) {
if (cmdmod.tab != 0) {
@@ -4522,7 +4522,7 @@ void ex_help(exarg_T *eap)
} else {
wp = NULL;
FOR_ALL_WINDOWS_IN_TAB(wp2, curtab) {
- if (wp2->w_buffer != NULL && wp2->w_buffer->b_help) {
+ if (bt_help(wp2->w_buffer)) {
wp = wp2;
break;
}
@@ -5509,7 +5509,7 @@ static int next_sign_typenr = 1;
void ex_helpclose(exarg_T *eap)
{
FOR_ALL_WINDOWS_IN_TAB(win, curtab) {
- if (win->w_buffer->b_help) {
+ if (bt_help(win->w_buffer)) {
win_close(win, FALSE);
return;
}
diff --git a/src/nvim/quickfix.c b/src/nvim/quickfix.c
index dad8f52653..fb7440f7da 100644
--- a/src/nvim/quickfix.c
+++ b/src/nvim/quickfix.c
@@ -1839,12 +1839,12 @@ void qf_jump(qf_info_T *qi, int dir, int errornr, int forceit)
/*
* For ":helpgrep" find a help window or open one.
*/
- if (qf_ptr->qf_type == 1 && (!curwin->w_buffer->b_help || cmdmod.tab != 0)) {
+ if (qf_ptr->qf_type == 1 && (!bt_help(curwin->w_buffer) || cmdmod.tab != 0)) {
win_T *wp = NULL;
if (cmdmod.tab == 0) {
FOR_ALL_WINDOWS_IN_TAB(wp2, curtab) {
- if (wp2->w_buffer != NULL && wp2->w_buffer->b_help) {
+ if (bt_help(wp2->w_buffer)) {
wp = wp2;
break;
}
@@ -4721,16 +4721,26 @@ void ex_helpgrep(exarg_T *eap)
p_cpo = empty_option;
if (eap->cmdidx == CMD_lhelpgrep) {
- qi = NULL;
+ win_T *wp = NULL;
- /* Find an existing help window */
- FOR_ALL_WINDOWS_IN_TAB(wp, curtab) {
- if (wp->w_buffer != NULL && wp->w_buffer->b_help) {
- qi = wp->w_llist;
+ // If the current window is a help window, then use it
+ if (bt_help(curwin->w_buffer)) {
+ wp = curwin;
+ } else {
+ // Find an existing help window
+ FOR_ALL_WINDOWS_IN_TAB(wp2, curtab) {
+ if (bt_help(wp2->w_buffer)) {
+ wp = wp2;
+ break;
+ }
}
}
- /* Help window not found */
+ if (wp == NULL) { // Help window not found
+ qi = NULL;
+ } else {
+ qi = wp->w_llist;
+ }
if (qi == NULL) {
/* Allocate a new location list for help text matches */
qi = ll_new_list();
@@ -4851,7 +4861,7 @@ void ex_helpgrep(exarg_T *eap)
if (eap->cmdidx == CMD_lhelpgrep) {
/* If the help window is not opened or if it already points to the
* correct location list, then free the new location list. */
- if (!curwin->w_buffer->b_help || curwin->w_llist == qi) {
+ if (!bt_help(curwin->w_buffer) || curwin->w_llist == qi) {
if (new_qi)
ll_free_all(&qi);
} else if (curwin->w_llist == NULL)
diff --git a/src/nvim/testdir/test_quickfix.vim b/src/nvim/testdir/test_quickfix.vim
index 33abb69ca6..ade656c45d 100644
--- a/src/nvim/testdir/test_quickfix.vim
+++ b/src/nvim/testdir/test_quickfix.vim
@@ -2269,3 +2269,17 @@ func Test_changedtick()
call Xchangedtick_tests('c')
call Xchangedtick_tests('l')
endfunc
+
+" Open multiple help windows using ":lhelpgrep
+" This test used to crash Vim
+func Test_Multi_LL_Help()
+ new | only
+ lhelpgrep window
+ lopen
+ e#
+ lhelpgrep buffer
+ call assert_equal(3, winnr('$'))
+ call assert_true(len(getloclist(1)) != 0)
+ call assert_true(len(getloclist(2)) != 0)
+ new | only
+endfunc
diff --git a/src/nvim/window.c b/src/nvim/window.c
index 9976ae9aff..04990fedae 100644
--- a/src/nvim/window.c
+++ b/src/nvim/window.c
@@ -1902,7 +1902,7 @@ int win_close(win_T *win, int free_buf)
/* When closing the help window, try restoring a snapshot after closing
* the window. Otherwise clear the snapshot, it's now invalid. */
- if (win->w_buffer != NULL && win->w_buffer->b_help)
+ if (bt_help(win->w_buffer))
help_window = TRUE;
else
clear_snapshot(curtab, SNAP_HELP_IDX);
@@ -1967,8 +1967,8 @@ int win_close(win_T *win, int free_buf)
if (only_one_window() && win_valid(win) && win->w_buffer == NULL
&& (last_window() || curtab != prev_curtab
|| close_last_window_tabpage(win, free_buf, prev_curtab))) {
- /* Autocommands have close all windows, quit now. Restore
- * curwin->w_buffer, otherwise writing ShaDa file may fail. */
+ // Autocommands have closed all windows, quit now. Restore
+ // curwin->w_buffer, otherwise writing ShaDa file may fail.
if (curwin->w_buffer == NULL)
curwin->w_buffer = curbuf;
getout(0);
@@ -5341,7 +5341,7 @@ bool only_one_window(void) FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
int count = 0;
FOR_ALL_WINDOWS_IN_TAB(wp, curtab) {
if (wp->w_buffer != NULL
- && (!((wp->w_buffer->b_help && !curbuf->b_help)
+ && (!((bt_help(wp->w_buffer) && !bt_help(curbuf))
|| wp->w_p_pvw) || wp == curwin) && wp != aucmd_win) {
count++;
}