Hi,
2016-8-11(Thu) 18:50:11 UTC+9 h_east:
> Hi guraga and list,
>
> 2016-8-11(Thu) 16:54:13 UTC+9 guraga:
> > Mark saved, if run
> >
> >
> > ./vim-7.4.230 test_file.txt
> >
> >
> > move cursor and press "ZQ".
> >
> >
> > Also mark saved, if run
> >
> >
> > ./vim-7.4.230
> >
> >
> > execute ":edit test_file.txt", move cursor, press "ZQ".
> >
> >
> > Why it is not saved, if executed ":tabnew" command? It's seems as a bug.
>
> I investegasted and grasped.
> This problem occurs with a combination of tabpage closed and buffer closed.
>
> I'm writing a patch now.
> Please wait a few hours.
I attached a patch.
I am glad if you could confirm.
Investigation result:
When `close_buffer()` has been called from `win_close_othertab()`, `curtab`
does not contained `win`.
So `win_valid()` result is FALSE, then doesn't save the last cursor position of
file.
I add the `tabpage_T *tp` to the argument of `close_buffer()`, it has been
changed to window validation check using it.
In order to realize this, I add the function `win_valid_in_tabpage()`.
Please confirm this.
--
Best regards,
Hirohito Higashi (a.k.a. h_east)
--
--
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php
---
You received this message because you are subscribed to the Google Groups
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.
diff --git a/src/buffer.c b/src/buffer.c
index 2a09a63..3d479c7 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -163,7 +163,7 @@ open_buffer(
* There MUST be a memfile, otherwise we can't do anything
* If we can't create one for the current buffer, take another buffer
*/
- close_buffer(NULL, curbuf, 0, FALSE);
+ close_buffer(NULL, NULL, curbuf, 0, FALSE);
FOR_ALL_BUFFERS(curbuf)
if (curbuf->b_ml.ml_mfp != NULL)
break;
@@ -438,6 +438,7 @@ buf_hashtab_remove(buf_T *buf)
*/
void
close_buffer(
+ tabpage_T *tp, /* if NULL, same as curtab */
win_T *win, /* if not NULL, set b_last_cursor */
buf_T *buf,
int action,
@@ -473,11 +474,14 @@ close_buffer(
unload_buf = TRUE;
#endif
- if (win != NULL
+ if (
#ifdef FEAT_WINDOWS
- && win_valid(win) /* in case autocommands closed the window */
+ /* in case autocommands closed the window */
+ win_valid_in_tabpage(tp, win)
+#else
+ win != NULL
#endif
- )
+ )
{
/* Set b_last_cursor when closing the last window for the buffer.
* Remember the last cursor position and window options of the buffer.
@@ -581,7 +585,7 @@ aucmd_abort:
if (
#ifdef FEAT_WINDOWS
- win_valid(win) &&
+ win_valid_in_tabpage(tp, win) &&
#else
win != NULL &&
#endif
@@ -948,7 +952,7 @@ handle_swap_exists(bufref_T *old_curbuf)
* open a new, empty buffer. */
swap_exists_action = SEA_NONE; /* don't want it again */
swap_exists_did_quit = TRUE;
- close_buffer(curwin, curbuf, DOBUF_UNLOAD, FALSE);
+ close_buffer(NULL, curwin, curbuf, DOBUF_UNLOAD, FALSE);
if (old_curbuf == NULL || !bufref_valid(old_curbuf)
|| old_curbuf->br_buf == curbuf)
buf = buflist_new(NULL, NULL, 1L, BLN_CURBUF | BLN_LISTED);
@@ -1166,7 +1170,7 @@ empty_curbuf(
* if the buffer still exists.
*/
if (buf != curbuf && bufref_valid(&bufref) && buf->b_nwindows == 0)
- close_buffer(NULL, buf, action, FALSE);
+ close_buffer(NULL, NULL, buf, action, FALSE);
if (!close_others)
need_fileinfo = FALSE;
return retval;
@@ -1365,7 +1369,7 @@ do_buffer(
if (buf != curbuf && bufref_valid(&bufref))
#endif
if (buf->b_nwindows <= 0)
- close_buffer(NULL, buf, action, FALSE);
+ close_buffer(NULL, NULL, buf, action, FALSE);
return OK;
}
@@ -1610,8 +1614,8 @@ set_curbuf(buf_T *buf, int action)
#endif
if (prevbuf == curbuf)
u_sync(FALSE);
- close_buffer(prevbuf == curwin->w_buffer ? curwin : NULL, prevbuf,
- unload ? action : (action == DOBUF_GOTO
+ close_buffer(NULL, prevbuf == curwin->w_buffer ? curwin : NULL,
+ prevbuf, unload ? action : (action == DOBUF_GOTO
&& !P_HID(prevbuf)
&& !bufIsChanged(prevbuf)) ? DOBUF_UNLOAD : 0, FALSE);
#ifdef FEAT_WINDOWS
@@ -3048,7 +3052,7 @@ setfname(
return FAIL;
}
/* delete from the list */
- close_buffer(NULL, obuf, DOBUF_WIPE, FALSE);
+ close_buffer(NULL, NULL, obuf, DOBUF_WIPE, FALSE);
}
sfname = vim_strsave(sfname);
if (ffname == NULL || sfname == NULL)
@@ -6055,7 +6059,7 @@ wipe_buffer(
if (!aucmd) /* Don't trigger BufDelete autocommands here. */
block_autocmds();
#endif
- close_buffer(NULL, buf, DOBUF_WIPE, FALSE);
+ close_buffer(NULL, NULL, buf, DOBUF_WIPE, FALSE);
#ifdef FEAT_AUTOCMD
if (!aucmd)
unblock_autocmds();
diff --git a/src/ex_cmds.c b/src/ex_cmds.c
index 30b0d5c..d5c9a44 100644
--- a/src/ex_cmds.c
+++ b/src/ex_cmds.c
@@ -3941,7 +3941,7 @@ do_ecmd(
/* close the link to the current buffer */
u_sync(FALSE);
- close_buffer(oldwin, curbuf,
+ close_buffer(NULL, oldwin, curbuf,
(flags & ECMD_HIDE) ? 0 : DOBUF_UNLOAD, FALSE);
#ifdef FEAT_AUTOCMD
diff --git a/src/ex_getln.c b/src/ex_getln.c
index 642e090..332b859 100644
--- a/src/ex_getln.c
+++ b/src/ex_getln.c
@@ -6911,7 +6911,7 @@ ex_window(void)
/* win_close() may have already wiped the buffer when 'bh' is
* set to 'wipe' */
if (bufref_valid(&bufref))
- close_buffer(NULL, bufref.br_buf, DOBUF_WIPE, FALSE);
+ close_buffer(NULL, NULL, bufref.br_buf, DOBUF_WIPE, FALSE);
/* Restore window sizes. */
win_size_restore(&winsizes);
diff --git a/src/misc2.c b/src/misc2.c
index f44c33c..8710644 100644
--- a/src/misc2.c
+++ b/src/misc2.c
@@ -1177,7 +1177,7 @@ free_all_mem(void)
set_bufref(&bufref, buf);
nextbuf = buf->b_next;
- close_buffer(NULL, buf, DOBUF_WIPE, FALSE);
+ close_buffer(NULL, NULL, buf, DOBUF_WIPE, FALSE);
if (bufref_valid(&bufref))
buf = nextbuf; /* didn't work, try next one */
else
diff --git a/src/proto/buffer.pro b/src/proto/buffer.pro
index 183f79a..3d75dbb 100644
--- a/src/proto/buffer.pro
+++ b/src/proto/buffer.pro
@@ -3,7 +3,7 @@ int open_buffer(int read_stdin, exarg_T *eap, int flags);
void set_bufref(bufref_T *bufref, buf_T *buf);
int bufref_valid(bufref_T *bufref);
int buf_valid(buf_T *buf);
-void close_buffer(win_T *win, buf_T *buf, int action, int abort_if_last);
+void close_buffer(tabpage_T *tp, win_T *win, buf_T *buf, int action, int abort_if_last);
void buf_clear_file(buf_T *buf);
void buf_freeall(buf_T *buf, int flags);
void goto_buffer(exarg_T *eap, int start, int dir, int count);
diff --git a/src/proto/window.pro b/src/proto/window.pro
index e091e34..1ee2215 100644
--- a/src/proto/window.pro
+++ b/src/proto/window.pro
@@ -4,6 +4,7 @@ void get_wincmd_addr_type(char_u *arg, exarg_T *eap);
int win_split(int size, int flags);
int win_split_ins(int size, int flags, win_T *new_wp, int dir);
int win_valid(win_T *win);
+int win_valid_in_tabpage(tabpage_T *tp, win_T *win);
int win_count(void);
int make_windows(int count, int vertical);
void win_move_after(win_T *win1, win_T *win2);
diff --git a/src/quickfix.c b/src/quickfix.c
index aa94ae6..a40e78d 100644
--- a/src/quickfix.c
+++ b/src/quickfix.c
@@ -4522,7 +4522,7 @@ unload_dummy_buffer(buf_T *buf, char_u *dirname_start)
{
if (curbuf != buf) /* safety check */
{
- close_buffer(NULL, buf, DOBUF_UNLOAD, FALSE);
+ close_buffer(NULL, NULL, buf, DOBUF_UNLOAD, FALSE);
/* When autocommands/'autochdir' option changed directory: go back. */
restore_start_dir(dirname_start);
diff --git a/src/window.c b/src/window.c
index 925a147..7c5bf1a 100644
--- a/src/window.c
+++ b/src/window.c
@@ -1374,6 +1374,22 @@ win_valid(win_T *win)
}
/*
+ * Check if "win" is a pointer to an existing window in tabpage.
+ */
+ int
+win_valid_in_tabpage(tabpage_T *tp, win_T *win)
+{
+ win_T *wp;
+
+ if (win == NULL)
+ return FALSE;
+ FOR_ALL_WINDOWS_IN_TAB(tp, wp)
+ if (wp == win)
+ return TRUE;
+ return FALSE;
+}
+
+/*
* Return the number of windows.
*/
int
@@ -2355,7 +2371,8 @@ win_close(win_T *win, int free_buf)
#ifdef FEAT_AUTOCMD
win->w_closing = TRUE;
#endif
- close_buffer(win, win->w_buffer, free_buf ? DOBUF_UNLOAD : 0, TRUE);
+ close_buffer(NULL, win, win->w_buffer, free_buf ? DOBUF_UNLOAD : 0,
+ TRUE);
#ifdef FEAT_AUTOCMD
if (win_valid(win))
win->w_closing = FALSE;
@@ -2475,7 +2492,7 @@ win_close_othertab(win_T *win, int free_buf, tabpage_T *tp)
#endif
/* Close the link to the buffer. */
- close_buffer(win, win->w_buffer, free_buf ? DOBUF_UNLOAD : 0, FALSE);
+ close_buffer(tp, win, win->w_buffer, free_buf ? DOBUF_UNLOAD : 0, FALSE);
/* Careful: Autocommands may have closed the tab page or made it the
* current tab page. */