diff src/evalwindow.c @ 18049:a9f1656f13c9 v8.1.2020

patch 8.1.2020: it is not easy to change the window layout Commit: https://github.com/vim/vim/commit/d20dcb3d011da6111153109f6e46fbd5c7fe9fb6 Author: Bram Moolenaar <Bram@vim.org> Date: Tue Sep 10 21:22:58 2019 +0200 patch 8.1.2020: it is not easy to change the window layout Problem: It is not easy to change the window layout. Solution: Add win_splitmove(). (Andy Massimino, closes https://github.com/vim/vim/issues/4561)
author Bram Moolenaar <Bram@vim.org>
date Tue, 10 Sep 2019 21:30:05 +0200
parents cf8e0c7e0cb9
children f4b51934d4f8
line wrap: on
line diff
--- a/src/evalwindow.c
+++ b/src/evalwindow.c
@@ -744,6 +744,92 @@ f_win_screenpos(typval_T *argvars, typva
 }
 
 /*
+ * Move the window wp into a new split of targetwin in a given direction
+ */
+    static void
+win_move_into_split(win_T *wp, win_T *targetwin, int size, int flags)
+{
+    int	    dir;
+    int	    height = wp->w_height;
+    win_T   *oldwin = curwin;
+
+    if (wp == targetwin)
+	return;
+
+    // Jump to the target window
+    if (curwin != targetwin)
+	win_goto(targetwin);
+
+    // Remove the old window and frame from the tree of frames
+    (void)winframe_remove(wp, &dir, NULL);
+    win_remove(wp, NULL);
+    last_status(FALSE);	    // may need to remove last status line
+    (void)win_comp_pos();   // recompute window positions
+
+    // Split a window on the desired side and put the old window there
+    (void)win_split_ins(size, flags, wp, dir);
+
+    // If splitting horizontally, try to preserve height
+    if (size == 0 && !(flags & WSP_VERT))
+    {
+	win_setheight_win(height, wp);
+	if (p_ea)
+	    win_equal(wp, TRUE, 'v');
+    }
+
+#if defined(FEAT_GUI)
+    // When 'guioptions' includes 'L' or 'R' may have to remove or add
+    // scrollbars.  Have to update them anyway.
+    gui_may_update_scrollbars();
+#endif
+
+    if (oldwin != curwin)
+	win_goto(oldwin);
+}
+
+/*
+ * "win_splitmove()" function
+ */
+    void
+f_win_splitmove(typval_T *argvars, typval_T *rettv)
+{
+    win_T   *wp;
+    win_T   *targetwin;
+    int     flags = 0, size = 0;
+
+    wp = find_win_by_nr_or_id(&argvars[0]);
+    targetwin = find_win_by_nr_or_id(&argvars[1]);
+
+    if (wp == NULL || targetwin == NULL || wp == targetwin)
+    {
+        emsg(_(e_invalwindow));
+	rettv->vval.v_number = -1;
+	return;
+    }
+
+    if (argvars[2].v_type != VAR_UNKNOWN)
+    {
+        dict_T      *d;
+        dictitem_T  *di;
+
+        if (argvars[2].v_type != VAR_DICT || argvars[2].vval.v_dict == NULL)
+        {
+            emsg(_(e_invarg));
+            return;
+        }
+
+        d = argvars[2].vval.v_dict;
+        if (dict_get_number(d, (char_u *)"vertical"))
+            flags |= WSP_VERT;
+        if ((di = dict_find(d, (char_u *)"rightbelow", -1)) != NULL)
+            flags |= tv_get_number(&di->di_tv) ? WSP_BELOW : WSP_ABOVE;
+        size = (int)dict_get_number(d, (char_u *)"size");
+    }
+
+    win_move_into_split(wp, targetwin, size, flags);
+}
+
+/*
  * "winbufnr(nr)" function
  */
     void