From abe38f7d26d68d7032ea391c039c56c8b87675a5 Mon Sep 17 00:00:00 2001 From: glacambre Date: Sun, 26 Nov 2017 13:29:32 +0100 Subject: window.c: do BufEnter in correct window after closing help #7431 closes #7429 Problem: after a help window was closed, a window was selected and its autocommands triggered. After that, restore_snapshot was called and the focused window changed, confusing the user. Solution: Add function get_snapshot_focus() that returns the window that holds the cursor in a snapshot. Use this function in win_close to make sure the right window is selected before any autocommand is triggered. --- src/nvim/window.c | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) (limited to 'src/nvim/window.c') diff --git a/src/nvim/window.c b/src/nvim/window.c index 4e4eb297aa..e39569321e 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -1991,6 +1991,14 @@ int win_close(win_T *win, int free_buf) * the screen space. */ wp = win_free_mem(win, &dir, NULL); + if (help_window) { + // Closing the help window moves the cursor back to the original window. + win_T *tmpwp = get_snapshot_focus(SNAP_HELP_IDX); + if (tmpwp != NULL) { + wp = tmpwp; + } + } + /* Make sure curwin isn't invalid. It can cause severe trouble when * printing an error message. For win_equal() curbuf needs to be valid * too. */ @@ -5421,6 +5429,27 @@ static win_T *restore_snapshot_rec(frame_T *sn, frame_T *fr) return wp; } +/// Gets the focused window (the one holding the cursor) of the snapshot. +static win_T *get_snapshot_focus(int idx) +{ + if (curtab->tp_snapshot[idx] == NULL) { + return NULL; + } + + frame_T *sn = curtab->tp_snapshot[idx]; + // This should be equivalent to the recursive algorithm found in + // restore_snapshot as far as traveling nodes go. + while (sn->fr_child != NULL || sn->fr_next != NULL) { + while (sn->fr_child != NULL) { + sn = sn->fr_child; + } + if (sn->fr_next != NULL) { + sn = sn->fr_next; + } + } + + return sn->fr_win; +} /* * Set "win" to be the curwin and "tp" to be the current tab page. -- cgit From ac4bbf55f6d6b9b252dd90fe800626850022b690 Mon Sep 17 00:00:00 2001 From: ZyX Date: Sun, 10 Dec 2017 22:04:43 +0300 Subject: *: Hide list implementation in other files as well --- src/nvim/window.c | 50 +++++++++++++++++++++++++------------------------- 1 file changed, 25 insertions(+), 25 deletions(-) (limited to 'src/nvim/window.c') diff --git a/src/nvim/window.c b/src/nvim/window.c index 4e4eb297aa..21d668a2bd 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -5579,30 +5579,26 @@ int match_add(win_T *wp, const char *const grp, const char *const pat, // Set up position matches if (pos_list != NULL) { - linenr_T toplnum = 0; - linenr_T botlnum = 0; - listitem_T *li; - int i; - - for (i = 0, li = pos_list->lv_first; li != NULL && i < MAXPOSMATCH; - i++, li = li->li_next) { - linenr_T lnum = 0; - colnr_T col = 0; - int len = 1; - list_T *subl; - listitem_T *subli; + linenr_T toplnum = 0; + linenr_T botlnum = 0; + + int i = 0; + TV_LIST_ITER(pos_list, li, { + linenr_T lnum = 0; + colnr_T col = 0; + int len = 1; bool error = false; - if (li->li_tv.v_type == VAR_LIST) { - subl = li->li_tv.vval.v_list; + if (TV_LIST_ITEM_TV(li)->v_type == VAR_LIST) { + const list_T *const subl = TV_LIST_ITEM_TV(li)->vval.v_list; if (subl == NULL) { goto fail; } - subli = subl->lv_first; + const listitem_T *subli = tv_list_first(subl); if (subli == NULL) { goto fail; } - lnum = tv_get_number_chk(&subli->li_tv, &error); + lnum = tv_get_number_chk(TV_LIST_ITEM_TV(subli), &error); if (error) { goto fail; } @@ -5611,15 +5607,15 @@ int match_add(win_T *wp, const char *const grp, const char *const pat, continue; } m->pos.pos[i].lnum = lnum; - subli = subli->li_next; + subli = TV_LIST_ITEM_NEXT(subl, subli); if (subli != NULL) { - col = tv_get_number_chk(&subli->li_tv, &error); + col = tv_get_number_chk(TV_LIST_ITEM_TV(subli), &error); if (error) { goto fail; } - subli = subli->li_next; + subli = TV_LIST_ITEM_NEXT(subl, subli); if (subli != NULL) { - len = tv_get_number_chk(&subli->li_tv, &error); + len = tv_get_number_chk(TV_LIST_ITEM_TV(subli), &error); if (error) { goto fail; } @@ -5627,12 +5623,12 @@ int match_add(win_T *wp, const char *const grp, const char *const pat, } m->pos.pos[i].col = col; m->pos.pos[i].len = len; - } else if (li->li_tv.v_type == VAR_NUMBER) { - if (li->li_tv.vval.v_number == 0) { - --i; + } else if (TV_LIST_ITEM_TV(li)->v_type == VAR_NUMBER) { + if (TV_LIST_ITEM_TV(li)->vval.v_number == 0) { + i--; continue; } - m->pos.pos[i].lnum = li->li_tv.vval.v_number; + m->pos.pos[i].lnum = TV_LIST_ITEM_TV(li)->vval.v_number; m->pos.pos[i].col = 0; m->pos.pos[i].len = 0; } else { @@ -5645,7 +5641,11 @@ int match_add(win_T *wp, const char *const grp, const char *const pat, if (botlnum == 0 || lnum >= botlnum) { botlnum = lnum + 1; } - } + i++; + if (i >= MAXPOSMATCH) { + break; + } + }); // Calculate top and bottom lines for redrawing area if (toplnum != 0){ -- cgit From f4132fb38b1355115d824b7c04eff25733d059d6 Mon Sep 17 00:00:00 2001 From: ZyX Date: Mon, 11 Dec 2017 10:19:20 +0300 Subject: *: Fix linter errors --- src/nvim/window.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'src/nvim/window.c') diff --git a/src/nvim/window.c b/src/nvim/window.c index 21d668a2bd..4c996aea79 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -5577,8 +5577,7 @@ int match_add(win_T *wp, const char *const grp, const char *const pat, } // Set up position matches - if (pos_list != NULL) - { + if (pos_list != NULL) { linenr_T toplnum = 0; linenr_T botlnum = 0; -- cgit From fb07391ce46b8bff90ef7ef073b75919a307e64c Mon Sep 17 00:00:00 2001 From: ZyX Date: Fri, 15 Dec 2017 11:38:34 +0300 Subject: window: Fix matchaddpos() and enhance error reporting --- src/nvim/window.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) (limited to 'src/nvim/window.c') diff --git a/src/nvim/window.c b/src/nvim/window.c index 28cb9449d1..583314d437 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -5619,19 +5619,17 @@ int match_add(win_T *wp, const char *const grp, const char *const pat, if (TV_LIST_ITEM_TV(li)->v_type == VAR_LIST) { const list_T *const subl = TV_LIST_ITEM_TV(li)->vval.v_list; - if (subl == NULL) { - goto fail; - } const listitem_T *subli = tv_list_first(subl); if (subli == NULL) { + emsgf(_("E5030: Empty list at position %d"), + (int)tv_list_idx_of_item(pos_list, li)); goto fail; } lnum = tv_get_number_chk(TV_LIST_ITEM_TV(subli), &error); if (error) { goto fail; } - if (lnum == 0) { - --i; + if (lnum <= 0) { continue; } m->pos.pos[i].lnum = lnum; @@ -5641,9 +5639,15 @@ int match_add(win_T *wp, const char *const grp, const char *const pat, if (error) { goto fail; } + if (col < 0) { + continue; + } subli = TV_LIST_ITEM_NEXT(subl, subli); if (subli != NULL) { len = tv_get_number_chk(TV_LIST_ITEM_TV(subli), &error); + if (len < 0) { + continue; + } if (error) { goto fail; } @@ -5652,15 +5656,15 @@ int match_add(win_T *wp, const char *const grp, const char *const pat, m->pos.pos[i].col = col; m->pos.pos[i].len = len; } else if (TV_LIST_ITEM_TV(li)->v_type == VAR_NUMBER) { - if (TV_LIST_ITEM_TV(li)->vval.v_number == 0) { - i--; + if (TV_LIST_ITEM_TV(li)->vval.v_number <= 0) { continue; } m->pos.pos[i].lnum = TV_LIST_ITEM_TV(li)->vval.v_number; m->pos.pos[i].col = 0; m->pos.pos[i].len = 0; } else { - EMSG(_("List or number required")); + emsgf(_("E5031: List or number required at position %d"), + (int)tv_list_idx_of_item(pos_list, li)); goto fail; } if (toplnum == 0 || lnum < toplnum) { -- cgit From d5bce42b524708a54243658e87b1e3bd9c7acdf3 Mon Sep 17 00:00:00 2001 From: Michael Schupikov Date: Sat, 23 Sep 2017 09:56:44 +0200 Subject: vim-patch:8.0.0074 Problem: Cannot make Vim fail on an internal error. Solution: Add IEMSG() and IEMSG2(). (Domenique Pelle) Avoid reporting an internal error without mentioning where. https://github.com/vim/vim/commit/95f096030ed1a8afea028f2ea295d6f6a70f466f Signed-off-by: Michael Schupikov --- src/nvim/window.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/nvim/window.c') diff --git a/src/nvim/window.c b/src/nvim/window.c index e39569321e..63c9361663 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -2115,7 +2115,7 @@ void win_close_othertab(win_T *win, int free_buf, tabpage_T *tp) ptp = ptp->tp_next) ; if (ptp == NULL) { - EMSG2(_(e_intern2), "win_close_othertab()"); + internal_error("win_close_othertab()"); return; } ptp->tp_next = tp->tp_next; -- cgit From 2c436b33621a3064aae94e88db90095ae69aabc8 Mon Sep 17 00:00:00 2001 From: Daniel Hahler Date: Fri, 29 Dec 2017 16:56:14 +0100 Subject: Fix TabClose autocommand via close_windows Fixes https://github.com/neovim/neovim/issues/7781 --- src/nvim/window.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) (limited to 'src/nvim/window.c') diff --git a/src/nvim/window.c b/src/nvim/window.c index 5e85a9bede..bbdf40b874 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -1741,6 +1741,11 @@ void close_windows(buf_T *buf, int keep_curwin) } else wp = wp->w_next; } + if (count != tabpage_index(NULL)) { + char_u prev_idx[NUMBUFLEN]; + sprintf((char *)prev_idx, "%i", tabpage_index(curtab)); + apply_autocmds(EVENT_TABCLOSED, prev_idx, prev_idx, false, curbuf); + } /* Also check windows in other tab pages. */ for (tp = first_tabpage; tp != NULL; tp = nexttp) { @@ -1757,15 +1762,16 @@ void close_windows(buf_T *buf, int keep_curwin) break; } } + if (count != tabpage_index(NULL)) { + char_u prev_idx[NUMBUFLEN]; + sprintf((char *)prev_idx, "%i", tabpage_index(tp)); + apply_autocmds(EVENT_TABCLOSED, prev_idx, prev_idx, false, curbuf); + } } } --RedrawingDisabled; - if (count != tabpage_index(NULL)) { - apply_autocmds(EVENT_TABCLOSED, NULL, NULL, false, curbuf); - } - redraw_tabline = true; if (h != tabline_height()) { shell_new_rows(); -- cgit From e84e1b68c13443efc3e0c39a16c6a6945fbde20b Mon Sep 17 00:00:00 2001 From: Daniel Hahler Date: Fri, 29 Dec 2017 20:35:52 +0100 Subject: Move applying of TabClosed to win_close_othertab --- src/nvim/window.c | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) (limited to 'src/nvim/window.c') diff --git a/src/nvim/window.c b/src/nvim/window.c index bbdf40b874..81e986c5f2 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -1724,7 +1724,6 @@ void close_windows(buf_T *buf, int keep_curwin) { tabpage_T *tp, *nexttp; int h = tabline_height(); - int count = tabpage_index(NULL); ++RedrawingDisabled; @@ -1741,11 +1740,6 @@ void close_windows(buf_T *buf, int keep_curwin) } else wp = wp->w_next; } - if (count != tabpage_index(NULL)) { - char_u prev_idx[NUMBUFLEN]; - sprintf((char *)prev_idx, "%i", tabpage_index(curtab)); - apply_autocmds(EVENT_TABCLOSED, prev_idx, prev_idx, false, curbuf); - } /* Also check windows in other tab pages. */ for (tp = first_tabpage; tp != NULL; tp = nexttp) { @@ -1762,11 +1756,6 @@ void close_windows(buf_T *buf, int keep_curwin) break; } } - if (count != tabpage_index(NULL)) { - char_u prev_idx[NUMBUFLEN]; - sprintf((char *)prev_idx, "%i", tabpage_index(tp)); - apply_autocmds(EVENT_TABCLOSED, prev_idx, prev_idx, false, curbuf); - } } } @@ -1854,7 +1843,6 @@ static bool close_last_window_tabpage(win_T *win, bool free_buf, // Since goto_tabpage_tp above did not trigger *Enter autocommands, do // that now. - apply_autocmds(EVENT_TABCLOSED, prev_idx, prev_idx, false, curbuf); apply_autocmds(EVENT_WINENTER, NULL, NULL, false, curbuf); apply_autocmds(EVENT_TABENTER, NULL, NULL, false, curbuf); if (old_curbuf != curbuf) { @@ -2114,6 +2102,10 @@ void win_close_othertab(win_T *win, int free_buf, tabpage_T *tp) /* When closing the last window in a tab page remove the tab page. */ if (tp->tp_firstwin == tp->tp_lastwin) { + // save index for tabclosed event + char_u prev_idx[NUMBUFLEN]; + sprintf((char *)prev_idx, "%i", tabpage_index(tp)); + if (tp == first_tabpage) first_tabpage = tp->tp_next; else { @@ -2127,6 +2119,8 @@ void win_close_othertab(win_T *win, int free_buf, tabpage_T *tp) ptp->tp_next = tp->tp_next; } free_tp = TRUE; + + apply_autocmds(EVENT_TABCLOSED, prev_idx, prev_idx, false, win->w_buffer); } /* Free the memory used for the window. */ -- cgit From 5dd2ca767f3163cb9d051a9a2676ac88f600ebad Mon Sep 17 00:00:00 2001 From: Daniel Hahler Date: Fri, 29 Dec 2017 20:52:56 +0100 Subject: use snprintf and has_event --- src/nvim/window.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'src/nvim/window.c') diff --git a/src/nvim/window.c b/src/nvim/window.c index 81e986c5f2..2e1507c0ee 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -2102,9 +2102,10 @@ void win_close_othertab(win_T *win, int free_buf, tabpage_T *tp) /* When closing the last window in a tab page remove the tab page. */ if (tp->tp_firstwin == tp->tp_lastwin) { - // save index for tabclosed event char_u prev_idx[NUMBUFLEN]; - sprintf((char *)prev_idx, "%i", tabpage_index(tp)); + if (has_event(EVENT_TABCLOSED)) { + vim_snprintf((char *)prev_idx, NUMBUFLEN, "%i", tabpage_index(tp)); + } if (tp == first_tabpage) first_tabpage = tp->tp_next; @@ -2120,7 +2121,9 @@ void win_close_othertab(win_T *win, int free_buf, tabpage_T *tp) } free_tp = TRUE; - apply_autocmds(EVENT_TABCLOSED, prev_idx, prev_idx, false, win->w_buffer); + if (has_event(EVENT_TABCLOSED)) { + apply_autocmds(EVENT_TABCLOSED, prev_idx, prev_idx, false, win->w_buffer); + } } /* Free the memory used for the window. */ -- cgit From 46f432074e739a0eca9bb204e9c7769935669dbd Mon Sep 17 00:00:00 2001 From: Daniel Hahler Date: Fri, 29 Dec 2017 21:13:21 +0100 Subject: tests: termclose_spec: fix flaky SIGTERM test #7787 Followup to https://github.com/neovim/neovim/pull/7217. Build failure: https://travis-ci.org/neovim/neovim/jobs/322930672#L2958. --- src/nvim/window.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) (limited to 'src/nvim/window.c') diff --git a/src/nvim/window.c b/src/nvim/window.c index 2e1507c0ee..b687781dfb 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -2104,25 +2104,26 @@ void win_close_othertab(win_T *win, int free_buf, tabpage_T *tp) if (tp->tp_firstwin == tp->tp_lastwin) { char_u prev_idx[NUMBUFLEN]; if (has_event(EVENT_TABCLOSED)) { - vim_snprintf((char *)prev_idx, NUMBUFLEN, "%i", tabpage_index(tp)); + vim_snprintf((char *)prev_idx, NUMBUFLEN, "%i", tabpage_index(tp)); } - if (tp == first_tabpage) + if (tp == first_tabpage) { first_tabpage = tp->tp_next; - else { + } else { for (ptp = first_tabpage; ptp != NULL && ptp->tp_next != tp; - ptp = ptp->tp_next) - ; + ptp = ptp->tp_next) { + // loop + } if (ptp == NULL) { internal_error("win_close_othertab()"); return; } ptp->tp_next = tp->tp_next; } - free_tp = TRUE; + free_tp = true; if (has_event(EVENT_TABCLOSED)) { - apply_autocmds(EVENT_TABCLOSED, prev_idx, prev_idx, false, win->w_buffer); + apply_autocmds(EVENT_TABCLOSED, prev_idx, prev_idx, false, win->w_buffer); } } -- cgit From 9ea1752d60589e8fc5e7184144bc6d1c1b9f16a3 Mon Sep 17 00:00:00 2001 From: ZyX Date: Wed, 3 Jan 2018 00:00:16 +0300 Subject: *: Provide list length when allocating lists --- src/nvim/window.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src/nvim/window.c') diff --git a/src/nvim/window.c b/src/nvim/window.c index b687781dfb..4dfc72f212 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -5921,13 +5921,15 @@ void win_get_tabwin(handle_T id, int *tabnr, int *winnr) } } -void win_id2tabwin(typval_T *argvars, list_T *list) +void win_id2tabwin(typval_T *const argvars, typval_T *const rettv) { int winnr = 1; int tabnr = 1; handle_T id = (handle_T)tv_get_number(&argvars[0]); win_get_tabwin(id, &tabnr, &winnr); + + list_T *const list = tv_list_alloc_ret(rettv, 2); tv_list_append_number(list, tabnr); tv_list_append_number(list, winnr); } -- cgit From 2929dbf2233f05f58e094ce4a80fb1320ac6d336 Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Sun, 11 Feb 2018 20:56:55 +0100 Subject: vim-patch:8.0.0858: can exit while a terminal is still running a job Problem: Can exit while a terminal is still running a job. Solution: Consider a buffer with a running job like a changed file. https://github.com/vim/vim/commit/eb44a68b42eda207a5bc4def9ea8fc4d38acb650 --- src/nvim/window.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/nvim/window.c') diff --git a/src/nvim/window.c b/src/nvim/window.c index 4dfc72f212..22c4c5f9c0 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -2857,7 +2857,7 @@ close_others ( if (bufIsChanged(wp->w_buffer)) continue; } - win_close(wp, !P_HID(wp->w_buffer) && !bufIsChanged(wp->w_buffer)); + win_close(wp, !buf_hide(wp->w_buffer) && !bufIsChanged(wp->w_buffer)); } if (message && !ONE_WINDOW) -- cgit From 6bcee20806960fca2876cb76544cbca50831692e Mon Sep 17 00:00:00 2001 From: KunMing Xie Date: Mon, 12 Feb 2018 07:00:24 +0800 Subject: vim-patch:8.0.0490: vertical split makes 'winfixwidth' window smaller (#7990) Problem: Splitting a 'winfixwidth' window vertically makes it one column smaller. (Dominique Pelle) Solution: Add one to the width for the separator. https://github.com/vim/vim/commit/38e3483637c16e018f88c07b1dcff97cdb821a29 --- src/nvim/window.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'src/nvim/window.c') diff --git a/src/nvim/window.c b/src/nvim/window.c index 4dfc72f212..8d7e20bb73 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -641,11 +641,12 @@ int win_split_ins(int size, int flags, win_T *new_wp, int dir) if (oldwin->w_width - new_size - 1 < p_wmw) do_equal = TRUE; - /* We don't like to take lines for the new window from a - * 'winfixwidth' window. Take them from a window to the left or right - * instead, if possible. */ - if (oldwin->w_p_wfw) - win_setwidth_win(oldwin->w_width + new_size, oldwin); + // We don't like to take lines for the new window from a + // 'winfixwidth' window. Take them from a window to the left or right + // instead, if possible. Add one for the separator. + if (oldwin->w_p_wfw) { + win_setwidth_win(oldwin->w_width + new_size + 1, oldwin); + } /* Only make all windows the same width if one of them (except oldwin) * is wider than one of the split windows. */ -- cgit