diff options
Diffstat (limited to 'src/nvim/window.c')
-rw-r--r-- | src/nvim/window.c | 389 |
1 files changed, 221 insertions, 168 deletions
diff --git a/src/nvim/window.c b/src/nvim/window.c index 16ff7dfb14..39106a7b8d 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -1044,19 +1044,21 @@ static void win_init_some(win_T *newp, win_T *oldp) } -/* - * Check if "win" is a pointer to an existing window. - */ -int win_valid(win_T *win) +/// Check if "win" is a pointer to an existing window in the current tabpage. +/// +/// @param win window to check +bool win_valid(win_T *win) FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT { - if (win == NULL) - return FALSE; + if (win == NULL) { + return false; + } + FOR_ALL_WINDOWS_IN_TAB(wp, curtab) { if (wp == win) { - return TRUE; + return true; } } - return FALSE; + return false; } /* @@ -1732,21 +1734,18 @@ close_windows ( shell_new_rows(); } -/* - * Return TRUE if the current window is the only window that exists (ignoring - * "aucmd_win"). - * Returns FALSE if there is a window, possibly in another tab page. - */ -static int last_window(void) +/// Check that current window is the last one. +/// +/// @return true if the current window is the only window that exists, false if +/// there is another, possibly in another tab page. +static bool last_window(void) FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT { return one_window() && first_tabpage->tp_next == NULL; } -/* - * Return TRUE if there is only one window other than "aucmd_win" in the - * current tab page. - */ -bool one_window(void) +/// Check that current tab page contains no more then one window other than +/// "aucmd_win". +bool one_window(void) FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT { bool seen_one = false; @@ -1761,14 +1760,20 @@ bool one_window(void) return true; } -/* - * Close the possibly last window in a tab page. - * Returns TRUE when the window was closed already. - */ -static int close_last_window_tabpage(win_T *win, int free_buf, tabpage_T *prev_curtab) +/// Close the possibly last window in a tab page. +/// +/// @param win window to close +/// @param free_buf whether to free the window's current buffer +/// @param prev_curtab previous tabpage that will be closed if "win" is the +/// last window in the tabpage +/// +/// @return true when the window was closed already. +static bool close_last_window_tabpage(win_T *win, bool free_buf, + tabpage_T *prev_curtab) + FUNC_ATTR_NONNULL_ARG(1) { if (firstwin != lastwin) { - return FALSE; + return false; } buf_T *old_curbuf = curbuf; @@ -1809,14 +1814,15 @@ static int close_last_window_tabpage(win_T *win, int free_buf, tabpage_T *prev_c terminal_resize(term, 0, 0); } - /* 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) - apply_autocmds(EVENT_BUFENTER, NULL, NULL, FALSE, curbuf); - return TRUE; + // 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) { + apply_autocmds(EVENT_BUFENTER, NULL, NULL, false, curbuf); + } + return true; } /* @@ -1907,9 +1913,16 @@ int win_close(win_T *win, int free_buf) */ if (win->w_buffer != NULL) { win->w_closing = true; - close_buffer(win, win->w_buffer, free_buf ? DOBUF_UNLOAD : 0, TRUE); - if (win_valid(win)) + close_buffer(win, win->w_buffer, free_buf ? DOBUF_UNLOAD : 0, true); + if (win_valid(win)) { win->w_closing = false; + } + + // Make sure curbuf is valid. It can become invalid if 'bufhidden' is + // "wipe". + if (!buf_valid(curbuf)) { + curbuf = firstbuf; + } } if (only_one_window() && win_valid(win) && win->w_buffer == NULL @@ -2301,20 +2314,22 @@ static win_T *frame2win(frame_T *frp) return frp->fr_win; } -/* - * Return TRUE if frame "frp" contains window "wp". - */ -static int frame_has_win(frame_T *frp, win_T *wp) +/// Check that the frame "frp" contains the window "wp". +/// +/// @param frp frame +/// @param wp window +static bool frame_has_win(frame_T *frp, win_T *wp) + FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ARG(1) { - frame_T *p; - - if (frp->fr_layout == FR_LEAF) + if (frp->fr_layout == FR_LEAF) { return frp->fr_win == wp; - - for (p = frp->fr_child; p != NULL; p = p->fr_next) - if (frame_has_win(p, wp)) - return TRUE; - return FALSE; + } + for (frame_T *p = frp->fr_child; p != NULL; p = p->fr_next) { + if (frame_has_win(p, wp)) { + return true; + } + } + return false; } /* @@ -2406,58 +2421,72 @@ frame_new_height ( topfrp->fr_height = height; } -/* - * Return TRUE if height of frame "frp" should not be changed because of - * the 'winfixheight' option. - */ -static int frame_fixed_height(frame_T *frp) +/// Return true if height of frame "frp" should not be changed because of +/// the 'winfixheight' option. +/// +/// @param frp frame +/// +/// @return true if the frame has a fixed height +static bool frame_fixed_height(frame_T *frp) + FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL { - /* frame with one window: fixed height if 'winfixheight' set. */ - if (frp->fr_win != NULL) + // frame with one window: fixed height if 'winfixheight' set. + if (frp->fr_win != NULL) { return frp->fr_win->w_p_wfh; - + } if (frp->fr_layout == FR_ROW) { - /* The frame is fixed height if one of the frames in the row is fixed - * height. */ - for (frp = frp->fr_child; frp != NULL; frp = frp->fr_next) - if (frame_fixed_height(frp)) - return TRUE; - return FALSE; + // The frame is fixed height if one of the frames in the row is fixed + // height. + for (frp = frp->fr_child; frp != NULL; frp = frp->fr_next) { + if (frame_fixed_height(frp)) { + return true; + } + } + return false; } - /* frp->fr_layout == FR_COL: The frame is fixed height if all of the - * frames in the row are fixed height. */ - for (frp = frp->fr_child; frp != NULL; frp = frp->fr_next) - if (!frame_fixed_height(frp)) - return FALSE; - return TRUE; + // frp->fr_layout == FR_COL: The frame is fixed height if all of the + // frames in the row are fixed height. + for (frp = frp->fr_child; frp != NULL; frp = frp->fr_next) { + if (!frame_fixed_height(frp)) { + return false; + } + } + return true; } -/* - * Return TRUE if width of frame "frp" should not be changed because of - * the 'winfixwidth' option. - */ -static int frame_fixed_width(frame_T *frp) +/// Return true if width of frame "frp" should not be changed because of +/// the 'winfixwidth' option. +/// +/// @param frp frame +/// +/// @return true if the frame has a fixed width +static bool frame_fixed_width(frame_T *frp) + FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL { - /* frame with one window: fixed width if 'winfixwidth' set. */ - if (frp->fr_win != NULL) + // frame with one window: fixed width if 'winfixwidth' set. + if (frp->fr_win != NULL) { return frp->fr_win->w_p_wfw; - + } if (frp->fr_layout == FR_COL) { - /* The frame is fixed width if one of the frames in the row is fixed - * width. */ - for (frp = frp->fr_child; frp != NULL; frp = frp->fr_next) - if (frame_fixed_width(frp)) - return TRUE; - return FALSE; + // The frame is fixed width if one of the frames in the row is fixed + // width. + for (frp = frp->fr_child; frp != NULL; frp = frp->fr_next) { + if (frame_fixed_width(frp)) { + return true; + } + } + return false; } - /* frp->fr_layout == FR_ROW: The frame is fixed width if all of the - * frames in the row are fixed width. */ - for (frp = frp->fr_child; frp != NULL; frp = frp->fr_next) - if (!frame_fixed_width(frp)) - return FALSE; - return TRUE; + // frp->fr_layout == FR_ROW: The frame is fixed width if all of the + // frames in the row are fixed width. + for (frp = frp->fr_child; frp != NULL; frp = frp->fr_next) { + if (!frame_fixed_width(frp)) { + return false; + } + } + return true; } /* @@ -3028,10 +3057,10 @@ int make_tabpages(int maxcount) return count - todo; } -/* - * Return TRUE when "tpc" points to a valid tab page. - */ -bool valid_tabpage(tabpage_T *tpc) +/// Check that tpc points to a valid tab page. +/// +/// @param[in] tpc Tabpage to check. +bool valid_tabpage(tabpage_T *tpc) FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT { FOR_ALL_TABS(tp) { if (tp == tpc) { @@ -3252,17 +3281,27 @@ void goto_tabpage_win(tabpage_T *tp, win_T *wp) } } -/* - * Move the current tab page to before tab page "nr". - */ +// Move the current tab page to after tab page "nr". void tabpage_move(int nr) { - int n = nr; - tabpage_T *tp; + int n = 1; + tabpage_T *tp; + tabpage_T *tp_dst; if (first_tabpage->tp_next == NULL) return; + for (tp = first_tabpage; tp->tp_next != NULL && n < nr; tp = tp->tp_next) { + ++n; + } + + if (tp == curtab || (nr > 0 && tp->tp_next != NULL + && tp->tp_next == curtab)) { + return; + } + + tp_dst = tp; + /* Remove the current tab page from the list of tab pages. */ if (curtab == first_tabpage) first_tabpage = curtab->tp_next; @@ -3275,15 +3314,13 @@ void tabpage_move(int nr) tp->tp_next = curtab->tp_next; } - /* Re-insert it at the specified position. */ - if (n <= 0) { + // Re-insert it at the specified position. + if (nr <= 0) { curtab->tp_next = first_tabpage; first_tabpage = curtab; } else { - for (tp = first_tabpage; tp->tp_next != NULL && n > 1; tp = tp->tp_next) - --n; - curtab->tp_next = tp->tp_next; - tp->tp_next = curtab; + curtab->tp_next = tp_dst->tp_next; + tp_dst->tp_next = curtab; } /* Need to redraw the tabline. Tab page contents doesn't change. */ @@ -4538,10 +4575,19 @@ void win_drag_vsep_line(win_T *dragwin, int offset) } assert(fr); - if (room < offset) /* Not enough room */ - offset = room; /* Move as far as we can */ - if (offset <= 0) /* No room at all, quit. */ + // Not enough room + if (room < offset) { + offset = room; // Move as far as we can + } + + // No room at all, quit. + if (offset <= 0) { return; + } + + if (fr == NULL) { + return; // Safety check, should not happen. + } /* grow frame fr by offset lines */ frame_new_width(fr, fr->fr_width + offset, left, FALSE); @@ -4837,17 +4883,15 @@ static void frame_add_height(frame_T *frp, int n) */ char_u *grab_file_name(long count, linenr_T *file_lnum) { + int options = FNAME_MESS | FNAME_EXP | FNAME_REL | FNAME_UNESC; if (VIsual_active) { size_t len; char_u *ptr; if (get_visual_text(NULL, &ptr, &len) == FAIL) return NULL; - return find_file_name_in_path(ptr, len, - FNAME_MESS|FNAME_EXP|FNAME_REL, - count, curbuf->b_ffname); + return find_file_name_in_path(ptr, len, options, count, curbuf->b_ffname); } - return file_name_at_cursor(FNAME_MESS|FNAME_HYP|FNAME_EXP|FNAME_REL, count, - file_lnum); + return file_name_at_cursor(options | FNAME_HYP, count, file_lnum); } /* @@ -4918,12 +4962,18 @@ file_name_in_line ( * Also allow "://" when ':' is not in 'isfname'. */ len = 0; - while (vim_isfilec(ptr[len]) - || ((options & FNAME_HYP) && path_is_url((char *)ptr + len))) - if (has_mbyte) + while (vim_isfilec(ptr[len]) || (ptr[len] == '\\' && ptr[len + 1] == ' ') + || ((options & FNAME_HYP) && path_is_url((char *)ptr + len))) { + if (ptr[len] == '\\' && ptr[len + 1] == ' ') { + // Skip over the "\" in "\ ". + ++len; + } + if (has_mbyte) { len += (size_t)(*mb_ptr2len)(ptr + len); - else + } else { ++len; + } + } /* * If there is trailing punctuation, remove it. @@ -5048,27 +5098,22 @@ int min_rows(void) return total; } -/* - * Return TRUE if there is only one window (in the current tab page), not - * counting a help or preview window, unless it is the current window. - * Does not count "aucmd_win". - */ -int only_one_window(void) +/// Check that there is only one window (and only one tab page), not counting a +/// help or preview window, unless it is the current window. Does not count +/// "aucmd_win". +bool only_one_window(void) FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT { - int count = 0; - - /* If there is another tab page there always is another window. */ - if (first_tabpage->tp_next != NULL) - return FALSE; + // If there is another tab page there always is another window. + if (first_tabpage->tp_next != NULL) { + return false; + } + int count = 0; FOR_ALL_WINDOWS_IN_TAB(wp, curtab) { if (wp->w_buffer != NULL && (!((wp->w_buffer->b_help && !curbuf->b_help) - || wp->w_p_pvw - ) || wp == curwin) - && wp != aucmd_win - ) { - ++count; + || wp->w_p_pvw) || wp == curwin) && wp != aucmd_win) { + count++; } } return count <= 1; @@ -5306,14 +5351,14 @@ void restore_buffer(buf_T *save_curbuf) } -/* - * Add match to the match list of window 'wp'. The pattern 'pat' will be - * highlighted with the group 'grp' with priority 'prio'. - * Optionally, a desired ID 'id' can be specified (greater than or equal to 1). - * If no particular ID is desired, -1 must be specified for 'id'. - * Return ID of added match, -1 on failure. - */ -int match_add(win_T *wp, char_u *grp, char_u *pat, int prio, int id, list_T *pos_list) +// Add match to the match list of window 'wp'. The pattern 'pat' will be +// highlighted with the group 'grp' with priority 'prio'. +// Optionally, a desired ID 'id' can be specified (greater than or equal to 1). +// If no particular ID is desired, -1 must be specified for 'id'. +// Return ID of added match, -1 on failure. +int match_add(win_T *wp, char_u *grp, char_u *pat, + int prio, int id, list_T *pos_list, + char_u *conceal_char) { matchitem_T *cur; matchitem_T *prev; @@ -5369,6 +5414,10 @@ int match_add(win_T *wp, char_u *grp, char_u *pat, int prio, int id, list_T *pos m->match.regprog = regprog; m->match.rmm_ic = FALSE; m->match.rmm_maxcol = 0; + m->conceal_char = 0; + if (conceal_char != NULL) { + m->conceal_char = (*mb_ptr2char)(conceal_char); + } // Set up position matches if (pos_list != NULL) @@ -5567,38 +5616,42 @@ matchitem_T *get_match(win_T *wp, int id) } -/* - * Return TRUE if "topfrp" and its children are at the right height. - */ -static int frame_check_height(frame_T *topfrp, int height) +/// Check that "topfrp" and its children are at the right height. +/// +/// @param topfrp top frame pointer +/// @param height expected height +static bool frame_check_height(frame_T *topfrp, int height) + FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL { - frame_T *frp; - - if (topfrp->fr_height != height) - return FALSE; - - if (topfrp->fr_layout == FR_ROW) - for (frp = topfrp->fr_child; frp != NULL; frp = frp->fr_next) - if (frp->fr_height != height) - return FALSE; - - return TRUE; + if (topfrp->fr_height != height) { + return false; + } + if (topfrp->fr_layout == FR_ROW) { + for (frame_T *frp = topfrp->fr_child; frp != NULL; frp = frp->fr_next) { + if (frp->fr_height != height) { + return false; + } + } + } + return true; } -/* - * Return TRUE if "topfrp" and its children are at the right width. - */ -static int frame_check_width(frame_T *topfrp, int width) +/// Check that "topfrp" and its children are at the right width. +/// +/// @param topfrp top frame pointer +/// @param width expected width +static bool frame_check_width(frame_T *topfrp, int width) + FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL { - frame_T *frp; - - if (topfrp->fr_width != width) - return FALSE; - - if (topfrp->fr_layout == FR_COL) - for (frp = topfrp->fr_child; frp != NULL; frp = frp->fr_next) - if (frp->fr_width != width) - return FALSE; - - return TRUE; + if (topfrp->fr_width != width) { + return false; + } + if (topfrp->fr_layout == FR_COL) { + for (frame_T *frp = topfrp->fr_child; frp != NULL; frp = frp->fr_next) { + if (frp->fr_width != width) { + return false; + } + } + } + return true; } |