updated for version 7.0090
diff --git a/src/proto/spell.pro b/src/proto/spell.pro
index 15a68a6..2771a90 100644
--- a/src/proto/spell.pro
+++ b/src/proto/spell.pro
@@ -1,6 +1,7 @@
 /* spell.c */
 int spell_check __ARGS((win_T *wp, char_u *ptr, int *attrp));
 int spell_move_to __ARGS((int dir, int allwords, int curline));
+void spell_cat_line __ARGS((char_u *buf, char_u *line, int maxlen));
 char_u *did_set_spelllang __ARGS((buf_T *buf));
 void spell_reload __ARGS((void));
 void put_bytes __ARGS((FILE *fd, long_u nr, int len));
diff --git a/src/screen.c b/src/screen.c
index b1fbedf..6fb5931 100644
--- a/src/screen.c
+++ b/src/screen.c
@@ -2502,8 +2502,17 @@
     int		has_syntax = FALSE;	/* this buffer has syntax highl. */
     int		save_did_emsg;
     int		has_spell = FALSE;	/* this buffer has spell checking */
+# define SPWORDLEN 150
+    char_u	nextline[SPWORDLEN * 2];/* text with start of the next line */
+    int		nextlinecol;		/* column where nextline[] starts */
+    int		nextline_idx;		/* index in nextline[] where next line
+					   starts */
     int		spell_attr = 0;		/* attributes desired by spelling */
     int		word_end = 0;		/* last byte with same spell_attr */
+    static linenr_T  checked_lnum = 0;	/* line number for checked_col */
+    static int	checked_col = 0;	/* column in checked_lnum up to which
+					 * there are no spell errors */
+    int		cur_checked_col = 0;	/* checked column for current line */
 #endif
     int		extra_check;		/* has syntax or linebreak */
 #ifdef FEAT_MBYTE
@@ -2609,6 +2618,22 @@
 	/* Prepare for spell checking. */
 	has_spell = TRUE;
 	extra_check = TRUE;
+
+	/* Get the start of the next line, so that words that wrap to the next
+	 * line are found too: "et<line-break>al.".
+	 * Trick: skip a few chars for C/shell/Vim comments */
+	nextline[SPWORDLEN] = NUL;
+	if (lnum < wp->w_buffer->b_ml.ml_line_count)
+	{
+	    line = ml_get_buf(wp->w_buffer, lnum + 1, FALSE);
+	    spell_cat_line(nextline + SPWORDLEN, line, SPWORDLEN);
+	}
+
+	/* When a word wrapped from the previous line the start of the current
+	 * line is valid. */
+	if (lnum == checked_lnum)
+	    cur_checked_col = checked_col;
+	checked_lnum = 0;
     }
 #endif
 
@@ -2774,6 +2799,42 @@
     line = ml_get_buf(wp->w_buffer, lnum, FALSE);
     ptr = line;
 
+#ifdef FEAT_SYN_HL
+    if (has_spell)
+    {
+	/* To be able to spell-check over line boundaries copy the end of the
+	 * current line into nextline[].  Above the start of the next line was
+	 * copied to nextline[SPWORDLEN]. */
+	if (nextline[SPWORDLEN] == NUL)
+	{
+	    /* No next line or it is empty. */
+	    nextlinecol = MAXCOL;
+	    nextline_idx = 0;
+	}
+	else
+	{
+	    v = STRLEN(line);
+	    if (v < SPWORDLEN)
+	    {
+		/* Short line, use it completely and append the start of the
+		 * next line. */
+		nextlinecol = 0;
+		mch_memmove(nextline, line, (size_t)v);
+		mch_memmove(nextline + v, nextline + SPWORDLEN,
+					    STRLEN(nextline + SPWORDLEN) + 1);
+		nextline_idx = v + 1;
+	    }
+	    else
+	    {
+		/* Long line, use only the last SPWORDLEN bytes. */
+		nextlinecol = v - SPWORDLEN;
+		mch_memmove(nextline, line + nextlinecol, SPWORDLEN);
+		nextline_idx = SPWORDLEN + 1;
+	    }
+	}
+    }
+#endif
+
     /* find start of trailing whitespace */
     if (wp->w_p_list && lcs_trail)
     {
@@ -3587,14 +3648,15 @@
 		 * Only do this when there is no syntax highlighting, the
 		 * @Spell cluster is not used or the current syntax item
 		 * contains the @Spell cluster. */
-		if (has_spell && v >= word_end)
+		if (has_spell && v >= word_end && v > cur_checked_col)
 		{
 		    spell_attr = 0;
 		    if (area_attr == 0 && search_attr == 0)
 			char_attr = syntax_attr;
 		    if (c != 0 && (!has_syntax || can_spell))
 		    {
-			char_u	*prev_ptr;
+			char_u	*prev_ptr, *p;
+			int	len;
 # ifdef FEAT_MBYTE
 			if (has_mbyte)
 			{
@@ -3604,7 +3666,15 @@
 			else
 # endif
 			    prev_ptr = ptr - 1;
-			word_end = v + spell_check(wp, prev_ptr, &spell_attr);
+
+			/* Use nextline[] if possible, it has the start of the
+			 * next line concatenated. */
+			if ((prev_ptr - line) - nextlinecol >= 0)
+			    p = nextline + (prev_ptr - line) - nextlinecol;
+			else
+			    p = prev_ptr;
+			len = spell_check(wp, p, &spell_attr);
+			word_end = v + len;
 
 			/* In Insert mode only highlight a word that
 			 * doesn't touch the cursor. */
@@ -3618,10 +3688,24 @@
 			    spell_attr = 0;
 			    spell_redraw_lnum = lnum;
 			}
+
+			if (spell_attr == 0 && p != prev_ptr
+				       && (p - nextline) + len > nextline_idx)
+			{
+			    /* Remember that the good word continues at the
+			     * start of the next line. */
+			    checked_lnum = lnum + 1;
+			    checked_col = (p - nextline) + len - nextline_idx;
+			}
 		    }
 		}
 		if (spell_attr != 0)
-		    char_attr = hl_combine_attr(char_attr, spell_attr);
+		{
+		    if (area_attr == 0 && search_attr == 0)
+			char_attr = hl_combine_attr(char_attr, spell_attr);
+		    else
+			char_attr = hl_combine_attr(spell_attr, char_attr);
+		}
 #endif
 #ifdef FEAT_LINEBREAK
 		/*
diff --git a/src/syntax.c b/src/syntax.c
index 1d8f41b..4fdbbbf 100644
--- a/src/syntax.c
+++ b/src/syntax.c
@@ -7591,26 +7591,27 @@
 
 #if defined(FEAT_SYN_HL) || defined(PROTO)
 /*
- * Combine the spelling attributes with other attributes.  "spell_attr"
- * overrules "char_attr".
+ * Combine special attributes (e.g., for spelling) with other attributes
+ * (e.g., for syntax highlighting).
+ * "prim_attr" overrules "char_attr".
  * This creates a new group when required.
  * Since we expect there to be few spelling mistakes we don't cache the
  * result.
  * Return the resulting attributes.
  */
     int
-hl_combine_attr(char_attr, spell_attr)
+hl_combine_attr(char_attr, prim_attr)
     int	    char_attr;
-    int	    spell_attr;
+    int	    prim_attr;
 {
     attrentry_T *char_aep = NULL;
     attrentry_T *spell_aep;
     attrentry_T new_en;
 
     if (char_attr == 0)
-	return spell_attr;
-    if (char_attr <= HL_ALL && spell_attr <= HL_ALL)
-	return char_attr | spell_attr;
+	return prim_attr;
+    if (char_attr <= HL_ALL && prim_attr <= HL_ALL)
+	return char_attr | prim_attr;
 #ifdef FEAT_GUI
     if (gui.in_use)
     {
@@ -7625,11 +7626,11 @@
 		new_en.ae_attr = char_attr;
 	}
 
-	if (spell_attr <= HL_ALL)
-	    new_en.ae_attr |= spell_attr;
+	if (prim_attr <= HL_ALL)
+	    new_en.ae_attr |= prim_attr;
 	else
 	{
-	    spell_aep = syn_gui_attr2entry(spell_attr);
+	    spell_aep = syn_gui_attr2entry(prim_attr);
 	    if (spell_aep != NULL)
 	    {
 		new_en.ae_attr |= spell_aep->ae_attr;
@@ -7664,11 +7665,11 @@
 		new_en.ae_attr = char_attr;
 	}
 
-	if (spell_attr <= HL_ALL)
-	    new_en.ae_attr |= spell_attr;
+	if (prim_attr <= HL_ALL)
+	    new_en.ae_attr |= prim_attr;
 	else
 	{
-	    spell_aep = syn_cterm_attr2entry(spell_attr);
+	    spell_aep = syn_cterm_attr2entry(prim_attr);
 	    if (spell_aep != NULL)
 	    {
 		new_en.ae_attr |= spell_aep->ae_attr;
@@ -7692,11 +7693,11 @@
 	    new_en.ae_attr = char_attr;
     }
 
-    if (spell_attr <= HL_ALL)
-	new_en.ae_attr |= spell_attr;
+    if (prim_attr <= HL_ALL)
+	new_en.ae_attr |= prim_attr;
     else
     {
-	spell_aep = syn_cterm_attr2entry(spell_attr);
+	spell_aep = syn_cterm_attr2entry(prim_attr);
 	if (spell_aep != NULL)
 	{
 	    new_en.ae_attr |= spell_aep->ae_attr;