Fixed cursor mis-positioned on tab characters

This commit is contained in:
斟酌 鵬兄 2017-01-25 11:04:29 +08:00
parent 4b200697dc
commit 42bbc3b240
6 changed files with 90 additions and 23 deletions

View File

@ -60,7 +60,7 @@
}
this.__msg = "";
this.__rec( "", true );
this.__cursor.moveX( -1 );
this.__cursor.moveX( -1, false, false, true );
};
INSERT.prototype.__rec = function( c, newRec )
@ -197,7 +197,7 @@
{
this.__realizeIndent();
feeder.pan();
cur.moveX( inputChar == "\t" ? feeder.firstBuffer.tabWidth : 1, false, true );
cur.moveX( inputChar == "\t" ? feeder.firstBuffer.tabWidth : 1, false, true, true );
}
feeder.dispatcher.dispatchEvent( new BotanEvent( "VisualUpdate" ) );
@ -262,7 +262,7 @@
feeder.softReset();
feeder.pan();
cur.moveX( i * feeder.firstBuffer.tabWidth, false, true );
cur.moveX( i, false, true );
var a = [];
a[ IN_START ] = f;

View File

@ -345,7 +345,7 @@
f();
// Offset correction after REDO / UNDO
cur.moveTo( recStart );
cur.lineStart();
cur.lineStart( true );
} );
cur.moveTo( recStart );

View File

@ -220,13 +220,13 @@
if( cur.aPos == startLine.aPos )
{
cur.moveTo( r.open, true );
cur.moveTo( r.open, true, false, true );
this.__reset( cur );
startLine = this.__startLine;
}
cur.unsuppressEvent();
cur.moveTo( r.close, true );
cur.moveTo( r.close, true, false, true );
}
var currAp = cur.aPos;

View File

@ -259,9 +259,17 @@
{
case SHIFT + A: // Append at the line end
ccur.lineEnd();
case A: // Append
ccur.moveX( 1, true, true );
ccur.moveX( 1, true, true, true );
ccur.openAction( "INSERT", e );
break;
case I: // Insert
ccur.moveX( -1 );
case A: // Append
ccur.moveX( 1, true, true, true );
ccur.openAction( "INSERT", e );
break;
case SHIFT + I: // Append at line start
ccur.lineStart( true );
ccur.openAction( "INSERT", e );
break;
@ -515,11 +523,11 @@
case SHIFT + L: // Last line buffer
break;
case _0: // Really - line Start
case _0: // Really line Start
ccur.lineStart();
break;
case SHIFT + _6: // ^, line Start, XXX: skip tabs
ccur.lineStart();
case SHIFT + _6: // ^, line Start at word
ccur.lineStart( true );
break;
case SHIFT + _4: // $, End
ccur.lineEnd( ccur.pSpace );

View File

@ -103,7 +103,7 @@
Cursor.prototype.Vim;
// Move to an absolute position
Cursor.prototype.moveTo = function( aPos, phantomSpace )
Cursor.prototype.moveTo = function( aPos, phantomSpace, skipTabs )
{
var content = this.feeder.content;
var pline = this.getLine();
@ -133,19 +133,18 @@
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 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 );
this.moveX( jumpX, false, phantomSpace );
this.moveX( - Number.MAX_VALUE, false, false, true );
this.moveX( jumpX, false, phantomSpace, skipTabs );
};
// 0 will be treated as default ( 1 )
Cursor.prototype.moveX = function( d, penetrate, phantomSpace )
Cursor.prototype.moveX = function( d, penetrate, phantomSpace, skipTab )
{
var x = this.pX;
var updatePx = Boolean( d );
@ -177,6 +176,8 @@
/** @type {Components.Vim.LineBuffer} */
var line = this.getLine();
var tabStep = line.tabWidth - 1;
var rline = this.rawLine;
var content = line.visualLines.join( "\n" );
var cLen = content.length;
@ -190,8 +191,7 @@
{
// 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;
hasPhantomSpace = 0 < ( rline.length + occurence( rline, "\t" ) * tabStep ) % line.cols;
if( hasPhantomSpace )
{
@ -203,6 +203,56 @@
}
}
// Hacky tab compensations
if( !skipTab )
{
var s = this.aX;
var a = rline[ s + d ];
var e = s;
if( d < 0 )
{
if( rline[ s ] == "\t" )
{
x -= tabStep;
if( x < 0 )
x = tabStep;
}
s += d;
var ntabs = occurence( rline.substring( s, e ), "\t" ) - 1;
if( 0 < ntabs ) x -= ntabs * tabStep;
}
else if( updatePx ) // && 0 < d ( assuming d can never be 0 )
{
// Going from one line to next
// linebreaks are *invisible*
var isLF = ( content[ x ] == "\n" ) ? 1 : 0;
if( s == 0 )
{
x = 1;
if ( rline[ 0 ] == "\t" )
{
x += tabStep;
}
}
e += d;
var ntabs = occurence( rline.substring( s + 1, e + 1 ), "\t" );
x += ntabs * tabStep + isLF;
if( 1 < d ) x += d - 1;
}
else // jk, non-X navigation. i.e., pX does not change
{
// s = 0, which is unused here
e = x + d;
x += ( occurence( rline.substring( 0, e ), "\t" ) ) * tabStep;
if( 1 < d ) x += d - 1;
}
}
var c = content[ x ];
// Whether x is at line boundary
@ -227,22 +277,31 @@
if( updatePx )
{
this.pX = x;
this.pX = this.aX;
this.updatePosition();
}
};
Cursor.prototype.lineStart = function()
Cursor.prototype.lineStart = function( atWord )
{
this.pX = 0;
if( atWord )
{
var a = this.rawLine.match( /^[ \t]+/g );
this.pX = a ? a[0].length : 0;
}
else
{
this.pX = 0;
}
this.moveX();
this.updatePosition();
};
Cursor.prototype.lineEnd = function( phantomSpace )
{
this.moveX( Number.MAX_VALUE, false, phantomSpace );
this.moveX( Number.MAX_VALUE, false, phantomSpace, true );
};
Cursor.prototype.updatePosition = function()

View File

@ -6,7 +6,7 @@ VIMRE_VERSION = "1.0.0b";
"INSERT": "-- INSERT --"
, "REPLACE": "-- REPLACE --"
, "MORE": "-- MORE --"
, "VISUAL": "-- VISUAL --"
, "VISUAL": "-- VISUAL --"
, "VISLINE": "-- VISUAL LINE --"
, "REGISTERS": "--- Registers ---"
, "WRITE": "\"%1\" %2L, %3C written"