summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2006-04-28 22:32:28 +0000
committerBram Moolenaar <Bram@vim.org>2006-04-28 22:32:28 +0000
commitc1b5286315db24e25b05f9ac8d19f11e11793a8f (patch)
treee7456863ab65a4b65059742ff2f95e2682181c0d
parent437df8f48460ad687c6f4cc5dd4c9b66155c7b05 (diff)
updated for version 7.0f04
-rw-r--r--src/getchar.c8
-rw-r--r--src/window.c40
2 files changed, 32 insertions, 16 deletions
diff --git a/src/getchar.c b/src/getchar.c
index 629ad770be..7b1cf875cb 100644
--- a/src/getchar.c
+++ b/src/getchar.c
@@ -2321,7 +2321,8 @@ vgetorpeek(advance)
/*
* Handle ":map <expr>": evaluate the {rhs} as an
* expression. Save and restore the typeahead so that
- * getchar() can be used.
+ * getchar() can be used. Also save and restore the
+ * command line for "normal :".
*/
if (mp->m_expr)
{
@@ -4301,8 +4302,13 @@ eval_map_expr(str)
{
char_u *res;
char_u *p;
+ char_u *save_cmd;
+ save_cmd = save_cmdline_alloc();
+ if (save_cmd == NULL)
+ return NULL;
p = eval_to_string(str, NULL, FALSE);
+ restore_cmdline_alloc(save_cmd);
if (p == NULL)
return NULL;
res = vim_strsave_escape_csi(p);
diff --git a/src/window.c b/src/window.c
index 628f9e0f97..8c031bf625 100644
--- a/src/window.c
+++ b/src/window.c
@@ -2003,6 +2003,7 @@ win_close(win, free_buf)
int close_curwin = FALSE;
int dir;
int help_window = FALSE;
+ tabpage_T *prev_curtab = curtab;
if (last_window())
{
@@ -2051,44 +2052,53 @@ win_close(win, free_buf)
* Close the link to the buffer.
*/
close_buffer(win, win->w_buffer, free_buf ? DOBUF_UNLOAD : 0);
+
/* Autocommands may have closed the window already, or closed the only
- * other window. */
- if (!win_valid(win) || last_window())
+ * other window or moved to another tab page. */
+ if (!win_valid(win) || last_window() || curtab != prev_curtab)
return;
- /* Free the memory used for the window. */
- wp = win_free_mem(win, &dir, NULL);
-
- /* When closing the last window in a tab page go to another tab page. */
- if (wp == NULL)
+ /* When closing the last window in a tab page go to another tab page. This
+ * must be done before freeing memory to avoid that "topframe" becomes
+ * invalid (it may be used in GUI events). */
+ if (firstwin == lastwin)
{
tabpage_T *ptp = NULL;
tabpage_T *tp;
tabpage_T *atp = alt_tabpage();
- for (tp = first_tabpage; tp != curtab; tp = tp->tp_next)
+ /* We don't do the window resizing stuff, let enter_tabpage() take
+ * care of entering a window in another tab page. */
+ enter_tabpage(atp, old_curbuf);
+
+ for (tp = first_tabpage; tp != NULL && tp != prev_curtab;
+ tp = tp->tp_next)
ptp = tp;
- if (tp == NULL)
+ if (tp != prev_curtab || tp->tp_firstwin != win)
{
- EMSG2(_(e_intern2), "win_close()");
+ /* Autocommands must have closed it when jumping to the other tab
+ * page. */
return;
}
+
+ (void)win_free_mem(win, &dir, tp);
+
if (ptp == NULL)
first_tabpage = tp->tp_next;
else
ptp->tp_next = tp->tp_next;
free_tabpage(tp);
- /* We don't do the window resizing stuff, let enter_tabpage() take
- * care of entering a window in another tab page. */
- enter_tabpage(atp, old_curbuf);
return;
}
+ /* Free the memory used for the window. */
+ wp = win_free_mem(win, &dir, NULL);
+
/* 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. */
- else if (win == curwin)
+ if (win == curwin)
{
curwin = wp;
#ifdef FEAT_QUICKFIX
@@ -2213,7 +2223,7 @@ win_close_othertab(win, free_buf, tp)
}
ptp->tp_next = tp->tp_next;
}
- vim_free(tp);
+ free_tabpage(tp);
}
}