updated for version 7.0180
diff --git a/src/Makefile b/src/Makefile
index 810dd7b..5236e9d 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -541,7 +541,7 @@
 
 # MEMORY LEAK DETECTION
 # Requires installing the ccmalloc library.
-# Configuration is in the .ccmalloc file.
+# Configuration is in the .ccmalloc or ~/.ccmalloc file.
 # Doesn't work very well, since memory linked to from global variables
 # (indirectly) is also marked as leaked memory.
 #PROFILE_CFLAGS = -DEXITFREE
diff --git a/src/edit.c b/src/edit.c
index c037d1f..298ebc3 100644
--- a/src/edit.c
+++ b/src/edit.c
@@ -6527,6 +6527,10 @@
 	/* CTRL-G u: start new undoable edit */
 	case 'u': u_sync();
 		  ins_need_undo = TRUE;
+
+		  /* Need to reset Insstart, esp. because a BS that joins
+		   * aline to the previous one must save for undo. */
+		  Insstart = curwin->w_cursor;
 		  break;
 
 	/* Unknown CTRL-G command, reserved for future expansion. */
diff --git a/src/main.c b/src/main.c
index 551e980..fd85ea8 100644
--- a/src/main.c
+++ b/src/main.c
@@ -844,6 +844,12 @@
     no_wait_return = FALSE;
     starting = 0;
 
+#ifdef FEAT_TERMRESPONSE
+    /* Requesting the termresponse is postponed until here, so that a "-c q"
+     * argument doesn't make it appear in the shell Vim was started from. */
+    may_req_termresponse();
+#endif
+
     /* start in insert mode */
     if (p_im)
 	need_start_insertmode = TRUE;
diff --git a/src/message.c b/src/message.c
index 465b25e..1cea013 100644
--- a/src/message.c
+++ b/src/message.c
@@ -2188,7 +2188,6 @@
 	vim_free(last_msgchunk);
 	last_msgchunk = mp;
     }
-    last_msgchunk = NULL;
 }
 
 /*
diff --git a/src/misc1.c b/src/misc1.c
index 08cd20c..c459174 100644
--- a/src/misc1.c
+++ b/src/misc1.c
@@ -3583,6 +3583,8 @@
 		{
 		    struct passwd *pw;
 
+		    /* Note: memory allocated by getpwnam() is never freed.
+		     * Calling endpwent() apparently doesn't help. */
 		    pw = getpwnam((char *)dst + 1);
 		    if (pw != NULL)
 			var = (char_u *)pw->pw_dir;
diff --git a/src/misc2.c b/src/misc2.c
index f5b13e7..fb873fb 100644
--- a/src/misc2.c
+++ b/src/misc2.c
@@ -1012,6 +1012,7 @@
     free_cd_dir();
     set_expr_line(NULL);
     diff_clear();
+    clear_sb_text();	      /* free any scrollback text */
 
     /* Free some global vars. */
     vim_free(username);
diff --git a/src/proto/term.pro b/src/proto/term.pro
index f5bdfc4..91bb85c 100644
--- a/src/proto/term.pro
+++ b/src/proto/term.pro
@@ -33,6 +33,7 @@
 void settmode __ARGS((int tmode));
 void starttermcap __ARGS((void));
 void stoptermcap __ARGS((void));
+void may_req_termresponse __ARGS((void));
 int swapping_screen __ARGS((void));
 void setmouse __ARGS((void));
 int mouse_has __ARGS((int c));
diff --git a/src/quickfix.c b/src/quickfix.c
index f550f11..35f278c 100644
--- a/src/quickfix.c
+++ b/src/quickfix.c
@@ -3001,7 +3001,7 @@
 		qf_jump(0, 0, eap->forceit);	/* display first error */
 	}
 	else
-	    EMSG(_("E999: String or List expected"));
+	    EMSG(_("E777: String or List expected"));
 	free_tv(tv);
     }
 }
diff --git a/src/spell.c b/src/spell.c
index a1ab89c..9d8f2bf 100644
--- a/src/spell.c
+++ b/src/spell.c
@@ -945,6 +945,10 @@
 static char *e_affrange = N_("E762: Character in FOL, LOW or UPP is out of range");
 static char *msg_compressing = N_("Compressing word tree...");
 
+/* Remember what "z?" replaced. */
+static char_u	*repl_from = NULL;
+static char_u	*repl_to = NULL;
+
 /*
  * Main spell-checking function.
  * "ptr" points to a character that could be the start of a word.
@@ -1657,8 +1661,8 @@
 }
 
 /*
- * Return TRUE if "flags" is a valid sequence of compound flags and
- * "word[len]" does not have too many syllables.
+ * Return TRUE if "flags" is a valid sequence of compound flags and "word"
+ * does not have too many syllables.
  */
     static int
 can_compound(slang, word, flags)
@@ -1884,7 +1888,7 @@
 
 /*
  * Need to fold at least one more character.  Do until next non-word character
- * for efficiency.
+ * for efficiency.  Include the non-word character too.
  * Return the length of the folded chars in bytes.
  */
     static int
@@ -1900,8 +1904,7 @@
 	mb_ptr_adv(mip->mi_fend);
     } while (*mip->mi_fend != NUL && spell_iswordp(mip->mi_fend, mip->mi_buf));
 
-    /* Include the non-word character so that we can check for the
-     * word end. */
+    /* Include the non-word character so that we can check for the word end. */
     if (*mip->mi_fend != NUL)
 	mb_ptr_adv(mip->mi_fend);
 
@@ -2201,6 +2204,9 @@
     }
 }
 
+/*
+ * Structure used for the cookie argument of do_in_runtimepath().
+ */
 typedef struct spelload_S
 {
     char_u  sl_lang[MAXWLEN + 1];	/* language name */
@@ -2246,7 +2252,7 @@
 						     lang, spell_enc(), lang);
     else if (sl.sl_slang != NULL)
     {
-	/* At least one file was loaded, now load all the additions. */
+	/* At least one file was loaded, now load ALL the additions. */
 	STRCPY(fname_enc + STRLEN(fname_enc) - 3, "add.spl");
 	do_in_runtimepath(fname_enc, TRUE, spell_load_cb, &sl);
     }
@@ -2469,7 +2475,8 @@
  * - To reload a spell file that was changed.  "lang" is NULL and "old_lp"
  *   points to the existing slang_T.
  * - Just after writing a .spl file; it's read back to produce the .sug file.
- *   "old_lp" is NULL and "lang" is a dummy name.  Will allocate an slang_T.
+ *   "old_lp" is NULL and "lang" is NULL.  Will allocate an slang_T.
+ *
  * Returns the slang_T the spell file was loaded into.  NULL for error.
  */
     static slang_T *
@@ -2686,7 +2693,7 @@
 	goto someerror;
 
     /* For a new file link it in the list of spell files. */
-    if (old_lp == NULL)
+    if (old_lp == NULL && lang != NULL)
     {
 	lp->sl_next = first_lang;
 	first_lang = lp;
@@ -4358,6 +4365,11 @@
     }
 
     init_spell_chartab();
+
+    vim_free(repl_to);
+    repl_to = NULL;
+    vim_free(repl_from);
+    repl_from = NULL;
 }
 # endif
 
@@ -4423,7 +4435,7 @@
     }
 
     /* When "zg" was used and the file wasn't loaded yet, should redo
-     * 'spelllang' to get it loaded. */
+     * 'spelllang' to load it now. */
     if (added_word && !didit)
 	did_set_spelllang(curbuf);
 }
@@ -7875,9 +7887,6 @@
 	slang = spell_load_file(wfname, NULL, NULL, FALSE);
 	if (slang == NULL)
 	    return;
-	/* don't want this language in the list */
-	if (first_lang == slang)
-	    first_lang = slang->sl_next;
 	free_slang = TRUE;
     }
 
@@ -9339,10 +9348,6 @@
     return OK;
 }
 
-/* Remember what "z?" replaced. */
-static char_u	*repl_from = NULL;
-static char_u	*repl_to = NULL;
-
 /*
  * "z?": Find badly spelled word under or after the cursor.
  * Give suggestions for the properly spelled word.
@@ -9720,22 +9725,22 @@
 
     /* Make room in "gap". */
     ga_init2(gap, sizeof(char_u *), sug.su_ga.ga_len + 1);
-    if (ga_grow(gap, sug.su_ga.ga_len) == FAIL)
-	return;
-
-    for (i = 0; i < sug.su_ga.ga_len; ++i)
+    if (ga_grow(gap, sug.su_ga.ga_len) == OK)
     {
-	stp = &SUG(sug.su_ga, i);
+	for (i = 0; i < sug.su_ga.ga_len; ++i)
+	{
+	    stp = &SUG(sug.su_ga, i);
 
-	/* The suggested word may replace only part of "word", add the not
-	 * replaced part. */
-	wcopy = alloc(stp->st_wordlen
+	    /* The suggested word may replace only part of "word", add the not
+	     * replaced part. */
+	    wcopy = alloc(stp->st_wordlen
 				+ STRLEN(sug.su_badptr + stp->st_orglen) + 1);
-	if (wcopy == NULL)
-	    break;
-	STRCPY(wcopy, stp->st_word);
-	STRCPY(wcopy + stp->st_wordlen, sug.su_badptr + stp->st_orglen);
-	((char_u **)gap->ga_data)[gap->ga_len++] = wcopy;
+	    if (wcopy == NULL)
+		break;
+	    STRCPY(wcopy, stp->st_word);
+	    STRCPY(wcopy + stp->st_wordlen, sug.su_badptr + stp->st_orglen);
+	    ((char_u **)gap->ga_data)[gap->ga_len++] = wcopy;
+	}
     }
 
     spell_find_cleanup(&sug);
@@ -10110,20 +10115,20 @@
 		buf[i] = getc(fd);			/* <fileID> */
 	    if (STRNCMP(buf, VIMSUGMAGIC, VIMSUGMAGICL) != 0)
 	    {
-		EMSG2(_("E999: This does not look like a .sug file: %s"),
+		EMSG2(_("E778: This does not look like a .sug file: %s"),
 							     slang->sl_fname);
 		goto nextone;
 	    }
 	    c = getc(fd);				/* <versionnr> */
 	    if (c < VIMSUGVERSION)
 	    {
-		EMSG2(_("E999: Old .sug file, needs to be updated: %s"),
+		EMSG2(_("E779: Old .sug file, needs to be updated: %s"),
 							     slang->sl_fname);
 		goto nextone;
 	    }
 	    else if (c > VIMSUGVERSION)
 	    {
-		EMSG2(_("E999: .sug file is for newer version of Vim: %s"),
+		EMSG2(_("E780: .sug file is for newer version of Vim: %s"),
 							     slang->sl_fname);
 		goto nextone;
 	    }
@@ -10135,7 +10140,7 @@
 		timestamp += getc(fd) << (i * 8);
 	    if (timestamp != slang->sl_sugtime)
 	    {
-		EMSG2(_("E999: .sug file doesn't match .spl file: %s"),
+		EMSG2(_("E781: .sug file doesn't match .spl file: %s"),
 							     slang->sl_fname);
 		goto nextone;
 	    }
@@ -10148,7 +10153,7 @@
 							       FALSE, 0) != 0)
 	    {
 someerror:
-		EMSG2(_("E999: error while reading .sug file: %s"),
+		EMSG2(_("E782: error while reading .sug file: %s"),
 							     slang->sl_fname);
 		slang_clear_sug(slang);
 		goto nextone;
@@ -12786,7 +12791,7 @@
 		{
 		    /* This should have been checked when generating the .spl
 		     * file. */
-		    EMSG(_("E999: duplicate char in MAP entry"));
+		    EMSG(_("E783: duplicate char in MAP entry"));
 		    vim_free(b);
 		}
 	    }
@@ -13026,7 +13031,7 @@
     suginfo_T	*su;
     char_u	*word;
 {
-    char_u	*s = vim_strsave(word);
+    char_u	*s;
     hash_T	hash;
     hashitem_T	*hi;
 
@@ -14888,7 +14893,7 @@
     int		len;
     int		i;
 
-    /* if the word starts with a lower-case letter make the word with an
+    /* If the word starts with a lower-case letter make the word with an
      * upper-case letter in word_up[]. */
     c = PTR2CHAR(word);
     if (SPELL_TOUPPER(c) != c)
@@ -14973,7 +14978,8 @@
 }
 
 /*
- * Move "p" to end of word.
+ * Move "p" to the end of word "start".
+ * Uses the spell-checking word characters.
  */
     char_u *
 spell_to_word_end(start, buf)
@@ -14989,10 +14995,10 @@
 
 #if defined(FEAT_INS_EXPAND) || defined(PROTO)
 /*
- * Find start of the word in front of the cursor.  We don't check if it is
- * badly spelled, with completion we can only change the word in front of the
- * cursor.
- * Used for Insert mode completion CTRL-X ?.
+ * For Insert mode completion CTRL-X s:
+ * Find start of the word in front of column "startcol".
+ * We don't check if it is badly spelled, with completion we can only change
+ * the word in front of the cursor.
  * Returns the column number of the word.
  */
     int
diff --git a/src/syntax.c b/src/syntax.c
index 01a476e..1c093a0 100644
--- a/src/syntax.c
+++ b/src/syntax.c
@@ -2956,6 +2956,7 @@
     int		extra;		/* extra chars for offset to start */
 {
     int		col;
+    int		len;
 
     if (spp->sp_off_flags & (1 << idx))
     {
@@ -2971,7 +2972,15 @@
     if (col < 0)
 	result->col = 0;
     else
-	result->col = col;
+    {
+	/* Don't go past the end of the line.  Matters for "rs=e+2" when there
+	 * is a matchgroup. */
+	len = STRLEN(ml_get_buf(syn_buf, result->lnum, FALSE));
+	if (col > len)
+	    result->col = len;
+	else
+	    result->col = col;
+    }
 }
 
 /*
diff --git a/src/term.c b/src/term.c
index cc3c036..1f27533 100644
--- a/src/term.c
+++ b/src/term.c
@@ -88,9 +88,6 @@
     || (defined(FEAT_MOUSE) && (!defined(UNIX) || defined(FEAT_MOUSE_XTERM)))
 static int get_bytes_from_buf __ARGS((char_u *, char_u *, int));
 #endif
-#ifdef FEAT_TERMRESPONSE
-static void may_req_termresponse __ARGS((void));
-#endif
 static void del_termcode_idx __ARGS((int idx));
 static int term_is_builtin __ARGS((char_u *name));
 static int term_7to8bit __ARGS((char_u *p));
@@ -3249,11 +3246,13 @@
     }
 }
 
-#ifdef FEAT_TERMRESPONSE
+#if defined(FEAT_TERMRESPONSE) || defined(PROTO)
 /*
  * Request version string (for xterm) when needed.
  * Only do this after switching to raw mode, otherwise the result will be
  * echoed.
+ * Only do this after startup has finished, to avoid that the response comes
+ * while excuting "-c !cmd" or even after "-c quit".
  * Only do this after termcap mode has been started, otherwise the codes for
  * the cursor keys may be wrong.
  * Only do this when 'esckeys' is on, otherwise the response causes trouble in
@@ -3262,17 +3261,18 @@
  * request to terminal while reading from a file).
  * The result is caught in check_termcode().
  */
-    static void
+    void
 may_req_termresponse()
 {
     if (crv_status == CRV_GET
 	    && cur_tmode == TMODE_RAW
+	    && starting == 0
 	    && termcap_active
 	    && p_ek
-#ifdef UNIX
+# ifdef UNIX
 	    && isatty(1)
 	    && isatty(read_cmd_fd)
-#endif
+# endif
 	    && *T_CRV != NUL)
     {
 	out_str(T_CRV);
diff --git a/src/version.h b/src/version.h
index 447f4fa..7319ff9 100644
--- a/src/version.h
+++ b/src/version.h
@@ -36,5 +36,5 @@
 #define VIM_VERSION_NODOT	"vim70aa"
 #define VIM_VERSION_SHORT	"7.0aa"
 #define VIM_VERSION_MEDIUM	"7.0aa ALPHA"
-#define VIM_VERSION_LONG	"VIM - Vi IMproved 7.0aa ALPHA (2006 Jan 12)"
-#define VIM_VERSION_LONG_DATE	"VIM - Vi IMproved 7.0aa ALPHA (2006 Jan 12, compiled "
+#define VIM_VERSION_LONG	"VIM - Vi IMproved 7.0aa ALPHA (2006 Jan 13)"
+#define VIM_VERSION_LONG_DATE	"VIM - Vi IMproved 7.0aa ALPHA (2006 Jan 13, compiled "