diff --git a/botanjs/src/Components/Vim/Actions/BUFFERS.js b/botanjs/src/Components/Vim/Actions/BUFFERS.js
index e02dc78c..92488779 100644
--- a/botanjs/src/Components/Vim/Actions/BUFFERS.js
+++ b/botanjs/src/Components/Vim/Actions/BUFFERS.js
@@ -40,6 +40,9 @@
 
 		var cur = this.__cursor;
 		var Vim = cur.Vim;
+
+		/** @type {Components.Vim.VimArea} */
+		var VimArea = shadowImport( "Components.Vim.VimArea" );
 		var Insts = VimArea.Instances;
 
 
diff --git a/botanjs/src/Components/Vim/Actions/FIND.js b/botanjs/src/Components/Vim/Actions/FIND.js
index 86db51da..461ddc48 100644
--- a/botanjs/src/Components/Vim/Actions/FIND.js
+++ b/botanjs/src/Components/Vim/Actions/FIND.js
@@ -39,7 +39,7 @@
 		}
 
 		// The root bracket as back ref 0
-		var RegEx = new RegExp( "(" +  parsed + ")", "g" );
+		var RegEx = new RegExp( "(" +  parsed + ")", "gm" );
 
 		return RegEx;
 	};
@@ -104,9 +104,20 @@
 		var FirstHit;
 		var PrevStack = [];
 
+		var LoopGuard;
 		while( ( r = search.exec( content ) ) !== null )
 		{
-			if( !FirstHit ) FirstHit = r.index;
+			if( FirstHit == undefined )
+			{
+				FirstHit = r.index;
+			}
+
+			if( LoopGuard == r.index )
+			{
+				this.__msg = VimError( "EX2", PATTERN.slice( 1 ).join( "" ) );
+				return true;
+			}
+
 			if( p < r.index )
 			{
 				Hit = r.index;
@@ -114,6 +125,7 @@
 			}
 
 			PrevStack.push( r.index );
+			LoopGuard = r.index;
 		}
 
 		if( e.kMap( "N" ) )
diff --git a/botanjs/src/Components/Vim/Actions/JOIN_LINES.js b/botanjs/src/Components/Vim/Actions/JOIN_LINES.js
new file mode 100644
index 00000000..4f21af69
--- /dev/null
+++ b/botanjs/src/Components/Vim/Actions/JOIN_LINES.js
@@ -0,0 +1,89 @@
+(function(){
+	var ns = __namespace( "Components.Vim.Actions" );
+
+	/** @type {System.Debug} */
+	var debug                                  = __import( "System.Debug" );
+	/** @type {Components.Vim.State.Stator} */
+	var Stator                                 = __import( "Components.Vim.State.Stator" );
+	/** @type {Components.Vim.State.Stack} */
+	var Stack                                  = __import( "Components.Vim.State.Stack" );
+
+	var beep = __import( "Components.Vim.Beep" );
+	var Mesg = __import( "Components.Vim.Message" );
+
+	var occurance = __import( "System.utils.Perf.CountSubstr" );
+
+	/** @type {Components.Vim.IAction} */
+	var JOIN_LINES = function( Cursor )
+	{
+		/** @type {Components.Vim.Cursor} */
+		this.__cursor = Cursor;
+		this.__msg = "";
+		Cursor.suppressEvent();
+	};
+
+	JOIN_LINES.prototype.dispose = function()
+	{
+		this.__cursor.unsuppressEvent();
+	};
+
+	JOIN_LINES.prototype.handler = function( e, range )
+	{
+		e.preventDefault();
+
+		var cur = this.__cursor;
+		var feeder = cur.feeder;
+
+		var start;
+		var end;
+
+		var stack;
+		var stator;
+
+		var contentUndo;
+		if( range )
+		{
+			start = range.start;
+			end = range.close;
+		}
+		else
+		{
+			var oPos = cur.aPos;
+			cur.lineEnd( true );
+			stator = new Stator( cur );
+			start = cur.aPos;
+			cur.moveY( 1 );
+			cur.lineStart();
+			end = cur.aPos;
+
+			// This happens on the last line
+			if( end < start )
+			{
+				cur.moveTo( oPos );
+				beep();
+				return true;
+			}
+
+			var content = feeder.content;
+
+			contentUndo = feeder.content.substring( start, end );
+			feeder.content = content.substring( 0, start ) + " " + content.substr( end );
+		}
+
+		feeder.pan();
+
+		cur.moveTo( start );
+
+		var stack = new Stack();
+		stack.store( stator.save( 1, contentUndo ) );
+
+		cur.rec.record( stack );
+	};
+
+	JOIN_LINES.prototype.getMessage = function()
+	{
+		return this.__msg;
+	};
+
+	ns[ NS_EXPORT ]( EX_CLASS, "JOIN_LINES", JOIN_LINES );
+})();
diff --git a/botanjs/src/Components/Vim/Actions/TO.js b/botanjs/src/Components/Vim/Actions/TO.js
new file mode 100644
index 00000000..1ff0bcd9
--- /dev/null
+++ b/botanjs/src/Components/Vim/Actions/TO.js
@@ -0,0 +1,82 @@
+(function(){
+	var ns = __namespace( "Components.Vim.Actions" );
+
+	/** @type {System.Debug} */
+	var debug                                 = __import( "System.Debug" );
+
+	var beep = __import( "Components.Vim.Beep" );
+
+	/** @type {Components.Vim.IAction} */
+	var TO = function( Cursor )
+	{
+		/** @type {Components.Vim.Cursor} */
+		this.__cursor = Cursor;
+		this.__msg = "<TO COMMAND>";
+		Cursor.suppressEvent();
+	};
+
+	TO.prototype.dispose = function()
+	{
+		this.__cursor.unsuppressEvent();
+	};
+
+	TO.prototype.handler = function( em, et )
+	{
+		et.preventDefault();
+
+		var cur = this.__cursor;
+		var f = cur.feeder;
+		var n = cur.getLine().lineNum;
+
+		var p = 0;
+		for( i = 0; p != -1 && i < n; i ++ )
+		{
+			p = f.content.indexOf( "\n", p + 1 );
+		}
+
+		var upperLimit = f.content.indexOf( "\n", p + 1 );
+
+		if( 0 < n ) p ++;
+
+		var lowerLimmit = p;
+
+		var cX = cur.X;
+		var tX = cX;
+
+		var Char = et.key;
+		if( et.kMap( "Tab" ) )
+		{
+			Char = "\t";
+		}
+
+		if( 1 < Char.length )
+		{
+			beep();
+			return;
+		}
+
+		// Forward
+		if( em.kMap( "t" ) || em.kMap( "f" ) )
+		{
+			tX = f.content.indexOf( Char, p + cX + 1 );
+		}
+		// backward
+		else
+		{
+			tX = f.content.lastIndexOf( Char, p + cX - 1 );
+		}
+
+		if( lowerLimmit <= tX && tX < upperLimit )
+		{
+			cur.moveTo( tX );
+		}
+		else beep();
+	};
+
+	TO.prototype.getMessage = function()
+	{
+		return this.__msg;
+	};
+
+	ns[ NS_EXPORT ]( EX_CLASS, "TO", TO );
+})();
diff --git a/botanjs/src/Components/Vim/Actions/WORD.js b/botanjs/src/Components/Vim/Actions/WORD.js
new file mode 100644
index 00000000..7d69be41
--- /dev/null
+++ b/botanjs/src/Components/Vim/Actions/WORD.js
@@ -0,0 +1,74 @@
+(function(){
+	var ns = __namespace( "Components.Vim.Actions" );
+
+	/** @type {System.Debug} */
+	var debug                                 = __import( "System.Debug" );
+
+	/** @type {Components.Vim.IAction} */
+	var WORD = function( Cursor )
+	{
+		/** @type {Components.Vim.Cursor} */
+		this.__cursor = Cursor;
+		this.__msg = "<WORD COMMAND>";
+		Cursor.suppressEvent();
+	};
+
+	WORD.prototype.dispose = function()
+	{
+		this.__cursor.unsuppressEvent();
+	};
+
+	WORD.prototype.handler = function( e )
+	{
+		e.preventDefault();
+
+		var cur = this.__cursor;
+		var feeder = cur.feeder;
+
+		var analyzer = cur.Vim.contentAnalyzer;
+		var p = cur.aPos;
+
+
+		var d = 1;
+		// forward
+		if( e.kMap( "w" ) || e.kMap( "W" ) )
+		{
+			if( feeder.content[ p + 1 ] == "\n" )
+			{
+				p ++;
+			}
+
+			var wordRange = analyzer.wordAt( p );
+			if( wordRange.open != -1 )
+			{
+				p = wordRange.close + 1;
+			}
+		}
+		// Backward
+		if( e.kMap( "b" ) || e.kMap( "B" ) )
+		{
+			if( p == 0 ) return;
+			d = -1;
+
+			var wordRange = analyzer.wordAt( p - 1 );
+			if( wordRange.open != -1 )
+			{
+				p = wordRange.open;
+			}
+		}
+
+		while( " \t".indexOf( feeder.content[ p ] ) != -1 )
+		{
+			p += d;
+		}
+
+		cur.moveTo( p );
+	};
+
+	WORD.prototype.getMessage = function()
+	{
+		return this.__msg;
+	};
+
+	ns[ NS_EXPORT ]( EX_CLASS, "WORD", WORD );
+})();
diff --git a/botanjs/src/Components/Vim/Controls.js b/botanjs/src/Components/Vim/Controls.js
index b52b7c28..f38b8479 100644
--- a/botanjs/src/Components/Vim/Controls.js
+++ b/botanjs/src/Components/Vim/Controls.js
@@ -47,6 +47,8 @@
 	var COMMA = 188; var FULLSTOP = 190;
 	var SLASH = 191; var BACK_SLASH = 220;
 
+	var ANY_KEY = -1;
+
 	var __maps = {};
 	var Map = function( str )
 	{
@@ -169,8 +171,9 @@
 		{
 			var compReg = this.__compositeReg[i];
 			var keys = compReg.keys;
+			var key = keys[ compReg.i ++ ];
 
-			if( keys[ compReg.i ++ ] == kCode )
+			if( key == ANY_KEY || key == kCode )
 			{
 				if( compReg.i == keys.length )
 				{
@@ -262,6 +265,7 @@
 			case SHIFT + I: // Append before the line start, after spaces
 				break;
 			case SHIFT + J: // Join lines
+				ccur.openRunAction( "JOIN_LINES", e );
 				break;
 			case SHIFT + K: // Find the manual entry
 				break;
@@ -374,7 +378,11 @@
 				break;
 			case SHIFT + L: // Last line buffer
 				break;
-			case SHIFT + _6: // ^, Start
+
+			case _0: // Really - line Start
+				ccur.lineStart();
+				break;
+			case SHIFT + _6: // ^, line Start, XXX: skip tabs
 				ccur.lineStart();
 				break;
 			case SHIFT + _4: // $, End
@@ -404,8 +412,45 @@
 				);
 
 				break;
+
+
+			case SHIFT + T: // To
 			case T: // To
+				this.__cMovement = true;
+
+				this.__composite( e, function( e2 ) {
+					var oX = ccur.X;
+					ccur.openRunAction( "TO", e, e2 );
+
+					if( ccur.X < oX )
+					{
+						ccur.moveX( 1 );
+					}
+					else if( oX < ccur.X )
+					{
+						ccur.moveX( -1 );
+					}
+				}, ANY_KEY );
+
 				break;
+			case SHIFT + F: // To
+			case F: // To
+				this.__cMovement = true;
+
+				this.__composite( e, function( e2 ) {
+					ccur.openRunAction( "TO", e, e2 );
+				}, ANY_KEY );
+
+				break;
+
+			case W: // word
+			case SHIFT + W:
+			case B:
+			case SHIFT + B:
+				ccur.openRunAction( "WORD", e );
+				break
+
+
 			case I: // In between boundary
 				if( !ccur.action )
 				{
diff --git a/botanjs/src/Components/Vim/Cursor.js b/botanjs/src/Components/Vim/Cursor.js
index 2fd98339..3eaaac05 100644
--- a/botanjs/src/Components/Vim/Cursor.js
+++ b/botanjs/src/Components/Vim/Cursor.js
@@ -137,7 +137,6 @@
 
 		this.moveX( - Number.MAX_VALUE );
 		this.moveX( jumpX, false, phantomSpace );
-
 	};
 
 	// 0 will be treated as default ( 1 )
diff --git a/botanjs/src/Components/Vim/Syntax/Word.js b/botanjs/src/Components/Vim/Syntax/Word.js
index d879e595..e76818b5 100644
--- a/botanjs/src/Components/Vim/Syntax/Word.js
+++ b/botanjs/src/Components/Vim/Syntax/Word.js
@@ -199,6 +199,10 @@
 			// C1 Controls and Latin-1 Supplement (Extended ASCII)
 			[ 0x00A1, 0x00AC ], [ 0x00AE, 0x00BF ]
 		]
+		,
+		[ // Spaces & tabs
+			[ 0x0020, 0x0020 ], [ 0x0009, 0x0009 ]
+		]
 	];
 
 	var NUM_KINGDOM = KINGDOMS.length;
diff --git a/botanjs/src/Components/Vim/VimArea.js b/botanjs/src/Components/Vim/VimArea.js
index 36148092..1817debe 100644
--- a/botanjs/src/Components/Vim/VimArea.js
+++ b/botanjs/src/Components/Vim/VimArea.js
@@ -42,16 +42,27 @@
 	};
 
 	/* stage @param {Dandelion.IDOMElement} */
-	var VimArea = function( stage )
+	var VimArea = function( stage, detectScreenSize )
 	{
-		if( !stage ) return;
+		if( !stage ) throw new Error( "Invalid argument" );
+
+		stage = IDOMElement( stage );
 
 		var element = stage.element;
 
-		if( element.nodeName != "TEXTAREA" )
+		if(!( element && element.nodeName == "TEXTAREA" ))
 		{
-			debug.Error( "Element is not compatible for VimArea" );
-			return;
+			throw new Error( "This element is not compatible for VimArea" );
+		}
+
+		for( var i in Insts )
+		{
+			var inst = Insts[ i ];
+			if( inst.stage.element == element )
+			{
+				debug.Info( "Instance exists" );
+				return inst;
+			}
 		}
 
 		stage.setAttribute( new DataKey( "vimarea", 1 ) );
@@ -69,10 +80,16 @@
 			, new EventKey( "Blur", function() { _self.__active = false; } )
 		];
 
-		this.__removeText
 
-		// Init
-		this.VisualizeVimFrame( element.value );
+		if( detectScreenSize )
+		{
+			var val = element.value;
+			this.__testScreen(function() { _self.VisualizeVimFrame( val ); });
+		}
+		else
+		{
+			this.VisualizeVimFrame( element.value );
+		}
 
 		// Set buffer index
 		this.__instIndex = InstIndex ++;
@@ -81,6 +98,68 @@
 		Insts[ this.__instIndex ] = this;
 	};
 
+	VimArea.prototype.__testScreen = function( handler )
+	{
+		var area = this.stage.element;
+		area.value = "";
+
+		var msg = "Please wait while Vim;Re is testing for screen dimensions";
+		var m = function() { return msg[ i ++ ] || "."; };
+
+		var i = 0;
+
+		var oX = area.style.overflowX;
+		var oY = area.style.overflowY;
+
+		area.style.whiteSpace = "nowrap";
+
+		var oWidth = area.scrollWidth;
+		var testWidth = function()
+		{
+			area.value += m();
+			if( oWidth == area.scrollWidth )
+			{
+				Cycle.next( testWidth );
+			}
+			else
+			{
+				var t = "";
+				i -= 3;
+				for( var k = 0; k < i; k ++ ) t += ".";
+				area.value = t;
+
+				area.style.whiteSpace = "";
+				m = function() { return "\n" + t; };
+				testHeight();
+			}
+		};
+
+		testWidth();
+
+		var oHeight = area.scrollHeight;
+
+		var l = 0;
+
+		var _self = this;
+
+		var testHeight = function() {
+			area.value += m();
+			l ++;
+
+			if( oHeight == area.scrollHeight )
+			{
+				Cycle.next( testHeight );
+			}
+			else
+			{
+				_self.rows = l;
+				_self.cols = i;
+
+				handler();
+			}
+		};
+	};
+
 	VimArea.prototype.select = function( sel )
 	{
 		if( !this.__active ) return;
diff --git a/botanjs/src/Components/Vim/_this.js b/botanjs/src/Components/Vim/_this.js
index d55ec639..ab267064 100644
--- a/botanjs/src/Components/Vim/_this.js
+++ b/botanjs/src/Components/Vim/_this.js
@@ -38,6 +38,7 @@ VIMRE_VERSION = "1.0.0b";
 
 		// EXtended Errors
 		, "EX1": "Pattern Error( %1 )"
+		, "EX2": "This pattern is causing infinite loop: %1"
 
 		, "TODO": "%1 is not implemented yet"
 		, "MISSING_FEATURE": "Sorry, I thought this command wasn't useful enough to implement. Please file a feature request titled \"Implement %1\" in github if you think this is important."
diff --git a/botanjs/src/System/Cycle/_this.js b/botanjs/src/System/Cycle/_this.js
index f9431a10..f31bb5cf 100644
--- a/botanjs/src/System/Cycle/_this.js
+++ b/botanjs/src/System/Cycle/_this.js
@@ -10,6 +10,12 @@
 
 	var tList = [];
 
+	var C_CALLBACK = 0;
+	var C_TIME = 1;
+	var C_ONCE = 2;
+	var C_ID = 3;
+	var C_INTVL = 4;
+
 	var stepper = function()
 	{
 		var thisTime = new Date().getTime();
@@ -21,11 +27,11 @@
 		for ( var i in tList )
 		{
 			var f = tList[i];
-			if( f && thisTime > f[1] )
+			if( f && thisTime > f[ C_TIME ] )
 			{
 				try
 				{
-					f[0]();
+					f[ C_CALLBACK ]();
 				}
 				catch(e)
 				{
@@ -34,13 +40,13 @@
 					continue;
 				}
 
-				if( f[2] )
+				if( f[ C_ONCE ] )
 				{
 					delete tList[i];
 				}
 				else
 				{
-					f[1] = thisTime + f[4];
+					f[ C_TIME ] = thisTime + f[ C_INTVL ];
 				}
 			}
 		}
@@ -56,7 +62,7 @@
 	{
 		for ( var i in tList )
 		{
-			if( tList[i][3] == id )
+			if( tList[i][ C_ID ] == id )
 				return false;
 		}
 
@@ -68,14 +74,19 @@
 		// 3: id
 		for ( var i in tList )
 		{
-			if( tList[i][3] == id )
+			if( tList[i][ C_ID ] == id )
 				delete tList[i];
 		}
 	};
 
 	var next = function( func )
 	{
-		tList[ tList.length ] = [ func, 0, true ];
+		var a = [];
+		a[ C_CALLBACK ] = func;
+		a[ C_TIME ] = 0;
+		a[ C_ONCE ] = true;
+
+		tList[ tList.length ] = a;
 	};
 
 	var ourTick = new Tick();