penguin/AstroJS

Javascript framework for my blog

commit a927c901345730e8053cea9ec89cc27e9f910d3c

author斟酌 鵬兄 <tgckpg@gmail.com>
date2016-03-31T20:05:43Z
subjectRewrite moveX function
commit a927c901345730e8053cea9ec89cc27e9f910d3c
Author: 斟酌 鵬兄 <tgckpg@gmail.com>
Date:   2016-03-31T20:05:43Z

    Rewrite moveX function
---
 botanjs/src/Components/Vim/Actions/PUT.js    |  8 +++-
 botanjs/src/Components/Vim/Actions/VISUAL.js | 18 +++++--
 botanjs/src/Components/Vim/Controls.js       |  9 ++++
 botanjs/src/Components/Vim/Cursor.js         | 71 ++++++++++++++++++++++++----
 botanjs/src/Components/Vim/LineBuffer.js     | 11 ++++-
 5 files changed, 100 insertions(+), 17 deletions(-)

diff --git a/botanjs/src/Components/Vim/Actions/PUT.js b/botanjs/src/Components/Vim/Actions/PUT.js
index 81ff721..2dbb263 100644
--- a/botanjs/src/Components/Vim/Actions/PUT.js
+++ b/botanjs/src/Components/Vim/Actions/PUT.js
@@ -44,9 +44,13 @@
 		var feeder = cur.feeder;
 
 		var newLine = cput.newLine;
+
+		// Compensation
+		var c = e.kMap( "P" ) ? 0 : -1;
+
 		if( newLine )
 		{
-			cur.moveY( 1 );
+			cur.moveY( -c );
 			cur.lineStart();
 		}
 
@@ -69,7 +73,7 @@
 			stack.store( function()
 			{
 				f();
-				cur.moveY( -1 );
+				cur.moveY( c );
 			} );
 		}
 		else
diff --git a/botanjs/src/Components/Vim/Actions/VISUAL.js b/botanjs/src/Components/Vim/Actions/VISUAL.js
index caac607..060cdbf 100644
--- a/botanjs/src/Components/Vim/Actions/VISUAL.js
+++ b/botanjs/src/Components/Vim/Actions/VISUAL.js
@@ -36,10 +36,20 @@
 	VISUAL.prototype.dispose = function()
 	{
 		this.__msg = this.__leaveMesg;
-		this.__cursor.blink = true;
-		this.__cursor.pSpace = false;
-		this.__cursor.PStart = this.__selStart;
-		this.__cursor.PEnd = this.__selStart + 1;
+		var c = this.__cursor;
+
+		c.blink = true;
+		c.pSpace = false;
+		c.PStart = this.__selStart;
+		c.PEnd = this.__selStart + 1;
+
+		// This fix the highlighting position of missing phantomSpace
+		// for maximum filled line
+		if( c.feeder.wrap )
+		{
+			c.moveX( -1 );
+			c.moveX( 1 );
+		}
 	};
 
 	VISUAL.prototype.handler = function( e, done )
diff --git a/botanjs/src/Components/Vim/Controls.js b/botanjs/src/Components/Vim/Controls.js
index 1163433..8dc0ac3 100644
--- a/botanjs/src/Components/Vim/Controls.js
+++ b/botanjs/src/Components/Vim/Controls.js
@@ -396,6 +396,7 @@
 				}, _8 );
 				break;
 
+			case SLASH: // "/" Seach movement
 			case SLASH: // "/" Seach movement
 				this.__cMovement = true;
 				break;
@@ -443,7 +444,15 @@
 			else
 			{
 				if( ccur.action.allowMovement )
+				{
+					var SubCommand = !this.__compositeReg;
 					this.__cursorCommand( e, kCode );
+					if( SubCommand && this.__compositeReg )
+					{
+						e.preventDefault();
+						return;
+					}
+				}
 
 				if( ccur.action.handler( e ) )
 				{
diff --git a/botanjs/src/Components/Vim/Cursor.js b/botanjs/src/Components/Vim/Cursor.js
index 3f884cc..3c4927f 100644
--- a/botanjs/src/Components/Vim/Cursor.js
+++ b/botanjs/src/Components/Vim/Cursor.js
@@ -83,6 +83,9 @@
 		this.pSpace = false;
 
 		this.__suppEvt = 0;
+
+		// Offset compensation for max filled wrapped line
+		this.__off = 0;
 	};
 
 	// Set by VimArea
@@ -118,6 +121,8 @@
 		var jumpY = expLineNum - lastLineNum;
 		var jumpX = aPos < lineStart ? lineStart - aPos : aPos - lineStart;
 
+		jumpX += Math.ceil( jumpX / pline.cols ) - 1;
+
 		if( jumpY ) this.moveY( jumpY );
 		if( 0 < this.getLine().lineNum && lineStart <= aPos ) jumpX --;
 
@@ -130,13 +135,19 @@
 	Cursor.prototype.moveX = function( d, penetrate, phantomSpace )
 	{
 		var x = this.pX;
+		if( 0 < this.__off )
+		{
+			d += this.__off;
+			this.__off = 0;
+		}
 
 		var updatePx = Boolean( d );
 		if( updatePx ) x = this.X + d;
 
 		if( !d ) d = 1;
 
-		var buffs = this.feeder.lineBuffers;
+		var feeder = this.feeder;
+		var buffs = feeder.lineBuffers;
 
 		if( penetrate )
 		{
@@ -153,23 +164,61 @@
 		var content = line.visualLines.join( "\n" );
 		var cLen = content.length;
 
-		var c = content[ x ];
+		var lineEnd = 0;
+		var hasPhantomSpace = true;
 
-		// Motion includes empty lines before cursor end
-		if( ( phantomSpace && cLen - 1 <= x ) || ( cLen == 1 && c == undefined ) )
+		// Empty lines has length of 1
+		// If length larger than a, need to compensate the lineEnd
+		// for phantomSpace
+		if( 1 < cLen )
 		{
-			x = 0 < d ? cLen - 1 : 0;
+			// Begin check if whether this line contains phantomSpace
+			var lineNum = line.lineNum - 1;
+			var str = feeder.content;
+			for( var i = str.indexOf( "\n" ), j = 0; 0 <= i; i = str.indexOf( "\n", i ), j ++ )
+			{
+				if( lineNum == j ) break;
+				i ++;
+			}
+
+			if( j == 0 && i == -1 ) i = 0;
+
+			var end = str.indexOf( "\n", i + 1 );
+			end = end == -1 ? str.length : end;
+
+			// Actual LineLength
+			var hasPhantomSpace = 0 < ( end - i - 1 ) % line.cols;
+
+			if( hasPhantomSpace )
+			{
+				lineEnd = phantomSpace ? cLen - 1 : cLen - 2;
+			}
+			else
+			{
+				lineEnd = phantomSpace ? cLen : cLen - 1;
+			}
 		}
-		// ( 2 < cLen ) motion excludes empty lines at cursor end
-		else if( ( 2 <= cLen && x == cLen - 1 && c == " " ) || c == undefined )
+
+		var c = content[ x ];
+
+		// Whether x is at line boundary
+		var boundary = c == undefined || ( cLen == x + 1 && c == " " );
+
+		if( boundary )
 		{
-			x = 0 < d ? cLen - 2 : 0;
+			x = 0 < d ? lineEnd : 0;
 		}
 		else if( c == "\n" )
 		{
 			x += d;
 		}
 
+		// Wordwrap phantomSpace movement compensation on max filled lines
+		if( feeder.wrap && boundary && !hasPhantomSpace && phantomSpace )
+		{
+			this.__off = 1;
+		}
+
 		this.X = x;
 
 		if( updatePx )
@@ -177,6 +226,7 @@
 			this.pX = x;
 			this.updatePosition();
 		}
+
 	};
 
 	Cursor.prototype.lineStart = function()
@@ -193,10 +243,11 @@
 
 	Cursor.prototype.updatePosition = function()
 	{
-		var P = this.X + LineOffset( this.feeder.lineBuffers, this.Y );
+		var feeder = this.feeder;
+		var P = this.X + LineOffset( feeder.lineBuffers, this.Y ) + this.__off;
+
 		this.PStart = P;
 		this.PEnd = P + 1;
-		this.__p = P;
 
 		this.__visualUpdate();
 	};
diff --git a/botanjs/src/Components/Vim/LineBuffer.js b/botanjs/src/Components/Vim/LineBuffer.js
index 238cfb3..e097f83 100644
--- a/botanjs/src/Components/Vim/LineBuffer.js
+++ b/botanjs/src/Components/Vim/LineBuffer.js
@@ -3,6 +3,8 @@
 
 	var debug = __import( "System.Debug" );
 
+	var occurence = __import( "System.utils.Perf.CountSubstr" );
+
 	var LineBuffer = function( cols, nextLineBuffer )
 	{
 		this.prev = null;
@@ -60,6 +62,12 @@
 
 				line += c;
 			}
+
+			if( !br && i == this.cols && content[i] == "\n" )
+			{
+				i ++;
+				br = true;
+			}
 		}
 		else
 		{
@@ -97,7 +105,8 @@
 
 	LineBuffer.prototype.toString = function()
 	{
-		if( this.content.length < this.cols )
+		var c = this.cols - occurence( this.content, "\t" ) * ( this.tabWidth - 1 );
+		if( this.content.length < c )
 		{
 			return this.content + " ";
 		}