Index: binaries/data/mods/public/gui/common/functions_utility.js
===================================================================
--- binaries/data/mods/public/gui/common/functions_utility.js	(revision 16105)
+++ binaries/data/mods/public/gui/common/functions_utility.js	(working copy)
@@ -240,3 +240,25 @@
 	// Limit the length to 20 characters
 	return sanitizedName.substr(0,20);
 }
+
+function tryAutoComplete(text, autoCompleteList)
+{
+	if (text.length == 0)
+		return text;
+
+	var wordSplit = text.split(/\s+/g);
+
+	if(!wordSplit.length)
+		return text;
+
+	var lastWord = wordSplit.pop();
+	for (var wordAutoCompletion of autoCompleteList)
+	{
+		if (wordAutoCompletion.toLowerCase().indexOf(lastWord.toLowerCase()) == 0) 
+		{
+			text = wordSplit.join(" ") + " " + wordAutoCompletion;
+			break;
+		}
+	}
+	return text;
+}
\ No newline at end of file
Index: binaries/data/mods/public/gui/lobby/lobby.js
===================================================================
--- binaries/data/mods/public/gui/lobby/lobby.js	(revision 16105)
+++ binaries/data/mods/public/gui/lobby/lobby.js	(working copy)
@@ -753,29 +753,16 @@
 {
 	var input = Engine.GetGUIObjectByName("chatInput");
 	var text = escapeText(input.caption);
-	if (text.length)
+	if (!text.length)
+		return;
+
+	var autoCompletionList = [];
+	for each (var playerObj in Engine.GetPlayerList())
 	{
-		var matched = false;
-		for each (var playerObj in Engine.GetPlayerList())
-		{
-			var player = playerObj.name;
-			var breaks = text.match(/(\s+)/g) || [];
-			text.split(/\s+/g).reduceRight(function (wordsSoFar, word, index)
-			{
-				if (matched)
-					return null;
-				var matchCandidate = word + (breaks[index - 1] || "") + wordsSoFar;
-				if (player.toUpperCase().indexOf(matchCandidate.toUpperCase().trim()) == 0)
-				{
-					input.caption = text.replace(matchCandidate.trim(), player);
-					matched = true;
-				}
-				return matchCandidate;
-			}, "");
-		if (matched)
-			break;
-		}
+		autoCompletionList.push(playerObj.name);
 	}
+
+	input.caption = tryAutoComplete(text, autoCompletionList);
 }
 
 function isValidNick(nick)
Index: binaries/data/mods/public/gui/session/messages.js
===================================================================
--- binaries/data/mods/public/gui/session/messages.js	(revision 16105)
+++ binaries/data/mods/public/gui/session/messages.js	(working copy)
@@ -308,6 +308,23 @@
 	}
 }
 
+function autoCompleteNick()
+{
+	var input = Engine.GetGUIObjectByName("chatInput");
+	var text = input.caption;
+
+	if (!text.length)
+		return;
+
+	var autoCompletionList = [];
+	for (var player of g_Players)
+	{
+		autoCompletionList.push(player.name);
+	}
+
+	input.caption = tryAutoComplete(text, autoCompletionList);
+}
+
 function submitChatInput()
 {
 	var input = Engine.GetGUIObjectByName("chatInput");
@@ -612,6 +629,16 @@
 			msg.hide = true;
 		recurse = true;
 		break;
+	case "/allies":
+		var player = g_Players[Engine.GetPlayerID()];
+
+		if (player && player.isAlly[sender]) 
+			msg.context = translate("Ally");
+		else 
+			msg.hide = true;
+		
+		recurse = true;
+		break;
 	case "/enemy":
 		// Check if we are in a team.
 		if (g_Players[Engine.GetPlayerID()] && g_Players[Engine.GetPlayerID()].team != -1)
Index: binaries/data/mods/public/gui/session/session.xml
===================================================================
--- binaries/data/mods/public/gui/session/session.xml	(revision 16105)
+++ binaries/data/mods/public/gui/session/session.xml	(working copy)
@@ -195,6 +195,7 @@
 	<object name="chatDialogPanel" size="50%-180 50%-48 50%+180 50%+36" type="image" hidden="true" sprite="genericPanel">
 		<object name="chatInput" size="16 12 100%-16 36" type="input" style="ModernInput" max_length="80">
 			<action on="Press">submitChatInput();</action>
+			<action on="Tab">autoCompleteNick();</action>
 		</object>
 
 		<object size="16 100%-40 30%+16 100%-12" type="button" style="StoneButton">
Index: source/gui/CInput.cpp
===================================================================
--- source/gui/CInput.cpp	(revision 16105)
+++ source/gui/CInput.cpp	(working copy)
@@ -840,6 +840,16 @@
 
 			GetScrollBar(0).SetScrollBarStyle(scrollbar_style);
 		}
+		
+		if (Message.value == CStr("caption"))
+		{
+			if (m_iBufferPos > 0)
+			{
+				CStrW caption;
+				GUI<CStrW>::GetSetting(this, "caption", caption);
+				m_iBufferPos = m_iBufferPos_Tail = (int)caption.size();
+			}
+		}
 
 		if (Message.value == CStr("size") || 
 			Message.value == CStr("z") ||
