History stacks

This commit is contained in:
斟酌 鵬兄 2016-04-02 18:35:12 +08:00
parent c7249c071c
commit 3ed7d2be84
6 changed files with 212 additions and 33 deletions

View File

@ -4,8 +4,8 @@
/** @type {System.Debug} */
var debug = __import( "System.Debug" );
/** @type {Components.Vim.Ex.Search} */
var ExSearch = __import( "Components.Vim.Ex.Search" );
/** @type {Components.Vim.Ex.Command} */
var ExCommand = __import( "Components.Vim.Ex.Command" );
var beep = ns[ NS_INVOKE ]( "Beep" );
@ -441,10 +441,10 @@
}, _8 );
break;
case SLASH: // "/" Seach movement
case SLASH: // "/" Search movement
this.__cMovement = true;
this.__divedCCmd = new ExSearch( ccur );
this.__divedCCmd = new ExCommand( ccur, "/" );
this.__divedCCmd.handler( e );
break;
default:
@ -499,7 +499,8 @@
this.__cMovement = false;
this.__divedCCmd = null;
}
else return;
if( e.canceled ) return;
}
var cfeeder = this.__cfeeder;
@ -545,6 +546,7 @@
var InputEvent = function( sender, e )
{
this.__target = sender;
this.__canceled = false;
if( typeof( e ) == "string" )
{
@ -572,11 +574,14 @@
this.__range = null;
};
InputEvent.prototype.cancel = function() { this.__canceled = true; };
__readOnly( InputEvent.prototype, "target", function() { return this.__target; } );
__readOnly( InputEvent.prototype, "key", function() { return this.__key; } );
__readOnly( InputEvent.prototype, "keyCode", function() { return this.__kCode; } );
__readOnly( InputEvent.prototype, "ModKeys", function() { return this.__modKeys; } );
__readOnly( InputEvent.prototype, "Escape", function() { return this.__escape; } );
__readOnly( InputEvent.prototype, "canceled", function() { return this.__canceled; } );
__readOnly( InputEvent.prototype, "range", function() {

View File

@ -8,25 +8,35 @@
/** @type {System.utils.Perf} */
var Perf = __import( "System.utils.Perf" );
/**j@type {Components.Vim.State.History} */
var History = __import( "Components.Vim.State.History" );
var Mesg = __import( "Components.Vim.Message" );
var beep = __import( "Components.Vim.Beep" );
// This is for security & privacy concerns?
var ZMap = {
"/": Perf.uuid
, ":" : Perf.uuid
};
/** @type {Components.Vim.Cursor.IAction} */
var Search = function( Cursor )
var Command = function( Cursor, Mode )
{
var _self = this;
if( !ZMap[ Mode ] ) throw new Error( "Unsupport mode: " + Mode );
/** @type {Components.Vim.Cursor} */
this.__cursor = Cursor;
this.__statusBar = Cursor.Vim.statusBar;
this.__command = [];
this.__blinkId = "ExSearchBlinkCycle" + Perf.uuid;
this.__curPos = 0;
this.__mode = Mode;
this.__hist = new History( ZMap[ Mode ] );
this.__disp = function()
{
};
this.__command = [];
this.__currentCommand = null;
this.__blinkId = "ExCommandBlinkCycle" + Perf.uuid;
this.__curPos = 0;
var feeder = Cursor.feeder;
@ -77,7 +87,7 @@
this.__statusBar.override = this.__doBlink;
};
Search.prototype.dispose = function()
Command.prototype.dispose = function()
{
this.__statusBar.override = null;
@ -86,7 +96,7 @@
feeder.dispatcher.dispatchEvent( new BotanEvent( "VisualUpdate" ) );
};
Search.prototype.handler = function( e )
Command.prototype.handler = function( e )
{
e.preventDefault();
@ -96,6 +106,8 @@
var InputKey = null;
var histNav = false;
if( e.kMap( "Tab" ) )
{
InputKey = "^I";
@ -106,8 +118,15 @@
}
else if( e.kMap( "BS" ) )
{
if( this.__curPos == 1 && 1 < this.__command.length )
return false;
this.__command.splice( --this.__curPos, 1 );
if( this.__command.length == 0 ) return true;
if( this.__command.length == 0 )
{
e.cancel();
return true;
}
}
else if( e.kMap( "Del" ) )
{
@ -115,23 +134,56 @@
}
else if( e.kMap( "Enter" ) )
{
this.__process();
return true;
}
else if( e.kMap( "Up" ) ) // History navigations
{
}
else if( e.kMap( "Down" ) )
{
}
else if( e.kMap( "Left" ) )
{
if( 0 < this.__curPos ) this.__curPos --;
if( 1 < this.__curPos ) this.__curPos --;
}
else if( e.kMap( "Right" ) )
{
if( this.__curPos < this.__command.length )
this.__curPos ++;
}
// History stepping
else if( histNav = e.kMap( "Up" ) ) // History navigations
{
if( !this.__currentCommand )
{
this.__currentCommand = this.__command;
}
var n = this.__hist.prev( this.__currentCommand );
if( n )
{
this.__command = n;
this.__curPos = n.length;
}
else
{
beep();
}
}
else if( histNav = e.kMap( "Down" ) )
{
var n = this.__hist.next( this.__currentCommand );
if( n )
{
this.__command = n;
this.__curPos = n.length;
}
else if( this.__currentCommand )
{
this.__command = this.__currentCommand;
this.__currentCommand = null;
}
else beep();
}
else
{
InputKey = e.key;
@ -142,9 +194,22 @@
this.__command.splice( this.__curPos ++, 0, InputKey );
}
var feeder = this.__cursor.feeder;
feeder.dispatcher.dispatchEvent( new BotanEvent( "VisualUpdate" ) );
if( !histNav )
{
this.__hist.reset();
if( this.__currentCommand ) this.__currentCommand = this.__command;
}
ns[ NS_EXPORT ]( EX_CLASS, "Search", Search );
e.cancel();
var feeder = this.__cursor.feeder;
feeder.dispatcher.dispatchEvent( new BotanEvent( "VisualUpdate" ) );
};
Command.prototype.__process = function()
{
this.__hist.push( this.__command );
};
ns[ NS_EXPORT ]( EX_CLASS, "Command", Command );
})();

View File

@ -0,0 +1,96 @@
(function(){
var ns = __namespace( "Components.Vim.State" );
/** @type {System.Debug} */
var debug = __import( "System.Debug" );
// private static
var Zones = {};
var PartialBA = function( a, b )
{
var l = b.length;
if( a.length < l ) return false;
for( var i = 0; i < l; i ++ )
{
if( a[ i ] != b[ i ] ) return false;
}
return true;
};
var ExactAB = function( a, b )
{
var l = a.length < b.length ? b.length : a.length;
for( var i = 0; i < l; i ++ )
{
if( a[ i ] != b[ i ] ) return false;
}
return true;
}
var History = function( z )
{
if( !Zones[ z ] ) Zones[ z ] = [];
this.__pi = 0;
this.__zone = Zones[ z ];
this.reset();
};
History.prototype.push = function( stack )
{
if( this.__zone.length
&& ExactAB( this.__zone[ this.__zone.length - 1 ], stack )
) {
debug.Info( "This is the previous command, skipping" );
return;
}
this.__zone.push( stack );
};
History.prototype.prev = function( stack )
{
if( this.__zone.length <= this.__i ) this.reset();
while( -1 < this.__i )
{
var st = this.__zone[ this.__i -- ];
if( st && PartialBA( st, stack ) )
{
return st.slice();
}
}
return null;
};
History.prototype.next = function( stack )
{
if( this.__i < 0 )
{
this.__i ++;
this.next( stack );
}
while( this.__i < this.__zone.length )
{
var st = this.__zone[ this.__i ++ ];
if( st && PartialBA( st, stack ) )
{
return st.slice();
}
}
return null;
};
History.prototype.reset = function()
{
this.__i = this.__zone.length - 1;
};
ns[ NS_EXPORT ]( EX_CLASS, "History", History );
})();

View File

@ -11,7 +11,11 @@ Components.Vim.Controls.InputEvent.key;
Components.Vim.Controls.InputEvent.ModKeys;
/** @type Boolean */
Components.Vim.Controls.InputEvent.Escape;
/** @type Boolean */
Components.Vim.Controls.InputEvent.canceled;
/** @type Number */
Components.Vim.Controls.InputEvent.keyCode;
/** @type Function */
Components.Vim.Controls.InputEvent.kMap;
/** @type Function */
Components.Vim.Controls.InputEvent.cancel;

View File

@ -0,0 +1,9 @@
/** @constructor */
Components.Vim.State.History = function(){};
/** @type Function */
Components.Vim.State.History.push;
/** @type Function */
Components.Vim.State.History.prev;
/** @type Function */
Components.Vim.State.History.next;