aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/window.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/nvim/window.c')
-rw-r--r--src/nvim/window.c81
1 files changed, 64 insertions, 17 deletions
diff --git a/src/nvim/window.c b/src/nvim/window.c
index 1e6de73549..76fc36607c 100644
--- a/src/nvim/window.c
+++ b/src/nvim/window.c
@@ -70,8 +70,8 @@ static char *m_onlyone = N_("Already only one window");
/*
* all CTRL-W window commands are handled here, called from normal_cmd().
*/
-void
-do_window (
+void
+do_window(
int nchar,
long Prenum,
int xchar /* extra char from ":wincmd gx" or NUL */
@@ -131,8 +131,20 @@ do_window (
case '^':
CHECK_CMDWIN;
reset_VIsual_and_resel(); // stop Visual mode
- cmd_with_count("split #", (char_u *)cbuf, sizeof(cbuf), Prenum);
- do_cmdline_cmd(cbuf);
+
+ if (buflist_findnr(Prenum == 0 ? curwin->w_alt_fnum : Prenum) == NULL) {
+ if (Prenum == 0) {
+ EMSG(_(e_noalt));
+ } else {
+ EMSGN(_("E92: Buffer %" PRId64 " not found"), Prenum);
+ }
+ break;
+ }
+
+ if (!curbuf_locked() && win_split(0, 0) == OK) {
+ (void)buflist_getfile(Prenum == 0 ? curwin->w_alt_fnum : Prenum,
+ (linenr_T)0, GETF_ALT, false);
+ }
break;
/* open new window */
@@ -621,6 +633,12 @@ void win_set_minimal_style(win_T *wp)
xfree(wp->w_p_scl);
wp->w_p_scl = (char_u *)xstrdup("auto");
}
+
+ // colorcolumn: cleared
+ if (wp->w_p_cc != NULL && *wp->w_p_cc != NUL) {
+ xfree(wp->w_p_cc);
+ wp->w_p_cc = (char_u *)xstrdup("");
+ }
}
void win_config_float(win_T *wp, FloatConfig fconfig)
@@ -1518,17 +1536,22 @@ static void win_init(win_T *newp, win_T *oldp, int flags)
/* Don't copy the location list. */
newp->w_llist = NULL;
newp->w_llist_ref = NULL;
- } else
- copy_loclist(oldp, newp);
+ } else {
+ copy_loclist_stack(oldp, newp);
+ }
newp->w_localdir = (oldp->w_localdir == NULL)
? NULL : vim_strsave(oldp->w_localdir);
/* copy tagstack and folds */
for (i = 0; i < oldp->w_tagstacklen; i++) {
- newp->w_tagstack[i] = oldp->w_tagstack[i];
- if (newp->w_tagstack[i].tagname != NULL)
- newp->w_tagstack[i].tagname =
- vim_strsave(newp->w_tagstack[i].tagname);
+ taggy_T *tag = &newp->w_tagstack[i];
+ *tag = oldp->w_tagstack[i];
+ if (tag->tagname != NULL) {
+ tag->tagname = vim_strsave(tag->tagname);
+ }
+ if (tag->user_data != NULL) {
+ tag->user_data = vim_strsave(tag->user_data);
+ }
}
newp->w_tagstackidx = oldp->w_tagstackidx;
newp->w_tagstacklen = oldp->w_tagstacklen;
@@ -1558,7 +1581,7 @@ static void win_init_some(win_T *newp, win_T *oldp)
/// 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
+bool win_valid(const win_T *win) FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
{
if (win == NULL) {
return false;
@@ -2401,6 +2424,7 @@ int win_close(win_T *win, bool free_buf)
bool help_window = false;
tabpage_T *prev_curtab = curtab;
frame_T *win_frame = win->w_floating ? NULL : win->w_frame->fr_parent;
+ const bool had_diffmode = win->w_p_diff;
if (last_window() && !win->w_floating) {
EMSG(_("E444: Cannot close last window"));
@@ -2625,6 +2649,22 @@ int win_close(win_T *win, bool free_buf)
if (help_window)
restore_snapshot(SNAP_HELP_IDX, close_curwin);
+ // If the window had 'diff' set and now there is only one window left in
+ // the tab page with 'diff' set, and "closeoff" is in 'diffopt', then
+ // execute ":diffoff!".
+ if (diffopt_closeoff() && had_diffmode && curtab == prev_curtab) {
+ int diffcount = 0;
+
+ FOR_ALL_WINDOWS_IN_TAB(dwin, curtab) {
+ if (dwin->w_p_diff) {
+ diffcount++;
+ }
+ }
+ if (diffcount == 1) {
+ do_cmdline_cmd("diffoff!");
+ }
+ }
+
curwin->w_pos_changed = true;
redraw_all_later(NOT_VALID);
return OK;
@@ -4332,9 +4372,10 @@ static void win_goto_hor(bool left, long count)
}
}
-/*
- * Make window "wp" the current window.
- */
+/// Make window `wp` the current window.
+///
+/// @warning Autocmds may close the window immediately, so caller must check
+/// win_valid(wp).
void win_enter(win_T *wp, bool undo_sync)
{
win_enter_ext(wp, undo_sync, false, false, true, true);
@@ -4626,8 +4667,10 @@ win_free (
xfree(wp->w_lines);
- for (i = 0; i < wp->w_tagstacklen; ++i)
+ for (i = 0; i < wp->w_tagstacklen; i++) {
xfree(wp->w_tagstack[i].tagname);
+ xfree(wp->w_tagstack[i].user_data);
+ }
xfree(wp->w_localdir);
@@ -5598,10 +5641,14 @@ void scroll_to_fraction(win_T *wp, int prev_height)
int sline, line_size;
int height = wp->w_height_inner;
- // Don't change w_topline when height is zero. Don't set w_topline when
- // 'scrollbind' is set and this isn't the current window.
+ // Don't change w_topline in any of these cases:
+ // - window height is 0
+ // - 'scrollbind' is set and this isn't the current window
+ // - window height is sufficient to display the whole buffer and first line
+ // is visible.
if (height > 0
&& (!wp->w_p_scb || wp == curwin)
+ && (height < wp->w_buffer->b_ml.ml_line_count || wp->w_topline > 1)
) {
/*
* Find a value for w_topline that shows the cursor at the same