diff --git a/src/command.c b/src/command.c
index 33d8ead96a24fc326777f5dd5aeab2f3bcd68c61..3aa22b62f62f9103ba6c744926648b90349acf81 100644
--- a/src/command.c
+++ b/src/command.c
@@ -61,6 +61,8 @@ static consvar_t *consvar_vars; // list of registered console variables
 static char com_token[1024];
 static char *COM_Parse(char *data);
 
+static char * COM_Purge (char *text, int *lenp);
+
 CV_PossibleValue_t CV_OnOff[] = {{0, "Off"}, {1, "On"}, {0, NULL}};
 CV_PossibleValue_t CV_YesNo[] = {{0, "No"}, {1, "Yes"}, {0, NULL}};
 CV_PossibleValue_t CV_Unsigned[] = {{0, "MIN"}, {999999999, "MAX"}, {0, NULL}};
@@ -100,31 +102,61 @@ static cmdalias_t *com_alias; // aliases list
 
 static vsbuf_t com_text; // variable sized buffer
 
+/** Purges control characters out of some text.
+  *
+  * \param s The text.
+  * \param np Optionally a pointer to fill with the new string length.
+  * \return The new length.
+  * \sa COM_ExecuteString
+  */
+static char *
+COM_Purge (char *s, int *np)
+{
+	char *t;
+	char *p;
+	int n;
+	n = strlen(s);
+	t = s + n + 1;
+	p = s;
+	while (( p = strchr(p, '\033') ))
+	{
+		memmove(p, &p[1], t - p - 1);
+		n--;
+	}
+	if (np)
+		(*np) = n;
+	return s;
+}
+
 /** Adds text into the command buffer for later execution.
   *
   * \param ptext The text to add.
-  * \sa COM_BufInsertText
+  * \sa COM_BufInsertTextEx
   */
-void COM_BufAddText(const char *ptext)
+void COM_BufAddTextEx(const char *ptext, int flags)
 {
-	size_t l;
+	int l;
+	char *text;
 
-	l = strlen(ptext);
+	text = COM_Purge(Z_StrDup(ptext), &l);
 
-	if (com_text.cursize + l >= com_text.maxsize)
+	if (com_text.cursize + 2 + l >= com_text.maxsize)
 	{
 		CONS_Alert(CONS_WARNING, M_GetText("Command buffer full!\n"));
 		return;
 	}
-	VS_Write(&com_text, ptext, l);
+
+	VS_WriteEx(&com_text, text, l, flags);
+
+	Z_Free(text);
 }
 
 /** Adds command text and executes it immediately.
   *
   * \param ptext The text to execute. A newline is automatically added.
-  * \sa COM_BufAddText
+  * \sa COM_BufAddTextEx
   */
-void COM_BufInsertText(const char *ptext)
+void COM_BufInsertTextEx(const char *ptext, int flags)
 {
 	char *temp = NULL;
 	size_t templen;
@@ -138,7 +170,7 @@ void COM_BufInsertText(const char *ptext)
 	}
 
 	// add the entire text of the file (or alias)
-	COM_BufAddText(ptext);
+	COM_BufAddTextEx(ptext, flags);
 	COM_BufExecute(); // do it right away
 
 	// add the copied off data
@@ -272,6 +304,7 @@ static size_t com_argc;
 static char *com_argv[MAX_ARGS];
 static const char *com_null_string = "";
 static char *com_args = NULL; // current command args or NULL
+static int com_flags;
 
 static void Got_NetVar(UINT8 **p, INT32 playernum);
 
@@ -394,9 +427,16 @@ static void COM_TokenizeString(char *ptext)
 
 	com_argc = 0;
 	com_args = NULL;
+	com_flags = 0;
 
 	while (com_argc < MAX_ARGS)
 	{
+		if (ptext[0] == '\033')
+		{
+			com_flags = (unsigned)ptext[1];
+			ptext += 2;
+		}
+
 		// Skip whitespace up to a newline.
 		while (*ptext != '\0' && *ptext <= ' ' && *ptext != '\n')
 			ptext++;
@@ -1016,6 +1056,15 @@ void VS_Write(vsbuf_t *buf, const void *data, size_t length)
 	M_Memcpy(VS_GetSpace(buf, length), data, length);
 }
 
+void VS_WriteEx(vsbuf_t *buf, const void *data, size_t length, int flags)
+{
+	char *p;
+	p = VS_GetSpace(buf, 2 + length);
+	p[0] = '\033';
+	p[1] = flags;
+	M_Memcpy(&p[2], data, length);
+}
+
 /** Prints text in a variable buffer. Like VS_Write() plus a
   * trailing NUL.
   *
diff --git a/src/command.h b/src/command.h
index 51e161cd05943c7211d4e26f8b8cb78674a89511..af9d08ae165edcfc738f450ff865fde80478a15f 100644
--- a/src/command.h
+++ b/src/command.h
@@ -36,10 +36,12 @@ size_t COM_FirstOption(void);
 const char *COM_CompleteCommand(const char *partial, INT32 skips);
 
 // insert at queu (at end of other command)
-void COM_BufAddText(const char *btext);
+#define COM_BufAddText(s) COM_BufAddTextEx(s, 0)
+void COM_BufAddTextEx(const char *btext, int flags);
 
 // insert in head (before other command)
-void COM_BufInsertText(const char *btext);
+#define COM_BufInsertText(s) COM_BufInsertTextEx(s, 0)
+void COM_BufInsertTextEx(const char *btext, int flags);
 
 // don't bother inserting, just do immediately
 void COM_ImmedExecute(const char *ptext);
@@ -71,6 +73,7 @@ void VS_Free(vsbuf_t *buf);
 void VS_Clear(vsbuf_t *buf);
 void *VS_GetSpace(vsbuf_t *buf, size_t length);
 void VS_Write(vsbuf_t *buf, const void *data, size_t length);
+void VS_WriteEx(vsbuf_t *buf, const void *data, size_t length, int flags);
 void VS_Print(vsbuf_t *buf, const char *data); // strcats onto the sizebuf
 
 //==================