Fix wrong position of lines with tab character

This commit is contained in:
斟酌 鵬兄 2016-03-16 18:55:18 +08:00
parent 5be04d850d
commit bc3c511c6f
13 changed files with 263 additions and 36 deletions

View File

@ -1,10 +1,11 @@
(function(){
var ns = __namespace( "Components.Vim.Actions" );
/** @type {System.Debug} */
var debug = __import( "System.Debug" );
var Mesg = __import( "Components.Vim.Message" );
/** @type {Components.Vim.State.Stack} */
var Stack = __import( "Components.Vim.State.Stack" );
var Translate = function( c )
{
switch( c )
@ -16,15 +17,75 @@
}
};
/* @param {Components.Vim.LineFeeder} */
var ContentPosition = function( f )
{
var line = f.cursor.getLine();
var n = line.lineNum;
var p = 0;
if( 0 < n )
{
p = f.content.indexOf( "\n" );
for( i = 1; p != -1 && i < n; i ++ )
{
p = f.content.indexOf( "\n", p + 1 );
}
if( f.wrap )
{
// wordwrap offset
p ++;
}
}
p += f.cursor.aX;
return p;
};
/** @type {Components.Vim.Cursor.IAction} */
var INSERT = function( Cursor )
{
/** @type {Components.Vim.Cursor} */
this.cursor = Cursor;
this.__cursor = Cursor;
// Initialize this stack
this.__rec( "", true );
};
INSERT.prototype.dispose = function()
{
};
INSERT.prototype.__storeState = function( c, pos )
{
return function() {
debug.Inf( pos, c );
};
};
INSERT.prototype.__rec = function( c, newRec )
{
if( newRec || !this.__stack )
{
if( this.__stack )
{
var c = this.__content;
this.__stack.store(
this.__storeState( c, this.__startPosition )
);
this.__cursor.rec.store( this.__stack );
}
this.__content = "";
this.__stack = new Stack();
this.__startPosition = ContentPosition( this.__cursor.feeder );
}
this.__content += c;
};
INSERT.prototype.handler = function( e )
@ -34,42 +95,27 @@
if( inputChar.length != 1 ) return;
var cur = this.cursor;
var cur = this.__cursor;
var feeder = cur.feeder;
var line = cur.getLine();
var n = line.lineNum;
var f = ContentPosition( feeder );
var cont = feeder.content;
feeder.content =
feeder.content.substring( 0, f )
+ inputChar
+ feeder.content.substring( f );
var f = 0;
if( 0 < n )
{
f = cont.indexOf( "\n" );
for( i = 1; f != -1 && i < n; i ++ )
{
f = cont.indexOf( "\n", f + 1 );
}
if( this.cursor.feeder.wrap )
{
// wordwrap offset
f ++;
}
}
f += cur.aX;
feeder.content = cont.substring( 0, f ) + inputChar + cont.substring( f );
feeder.pan();
feeder.dispatcher.dispatchEvent( new BotanEvent( "VisualUpdate" ) );
this.__rec( inputChar );
cur.moveX( 1 );
};
INSERT.prototype.getMessage = function()
{
var l = this.cursor.feeder.firstBuffer.cols;
var l = this.__cursor.feeder.firstBuffer.cols;
var msg = Mesg( "INSERT" );
for( var i = msg.length; i < l; i ++ ) msg += " ";

View File

@ -0,0 +1,41 @@
(function(){
var ns = __namespace( "Components.Vim.Actions" );
var Mesg = __import( "Components.Vim.Message" );
/** @type {Components.Vim.Cursor.IAction} */
var UNDO = function( Cursor )
{
/** @type {Components.Vim.Cursor} */
this.__cursor = Cursor;
this.__message = "UNDO COMMAND";
};
UNDO.prototype.dispose = function()
{
};
UNDO.prototype.handler = function( e )
{
e.preventDefault();
/** @type {Components.Vim.State.Stack} */
var stack = this.__cursor.rec.undo();
if( stack )
{
stack.play();
}
else
{
this.__message = Mesg( "UNDO_LIMIT" );
}
};
UNDO.prototype.getMessage = function()
{
return this.__message;
};
ns[ NS_EXPORT ]( EX_CLASS, "UNDO", UNDO );
})();

View File

@ -62,10 +62,18 @@
case 65: // a
cfeeder.cursor.openAction( "INSERT" );
break;
case 73: // i
break;
case 85: // u, undo
cfeeder.cursor.openRunAction( "UNDO", e );
break;
case 88: // x, del
break;
case 1065: // A, append at the line end
break;
case 73: // i
case 1088: // X, delete before
break;
case 1085: // U, undo previous changes in oneline
break;
case 1073: // I, append before the line start, after spaces
break;

View File

@ -4,6 +4,9 @@
/** @type {System.Debug} */
var debug = __import( "System.Debug" );
/** @type {Components.Vim.State.Recorder} */
var Recorder = __import( "Components.Vim.State.Recorder" );
var Actions = __import( "Components.Vim.Actions.*" );
var GetLine = function( buffs, l )
@ -71,6 +74,9 @@
// The resulting position
this.P = 0;
// State recorder
this.rec = new Recorder();
this.action = null;
};
@ -210,6 +216,7 @@
{
if( this.action ) this.action.dispose();
this.action = new (Actions[ name ])( this );
this.__pulseMsg = null;
this.feeder.dispatcher.dispatchEvent( new BotanEvent( "VisualUpdate" ) );
};
@ -219,6 +226,18 @@
if( !this.action ) return;
this.action.dispose();
this.action = null;
this.__pulseMsg = null;
this.feeder.dispatcher.dispatchEvent( new BotanEvent( "VisualUpdate" ) );
};
Cursor.prototype.openRunAction = function( name, e )
{
/** @type {Components.Vim.IAction} */
var action = new (Actions[ name ])( this );
action.handler( e );
this.__pulseMsg = action.getMessage();
action.dispose();
this.feeder.dispatcher.dispatchEvent( new BotanEvent( "VisualUpdate" ) );
};
@ -244,23 +263,52 @@
var X = this.X;
var f = this.feeder;
var w = 1;
// Calculate wordwrap offset
if( f.wrap )
{
var cols = f.firstBuffer.cols + 1;
var w = X < cols ? 0 : Math.floor( X / cols );
var lines = this.getLine().visualLines;
if( 0 < w )
for( var i in lines )
{
X -= w;
/** @type {Components.Vim.LineBuffer} */
var vline = lines[ i ];
// Actual length
var aLen = vline.content.toString().length;
// Visual length
var vLen = vline.toString().length;
// Plus the "\n" character
X -= vLen + 1;
if( 0 <= X )
{
w += aLen;
}
else if( X < 0 )
{
w += X + vLen;
break;
}
}
}
return X;
return w;
} );
__readOnly( Cursor.prototype, "message", function()
{
if( this.__pulseMsg )
{
var m = this.__pulseMsg;
this.__pulseMsg = null;
return m;
}
return this.action && this.action.getMessage();
} );

View File

@ -195,7 +195,7 @@
} );
__readOnly( Feeder.prototype, "lineStat", function() {
var X = this.cursor.aX;
var X = this.cursor.aX + 1;
var line = this.cursor.getLine();
var tabStat = "";

View File

@ -0,0 +1,41 @@
(function(){
var ns = __namespace( "Components.Vim.State" );
var Recorder = function()
{
this.__steps = [];
this.__i = 0;
};
Recorder.prototype.undo = function()
{
var i = this.__i - 1;
if( i == -1 || !this.__steps.length ) return null;
return this.__steps[ this.__i = i ];
};
Recorder.prototype.redo = function()
{
var i = this.__i + 1;
if( i == -1 || !this.__steps.length ) return null;
var State = this.__steps[ i ];
if( State )
{
this.__i = i;
return State;
}
return null;
};
Recorder.prototype.record = function( StateObj )
{
this.__steps[ this.__i ] = StateObj;
delete this.__steps[ ++ this.__i ];
};
ns[ NS_EXPORT ]( EX_CLASS, "Recorder", Recorder );
})();

View File

@ -0,0 +1,19 @@
(function(){
var ns = __namespace( "Components.Vim.State" );
var Stack = function()
{
};
Stack.prototype.store = function( handler )
{
this.__handler = handler;
};
Stack.prototype.play = function()
{
if( this.__handler ) this.__handler();
};
ns[ NS_EXPORT ]( EX_CLASS, "Stack", Stack );
})();

View File

@ -32,7 +32,7 @@
if( text == undefined || text === "" ) continue;
display += text.substr( 0, avail );
i = display.length - 1;
i = display.length;
}
else display += " ";
}

View File

@ -13,6 +13,8 @@
, "BOTTOM": "Bot"
, "ALL": "All"
, "EXIT": "Type :quit<Enter> to exit Vim"
, "UNDO_LIMIT": "Already at oldest change"
};
var errors = {

View File

@ -5,6 +5,8 @@ Components.Vim.Cursor = function(){};
Components.Vim.Cursor.feeder;
/** @type {Components.Vim.IAction} */
Components.Vim.Cursor.action;
/** @type {Components.Vim.State.Recorder} */
Components.Vim.Cursor.rec;
/** @type Function */
Components.Vim.Cursor.moveX;
@ -19,6 +21,8 @@ Components.Vim.Cursor.updatePosition;
/** @type Function */
Components.Vim.Cursor.openAction;
/** @type Function */
Components.Vim.Cursor.openRunAction;
/** @type Function */
Components.Vim.Cursor.closeAction;
/** @type {Array} */

View File

@ -0,0 +1,9 @@
/** @constructor */
Components.Vim.State.Recorder = function(){};
/** @type Function */
Components.Vim.State.undo;
/** @type Function */
Components.Vim.State.redo;
/** @type Function */
Components.Vim.State.record;

View File

@ -0,0 +1,7 @@
/** @constructor */
Components.Vim.State.Stack = function(){};
/** @type Function */
Components.Vim.State.Stack.play;
/** @type Function */
Components.Vim.State.Stack.store;

View File

@ -0,0 +1,2 @@
/** @object */
Components.Vim.State = {};