updated for version 7.0122
diff --git a/src/ex_cmds.c b/src/ex_cmds.c
index 2118f26..5248246 100644
--- a/src/ex_cmds.c
+++ b/src/ex_cmds.c
@@ -2582,34 +2582,83 @@
 		|| ((buf->b_flags & BF_NEW)
 		    && vim_strchr(p_cpo, CPO_OVERNEW) == NULL)
 		|| (buf->b_flags & BF_READERR))
-	    && !eap->forceit
-	    && !eap->append
 	    && !p_wa
 	    && vim_fexists(ffname))
     {
-#ifdef UNIX
-	    /* with UNIX it is possible to open a directory */
-	if (mch_isdir(ffname))
+	if (!eap->forceit && !eap->append)
 	{
-	    EMSG2(_(e_isadir2), ffname);
-	    return FAIL;
-	}
+#ifdef UNIX
+		/* with UNIX it is possible to open a directory */
+	    if (mch_isdir(ffname))
+	    {
+		EMSG2(_(e_isadir2), ffname);
+		return FAIL;
+	    }
 #endif
 #if defined(FEAT_GUI_DIALOG) || defined(FEAT_CON_DIALOG)
-	if (p_confirm || cmdmod.confirm)
-	{
-	    char_u	buff[IOSIZE];
+	    if (p_confirm || cmdmod.confirm)
+	    {
+		char_u	buff[IOSIZE];
 
-	    dialog_msg(buff, _("Overwrite existing file \"%s\"?"), fname);
-	    if (vim_dialog_yesno(VIM_QUESTION, NULL, buff, 2) != VIM_YES)
-		return FAIL;
-	    eap->forceit = TRUE;
-	}
-	else
+		dialog_msg(buff, _("Overwrite existing file \"%s\"?"), fname);
+		if (vim_dialog_yesno(VIM_QUESTION, NULL, buff, 2) != VIM_YES)
+		    return FAIL;
+		eap->forceit = TRUE;
+	    }
+	    else
 #endif
+	    {
+		EMSG(_(e_exists));
+		return FAIL;
+	    }
+	}
+
+	/* For ":w! filename" check that no swap file exists for "filename". */
+	if (other && !emsg_silent)
 	{
-	    EMSG(_(e_exists));
-	    return FAIL;
+	    char_u	dir[MAXPATHL];
+	    char_u	*p;
+	    int		r;
+	    char_u	*swapname;
+
+	    /* We only try the first entry in 'directory', without checking if
+	     * it's writable.  If the "." directory is not writable the write
+	     * will probably fail anyway.
+	     * Use 'shortname' of the current buffer, since there is no buffer
+	     * for the written file. */
+	    if (*p_dir == NUL)
+		STRCPY(dir, ".");
+	    else
+	    {
+		p = p_dir;
+		copy_option_part(&p, dir, MAXPATHL, ",");
+	    }
+	    swapname = makeswapname(fname, ffname, curbuf, dir);
+	    r = vim_fexists(swapname);
+	    vim_free(swapname);
+	    if (r)
+	    {
+#if defined(FEAT_GUI_DIALOG) || defined(FEAT_CON_DIALOG)
+		if (p_confirm || cmdmod.confirm)
+		{
+		    char_u	buff[IOSIZE];
+
+		    dialog_msg(buff,
+			    _("Swap file \"%s\" exists, overwrite anyway?"),
+								    swapname);
+		    if (vim_dialog_yesno(VIM_QUESTION, NULL, buff, 2)
+								   != VIM_YES)
+			return FAIL;
+		    eap->forceit = TRUE;
+		}
+		else
+#endif
+		{
+		    EMSG2(_("E768: Swap file exists: %s (:silent! overrides)"),
+								    swapname);
+		    return FAIL;
+		}
+	    }
 	}
     }
     return OK;
diff --git a/src/memline.c b/src/memline.c
index d1cf71f..6633164 100644
--- a/src/memline.c
+++ b/src/memline.c
@@ -230,7 +230,6 @@
 static bhdr_T *ml_new_ptr __ARGS((memfile_T *));
 static bhdr_T *ml_find_line __ARGS((buf_T *, linenr_T, int));
 static int ml_add_stack __ARGS((buf_T *));
-static char_u *makeswapname __ARGS((buf_T *, char_u *));
 static void ml_lineadd __ARGS((buf_T *, int));
 static int b0_magic_wrong __ARGS((ZERO_BL *));
 #ifdef CHECK_INODE
@@ -3384,10 +3383,14 @@
 }
 
 /*
- * make swap file name out of the file name and a directory name
+ * Make swap file name out of the file name and a directory name.
+ * Returns pointer to allocated memory or NULL.
  */
-    static char_u *
-makeswapname(buf, dir_name)
+/*ARGSUSED*/
+    char_u *
+makeswapname(fname, ffname, buf, dir_name)
+    char_u	*fname;
+    char_u	*ffname;
     buf_T	*buf;
     char_u	*dir_name;
 {
@@ -3398,7 +3401,7 @@
     if (after_pathsep(dir_name, s) && s[-1] == s[-2])
     {			       /* Ends with '//', Use Full path */
 	r = NULL;
-	if ((s = make_percent_swname(dir_name, buf->b_fname)) != NULL)
+	if ((s = make_percent_swname(dir_name, fname)) != NULL)
 	{
 	    r = modname(s, (char_u *)".swp", FALSE);
 	    vim_free(s);
@@ -3415,9 +3418,9 @@
 #endif
 #ifdef RISCOS
 	    /* Avoid problems if fname has special chars, eg <Wimp$Scrap> */
-	    buf->b_ffname,
+	    ffname,
 #else
-	    buf->b_fname,
+	    fname,
 #endif
 	    (char_u *)
 #if defined(VMS) || defined(RISCOS)
@@ -3495,6 +3498,7 @@
  * Find out what name to use for the swap file for buffer 'buf'.
  *
  * Several names are tried to find one that does not exist
+ * Returns the name in allocated memory or NULL.
  *
  * Note: If BASENAMELEN is not correct, you will get error messages for
  *	 not being able to open the swapfile
@@ -3547,7 +3551,7 @@
     if (dir_name == NULL)	    /* out of memory */
 	fname = NULL;
     else
-	fname = makeswapname(buf, dir_name);
+	fname = makeswapname(buf->b_fname, buf->b_ffname, buf, dir_name);
 
     for (;;)
     {
@@ -3649,7 +3653,8 @@
 		    {
 			buf->b_shortname = TRUE;
 			vim_free(fname);
-			fname = makeswapname(buf, dir_name);
+			fname = makeswapname(buf->b_fname, buf->b_ffname,
+							       buf, dir_name);
 			continue;	/* try again with b_shortname set */
 		    }
 		}
@@ -3719,7 +3724,8 @@
 		{
 		    buf->b_shortname = TRUE;
 		    vim_free(fname);
-		    fname = makeswapname(buf, dir_name);
+		    fname = makeswapname(buf->b_fname, buf->b_ffname,
+							       buf, dir_name);
 		    continue;	    /* try again with '.' replaced with '_' */
 		}
 	    }
diff --git a/src/proto/memline.pro b/src/proto/memline.pro
index 1ebd7eb..4f75853 100644
--- a/src/proto/memline.pro
+++ b/src/proto/memline.pro
@@ -24,6 +24,7 @@
 void ml_setmarked __ARGS((linenr_T lnum));
 linenr_T ml_firstmarked __ARGS((void));
 void ml_clearmarked __ARGS((void));
+char_u *makeswapname __ARGS((char_u *fname, char_u *ffname, buf_T *buf, char_u *dir_name));
 char_u *get_file_in_dir __ARGS((char_u *fname, char_u *dname));
 void ml_setflags __ARGS((buf_T *buf));
 long ml_find_line_or_offset __ARGS((buf_T *buf, linenr_T lnum, long *offp));