Merge remote-tracking branches 'vim/master' and 'origin/master' into Astro

This commit is contained in:
斟酌 鵬兄 2016-04-05 06:57:25 +08:00
commit de65c665a3
10 changed files with 293 additions and 66 deletions

View File

@ -33,7 +33,7 @@
this.__cursor.unsuppressEvent(); this.__cursor.unsuppressEvent();
}; };
DELETE.prototype.handler = function( e, sp ) DELETE.prototype.handler = function( e, sp, newLine )
{ {
e.preventDefault(); e.preventDefault();
@ -45,8 +45,14 @@
var cur = this.__cursor; var cur = this.__cursor;
var feeder = cur.feeder; var feeder = cur.feeder;
// Do nothing if content is considered empty
if( feeder.firstBuffer.next.placeholder && feeder.content.length < 2 )
{
debug.Info( "Content is empty" );
return true;
}
var Triggered = false; var Triggered = false;
var newLine = false;
if( sp == undefined ) if( sp == undefined )
{ {
@ -135,7 +141,8 @@
} }
} }
var c = feeder.content; // last "\n" padding
var c = feeder.content.slice( 0, -1 );
var s = sp; var s = sp;
var e = cur.aPos; var e = cur.aPos;
@ -152,6 +159,7 @@
this.__nline = occurence( removed, "\n" ); this.__nline = occurence( removed, "\n" );
feeder.content = c.substring( 0, s ) + c.substring( e + 1 ); feeder.content = c.substring( 0, s ) + c.substring( e + 1 );
if( feeder.content === "" ) feeder.content = "\n";
// Try to keep the original panning if possible // Try to keep the original panning if possible
feeder.pan( undefined feeder.pan( undefined

View File

@ -30,6 +30,8 @@
this.__cursor = Cursor; this.__cursor = Cursor;
this.__stator = new Stator( Cursor ); this.__stator = new Stator( Cursor );
this.__minReach = 0;
this.__insertLen = 0;
// Initialize this stack // Initialize this stack
this.__rec( "", true ); this.__rec( "", true );
@ -57,18 +59,27 @@
if( this.__stack ) if( this.__stack )
{ {
// If nothings changed // If nothings changed
if( this.__insertLength == 0 if( this.__minReach == 0
&& this.__punch == 0
&& this.__contentUndo === "" && this.__contentUndo === ""
) return; ) return;
if( this.__punch < this.__minReach )
{
this.__minReach = this.__punch;
}
this.__stack.store( this.__stack.store(
this.__stator.save( this.__insertLength, this.__contentUndo ) this.__stator.save(
this.__insertLen
, this.__contentUndo
, -this.__minReach )
); );
this.__cursor.rec.record( this.__stack ); this.__cursor.rec.record( this.__stack );
} }
this.__insertLength = 0; this.__punch = 0;
this.__contentUndo = ""; this.__contentUndo = "";
this.__stack = new Stack(); this.__stack = new Stack();
} }
@ -78,7 +89,14 @@
// todo // todo
} }
this.__insertLength += c.length; if( this.__punch < this.__minReach )
{
this.__insertLen = 0;
this.__minReach = this.__punch;
}
this.__punch += c.length;
this.__insertLen += c.length;
}; };
INSERT.prototype.__specialKey = function( e, inputChar ) INSERT.prototype.__specialKey = function( e, inputChar )
@ -92,11 +110,9 @@
var oY = feeder.panY + cur.Y; var oY = feeder.panY + cur.Y;
if( cur.X == 0 && feeder.panY == 0 && cur.Y == 0 ) return; if( cur.X == 0 && feeder.panY == 0 && cur.Y == 0 ) return;
cur.moveX( -1, true, true ); var f = cur.aPos - 1;
var f = cur.aPos; if( this.__punch <= this.__minReach )
if( this.__insertLength <= 0 )
{ {
this.__contentUndo = feeder.content.substr( f, 1 ) + this.__contentUndo; this.__contentUndo = feeder.content.substr( f, 1 ) + this.__contentUndo;
} }
@ -105,7 +121,12 @@
feeder.content.substring( 0, f ) feeder.content.substring( 0, f )
+ feeder.content.substring( f + 1 ); + feeder.content.substring( f + 1 );
this.__insertLength --; feeder.pan();
cur.moveX( -1, true, true );
if( 0 < this.__insertLen ) this.__insertLen --;
this.__punch --;
} }
else if( e.kMap( "Del" ) ) else if( e.kMap( "Del" ) )
{ {
@ -116,16 +137,20 @@
feeder.content = feeder.content =
feeder.content.substring( 0, f ) feeder.content.substring( 0, f )
+ feeder.content.substring( f + 1 ); + feeder.content.substring( f + 1 );
feeder.pan();
} }
else return; else return;
feeder.pan();
feeder.dispatcher.dispatchEvent( new BotanEvent( "VisualUpdate" ) ); feeder.dispatcher.dispatchEvent( new BotanEvent( "VisualUpdate" ) );
}; };
INSERT.prototype.handler = function( e ) INSERT.prototype.handler = function( e )
{ {
e.preventDefault(); e.preventDefault();
if( e.ModKeys ) return;
var inputChar = Translate( e.key ); var inputChar = Translate( e.key );
if( inputChar.length != 1 ) if( inputChar.length != 1 )
@ -160,7 +185,6 @@
feeder.dispatcher.dispatchEvent( new BotanEvent( "VisualUpdate" ) ); feeder.dispatcher.dispatchEvent( new BotanEvent( "VisualUpdate" ) );
this.__rec( inputChar ); this.__rec( inputChar );
}; };
INSERT.prototype.getMessage = function() INSERT.prototype.getMessage = function()

View File

@ -40,9 +40,6 @@
var lowerLimmit = p; var lowerLimmit = p;
var cX = cur.X;
var tX = cX;
var Char = et.key; var Char = et.key;
if( et.kMap( "Tab" ) ) if( et.kMap( "Tab" ) )
{ {
@ -55,15 +52,16 @@
return; return;
} }
var tX = -1;
// Forward // Forward
if( em.kMap( "t" ) || em.kMap( "f" ) ) if( em.kMap( "t" ) || em.kMap( "f" ) )
{ {
tX = f.content.indexOf( Char, p + cX + 1 ); tX = f.content.indexOf( Char, cur.aPos + 1 );
} }
// backward // backward
else else
{ {
tX = f.content.lastIndexOf( Char, p + cX - 1 ); tX = f.content.lastIndexOf( Char, cur.aPos - 1 );
} }
if( lowerLimmit <= tX && tX < upperLimit ) if( lowerLimmit <= tX && tX < upperLimit )

View File

@ -11,12 +11,44 @@
/** @type {Components.Vim.IAction} */ /** @type {Components.Vim.IAction} */
var DELETE = ns[ NS_INVOKE ]( "DELETE" ); var DELETE = ns[ NS_INVOKE ]( "DELETE" );
var MODE_NULL = -1;
var MODE_VISUAL = 0;
var MODE_LINE = 1;
// The offset of given line relative to content
var offsetY = function( cur, l )
{
if( l == 0 ) return 0;
var f = cur.feeder;
var j = 0;
var last = -1;
for( var i = f.content.indexOf( "\n" ); 0 <= i; i = f.content.indexOf( "\n", i + 1 ) )
{
last = i;
j ++;
if( l <= j ) break;
}
if( f.EOF ) i = last;
// "\n" compensation
var c = f.content[ i + 1 ];
if(!( c == undefined || c == "\n" ))
{
i ++;
}
return i;
};
/** @type {Components.Vim.IAction} */ /** @type {Components.Vim.IAction} */
var VISUAL = function( Cursor ) var VISUAL = function( Cursor )
{ {
this.__reset( Cursor ); this.__reset( Cursor );
this.__msg = Mesg( "VISUAL" ); this.__msg = "";
Cursor.blink = false; Cursor.blink = false;
Cursor.pSpace = true; Cursor.pSpace = true;
}; };
@ -25,9 +57,25 @@
{ {
/** @type {Components.Vim.Cursor} */ /** @type {Components.Vim.Cursor} */
this.__cursor = Cursor; this.__cursor = Cursor;
this.__startaP = Cursor.aPos;
this.__start = Cursor.PStart; var s = {
this.__selStart = Cursor.PStart; lineNum: Cursor.getLine().lineNum
, X: Cursor.X
, aPos: Cursor.aPos
, pstart: Cursor.PStart
};
s.aStart = s.aPos - Cursor.aX;
Cursor.suppressEvent();
Cursor.lineEnd( true );
s.aEnd = Cursor.aPos;
Cursor.moveTo( s.aPos );
Cursor.unsuppressEvent();
this.__startLine = s;
}; };
VISUAL.prototype.allowMovement = true; VISUAL.prototype.allowMovement = true;
@ -38,8 +86,7 @@
c.blink = true; c.blink = true;
c.pSpace = false; c.pSpace = false;
c.PStart = this.__selStart; c.updatePosition();
c.PEnd = this.__selStart + 1;
// This fix the highlighting position of missing phantomSpace // This fix the highlighting position of missing phantomSpace
// for maximum filled line // for maximum filled line
@ -59,8 +106,11 @@
if( e.ModKeys ) return; if( e.ModKeys ) return;
var cur = this.__cursor; var cur = this.__cursor;
var feeder = cur.feeder;
var Action = null; var Action = null;
var dispatchUpdate = false;
if( e.kMap( "y" ) ) if( e.kMap( "y" ) )
{ {
Action = new YANK( cur ); Action = new YANK( cur );
@ -69,27 +119,73 @@
{ {
Action = new DELETE( cur ); Action = new DELETE( cur );
} }
else if( e.kMap( "V" ) )
{
if( this.__mode == MODE_LINE ) return true;
else
{
dispatchUpdate = true;
this.__mode = MODE_LINE;
this.__msg = Mesg( "VISLINE" );
}
}
else if( e.kMap( "v" ) )
{
if( this.__mode == MODE_VISUAL ) return true;
else
{
dispatchUpdate = true;
this.__mode = MODE_VISUAL;
this.__msg = Mesg( "VISUAL" );
cur.updatePosition();
}
}
if( dispatchUpdate )
feeder.dispatcher.dispatchEvent( new BotanEvent( "VisualUpdate" ) );
if( this.__mode == MODE_NULL )
{
debug.Error( new Error( "Mode is undefined" ) );
return true;
}
var startLine = this.__startLine;
if( Action ) if( Action )
{ {
cur.suppressEvent(); cur.suppressEvent();
// Low-level cursor position adjustment var lineMode = this.__mode == MODE_LINE;
if( lineMode )
{
if( startLine.aPos < cur.aPos )
{
cur.lineEnd( true );
startLine.aPos = startLine.aStart;
}
else
{
cur.lineStart();
startLine.aPos = startLine.aEnd;
}
}
// Cursor position adjustment
// this swap the cursor direction from LTR to RTL // this swap the cursor direction from LTR to RTL
// i.e. treat all delete as "e<----s" flow // i.e. treat all delete as "e<----s" flow
// to keep the cursor position as the top on UNDO / REDO // to keep the cursor position as the top on UNDO / REDO
if( Action.constructor == DELETE && this.__startaP < cur.aPos ) if( Action.constructor == DELETE && startLine.aPos < cur.aPos )
{ {
var o = cur.aPos; var o = cur.aPos;
cur.moveTo( this.__startaP, true ); cur.moveTo( startLine.aPos, true );
this.__startaP = o; startLine.aPos = o;
} }
Action.handler( e, this.__startaP ); Action.handler( e, startLine.aPos, lineMode );
if( Action.constructor != DELETE ) if( Action.constructor != DELETE )
{ {
cur.moveTo( this.__startaP ); cur.moveTo( startLine.aPos );
} }
this.__msg = Action.getMessage(); this.__msg = Action.getMessage();
@ -97,7 +193,7 @@
Action.dispose(); Action.dispose();
cur.unsuppressEvent(); cur.unsuppressEvent();
this.__selStart = cur.PStart; startLine.pstart = cur.PStart;
return true; return true;
} }
@ -109,30 +205,119 @@
var r = e.range; var r = e.range;
if( cur.aPos == this.__startaP ) if( cur.aPos == startLine.aPos )
{ {
cur.moveTo( r.open, true ); cur.moveTo( r.open, true );
this.__reset( cur ); this.__reset( cur );
startLine = this.__startLine;
} }
cur.unsuppressEvent(); cur.unsuppressEvent();
cur.moveTo( r.close, true ); cur.moveTo( r.close, true );
} }
var prevPos = this.__start; var currAp = cur.aPos;
var newPos = cur.PStart;
// Calculate the visible max min aPos of the current screen
var line = feeder.firstBuffer;
var firstLine = line.lineNum;
var minAp = offsetY( cur, firstLine );
var maxAp = offsetY( cur, firstLine + feeder.moreAt + 1 ) - 1;
debug.Info( "Min aPos: " + minAp, "Max aPos: " + maxAp );
var pstart = startLine.X;
var nstart = cur.PStart;
// highlight from the start
if( startLine.aPos < minAp )
{
pstart = 0;
}
// highlight from the end
else if( maxAp < startLine.aPos )
{
pstart = -2;
var i = 0;
do
{
if( line.placeholder ) break;
if( i <= feeder.moreAt )
{
pstart += line.toString().length + 1;
}
i ++;
}
while( line = line.next );
}
else
{
var l = startLine.lineNum;
if( this.__mode == MODE_LINE )
{
cur.suppressEvent();
pstart = 0;
if( currAp < startLine.aPos )
{
pstart = -1;
l ++;
cur.lineStart();
nstart = cur.PStart;
}
else if( startLine.aPos < currAp )
{
cur.lineEnd( true );
nstart = cur.PStart;
}
// aPos == currPos
else
{
cur.lineStart();
nstart = cur.PStart;
cur.lineEnd( true );
pstart = cur.PStart;
l = line.lineNum;
}
cur.moveTo( currAp, true );
cur.unsuppressEvent();
}
else if( this.__mode == MODE_VISUAL )
{
if( currAp == startLine.aPos ) return;
}
// Append the Y offset
var i = 0;
do
{
if( line.lineNum == l || line.placeholder ) break;
pstart += line.toString().length + 1;
}
while( line = line.next );
}
var prevPos = pstart;
var newPos = nstart;
var posDiff = newPos - prevPos; var posDiff = newPos - prevPos;
if( 0 <= posDiff )
var currAp = cur.aPos;
// Sets the visual position
// s-->e
if( 0 < posDiff )
{ {
this.__selStart = newPos;
newPos = newPos + 1; newPos = newPos + 1;
} }
// e<--s
else if( posDiff < 0 ) else if( posDiff < 0 )
{ {
prevPos += posDiff; prevPos += posDiff;
newPos = this.__start + 1; newPos = pstart + 1;
this.__selStart = prevPos;
} }
cur.PStart = prevPos; cur.PStart = prevPos;

View File

@ -27,7 +27,7 @@
this.__cursor.unsuppressEvent(); this.__cursor.unsuppressEvent();
}; };
YANK.prototype.handler = function( e, sp ) YANK.prototype.handler = function( e, sp, newLine )
{ {
e.preventDefault(); e.preventDefault();
@ -41,7 +41,6 @@
var Triggered = false; var Triggered = false;
var newLine = false;
if( sp == undefined ) if( sp == undefined )
{ {
Triggered = true; Triggered = true;

View File

@ -271,10 +271,9 @@
break; break;
case V: // Visual case V: // Visual
ccur.openAction( "VISUAL" );
break;
case SHIFT + V: // Visual line case SHIFT + V: // Visual line
ccur.openAction( "VISUAL_LINE" ); ccur.openAction( "VISUAL" );
ccur.action.handler( e );
break; break;
case SHIFT + SEMI_COLON: // ":" Command line case SHIFT + SEMI_COLON: // ":" Command line

View File

@ -147,7 +147,9 @@
if( 0 < this.__off ) if( 0 < this.__off )
{ {
d += this.__off; if( 0 < d && phantomSpace )
d += this.__off;
this.__off = 0; this.__off = 0;
} }
@ -215,7 +217,7 @@
if( boundary ) if( boundary )
{ {
x = 0 < d ? lineEnd : 0; x = 0 < x ? lineEnd : 0;
} }
else if( c == "\n" ) else if( c == "\n" )
{ {
@ -435,7 +437,7 @@
return null; return null;
}; };
// The absX for current Line // The position offset relative to current line
__readOnly( Cursor.prototype, "aX", function() __readOnly( Cursor.prototype, "aX", function()
{ {
var X = this.X; var X = this.X;
@ -473,6 +475,7 @@
} }
} }
} }
else return this.X;
return w; return w;
} ); } );

View File

@ -8,17 +8,12 @@
this.__startState = this.__saveCur(); this.__startState = this.__saveCur();
}; };
Stator.prototype.save = function( insertLength, contentUndo ) Stator.prototype.save = function( insertLength, contentUndo, removeLen )
{ {
if( removeLen == undefined ) removeLen = 0;
var cur = this.__cursor; var cur = this.__cursor;
var feeder = cur.feeder; var feeder = cur.feeder;
var startPos = this.__startPosition; var startPos = this.__startPosition - removeLen;
if( insertLength < 0 )
{
startPos += insertLength;
insertLength = 0;
}
var sSt = this.__startState; var sSt = this.__startState;
var eSt = this.__saveCur(); var eSt = this.__saveCur();
@ -38,6 +33,7 @@
cur.PEnd = st.p + 1; cur.PEnd = st.p + 1;
cur.X = st.x; cur.X = st.x;
cur.Y = st.y; cur.Y = st.y;
cur.pX = st.cpX - 1;
feeder.panX = st.px; feeder.panX = st.px;
feeder.panY = st.py; feeder.panY = st.py;
@ -54,6 +50,7 @@
p: c.PStart p: c.PStart
, x: c.X , x: c.X
, y: c.Y , y: c.Y
, cpX: c.pX
, px: c.feeder.panX , px: c.feeder.panX
, py: c.feeder.panY , py: c.feeder.panY
}; };

View File

@ -33,6 +33,7 @@
{ {
return function( e ) return function( e )
{ {
sender.__active = true;
e = e || window.event; e = e || window.event;
if ( e.keyCode ) code = e.keyCode; if ( e.keyCode ) code = e.keyCode;
else if ( e.which ) code = e.which; else if ( e.which ) code = e.which;
@ -124,7 +125,7 @@
else else
{ {
var t = ""; var t = "";
i -= 3; -- i;
for( var k = 0; k < i; k ++ ) t += "."; for( var k = 0; k < i; k ++ ) t += ".";
area.value = t; area.value = t;
@ -144,7 +145,7 @@
var testHeight = function() { var testHeight = function() {
area.value += m(); area.value += m();
l ++; ++ l;
if( oHeight == area.scrollHeight ) if( oHeight == area.scrollHeight )
{ {
@ -222,8 +223,14 @@
_self.select( cfeeder.cursor.position ); _self.select( cfeeder.cursor.position );
}; };
cfeeder.dispatcher.addEventListener( "SelectionChanged", function()
{
_self.select( cfeeder.cursor.position );
} );
cfeeder.dispatcher.addEventListener( "VisualUpdate", Update ); cfeeder.dispatcher.addEventListener( "VisualUpdate", Update );
Update(); element.value = "Please wait ...";
Cycle.delay( Update, 70 );
this.__visualUpdate = Update; this.__visualUpdate = Update;

View File

@ -19,11 +19,6 @@
var stepper = function() var stepper = function()
{ {
var thisTime = new Date().getTime(); var thisTime = new Date().getTime();
// 0: Callback
// 1: scheduled run time
// 2: Permanent
// ( 3: id )
// 4: interval
for ( var i in tList ) for ( var i in tList )
{ {
var f = tList[i]; var f = tList[i];
@ -55,7 +50,12 @@
// Should bind "func" before register // Should bind "func" before register
var registerDelay = function (func, milliSec) var registerDelay = function (func, milliSec)
{ {
tList[ tList.length ] = [ func, new Date().getTime() + milliSec, true ]; var a = [];
a[ C_CALLBACK ] = func;
a[ C_TIME ] = new Date().getTime() + milliSec;
a[ C_ONCE ] = true;
tList[ tList.length ] = a;
}; };
var registerPermanentTicker = function ( id, func, interval ) var registerPermanentTicker = function ( id, func, interval )
@ -66,7 +66,14 @@
return false; return false;
} }
tList[ tList.length ] = [ func, new Date().getTime() + interval, false, id, interval ]; var a = [];
a[ C_CALLBACK ] = func;
a[ C_TIME ] = new Date().getTime() + interval;
a[ C_ONCE ] = false;
a[ C_ID ] = id;
a[ C_INTVL ] = interval;
tList[ tList.length ] = a;
}; };
var deletePermanentTicker = function ( id ) var deletePermanentTicker = function ( id )