patch 7.4.2101
Problem:    Looping over windows, buffers and tab pages is inconsistant.
Solution:   Use FOR_ALL_ macros everywhere. (Yegappan Lakshmanan)
diff --git a/src/buffer.c b/src/buffer.c
index 8590e2a..60fb67a 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -105,7 +105,7 @@
 	 * If we can't create one for the current buffer, take another buffer
 	 */
 	close_buffer(NULL, curbuf, 0, FALSE);
-	for (curbuf = firstbuf; curbuf != NULL; curbuf = curbuf->b_next)
+	FOR_ALL_BUFFERS(curbuf)
 	    if (curbuf->b_ml.ml_mfp != NULL)
 		break;
 	/*
@@ -1284,7 +1284,7 @@
 	 * If deleting the last (listed) buffer, make it empty.
 	 * The last (listed) buffer cannot be unloaded.
 	 */
-	for (bp = firstbuf; bp != NULL; bp = bp->b_next)
+	FOR_ALL_BUFFERS(bp)
 	    if (bp->b_p_bl && bp != buf)
 		break;
 	if (bp == NULL && buf == curbuf)
@@ -1410,7 +1410,7 @@
 	    buf = bp;
 	if (buf == NULL)	/* No loaded buffer, find listed one */
 	{
-	    for (buf = firstbuf; buf != NULL; buf = buf->b_next)
+	    FOR_ALL_BUFFERS(buf)
 		if (buf->b_p_bl && buf != curbuf)
 		    break;
 	}
@@ -2406,7 +2406,7 @@
 #ifdef FEAT_WINDOWS
 			    win_T	*wp;
 
-			    for (wp = firstwin; wp != NULL; wp = wp->w_next)
+			    FOR_ALL_WINDOWS(wp)
 				if (wp->w_buffer == buf)
 				    break;
 			    if (wp == NULL)
@@ -2508,7 +2508,7 @@
 	for (round = 1; round <= 2; ++round)
 	{
 	    count = 0;
-	    for (buf = firstbuf; buf != NULL; buf = buf->b_next)
+	    FOR_ALL_BUFFERS(buf)
 	    {
 		if (!buf->b_p_bl)	/* skip unlisted buffers */
 		    continue;
@@ -2734,7 +2734,7 @@
 
     if (wip->wi_opt.wo_diff)
     {
-	for (wp = firstwin; wp != NULL; wp = wp->w_next)
+	FOR_ALL_WINDOWS(wp)
 	    /* return FALSE when it's a window in the current tab page, thus
 	     * the buffer was in diff mode here */
 	    if (wip->wi_win == wp)
@@ -3153,7 +3153,7 @@
 {
     buf_T	*bp;
 
-    for (bp = firstbuf; bp != NULL; bp = bp->b_next)
+    FOR_ALL_BUFFERS(bp)
     {
 	if (bp->b_ffname != NULL)
 	    slash_adjust(bp->b_ffname);
@@ -5083,7 +5083,7 @@
 #endif
 	{
 	    /* Check if this buffer already has a window */
-	    for (wp = firstwin; wp != NULL; wp = wp->w_next)
+	    FOR_ALL_WINDOWS(wp)
 		if (wp->w_buffer == buf)
 		    break;
 	    /* If the buffer already has a window, move it */
@@ -5461,7 +5461,7 @@
 #endif
 
     fputs(_("\n# Buffer list:\n"), fp);
-    for (buf = firstbuf; buf != NULL ; buf = buf->b_next)
+    FOR_ALL_BUFFERS(buf)
     {
 	if (buf->b_fname == NULL
 		|| !buf->b_p_bl
@@ -5847,7 +5847,7 @@
 {
     buf_T	*buf;		/* buffer we are checking for signs */
 
-    for (buf = firstbuf; buf != NULL; buf = buf->b_next)
+    FOR_ALL_BUFFERS(buf)
 	if (buf->b_signlist != NULL)
 	    buf_delete_signs(buf);
 }
diff --git a/src/diff.c b/src/diff.c
index 287f434..35e37d7 100644
--- a/src/diff.c
+++ b/src/diff.c
@@ -65,7 +65,7 @@
     int		i;
     tabpage_T	*tp;
 
-    for (tp = first_tabpage; tp != NULL; tp = tp->tp_next)
+    FOR_ALL_TABPAGES(tp)
     {
 	i = diff_buf_idx_tp(buf, tp);
 	if (i != DB_COUNT)
@@ -92,7 +92,7 @@
     {
 	/* When there is no window showing a diff for this buffer, remove
 	 * it from the diffs. */
-	for (wp = firstwin; wp != NULL; wp = wp->w_next)
+	FOR_ALL_WINDOWS(wp)
 	    if (wp->w_buffer == win->w_buffer && wp->w_p_diff)
 		break;
 	if (wp == NULL)
@@ -178,7 +178,7 @@
     tabpage_T	*tp;
     int		i;
 
-    for (tp = first_tabpage; tp != NULL; tp = tp->tp_next)
+    FOR_ALL_TABPAGES(tp)
     {
 	i = diff_buf_idx_tp(buf, tp);
 	if (i != DB_COUNT)
@@ -204,7 +204,7 @@
     tabpage_T	*tp;
 
     /* Handle all tab pages that use the current buffer in a diff. */
-    for (tp = first_tabpage; tp != NULL; tp = tp->tp_next)
+    FOR_ALL_TABPAGES(tp)
     {
 	idx = diff_buf_idx_tp(curbuf, tp);
 	if (idx != DB_COUNT)
@@ -591,7 +591,7 @@
     win_T	*wp;
     int		n;
 
-    for (wp = firstwin; wp != NULL; wp = wp->w_next)
+    FOR_ALL_WINDOWS(wp)
 	if (wp->w_p_diff)
 	{
 	    redraw_win_later(wp, SOME_VALID);
@@ -1198,7 +1198,7 @@
     int		diffwin = FALSE;
 #endif
 
-    for (wp = firstwin; wp != NULL; wp = wp->w_next)
+    FOR_ALL_WINDOWS(wp)
     {
 	if (eap->forceit ? wp->w_p_diff : wp == curwin)
 	{
@@ -1879,7 +1879,7 @@
 
     /* If "icase" or "iwhite" was added or removed, need to update the diff. */
     if (diff_flags != diff_flags_new)
-	for (tp = first_tabpage; tp != NULL; tp = tp->tp_next)
+	FOR_ALL_TABPAGES(tp)
 	    tp->tp_diff_invalid = TRUE;
 
     diff_flags = diff_flags_new;
@@ -2434,7 +2434,7 @@
     int		i;
     win_T	*wp;
 
-    for (wp = firstwin; wp != NULL; wp = wp->w_next)
+    FOR_ALL_WINDOWS(wp)
 	for (i = 0; i < DB_COUNT; ++i)
 	    if (curtab->tp_diffbuf[i] == wp->w_buffer && i != skip_idx)
 		foldUpdate(wp, dp->df_lnum[i],
@@ -2450,7 +2450,7 @@
 {
     tabpage_T	*tp;
 
-    for (tp = first_tabpage; tp != NULL; tp = tp->tp_next)
+    FOR_ALL_TABPAGES(tp)
 	if (diff_buf_idx_tp(buf, tp) != DB_COUNT)
 	    return TRUE;
     return FALSE;
diff --git a/src/edit.c b/src/edit.c
index 4bce8a3..a60d922 100644
--- a/src/edit.c
+++ b/src/edit.c
@@ -4239,7 +4239,7 @@
 
     if (!compl_started)
     {
-	for (ins_buf = firstbuf; ins_buf != NULL; ins_buf = ins_buf->b_next)
+	FOR_ALL_BUFFERS(ins_buf)
 	    ins_buf->b_scanned = 0;
 	found_all = FALSE;
 	ins_buf = curbuf;
diff --git a/src/eval.c b/src/eval.c
index 3bc2afd..6f10756 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -5253,7 +5253,7 @@
 	abort = abort || set_ref_in_ht(&SCRIPT_VARS(i), copyID, NULL);
 
     /* buffer-local variables */
-    for (buf = firstbuf; buf != NULL; buf = buf->b_next)
+    FOR_ALL_BUFFERS(buf)
 	abort = abort || set_ref_in_item(&buf->b_bufvar.di_tv, copyID,
 								  NULL, NULL);
 
@@ -5269,7 +5269,7 @@
 
 #ifdef FEAT_WINDOWS
     /* tabpage-local variables */
-    for (tp = first_tabpage; tp != NULL; tp = tp->tp_next)
+    FOR_ALL_TABPAGES(tp)
 	abort = abort || set_ref_in_item(&tp->tp_winvar.di_tv, copyID,
 								  NULL, NULL);
 #endif
@@ -8303,8 +8303,8 @@
     if (nr == 0)
 	return curwin;
 
-    for (wp = (tp == NULL || tp == curtab) ? firstwin : tp->tp_firstwin;
-						  wp != NULL; wp = wp->w_next)
+    FOR_ALL_WINDOWS_IN_TAB(tp, wp)
+    {
 	if (nr >= LOWEST_WIN_ID)
 	{
 	    if (wp->w_id == nr)
@@ -8312,6 +8312,7 @@
 	}
 	else if (--nr <= 0)
 	    break;
+    }
     if (nr >= LOWEST_WIN_ID)
 	return NULL;
     return wp;
diff --git a/src/evalfunc.c b/src/evalfunc.c
index ec347c1..ae17038 100644
--- a/src/evalfunc.c
+++ b/src/evalfunc.c
@@ -1439,7 +1439,7 @@
 	{
 	    /* No full path name match, try a match with a URL or a "nofile"
 	     * buffer, these don't use the full path. */
-	    for (buf = firstbuf; buf != NULL; buf = buf->b_next)
+	    FOR_ALL_BUFFERS(buf)
 		if (buf->b_fname != NULL
 			&& (path_with_url(buf->b_fname)
 #ifdef FEAT_QUICKFIX
@@ -1597,7 +1597,7 @@
     ++emsg_off;
     buf = get_buf_tv(&argvars[0], TRUE);
 #ifdef FEAT_WINDOWS
-    for (wp = firstwin; wp; wp = wp->w_next)
+    FOR_ALL_WINDOWS(wp)
     {
 	++winnr;
 	if (wp->w_buffer == buf)
@@ -6383,7 +6383,7 @@
     int		n = 0;
     buf_T	*buf;
 
-    for (buf = firstbuf; buf != NULL; buf = buf->b_next)
+    FOR_ALL_BUFFERS(buf)
 	if (n < buf->b_fnum)
 	    n = buf->b_fnum;
 
@@ -12373,7 +12373,7 @@
     char_u	buf[50];
 
     ga_init2(&ga, (int)sizeof(char), 70);
-    for (wp = firstwin; wp != NULL; wp = wp->w_next)
+    FOR_ALL_WINDOWS(wp)
     {
 	sprintf((char *)buf, "%dresize %d|", winnr, wp->w_height);
 	ga_concat(&ga, buf);
diff --git a/src/ex_cmds.c b/src/ex_cmds.c
index 7ec17b1..7d8196c 100644
--- a/src/ex_cmds.c
+++ b/src/ex_cmds.c
@@ -1497,7 +1497,7 @@
 		&& !autocmd_busy
 #endif
 		&& msg_silent == 0)
-	for (buf = firstbuf; buf; buf = buf->b_next)
+	FOR_ALL_BUFFERS(buf)
 	    if (bufIsChanged(buf))
 	    {
 #ifdef FEAT_GUI_MSWIN
@@ -2345,7 +2345,7 @@
 #endif
 
     /* Change file names to buffer numbers for fmarks. */
-    for (buf = firstbuf; buf != NULL; buf = buf->b_next)
+    FOR_ALL_BUFFERS(buf)
 	fmarks_check_names(buf);
 
     return eof;
@@ -3413,7 +3413,7 @@
     if (eap->cmdidx == CMD_xall || eap->cmdidx == CMD_wqall)
 	exiting = TRUE;
 
-    for (buf = firstbuf; buf != NULL; buf = buf->b_next)
+    FOR_ALL_BUFFERS(buf)
     {
 	if (bufIsChanged(buf))
 	{
@@ -6115,7 +6115,7 @@
      */
     if (!curwin->w_p_pvw)
     {
-	for (wp = firstwin; wp != NULL; wp = wp->w_next)
+	FOR_ALL_WINDOWS(wp)
 	    if (wp->w_p_pvw)
 		break;
 	if (wp != NULL)
@@ -6272,7 +6272,7 @@
 	if (cmdmod.tab != 0)
 	    wp = NULL;
 	else
-	    for (wp = firstwin; wp != NULL; wp = wp->w_next)
+	    FOR_ALL_WINDOWS(wp)
 		if (wp->w_buffer != NULL && wp->w_buffer->b_help)
 		    break;
 	if (wp != NULL && wp->w_buffer->b_nwindows > 0)
@@ -7745,7 +7745,7 @@
 		if (idx == SIGNCMD_UNPLACE && *arg == NUL)
 		{
 		    /* ":sign unplace {id}": remove placed sign by number */
-		    for (buf = firstbuf; buf != NULL; buf = buf->b_next)
+		    FOR_ALL_BUFFERS(buf)
 			if ((lnum = buf_delsign(buf, id)) != 0)
 			    update_debug_sign(buf, lnum);
 		    return;
diff --git a/src/ex_cmds2.c b/src/ex_cmds2.c
index adc5352..83305b2 100644
--- a/src/ex_cmds2.c
+++ b/src/ex_cmds2.c
@@ -1721,7 +1721,7 @@
 
     if (!(p_aw || p_awa) || !p_write)
 	return;
-    for (buf = firstbuf; buf; buf = buf->b_next)
+    FOR_ALL_BUFFERS(buf)
 	if (bufIsChanged(buf) && !buf->b_p_ro)
 	{
 #ifdef FEAT_AUTOCMD
@@ -1764,7 +1764,7 @@
 	    int		count = 0;
 
 	    if (flags & CCGD_ALLBUF)
-		for (buf2 = firstbuf; buf2 != NULL; buf2 = buf2->b_next)
+		FOR_ALL_BUFFERS(buf2)
 		    if (bufIsChanged(buf2)
 				     && (buf2->b_ffname != NULL
 # ifdef FEAT_BROWSE
@@ -1868,7 +1868,7 @@
 	 * Skip readonly buffers, these need to be confirmed
 	 * individually.
 	 */
-	for (buf2 = firstbuf; buf2 != NULL; buf2 = buf2->b_next)
+	FOR_ALL_BUFFERS(buf2)
 	{
 	    if (bufIsChanged(buf2)
 		    && (buf2->b_ffname != NULL
@@ -1904,7 +1904,7 @@
 	/*
 	 * mark all buffers as unchanged
 	 */
-	for (buf2 = firstbuf; buf2 != NULL; buf2 = buf2->b_next)
+	FOR_ALL_BUFFERS(buf2)
 	    unchanged(buf2, TRUE);
     }
 }
@@ -1964,7 +1964,7 @@
     win_T	*wp;
 #endif
 
-    for (buf = firstbuf; buf != NULL; buf = buf->b_next)
+    FOR_ALL_BUFFERS(buf)
 	++bufcount;
 
     if (bufcount == 0)
@@ -1983,13 +1983,13 @@
 	    add_bufnum(bufnrs, &bufnum, wp->w_buffer->b_fnum);
 
     /* buf in other tab */
-    for (tp = first_tabpage; tp != NULL; tp = tp->tp_next)
+    FOR_ALL_TABPAGES(tp)
 	if (tp != curtab)
 	    for (wp = tp->tp_firstwin; wp != NULL; wp = wp->w_next)
 		add_bufnum(bufnrs, &bufnum, wp->w_buffer->b_fnum);
 #endif
     /* any other buf */
-    for (buf = firstbuf; buf != NULL; buf = buf->b_next)
+    FOR_ALL_BUFFERS(buf)
 	add_bufnum(bufnrs, &bufnum, buf->b_fnum);
 
     for (i = 0; i < bufnum; ++i)
@@ -2924,7 +2924,7 @@
 		if (next_fnum < 0 || next_fnum > eap->line2)
 		    break;
 		/* Check if the buffer still exists. */
-		for (buf = firstbuf; buf != NULL; buf = buf->b_next)
+		FOR_ALL_BUFFERS(buf)
 		    if (buf->b_fnum == next_fnum)
 			break;
 		if (buf == NULL)
diff --git a/src/ex_docmd.c b/src/ex_docmd.c
index 41a228d..28de56a 100644
--- a/src/ex_docmd.c
+++ b/src/ex_docmd.c
@@ -1708,7 +1708,7 @@
     win_T	*wp;
     int		nr = 0;
 
-    for (wp = firstwin; wp != NULL; wp = wp->w_next)
+    FOR_ALL_WINDOWS(wp)
     {
 	++nr;
 	if (wp == win)
@@ -1723,7 +1723,7 @@
     tabpage_T	*tp;
     int		nr = 0;
 
-    for (tp = first_tabpage; tp != NULL; tp = tp->tp_next)
+    FOR_ALL_TABPAGES(tp)
     {
 	++nr;
 	if (tp == tab)
@@ -7273,7 +7273,7 @@
 	    if (eap->addr_count == 0)
 		ex_win_close(eap->forceit, curwin, NULL);
 	    else {
-		for (win = firstwin; win != NULL; win = win->w_next)
+		FOR_ALL_WINDOWS(win)
 		{
 		    winnr++;
 		    if (winnr == eap->line2)
@@ -7295,7 +7295,7 @@
 {
     win_T	*win;
 
-    for (win = firstwin; win != NULL; win = win->w_next)
+    FOR_ALL_WINDOWS(win)
 	if (win->w_p_pvw)
 	{
 	    ex_win_close(eap->forceit, win, NULL);
@@ -7415,7 +7415,7 @@
 	     * up the lists. */
 	    for (done = 0; done < 1000; ++done)
 	    {
-		for (tp = first_tabpage; tp != NULL; tp = tp->tp_next)
+		FOR_ALL_TABPAGES(tp)
 		    if (tp->tp_topframe != topframe)
 		    {
 			tabpage_close_other(tp, eap->forceit);
@@ -7474,6 +7474,10 @@
 	    break;
     }
 
+#ifdef FEAT_AUTOCMD
+    apply_autocmds(EVENT_TABCLOSED, NULL, NULL, FALSE, curbuf);
+#endif
+
     redraw_tabline = TRUE;
     if (h != tabline_height())
 	shell_new_rows();
@@ -7540,7 +7544,7 @@
 		int	winnr = 0;
 		win_T	*win;
 
-		for (win = firstwin; win != NULL; win = win->w_next)
+		FOR_ALL_WINDOWS(win)
 		{
 		    winnr++;
 		    if (winnr == eap->line2)
@@ -8686,7 +8690,7 @@
     if (curwin->w_p_scb)
     {
 	topline = curwin->w_topline;
-	for (wp = firstwin; wp; wp = wp->w_next)
+	FOR_ALL_WINDOWS(wp)
 	{
 	    if (wp->w_p_scb && wp->w_buffer)
 	    {
@@ -8707,7 +8711,7 @@
     /*
      * Set all scrollbind windows to the same topline.
      */
-    for (curwin = firstwin; curwin; curwin = curwin->w_next)
+    FOR_ALL_WINDOWS(curwin)
     {
 	if (curwin->w_p_scb)
 	{
@@ -10957,7 +10961,7 @@
 	return FAIL;
 
     /* Now put the other buffers into the buffer list */
-    for (buf = firstbuf; buf != NULL; buf = buf->b_next)
+    FOR_ALL_BUFFERS(buf)
     {
 	if (!(only_save_windows && buf->b_nwindows == 0)
 		&& !(buf->b_help && !(ssop_flags & SSOP_HELP))
diff --git a/src/fileio.c b/src/fileio.c
index ea01b76..c406617 100644
--- a/src/fileio.c
+++ b/src/fileio.c
@@ -6088,7 +6088,7 @@
     char_u	*p;
 
     mch_dirname(dirname, MAXPATHL);
-    for (buf = firstbuf; buf != NULL; buf = buf->b_next)
+    FOR_ALL_BUFFERS(buf)
     {
 	if (buf->b_fname != NULL
 #ifdef FEAT_QUICKFIX
@@ -6680,7 +6680,7 @@
 	++no_wait_return;
 	did_check_timestamps = TRUE;
 	already_warned = FALSE;
-	for (buf = firstbuf; buf != NULL; )
+	FOR_ALL_BUFFERS(buf)
 	{
 	    /* Only check buffers in a window. */
 	    if (buf->b_nwindows > 0)
@@ -6699,7 +6699,6 @@
 		    continue;
 		}
 	    }
-	    buf = buf->b_next;
 	}
 	--no_wait_return;
 	need_check_timestamps = FALSE;
@@ -8759,7 +8758,7 @@
      * gives problems when the autocommands make changes to the list of
      * buffers or windows...
      */
-    for (buf = firstbuf; buf != NULL; buf = buf->b_next)
+    FOR_ALL_BUFFERS(buf)
     {
 	if (buf->b_ml.ml_mfp != NULL)
 	{
@@ -8831,7 +8830,7 @@
 	win = curwin;
     else
 #ifdef FEAT_WINDOWS
-	for (win = firstwin; win != NULL; win = win->w_next)
+	FOR_ALL_WINDOWS(win)
 	    if (win->w_buffer == buf)
 		break;
 #else
diff --git a/src/globals.h b/src/globals.h
index b569680..a3d6b4e 100644
--- a/src/globals.h
+++ b/src/globals.h
@@ -548,6 +548,10 @@
 EXTERN win_T	*prevwin INIT(= NULL);	/* previous window */
 # define W_NEXT(wp) ((wp)->w_next)
 # define FOR_ALL_WINDOWS(wp) for (wp = firstwin; wp != NULL; wp = wp->w_next)
+# define FOR_ALL_TABPAGES(tp) for (tp = first_tabpage; tp != NULL; tp = tp->tp_next)
+# define FOR_ALL_WINDOWS_IN_TAB(tp, wp) \
+    for ((wp) = ((tp) == NULL || (tp) == curtab) \
+	    ? firstwin : (tp)->tp_firstwin; (wp); (wp) = (wp)->w_next)
 /*
  * When using this macro "break" only breaks out of the inner loop. Use "goto"
  * to break out of the tabpage loop.
@@ -561,6 +565,8 @@
 # define lastwin curwin
 # define W_NEXT(wp) NULL
 # define FOR_ALL_WINDOWS(wp) wp = curwin;
+# define FOR_ALL_TABPAGES(tp) for (;FALSE;)
+# define FOR_ALL_WINDOWS_IN_TAB(tp, wp) wp = curwin;
 # define FOR_ALL_TAB_WINDOWS(tp, wp) wp = curwin;
 #endif
 
@@ -595,6 +601,8 @@
 EXTERN buf_T	*lastbuf INIT(= NULL);	/* last buffer */
 EXTERN buf_T	*curbuf INIT(= NULL);	/* currently active buffer */
 
+#define FOR_ALL_BUFFERS(buf) for (buf = firstbuf; buf != NULL; buf = buf->b_next)
+
 /* Flag that is set when switching off 'swapfile'.  It means that all blocks
  * are to be loaded into memory.  Shouldn't be global... */
 EXTERN int	mf_dont_release INIT(= FALSE);	/* don't release blocks */
diff --git a/src/gui.c b/src/gui.c
index d4fd68a..ea049c3 100644
--- a/src/gui.c
+++ b/src/gui.c
@@ -4082,7 +4082,7 @@
     {
 	do_check_scrollbind(TRUE);
 	/* need to update the window right here */
-	for (wp = firstwin; wp != NULL; wp = wp->w_next)
+	FOR_ALL_WINDOWS(wp)
 	    if (wp->w_redr_type > 0)
 		updateWindow(wp);
 	setcursor();
@@ -4166,7 +4166,7 @@
     /* avoid that moving components around generates events */
     ++hold_gui_events;
 
-    for (wp = firstwin; wp != NULL; wp = W_NEXT(wp))
+    FOR_ALL_WINDOWS(wp)
     {
 	if (wp->w_buffer == NULL)	/* just in case */
 	    continue;
diff --git a/src/gui_mac.c b/src/gui_mac.c
index b2e4d4b..b78c903 100644
--- a/src/gui_mac.c
+++ b/src/gui_mac.c
@@ -633,7 +633,7 @@
     if (error)
 	return error;
 
-    for (buf = firstbuf; buf != NULL; buf = buf->b_next)
+    FOR_ALL_BUFFERS(buf)
 	if (buf->b_ml.ml_mfp != NULL
 		&& SearchData.theFile.parID == buf->b_FSSpec.parID
 		&& SearchData.theFile.name[0] == buf->b_FSSpec.name[0]
@@ -725,7 +725,7 @@
 #endif
 
     numFiles = 0;
-    for (buf = firstbuf; buf != NULL; buf = buf->b_next)
+    FOR_ALL_BUFFERS(buf)
 	if (buf->b_ml.ml_mfp != NULL)
 	{
 	    /* Add this file to the list */
@@ -807,7 +807,7 @@
     if (error)
 	return error;
 
-    for (buf = firstbuf; buf != NULL; buf = buf->b_next)
+    FOR_ALL_BUFFERS(buf)
 	if (buf->b_ml.ml_mfp != NULL)
 	    if (GetTextData.theFile.parID == buf->b_FSSpec.parID)
 	    {
@@ -6422,7 +6422,7 @@
     tabpage_T	*tp;
     int		numTabs = 0;
 
-    for (tp = first_tabpage; tp != NULL; tp = tp->tp_next)
+    FOR_ALL_TABPAGES(tp)
 	++numTabs;
     return numTabs;
 }
diff --git a/src/if_lua.c b/src/if_lua.c
index 8d76100..5803d07 100644
--- a/src/if_lua.c
+++ b/src/if_lua.c
@@ -1402,13 +1402,13 @@
 	if (lua_isnumber(L, 1)) /* by number? */
 	{
 	    int n = lua_tointeger(L, 1);
-	    for (buf = firstbuf; buf != NULL; buf = buf->b_next)
+	    FOR_ALL_BUFFERS(buf)
 		if (buf->b_fnum == n) break;
 	}
 	else { /* by name */
 	    size_t l;
 	    const char *s = lua_tolstring(L, 1, &l);
-	    for (buf = firstbuf; buf != NULL; buf = buf->b_next)
+	    FOR_ALL_BUFFERS(buf)
 	    {
 		if (buf->b_ffname == NULL || buf->b_sfname == NULL)
 		{
diff --git a/src/if_mzsch.c b/src/if_mzsch.c
index 645548f..daec6b0 100644
--- a/src/if_mzsch.c
+++ b/src/if_mzsch.c
@@ -1916,7 +1916,7 @@
 #ifdef FEAT_WINDOWS
     win_T   *w;
 
-    for (w = firstwin; w != NULL; w = w->w_next)
+    FOR_ALL_WINDOWS(w)
 #endif
 	++n;
     return scheme_make_integer(n);
@@ -2197,7 +2197,7 @@
 
     fnum = SCHEME_INT_VAL(GUARANTEE_INTEGER(prim->name, 0));
 
-    for (buf = firstbuf; buf; buf = buf->b_next)
+    FOR_ALL_BUFFERS(buf)
 	if (buf->b_fnum == fnum)
 	    return buffer_new(buf);
 
@@ -2220,7 +2220,7 @@
     fname = GUARANTEED_STRING_ARG(prim->name, 0);
     buffer = scheme_false;
 
-    for (buf = firstbuf; buf; buf = buf->b_next)
+    FOR_ALL_BUFFERS(buf)
     {
 	if (buf->b_ffname == NULL || buf->b_sfname == NULL)
 	    /* empty string */
@@ -2283,7 +2283,7 @@
     buf_T   *b;
     int	    n = 0;
 
-    for (b = firstbuf; b; b = b->b_next) ++n;
+    FOR_ALL_BUFFERS(b) ++n;
     return scheme_make_integer(n);
 }
 
diff --git a/src/if_perl.xs b/src/if_perl.xs
index a2ff452..5b5023c 100644
--- a/src/if_perl.xs
+++ b/src/if_perl.xs
@@ -1534,14 +1534,14 @@
 	if (GIMME == G_SCALAR)
 	{
 	    i = 0;
-	    for (vimbuf = firstbuf; vimbuf; vimbuf = vimbuf->b_next)
+	    FOR_ALL_BUFFERS(vimbuf)
 		++i;
 
 	    XPUSHs(sv_2mortal(newSViv(i)));
 	}
 	else
 	{
-	    for (vimbuf = firstbuf; vimbuf; vimbuf = vimbuf->b_next)
+	    FOR_ALL_BUFFERS(vimbuf)
 		XPUSHs(newBUFrv(newSV(0), vimbuf));
 	}
     }
@@ -1586,7 +1586,7 @@
 	    XPUSHs(sv_2mortal(newSViv(win_count())));
 	else
 	{
-	    for (vimwin = firstwin; vimwin != NULL; vimwin = W_NEXT(vimwin))
+	    FOR_ALL_WINDOWS(vimwin)
 		XPUSHs(newWINrv(newSV(0), vimwin));
 	}
     }
diff --git a/src/if_ruby.c b/src/if_ruby.c
index f0c441a..7111b99 100644
--- a/src/if_ruby.c
+++ b/src/if_ruby.c
@@ -1151,7 +1151,7 @@
     buf_T *b;
     int n = 0;
 
-    for (b = firstbuf; b != NULL; b = b->b_next)
+    FOR_ALL_BUFFERS(b)
     {
 	/*  Deleted buffers should not be counted
 	 *    SegPhault - 01/07/05 */
@@ -1167,7 +1167,7 @@
     buf_T *b;
     int n = NUM2INT(num);
 
-    for (b = firstbuf; b != NULL; b = b->b_next)
+    FOR_ALL_BUFFERS(b)
     {
 	/*  Deleted buffers should not be counted
 	 *    SegPhault - 01/07/05 */
@@ -1418,7 +1418,7 @@
     win_T	*w;
     int n = 0;
 
-    for (w = firstwin; w != NULL; w = w->w_next)
+    FOR_ALL_WINDOWS(w)
 	n++;
     return INT2NUM(n);
 #else
diff --git a/src/if_tcl.c b/src/if_tcl.c
index 3ef1544..a1d8d1a 100644
--- a/src/if_tcl.c
+++ b/src/if_tcl.c
@@ -388,7 +388,7 @@
 	    Tcl_WrongNumArgs(interp, 1, objv, "bufNumber");
 	    return TCL_ERROR;
 	}
-	for (buf = firstbuf; buf != NULL; buf = buf->b_next)
+	FOR_ALL_BUFFERS(buf)
 	{
 	    if (buf->b_fnum == n)
 	    {
@@ -416,7 +416,7 @@
 		err = TCL_ERROR;
 		break;
 	    }
-	    for (buf = firstbuf; buf != NULL; buf = buf->b_next)
+	    FOR_ALL_BUFFERS(buf)
 	    {
 		name = tclgetbuffer(interp, buf);
 		if (name == NULL)
diff --git a/src/main.c b/src/main.c
index ff82a9f..926b8ab 100644
--- a/src/main.c
+++ b/src/main.c
@@ -742,7 +742,7 @@
 	win_T	*wp;
 
 	/* set options in each window for "vimdiff". */
-	for (wp = firstwin; wp != NULL; wp = wp->w_next)
+	FOR_ALL_WINDOWS(wp)
 	    diff_win_options(wp, TRUE);
     }
 #endif
@@ -1375,8 +1375,7 @@
 	for (tp = first_tabpage; tp != NULL; tp = next_tp)
 	{
 	    next_tp = tp->tp_next;
-	    for (wp = (tp == curtab)
-		    ? firstwin : tp->tp_firstwin; wp != NULL; wp = wp->w_next)
+	    FOR_ALL_WINDOWS_IN_TAB(tp, wp)
 	    {
 		if (wp->w_buffer == NULL)
 		    /* Autocmd must have close the buffer already, skip. */
@@ -1399,7 +1398,7 @@
 # endif
 
 	/* Trigger BufUnload for buffers that are loaded */
-	for (buf = firstbuf; buf != NULL; buf = buf->b_next)
+	FOR_ALL_BUFFERS(buf)
 	    if (buf->b_ml.ml_mfp != NULL)
 	    {
 		bufref_T bufref;
diff --git a/src/mark.c b/src/mark.c
index 1e6b26a7..9f0faf9 100644
--- a/src/mark.c
+++ b/src/mark.c
@@ -1864,7 +1864,7 @@
 #endif
 
     fputs(_("\n# History of marks within files (newest to oldest):\n"), fp_out);
-    for (buf = firstbuf; buf != NULL; buf = buf->b_next)
+    FOR_ALL_BUFFERS(buf)
     {
 	/*
 	 * Only write something if buffer has been loaded and at least one
@@ -2018,7 +2018,7 @@
 	else /* fp_out != NULL */
 	{
 	    /* This is slow if there are many buffers!! */
-	    for (buf = firstbuf; buf != NULL; buf = buf->b_next)
+	    FOR_ALL_BUFFERS(buf)
 		if (buf->b_ffname != NULL)
 		{
 		    home_replace(NULL, buf->b_ffname, name_buf, LSIZE, TRUE);
diff --git a/src/memfile.c b/src/memfile.c
index e2fadc2..4a48430 100644
--- a/src/memfile.c
+++ b/src/memfile.c
@@ -796,7 +796,7 @@
     if (mfp->mf_fd < 0 && need_release && p_uc)
     {
 	/* find for which buffer this memfile is */
-	for (buf = firstbuf; buf != NULL; buf = buf->b_next)
+	FOR_ALL_BUFFERS(buf)
 	    if (buf->b_ml.ml_mfp == mfp)
 		break;
 	if (buf != NULL && buf->b_may_swap)
@@ -861,7 +861,7 @@
     bhdr_T	*hp;
     int		retval = FALSE;
 
-    for (buf = firstbuf; buf != NULL; buf = buf->b_next)
+    FOR_ALL_BUFFERS(buf)
     {
 	mfp = buf->b_ml.ml_mfp;
 	if (mfp != NULL)
diff --git a/src/memline.c b/src/memline.c
index f7c68b2..8f5cf5d 100644
--- a/src/memline.c
+++ b/src/memline.c
@@ -739,7 +739,7 @@
 {
     buf_T	*buf;
 
-    for (buf = firstbuf; buf != NULL; buf = buf->b_next)
+    FOR_ALL_BUFFERS(buf)
 	if (!buf->b_p_ro || buf->b_changed)
 	    ml_open_file(buf);
 }
@@ -873,7 +873,7 @@
 {
     buf_T	*buf;
 
-    for (buf = firstbuf; buf != NULL; buf = buf->b_next)
+    FOR_ALL_BUFFERS(buf)
 	ml_close(buf, del_file && ((buf->b_flags & BF_PRESERVED) == 0
 				 || vim_strchr(p_cpo, CPO_PRESERVE) == NULL));
 #ifdef FEAT_SPELL
@@ -893,7 +893,7 @@
 {
     buf_T	*buf;
 
-    for (buf = firstbuf; buf != NULL; buf = buf->b_next)
+    FOR_ALL_BUFFERS(buf)
 	if (!bufIsChanged(buf))
 	    ml_close(buf, TRUE);    /* close all not-modified buffers */
 }
@@ -2264,7 +2264,7 @@
     buf_T		*buf;
     stat_T		st;
 
-    for (buf = firstbuf; buf != NULL; buf = buf->b_next)
+    FOR_ALL_BUFFERS(buf)
     {
 	if (buf->b_ml.ml_mfp == NULL || buf->b_ml.ml_mfp->mf_fname == NULL)
 	    continue;			    /* no file */
diff --git a/src/misc1.c b/src/misc1.c
index 293ac9e..2ee87b1 100644
--- a/src/misc1.c
+++ b/src/misc1.c
@@ -2814,7 +2814,7 @@
 	win_T	    *wp;
 	linenr_T    wlnum;
 
-	for (wp = firstwin; wp != NULL; wp = wp->w_next)
+	FOR_ALL_WINDOWS(wp)
 	    if (wp->w_p_diff && wp != curwin)
 	    {
 		redraw_win_later(wp, VALID);
@@ -2924,7 +2924,7 @@
 	win_T	    *wp;
 	linenr_T    wlnum;
 
-	for (wp = firstwin; wp != NULL; wp = wp->w_next)
+	FOR_ALL_WINDOWS(wp)
 	    if (wp->w_p_diff && wp != curwin)
 	    {
 		redraw_win_later(wp, VALID);
@@ -3213,7 +3213,7 @@
 {
     win_T	*wp;
 
-    for (wp = firstwin; wp != NULL; wp = wp->w_next)
+    FOR_ALL_WINDOWS(wp)
 	if (wp->w_buffer == buf && wp->w_status_height)
 	{
 	    wp->w_redr_status = TRUE;
@@ -9475,7 +9475,7 @@
 
     ml_close_notmod();		    /* close all not-modified buffers */
 
-    for (buf = firstbuf; buf != NULL; buf = buf->b_next)
+    FOR_ALL_BUFFERS(buf)
     {
 	if (buf->b_ml.ml_mfp != NULL && buf->b_ml.ml_mfp->mf_fname != NULL)
 	{
diff --git a/src/move.c b/src/move.c
index 1a00a4d..136263f 100644
--- a/src/move.c
+++ b/src/move.c
@@ -2820,7 +2820,7 @@
      * loop through the cursorbound windows
      */
     VIsual_select = VIsual_active = 0;
-    for (curwin = firstwin; curwin; curwin = curwin->w_next)
+    FOR_ALL_WINDOWS(curwin)
     {
 	curbuf = curwin->w_buffer;
 	/* skip original window  and windows with 'noscrollbind' */
diff --git a/src/netbeans.c b/src/netbeans.c
index 7d6ec43..f1e7666 100644
--- a/src/netbeans.c
+++ b/src/netbeans.c
@@ -473,7 +473,7 @@
     {
 	buf_T	*buf;
 
-	for (buf = firstbuf; buf != NULL; buf = buf->b_next)
+	FOR_ALL_BUFFERS(buf)
 	    buf->b_has_sign_column = FALSE;
 
 	/* The IDE is breaking the connection. */
@@ -721,7 +721,7 @@
     int		n;
 
     n = 0;
-    for (bufp = firstbuf; bufp != NULL; bufp = bufp->b_next)
+    FOR_ALL_BUFFERS(bufp)
 	if (bufp->b_changed)
 	    ++n;
     return n;
diff --git a/src/normal.c b/src/normal.c
index bc72c81..bbcd618 100644
--- a/src/normal.c
+++ b/src/normal.c
@@ -4073,7 +4073,7 @@
      * loop through the scrollbound windows and scroll accordingly
      */
     VIsual_select = VIsual_active = 0;
-    for (curwin = firstwin; curwin; curwin = curwin->w_next)
+    FOR_ALL_WINDOWS(curwin)
     {
 	curbuf = curwin->w_buffer;
 	/* skip original window  and windows with 'noscrollbind' */
diff --git a/src/option.c b/src/option.c
index 288c01b..b9b59ee 100644
--- a/src/option.c
+++ b/src/option.c
@@ -6342,7 +6342,7 @@
 	    {
 		buf_T	*buf;
 
-		for (buf = firstbuf; buf != NULL; buf = buf->b_next)
+		FOR_ALL_BUFFERS(buf)
 		    if (buf != curbuf && *buf->b_p_cm == NUL)
 			ml_set_crypt_key(buf, buf->b_p_key, oldval);
 	    }
@@ -7864,7 +7864,7 @@
 	    char_u	hash[UNDO_HASH_SIZE];
 	    buf_T	*save_curbuf = curbuf;
 
-	    for (curbuf = firstbuf; curbuf != NULL; curbuf = curbuf->b_next)
+	    FOR_ALL_BUFFERS(curbuf)
 	    {
 		/* When 'undofile' is set globally: for every buffer, otherwise
 		 * only for the current buffer: Try to read in the undofile,
@@ -8040,7 +8040,7 @@
 	{
 	    win_T	*win;
 
-	    for (win = firstwin; win != NULL; win = win->w_next)
+	    FOR_ALL_WINDOWS(win)
 		if (win->w_p_pvw && win != curwin)
 		{
 		    curwin->w_p_pvw = FALSE;
@@ -11651,7 +11651,7 @@
 	if (!old_p_paste)
 	{
 	    /* save options for each buffer */
-	    for (buf = firstbuf; buf != NULL; buf = buf->b_next)
+	    FOR_ALL_BUFFERS(buf)
 	    {
 		buf->b_p_tw_nopaste = buf->b_p_tw;
 		buf->b_p_wm_nopaste = buf->b_p_wm;
@@ -11683,7 +11683,7 @@
 	 * already on.
 	 */
 	/* set options for each buffer */
-	for (buf = firstbuf; buf != NULL; buf = buf->b_next)
+	FOR_ALL_BUFFERS(buf)
 	{
 	    buf->b_p_tw = 0;	    /* textwidth is 0 */
 	    buf->b_p_wm = 0;	    /* wrapmargin is 0 */
@@ -11719,7 +11719,7 @@
     else if (old_p_paste)
     {
 	/* restore options for each buffer */
-	for (buf = firstbuf; buf != NULL; buf = buf->b_next)
+	FOR_ALL_BUFFERS(buf)
 	{
 	    buf->b_p_tw = buf->b_p_tw_nopaste;
 	    buf->b_p_wm = buf->b_p_wm_nopaste;
diff --git a/src/quickfix.c b/src/quickfix.c
index 51f96dc..b607170 100644
--- a/src/quickfix.c
+++ b/src/quickfix.c
@@ -2040,7 +2040,7 @@
 	if (cmdmod.tab != 0)
 	    wp = NULL;
 	else
-	    for (wp = firstwin; wp != NULL; wp = wp->w_next)
+	    FOR_ALL_WINDOWS(wp)
 		if (wp->w_buffer != NULL && wp->w_buffer->b_help)
 		    break;
 	if (wp != NULL && wp->w_buffer->b_nwindows > 0)
diff --git a/src/screen.c b/src/screen.c
index ccdf98c..1b364a4 100644
--- a/src/screen.c
+++ b/src/screen.c
@@ -730,7 +730,7 @@
 #ifdef FEAT_WINDOWS
     /* Reset b_mod_set flags.  Going through all windows is probably faster
      * than going through all buffers (there could be many buffers). */
-    for (wp = firstwin; wp != NULL; wp = wp->w_next)
+    FOR_ALL_WINDOWS(wp)
 	wp->w_buffer->b_mod_set = FALSE;
 #else
 	curbuf->b_mod_set = FALSE;
@@ -962,7 +962,7 @@
     update_prepare();
 
 # ifdef FEAT_WINDOWS
-    for (wp = firstwin; wp; wp = wp->w_next)
+    FOR_ALL_WINDOWS(wp)
     {
 	if (wp->w_redr_type != 0)
 	    win_update(wp);
@@ -6271,7 +6271,7 @@
 {
     win_T	*wp;
 
-    for (wp = firstwin; wp; wp = wp->w_next)
+    FOR_ALL_WINDOWS(wp)
 	if (wp->w_status_height)
 	{
 	    wp->w_redr_status = TRUE;
@@ -6287,7 +6287,7 @@
 {
     win_T	*wp;
 
-    for (wp = firstwin; wp; wp = wp->w_next)
+    FOR_ALL_WINDOWS(wp)
 	if (wp->w_status_height != 0 && wp->w_buffer == curbuf)
 	{
 	    wp->w_redr_status = TRUE;
@@ -6303,7 +6303,7 @@
 {
     win_T	*wp;
 
-    for (wp = firstwin; wp; wp = wp->w_next)
+    FOR_ALL_WINDOWS(wp)
 	if (wp->w_redr_status)
 	    win_redr_status(wp);
     if (redraw_tabline)
@@ -10360,7 +10360,7 @@
     else
 #endif
     {
-	for (tp = first_tabpage; tp != NULL; tp = tp->tp_next)
+	FOR_ALL_TABPAGES(tp)
 	    ++tabcount;
 
 	tabwidth = (Columns - 1 + tabcount / 2) / tabcount;
diff --git a/src/spell.c b/src/spell.c
index 0f09c12..35235e0 100644
--- a/src/spell.c
+++ b/src/spell.c
@@ -2875,7 +2875,7 @@
     buf_T	*buf;
 
     /* Go through all buffers and handle 'spelllang'. <VN> */
-    for (buf = firstbuf; buf != NULL; buf = buf->b_next)
+    FOR_ALL_BUFFERS(buf)
 	ga_clear(&buf->b_s.b_langp);
 
     while (first_lang != NULL)
@@ -2911,7 +2911,7 @@
     spell_free_all();
 
     /* Go through all buffers and handle 'spelllang'. */
-    for (wp = firstwin; wp != NULL; wp = wp->w_next)
+    FOR_ALL_WINDOWS(wp)
     {
 	/* Only load the wordlists when 'spelllang' is set and there is a
 	 * window for this buffer in which 'spell' is set. */
diff --git a/src/term.c b/src/term.c
index 506cf3c..6af82db 100644
--- a/src/term.c
+++ b/src/term.c
@@ -1907,7 +1907,7 @@
 	     * loaded.
 	     */
 	    set_bufref(&old_curbuf, curbuf);
-	    for (curbuf = firstbuf; curbuf != NULL; curbuf = curbuf->b_next)
+	    FOR_ALL_BUFFERS(curbuf)
 	    {
 		if (curbuf->b_ml.ml_mfp != NULL)
 		    apply_autocmds(EVENT_TERMCHANGED, NULL, NULL, FALSE,
diff --git a/src/version.c b/src/version.c
index 233b6b5..0b63a29 100644
--- a/src/version.c
+++ b/src/version.c
@@ -759,6 +759,8 @@
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    2101,
+/**/
     2100,
 /**/
     2099,
diff --git a/src/window.c b/src/window.c
index 4fbe6ca..925a1471 100644
--- a/src/window.c
+++ b/src/window.c
@@ -209,7 +209,7 @@
 
 /* cursor to preview window */
     case 'P':
-		for (wp = firstwin; wp != NULL; wp = wp->w_next)
+		FOR_ALL_WINDOWS(wp)
 		    if (wp->w_p_pvw)
 			break;
 		if (wp == NULL)
@@ -1367,7 +1367,7 @@
 
     if (win == NULL)
 	return FALSE;
-    for (wp = firstwin; wp != NULL; wp = wp->w_next)
+    FOR_ALL_WINDOWS(wp)
 	if (wp == win)
 	    return TRUE;
     return FALSE;
@@ -1382,7 +1382,7 @@
     win_T	*wp;
     int		count = 0;
 
-    for (wp = firstwin; wp != NULL; wp = wp->w_next)
+    FOR_ALL_WINDOWS(wp)
 	++count;
     return count;
 }
@@ -3712,7 +3712,7 @@
 {
     tabpage_T	*tp;
 
-    for (tp = first_tabpage; tp != NULL; tp = tp->tp_next)
+    FOR_ALL_TABPAGES(tp)
 	if (tp == tpc)
 	    return TRUE;
     return FALSE;
@@ -4012,7 +4012,7 @@
 	first_tabpage = curtab->tp_next;
     else
     {
-	for (tp = first_tabpage; tp != NULL; tp = tp->tp_next)
+	FOR_ALL_TABPAGES(tp)
 	    if (tp->tp_next == curtab)
 		break;
 	if (tp == NULL)	/* "cannot happen" */
@@ -4091,7 +4091,7 @@
     win_T	*wp;
 
 # ifdef FEAT_WINDOWS
-    for (wp = firstwin; wp != NULL; wp = wp->w_next)
+    FOR_ALL_WINDOWS(wp)
 	if (--winnr == 0)
 	    break;
     return wp;
@@ -4112,9 +4112,7 @@
     win_T	*wp;
     tabpage_T	*tp;
 
-    for (tp = first_tabpage; tp != NULL; tp = tp->tp_next)
-	for (wp = (tp == curtab ? firstwin : tp->tp_firstwin);
-						  wp != NULL; wp = wp->w_next)
+    FOR_ALL_TAB_WINDOWS(tp, wp)
 	    if (wp == win)
 		return tp;
     return NULL;
@@ -4404,7 +4402,7 @@
 	wp = curwin;
 # ifdef FEAT_WINDOWS
     else
-	for (wp = firstwin; wp != NULL; wp = wp->w_next)
+	FOR_ALL_WINDOWS(wp)
 	    if (wp->w_buffer == buf)
 		break;
     if (wp != NULL)
@@ -4428,7 +4426,7 @@
     if (wp != NULL)
 	return wp;
 
-    for (tp = first_tabpage; tp != NULL; tp = tp->tp_next)
+    FOR_ALL_TABPAGES(tp)
 	if (tp != curtab)
 	{
 	    for (wp = tp->tp_firstwin; wp != NULL; wp = wp->w_next)
@@ -4607,7 +4605,7 @@
 
 	if (prevwin == wp)
 	    prevwin = NULL;
-	for (ttp = first_tabpage; ttp != NULL; ttp = ttp->tp_next)
+	FOR_ALL_TABPAGES(ttp)
 	    if (ttp->tp_prevwin == wp)
 		ttp->tp_prevwin = NULL;
     }
@@ -4620,7 +4618,7 @@
 
     /* Remove the window from the b_wininfo lists, it may happen that the
      * freed memory is re-used for another window. */
-    for (buf = firstbuf; buf != NULL; buf = buf->b_next)
+    FOR_ALL_BUFFERS(buf)
 	for (wip = buf->b_wininfo; wip != NULL; wip = wip->wi_next)
 	    if (wip->wi_win == wp)
 		wip->wi_win = NULL;
@@ -4863,7 +4861,7 @@
 
     ga_init2(gap, (int)sizeof(int), 1);
     if (ga_grow(gap, win_count() * 2) == OK)
-	for (wp = firstwin; wp != NULL; wp = wp->w_next)
+	FOR_ALL_WINDOWS(wp)
 	{
 	    ((int *)gap->ga_data)[gap->ga_len++] =
 					       wp->w_width + wp->w_vsep_width;
@@ -4888,7 +4886,7 @@
 	for (j = 0; j < 2; ++j)
 	{
 	    i = 0;
-	    for (wp = firstwin; wp != NULL; wp = wp->w_next)
+	    FOR_ALL_WINDOWS(wp)
 	    {
 		frame_setwidth(wp->w_frame, ((int *)gap->ga_data)[i++]);
 		win_setheight_win(((int *)gap->ga_data)[i++], wp);
@@ -5384,7 +5382,7 @@
     {
 	/* TODO: handle vertical splits */
 	room = -p_wh;
-	for (wp = firstwin; wp != NULL; wp = wp->w_next)
+	FOR_ALL_WINDOWS(wp)
 	    room += wp->w_height - p_wmh;
 	if (room >= 0)
 	    break;
@@ -6344,7 +6342,7 @@
 
 #ifdef FEAT_WINDOWS
     total = 0;
-    for (tp = first_tabpage; tp != NULL; tp = tp->tp_next)
+    FOR_ALL_TABPAGES(tp)
     {
 	n = frame_minheight(tp->tp_topframe, NULL);
 	if (total < n)
@@ -6374,7 +6372,7 @@
     if (first_tabpage->tp_next != NULL)
 	return FALSE;
 
-    for (wp = firstwin; wp != NULL; wp = wp->w_next)
+    FOR_ALL_WINDOWS(wp)
 	if (wp->w_buffer != NULL
 		&& (!((wp->w_buffer->b_help && !curbuf->b_help)
 # ifdef FEAT_QUICKFIX
@@ -7091,7 +7089,7 @@
 	    tabpage_T	*tp;
 	    int		tabnr = get_tv_number(&argvars[1]);
 
-	    for (tp = first_tabpage; tp != NULL; tp = tp->tp_next)
+	    FOR_ALL_TABPAGES(tp)
 		if (--tabnr == 0)
 		    break;
 	    if (tp == NULL)
@@ -7112,9 +7110,7 @@
     tabpage_T   *tp;
     int		id = get_tv_number(&argvars[0]);
 
-    for (tp = first_tabpage; tp != NULL; tp = tp->tp_next)
-	for (wp = tp == curtab ? firstwin : tp->tp_firstwin;
-						  wp != NULL; wp = wp->w_next)
+    FOR_ALL_TAB_WINDOWS(tp, wp)
 	    if (wp->w_id == id)
 	    {
 		goto_tabpage_win(tp, wp);
@@ -7132,10 +7128,9 @@
     int		tabnr = 1;
     int		id = get_tv_number(&argvars[0]);
 
-    for (tp = first_tabpage; tp != NULL; tp = tp->tp_next)
+    FOR_ALL_TABPAGES(tp)
     {
-	for (wp = tp == curtab ? firstwin : tp->tp_firstwin;
-						  wp != NULL; wp = wp->w_next)
+	FOR_ALL_WINDOWS_IN_TAB(tp, wp)
 	{
 	    if (wp->w_id == id)
 	    {
@@ -7159,7 +7154,7 @@
     int	    nr = 1;
     int	    id = get_tv_number(&argvars[0]);
 
-    for (wp = firstwin; wp != NULL; wp = wp->w_next)
+    FOR_ALL_WINDOWS(wp)
     {
 	if (wp->w_id == id)
 	    return nr;
@@ -7175,9 +7170,7 @@
     tabpage_T   *tp;
     int		bufnr = get_tv_number(&argvars[0]);
 
-    for (tp = first_tabpage; tp != NULL; tp = tp->tp_next)
-	for (wp = tp == curtab ? firstwin : tp->tp_firstwin;
-						  wp != NULL; wp = wp->w_next)
+    FOR_ALL_TAB_WINDOWS(tp, wp)
 	    if (wp->w_buffer->b_fnum == bufnr)
 		list_append_number(list, wp->w_id);
 }
diff --git a/src/workshop.c b/src/workshop.c
index cf7b46b..fe59e1b 100644
--- a/src/workshop.c
+++ b/src/workshop.c
@@ -1319,7 +1319,7 @@
 {
     win_T	*wp = NULL;	/* window filename is in */
 
-    for (wp = firstwin; wp != NULL; wp = W_NEXT(wp))
+    FOR_ALL_WINDOWS(wp)
 	if (buf == wp->w_buffer)
 	    break;
     return wp;