Index: /FCKeditor/trunk/_whatsnew.html
===================================================================
--- /FCKeditor/trunk/_whatsnew.html	(revision 2235)
+++ /FCKeditor/trunk/_whatsnew.html	(revision 2236)
@@ -47,4 +47,6 @@
 		<li>[<a target="_blank" href="http://dev.fckeditor.net/ticket/2252">#2252</a>] It's now possible to enable the
 			browsers default menu using the configuration file (FCKConfig.BrowserContextMenu option).</li> 
+		<li>[<a target="_blank" href="http://dev.fckeditor.net/ticket/2247">#2247</a>] The SHIFT+SPACE
+			keystroke will now produce a &amp;nbsp; character.</li>
 	</ul>
 	<p>
Index: /FCKeditor/trunk/editor/_source/commandclasses/fck_othercommands.js
===================================================================
--- /FCKeditor/trunk/editor/_source/commandclasses/fck_othercommands.js	(revision 2235)
+++ /FCKeditor/trunk/editor/_source/commandclasses/fck_othercommands.js	(revision 2236)
@@ -614,2 +614,21 @@
 	}
 } ;
+
+// FCKRuleCommand
+var FCKNbsp = function()
+{
+	this.Name = 'Non Breaking Space' ;
+}
+
+FCKNbsp.prototype =
+{
+	Execute : function()
+	{
+		FCK.InsertHtml( '&nbsp;' ) ;
+	},
+
+	GetState : function()
+	{
+		return ( FCK.EditMode != FCK_EDITMODE_WYSIWYG ? FCK_TRISTATE_DISABLED : FCK_TRISTATE_OFF ) ;
+	}
+} ;
Index: /FCKeditor/trunk/editor/_source/internals/fck_gecko.js
===================================================================
--- /FCKeditor/trunk/editor/_source/internals/fck_gecko.js	(revision 2235)
+++ /FCKeditor/trunk/editor/_source/internals/fck_gecko.js	(revision 2236)
@@ -360,9 +360,43 @@
 	FCKUndo.SaveUndoStep() ;
 
-	if ( FCKBrowserInfo.IsGecko )
-	{
+	var fakeNodes = false ;
+	var prevCharNodeValue ;
+	if ( FCKBrowserInfo.IsGecko && /^(?:&nbsp;|&#160;)+$/.test( html ) )
+	{
+		// Get the previous character's text node value, if any.
+		var selection = FCK.EditorWindow.getSelection() ;
+		var range = selection && selection.rangeCount > 0 && selection.getRangeAt( 0 ) ;
+		var startNode, prevCharNode ;
+		if ( range ) 
+		{
+			if ( range.startContainer.nodeType == 1 )
+				startNode = range.startContainer.childNodes[ range.startOffset ] ;
+			else if ( range.startContainer.nodeType == 3 )
+				startNode = range.startContainer ;
+		}
+		if ( startNode )
+		{
+			if ( range.startContainer.nodeType == 1 )
+			{
+				var node = startNode.previousSibling ;
+				while ( node && node.nodeType == 3 && node.length < 1 )
+					node = node.previousSibling ;
+				if ( node && node.nodeType == 3 )
+					prevCharNode = node ;
+			}
+			else
+				prevCharNode = startNode ;
+		}
+		if ( prevCharNode )
+		{
+			prevCharNodeValue = prevCharNode.nodeValue ;
+			if ( range.startContainer.nodeType == 3 )
+				prevCharNodeValue = prevCharNodeValue.substr( 0, range.startOffset ) ;
+		}
+
 		// Using the following trick, &nbsp; present at the beginning and at
 		// the end of the HTML are preserved (#2248).
 		html = '<span id="__fakeFCKRemove1__" style="display:none;">fakeFCKRemove</span>' + html + '<span id="__fakeFCKRemove2__" style="display:none;">fakeFCKRemove</span>' ;
+		fakeNodes = true ;
 	}
 
@@ -370,9 +404,18 @@
 	doc.execCommand( 'inserthtml', false, html ) ;
 
-	if ( FCKBrowserInfo.IsGecko )
-	{
+	if ( fakeNodes )
+	{
+		// Retrieve the text node before the newly inserted text node.
+		// Note that this is a different node to the prevCharNode earlier.
+		var firstNode = doc.getElementById( '__fakeFCKRemove1__' ) ;
+		var textNode = firstNode.previousSibling ;
+
 		// Remove the fake nodes.
-		FCKDomTools.RemoveNode( doc.getElementById('__fakeFCKRemove1__') ) ;
+		FCKDomTools.RemoveNode( firstNode ) ;
 		FCKDomTools.RemoveNode( doc.getElementById('__fakeFCKRemove2__') ) ;
+
+		// Restore the previous character's text node value, if any.
+		if ( prevCharNodeValue && textNode && textNode.nodeType == 3 )
+			textNode.nodeValue = prevCharNodeValue ;
 	}
 
Index: /FCKeditor/trunk/editor/_source/internals/fckcommands.js
===================================================================
--- /FCKeditor/trunk/editor/_source/internals/fckcommands.js	(revision 2235)
+++ /FCKeditor/trunk/editor/_source/internals/fckcommands.js	(revision 2236)
@@ -81,4 +81,5 @@
 		case 'PageBreak'	: oCommand = new FCKPageBreakCommand() ; break ;
 		case 'Rule'			: oCommand = new FCKRuleCommand() ; break ;
+		case 'Nbsp'			: oCommand = new FCKNbsp() ; break ;
 
 		case 'TextColor'	: oCommand = new FCKTextColorCommand('ForeColor') ; break ;
Index: /FCKeditor/trunk/fckconfig.js
===================================================================
--- /FCKeditor/trunk/fckconfig.js	(revision 2235)
+++ /FCKeditor/trunk/fckconfig.js	(revision 2236)
@@ -143,5 +143,6 @@
 	[ CTRL + 85 /*U*/, 'Underline' ],
 	[ CTRL + SHIFT + 83 /*S*/, 'Save' ],
-	[ CTRL + ALT + 13 /*ENTER*/, 'FitWindow' ]
+	[ CTRL + ALT + 13 /*ENTER*/, 'FitWindow' ],
+	[ SHIFT + 32 /*SPACE*/, 'Nbsp' ]
 ] ;
 
