commit 50686073d8c055a0fea8bad2e5bfaf4caa7580b9
| author | 斟酌 鵬兄 <tgckpg@gmail.com> |
| date | 2017-01-09T02:18:21Z |
| subject | Replaced quirky tab char with virtual space chars |
commit 50686073d8c055a0fea8bad2e5bfaf4caa7580b9
Author: 斟酌 鵬兄 <tgckpg@gmail.com>
Date: 2017-01-09T02:18:21Z
Replaced quirky tab char with virtual space chars
---
botanjs/src/Components/Vim/Cursor.js | 92 ++++++++++++++++++++--------
botanjs/src/Components/Vim/LineBuffer.js | 13 ++--
botanjs/src/Components/Vim/LineFeeder.js | 16 +++--
botanjs/src/externs/Components.Vim.Cursor.js | 2 +
4 files changed, 87 insertions(+), 36 deletions(-)
diff --git a/botanjs/src/Components/Vim/Cursor.js b/botanjs/src/Components/Vim/Cursor.js
index f8d2dd9..810bf70 100644
--- a/botanjs/src/Components/Vim/Cursor.js
+++ b/botanjs/src/Components/Vim/Cursor.js
@@ -9,6 +9,8 @@
var Actions = __import( "Components.Vim.Actions.*" );
+ var occurence = __import( "System.utils.Perf.CountSubstr" );
+
var LineOffset = function( buffs, l )
{
/** @type {Components.Vim.LineBuffer} */
@@ -69,6 +71,8 @@
this.cols = feeder.firstBuffer.cols;
// The preferred X position
+ // i.e. last line was at pos 23
+ // moving to next line will prefer pos at 23
this.pX = 0;
// The displaying X position
@@ -129,10 +133,11 @@
var jumpX = aPos < lineStart ? lineStart - aPos : aPos - lineStart;
jumpX += Math.ceil( jumpX / pline.cols ) - 1;
+ jumpX += occurence( content.substring( lineStart + 1, aPos ), "\t" ) * ( pline.tabWidth - 1 );
if( jumpY ) this.moveY( jumpY );
- // This needed because first line does not contain first "\n" character
+ // This is needed because first line does not contain the first "\n" character
if( 0 < this.getLine().lineNum && lineStart <= aPos ) jumpX --;
this.moveX( - Number.MAX_VALUE );
@@ -179,26 +184,14 @@
var hasPhantomSpace = true;
// Empty lines has length of 1
- // If length larger than a, need to compensate the lineEnd
- // for phantomSpace
+ // Need to compensate the lineEnd for phantomSpace
+ // if length is 1 < and != line.cols
if( 1 < cLen )
{
- // 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;
+ // Begin check if this line contains phantomSpace
+ // hasPhantomSpace = 0 < ( rawLine.displayLength ) % cols
+ var rline = this.rawLine;
+ hasPhantomSpace = 0 < ( rline.length + occurence( rline, "\t" ) * ( line.tabWidth - 1 ) ) % line.cols;
if( hasPhantomSpace )
{
@@ -421,14 +414,12 @@
Cursor.prototype.suppressEvent = function() { ++ this.__suppEvt; };
Cursor.prototype.unsuppressEvent = function() { -- this.__suppEvt; };
- Cursor.prototype.getLine = function()
+ Cursor.prototype.getLine = function( raw )
{
var feeder = this.feeder;
var line = feeder.firstBuffer;
var eBuffer = feeder.lastBuffer.next;
- for( var i = 0;
- line != eBuffer;
- line = line.next )
+ for( var i = 0; line != eBuffer; line = line.next )
{
if( line.br ) i ++;
if( this.Y == i ) return line;
@@ -437,26 +428,49 @@
return null;
};
+ __readOnly( Cursor.prototype, "rawLine", function()
+ {
+ var str = this.feeder.content;
+ var lineNum = this.getLine().lineNum - 1;
+ var i = str.indexOf( "\n" ), j = 0;
+
+ for( ; 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 );
+ return str.substring( i + 1, end );
+ } );
+
// The position offset relative to current line
__readOnly( Cursor.prototype, "aX", function()
{
var X = this.X;
var f = this.feeder;
- var w = 1;
+ var w = 0;
// Calculate wordwrap offset
if( f.wrap )
{
var lines = this.getLine().visualLines;
+ // Since w represent valid absX position
+ // w couldn't handle INSERT at the line end with phantomSpace
+ // because phantomSpace is not a valid character
+ // So we calculate along with the phantomSpace here
+ var phantomSpace = X;
for( var i in lines )
{
/** @type {Components.Vim.LineBuffer} */
var vline = lines[ i ];
// Actual length
- var aLen = vline.content.toString().length;
+ var aLen = vline.content.length;
// Visual length
var vLen = vline.toString().length;
@@ -467,10 +481,36 @@
if( 0 <= X )
{
w += aLen;
+ phantomSpace -= 1 + occurence( vline.content, "\t" ) * ( vline.tabWidth - 1 );
}
else if( X < 0 )
{
- w += X + vLen;
+ X += vLen + 1;
+
+ var rline = this.rawLine.substr( w );
+ var l = rline.length;
+
+ var j = 0;
+
+ if( rline[ 0 ] == "\t" )
+ {
+ X -= vline.tabWidth - 1;
+ phantomSpace -= vline.tabWidth - 1;
+ }
+
+ for( var i = 1; j < X && i < rline.length; i ++ )
+ {
+ if( rline[ i ] == "\t" )
+ {
+ X -= vline.tabWidth - 1;
+ phantomSpace -= vline.tabWidth - 1;
+ }
+ j ++;
+ }
+
+ w += j;
+
+ if( w < phantomSpace ) w = phantomSpace;
break;
}
}
diff --git a/botanjs/src/Components/Vim/LineBuffer.js b/botanjs/src/Components/Vim/LineBuffer.js
index e097f83..88601fb 100644
--- a/botanjs/src/Components/Vim/LineBuffer.js
+++ b/botanjs/src/Components/Vim/LineBuffer.js
@@ -13,7 +13,9 @@
this.br = false;
this.placeholder = true;
this.lineNum = 0;
- this.tabWidth = 8;
+ this.tabWidth = 4;
+ this.__tabc = "";
+ for( var i = 0; i < this.tabWidth; i ++ ) this.__tabc += " ";
if( nextLineBuffer )
{
@@ -105,13 +107,14 @@
LineBuffer.prototype.toString = function()
{
- var c = this.cols - occurence( this.content, "\t" ) * ( this.tabWidth - 1 );
- if( this.content.length < c )
+ var cont = this.content.replace( /\t/g, this.__tabc );
+
+ if( cont.length < this.cols )
{
- return this.content + " ";
+ return cont + " ";
}
- return this.content || " ";
+ return cont || " ";
};
__readOnly( LineBuffer.prototype, "nextLine", function()
diff --git a/botanjs/src/Components/Vim/LineFeeder.js b/botanjs/src/Components/Vim/LineFeeder.js
index 95b5ab4..4098773 100644
--- a/botanjs/src/Components/Vim/LineFeeder.js
+++ b/botanjs/src/Components/Vim/LineFeeder.js
@@ -158,9 +158,7 @@
}
}
- this.firstBuffer.Push(
- this.content.substr( f + 1 )
- , this.wrap, i );
+ this.firstBuffer.Push( this.content.substr( f + 1 ), this.wrap, i );
this.panX = X;
this.panY = Y;
@@ -213,11 +211,19 @@
var line = this.cursor.getLine();
var tabStat = "";
- var tabs = line.content.match( /\t/g );
+ var tabs = 0;
+ var l = this.cursor.aPos;
+ var i = l - X;
+ do
+ {
+ if( this.content[ i + 1 ] == "\t" ) tabs ++;
+ i ++;
+ }
+ while( i < l )
if( tabs )
{
- tabStat = "-" + ( X + tabs.length * ( line.tabWidth - 1 ) );
+ tabStat = "-" + ( X + tabs * ( line.tabWidth - 1 ) );
}
return ( line.lineNum + 1 ) + "," + X + tabStat;
diff --git a/botanjs/src/externs/Components.Vim.Cursor.js b/botanjs/src/externs/Components.Vim.Cursor.js
index 8cf84f8..5bdc8b1 100644
--- a/botanjs/src/externs/Components.Vim.Cursor.js
+++ b/botanjs/src/externs/Components.Vim.Cursor.js
@@ -63,3 +63,5 @@ Components.Vim.Cursor.position;
Components.Vim.Cursor.position.start;
/** @type Number */
Components.Vim.Cursor.position.end;
+/** @type String */
+Components.Vim.Cursor.rawLine;