forked from Botanical/BotanJS
		
	Merge remote-tracking branches 'vim/master' and 'origin/master' into Astro
This commit is contained in:
		@@ -1,10 +1,12 @@
 | 
			
		||||
(function(){
 | 
			
		||||
	var ns = __namespace( "Components.Vim.Actions" );
 | 
			
		||||
 | 
			
		||||
	var Mesg = __import( "Components.Vim.Message" );
 | 
			
		||||
 | 
			
		||||
	/** @type {Components.Vim.State.Stack} */
 | 
			
		||||
	var Stack = __import( "Components.Vim.State.Stack" );
 | 
			
		||||
	var Stack                                 = __import( "Components.Vim.State.Stack" );
 | 
			
		||||
	/** @type {System.Debug} */
 | 
			
		||||
	var debug                                 = __import( "System.Debug" );
 | 
			
		||||
 | 
			
		||||
	var Mesg = __import( "Components.Vim.Message" );
 | 
			
		||||
 | 
			
		||||
	var Translate = function( c )
 | 
			
		||||
	{
 | 
			
		||||
@@ -12,56 +14,50 @@
 | 
			
		||||
		{
 | 
			
		||||
			case "Tab":
 | 
			
		||||
				return "\t";
 | 
			
		||||
			case "Enter":
 | 
			
		||||
				return "\n";
 | 
			
		||||
			default:
 | 
			
		||||
				return c;
 | 
			
		||||
		}
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	/* @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.__startX = Cursor.aPos;
 | 
			
		||||
 | 
			
		||||
		// Initialize this stack
 | 
			
		||||
		this.__rec( "", true );
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	INSERT.prototype.dispose = function()
 | 
			
		||||
	{
 | 
			
		||||
 | 
			
		||||
		this.__cursor.moveX( -1 );
 | 
			
		||||
		this.__rec( "", true );
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	INSERT.prototype.__storeState = function( c, pos )
 | 
			
		||||
	INSERT.prototype.__storeState = function()
 | 
			
		||||
	{
 | 
			
		||||
		var cur = this.__cursor;
 | 
			
		||||
		var feeder = cur.feeder;
 | 
			
		||||
		var insertLength = this.__insertLength;
 | 
			
		||||
		var contentUndo = this.__contentUndo;
 | 
			
		||||
		var startPos = this.__startPosition;
 | 
			
		||||
		var startX = this.__startX;
 | 
			
		||||
 | 
			
		||||
		return function() {
 | 
			
		||||
			debug.Inf( pos, c );
 | 
			
		||||
			var contentRedo = feeder.content.substr( startPos, insertLength );
 | 
			
		||||
			feeder.content =
 | 
			
		||||
				feeder.content.substring( 0, startPos )
 | 
			
		||||
				+ contentUndo
 | 
			
		||||
				+ feeder.content.substring( startPos + insertLength );
 | 
			
		||||
			insertLength = contentUndo.length;
 | 
			
		||||
			contentUndo = contentRedo;
 | 
			
		||||
 | 
			
		||||
			feeder.pan();
 | 
			
		||||
		};
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
@@ -71,21 +67,79 @@
 | 
			
		||||
		{
 | 
			
		||||
			if( this.__stack )
 | 
			
		||||
			{
 | 
			
		||||
				var c = this.__content;
 | 
			
		||||
				// If nothings changed
 | 
			
		||||
				if( this.__insertLength == 0
 | 
			
		||||
					&& this.__contentUndo === ""
 | 
			
		||||
				) return;
 | 
			
		||||
 | 
			
		||||
				this.__stack.store(
 | 
			
		||||
					this.__storeState( c, this.__startPosition )
 | 
			
		||||
					this.__storeState()
 | 
			
		||||
				);
 | 
			
		||||
 | 
			
		||||
				this.__cursor.rec.store( this.__stack );
 | 
			
		||||
				this.__cursor.rec.record( this.__stack );
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			this.__content = "";
 | 
			
		||||
			this.__insertLength = 0;
 | 
			
		||||
			this.__contentUndo = "";
 | 
			
		||||
			this.__stack = new Stack();
 | 
			
		||||
			this.__startPosition = ContentPosition( this.__cursor.feeder );
 | 
			
		||||
			this.__startPosition = this.__cursor.aPos;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		this.__content += c;
 | 
			
		||||
		if( c == "\n" )
 | 
			
		||||
		{
 | 
			
		||||
			// todo
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		this.__insertLength += c.length;
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	INSERT.prototype.__specialKey = function( e, inputChar )
 | 
			
		||||
	{
 | 
			
		||||
		var cur = this.__cursor;
 | 
			
		||||
		var feeder = cur.feeder;
 | 
			
		||||
 | 
			
		||||
		switch( e.keyCode )
 | 
			
		||||
		{
 | 
			
		||||
			case 8: // Backspace
 | 
			
		||||
				var oY = feeder.panY + cur.Y;
 | 
			
		||||
				if( cur.X == 0 && feeder.panY == 0 && cur.Y == 0 ) return;
 | 
			
		||||
 | 
			
		||||
				cur.moveX( -1, true, true );
 | 
			
		||||
 | 
			
		||||
				var f = cur.aPos;
 | 
			
		||||
 | 
			
		||||
				if( this.__insertLength <= 0 )
 | 
			
		||||
				{
 | 
			
		||||
					this.__contentUndo = feeder.content.substr( f, 1 ) + this.__contentUndo;
 | 
			
		||||
					this.__startPosition --;
 | 
			
		||||
				}
 | 
			
		||||
				else
 | 
			
		||||
				{
 | 
			
		||||
					this.__insertLength --;
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				feeder.content =
 | 
			
		||||
					feeder.content.substring( 0, f )
 | 
			
		||||
					+ feeder.content.substring( f + 1 );
 | 
			
		||||
 | 
			
		||||
				break;
 | 
			
		||||
			case 46: // Delete
 | 
			
		||||
				var f = cur.aPos;
 | 
			
		||||
 | 
			
		||||
				this.__contentUndo += feeder.content.substr( f, 1 );
 | 
			
		||||
 | 
			
		||||
				feeder.content =
 | 
			
		||||
					feeder.content.substring( 0, f )
 | 
			
		||||
					+ feeder.content.substring( f + 1 );
 | 
			
		||||
 | 
			
		||||
				break;
 | 
			
		||||
			default:
 | 
			
		||||
				// Do nothing
 | 
			
		||||
				return;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		feeder.pan();
 | 
			
		||||
		feeder.dispatcher.dispatchEvent( new BotanEvent( "VisualUpdate" ) );
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	INSERT.prototype.handler = function( e )
 | 
			
		||||
@@ -93,12 +147,16 @@
 | 
			
		||||
		e.preventDefault();
 | 
			
		||||
		var inputChar = Translate( e.key );
 | 
			
		||||
 | 
			
		||||
		if( inputChar.length != 1 ) return;
 | 
			
		||||
		if( inputChar.length != 1 )
 | 
			
		||||
		{
 | 
			
		||||
			this.__specialKey( e, inputChar );
 | 
			
		||||
			return;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		var cur = this.__cursor;
 | 
			
		||||
		var feeder = cur.feeder;
 | 
			
		||||
 | 
			
		||||
		var f = ContentPosition( feeder );
 | 
			
		||||
		var f = cur.aPos;
 | 
			
		||||
 | 
			
		||||
		feeder.content =
 | 
			
		||||
			feeder.content.substring( 0, f )
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										42
									
								
								botanjs/src/Components/Vim/Actions/REDO.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								botanjs/src/Components/Vim/Actions/REDO.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,42 @@
 | 
			
		||||
(function(){
 | 
			
		||||
	var ns = __namespace( "Components.Vim.Actions" );
 | 
			
		||||
 | 
			
		||||
	var Mesg = __import( "Components.Vim.Message" );
 | 
			
		||||
 | 
			
		||||
	/** @type {Components.Vim.Cursor.IAction} */
 | 
			
		||||
	var REDO = function( Cursor )
 | 
			
		||||
	{
 | 
			
		||||
		/** @type {Components.Vim.Cursor} */
 | 
			
		||||
		this.__cursor = Cursor;
 | 
			
		||||
		this.__message = "REDO COMMAND";
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	REDO.prototype.dispose = function()
 | 
			
		||||
	{
 | 
			
		||||
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	REDO.prototype.handler = function( e )
 | 
			
		||||
	{
 | 
			
		||||
		e.preventDefault();
 | 
			
		||||
 | 
			
		||||
		/** @type {Components.Vim.State.Stack} */
 | 
			
		||||
		var stack = this.__cursor.rec.redo();
 | 
			
		||||
		if( stack )
 | 
			
		||||
		{
 | 
			
		||||
			stack.play();
 | 
			
		||||
			this.__message = "<<TODO>>; before #" + stack.id + "  " + stack.time;
 | 
			
		||||
		}
 | 
			
		||||
		else
 | 
			
		||||
		{
 | 
			
		||||
			this.__message = Mesg( "REDO_LIMIT" );
 | 
			
		||||
		}
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	REDO.prototype.getMessage = function()
 | 
			
		||||
	{
 | 
			
		||||
		return this.__message;
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	ns[ NS_EXPORT ]( EX_CLASS, "REDO", REDO );
 | 
			
		||||
})();
 | 
			
		||||
@@ -25,6 +25,7 @@
 | 
			
		||||
		if( stack )
 | 
			
		||||
		{
 | 
			
		||||
			stack.play();
 | 
			
		||||
			this.__message = "<<TODO>>; before #" + stack.id + "  " + stack.time;
 | 
			
		||||
		}
 | 
			
		||||
		else
 | 
			
		||||
		{
 | 
			
		||||
 
 | 
			
		||||
@@ -2,8 +2,75 @@
 | 
			
		||||
	var ns = __namespace( "Components.Vim" );
 | 
			
		||||
 | 
			
		||||
	var debug = __import( "System.Debug" );
 | 
			
		||||
	var beep = ns[ NS_INVOKE ]( "Beep" );
 | 
			
		||||
 | 
			
		||||
	var Controls = function( sender, e )
 | 
			
		||||
	var SHIFT = 1 << 9;
 | 
			
		||||
	var CTRL = 1 << 10;
 | 
			
		||||
 | 
			
		||||
	var BACKSPACE = 8;
 | 
			
		||||
 | 
			
		||||
	var _0 = 48; var _1 = 49; var _2 = 50; var _3 = 51; var _4 = 52;
 | 
			
		||||
	var _5 = 53; var _6 = 54; var _7 = 55; var _8 = 56; var _9 = 57;
 | 
			
		||||
 | 
			
		||||
	var A = 65; var B = 66; var C = 67; var D = 68; var E = 69;
 | 
			
		||||
	var F = 70; var G = 71; var H = 72; var I = 73; var J = 74;
 | 
			
		||||
	var K = 75; var L = 76; var M = 77; var N = 78; var O = 79;
 | 
			
		||||
	var P = 80; var Q = 81; var R = 82; var S = 83; var T = 84;
 | 
			
		||||
	var U = 85; var V = 86; var W = 87; var X = 88; var Y = 89;
 | 
			
		||||
	var Z = 90;
 | 
			
		||||
 | 
			
		||||
	var Controls = function( vimArea )
 | 
			
		||||
	{
 | 
			
		||||
		/** @type {Components.Vim.VimArea} */
 | 
			
		||||
		this.__vimArea = vimArea
 | 
			
		||||
		this.__keyChains = [];
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	Controls.prototype.__comboG = function( keyCode )
 | 
			
		||||
	{
 | 
			
		||||
		var keyON = this.__keyChains[ 0 ] == G;
 | 
			
		||||
		if( keyON )
 | 
			
		||||
		{
 | 
			
		||||
			var cursor = this.__vimArea.contentFeeder.cursor;
 | 
			
		||||
			switch( keyCode )
 | 
			
		||||
			{
 | 
			
		||||
				case G:
 | 
			
		||||
					cursor.moveY( -Number.MAX_VALUE );
 | 
			
		||||
					cursor.moveX( -Number.MAX_VALUE, true );
 | 
			
		||||
					this.__keyChains = [];
 | 
			
		||||
					return true;
 | 
			
		||||
				default:
 | 
			
		||||
					this.__keyChains = [];
 | 
			
		||||
					beep();
 | 
			
		||||
					return true;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		else if( keyCode == G )
 | 
			
		||||
		{
 | 
			
		||||
			this.__keyChains[ 0 ] = G;
 | 
			
		||||
			return true;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		return false;
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	Controls.prototype.__comboT = function( e ) { return false; };
 | 
			
		||||
 | 
			
		||||
	// <
 | 
			
		||||
	Controls.prototype.__comboLeftShift = function( e ) { return false; };
 | 
			
		||||
 | 
			
		||||
	// >
 | 
			
		||||
	Controls.prototype.__comboRightShift = function( e ) { return false; };
 | 
			
		||||
 | 
			
		||||
	Controls.prototype.__comboKey = function( e )
 | 
			
		||||
	{
 | 
			
		||||
		return this.__comboG( e )
 | 
			
		||||
			|| this.__comboT( e )
 | 
			
		||||
			|| this.__comboLeftShift( e )
 | 
			
		||||
			|| this.__comboRightShift( e );
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	Controls.prototype.handler = function( sender, e )
 | 
			
		||||
	{
 | 
			
		||||
		// Neve capture these keys
 | 
			
		||||
		if( e.altKey
 | 
			
		||||
@@ -11,12 +78,24 @@
 | 
			
		||||
			|| ( 112 < e.keyCode && e.keyCode < 124 )
 | 
			
		||||
		) return;
 | 
			
		||||
 | 
			
		||||
		var vArea = this.__vimArea;
 | 
			
		||||
		// Action Mode handled by the actions themselves
 | 
			
		||||
		var cfeeder = sender.contentFeeder;
 | 
			
		||||
		var cfeeder = vArea.contentFeeder;
 | 
			
		||||
 | 
			
		||||
		// Esc OR Ctrl + c
 | 
			
		||||
		var Escape = e.keyCode == 27 || ( e.ctrlKey && e.keyCode == 67 );
 | 
			
		||||
 | 
			
		||||
		// Clear the keychains in combo commands
 | 
			
		||||
		if( Escape && this.__keyChains.length )
 | 
			
		||||
		{
 | 
			
		||||
			this.__keyChains = [];
 | 
			
		||||
			beep();
 | 
			
		||||
			return;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if( cfeeder.cursor.action )
 | 
			
		||||
		{
 | 
			
		||||
			// Esc OR Ctrl+c
 | 
			
		||||
			if( e.keyCode == 27 || ( e.ctrlKey && e.keyCode == 67 ) )
 | 
			
		||||
			if( Escape )
 | 
			
		||||
			{
 | 
			
		||||
				e.preventDefault();
 | 
			
		||||
				cfeeder.cursor.closeAction();
 | 
			
		||||
@@ -29,81 +108,110 @@
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		e.preventDefault();
 | 
			
		||||
		var kCode = e.keyCode
 | 
			
		||||
			+ ( e.shiftKey || e.getModifierState( "CapsLock" ) ? SHIFT : 0 )
 | 
			
		||||
			+ ( e.ctrlKey ? CTRL : 0 );
 | 
			
		||||
 | 
			
		||||
		if( e.ctrlKey )
 | 
			
		||||
		// Handles long commands
 | 
			
		||||
 | 
			
		||||
		if( this.__comboKey( kCode ) ) return;
 | 
			
		||||
 | 
			
		||||
		var cfeeder = vArea.contentFeeder;
 | 
			
		||||
		var sfeeder = vArea.statusFeeder;
 | 
			
		||||
 | 
			
		||||
		var ccur = cfeeder.cursor;
 | 
			
		||||
 | 
			
		||||
		var cMoveX = function( a, b, c )
 | 
			
		||||
		{
 | 
			
		||||
			VimComboFunc( sender, e );
 | 
			
		||||
			return;
 | 
			
		||||
		}
 | 
			
		||||
			var x = ccur.X;
 | 
			
		||||
			ccur.moveX( a, b, c );
 | 
			
		||||
			if( ccur.X == x ) beep();
 | 
			
		||||
		};
 | 
			
		||||
 | 
			
		||||
		var kCode = e.keyCode + ( e.shiftKey ? 1000 : 0 );
 | 
			
		||||
		var cMoveY = function( a )
 | 
			
		||||
		{
 | 
			
		||||
			var y = ccur.Y + cfeeder.panY;
 | 
			
		||||
			ccur.moveY( a );
 | 
			
		||||
			if( y == ( ccur.Y + cfeeder.panY ) )
 | 
			
		||||
			{
 | 
			
		||||
				if( 0 < a && !cfeeder.EOF ) return;
 | 
			
		||||
				beep();
 | 
			
		||||
			}
 | 
			
		||||
		};
 | 
			
		||||
 | 
			
		||||
		var cfeeder = sender.contentFeeder;
 | 
			
		||||
		var sfeeder = sender.statusFeeder;
 | 
			
		||||
		switch( kCode )
 | 
			
		||||
		{
 | 
			
		||||
			// Cursor movements
 | 
			
		||||
			case 8: // Backspace, go back 1 char, regardless of line
 | 
			
		||||
			case BACKSPACE: // Backspace, go back 1 char, regardless of line
 | 
			
		||||
				cMoveX( -1, true );
 | 
			
		||||
				break;
 | 
			
		||||
			case 72: // h
 | 
			
		||||
				cfeeder.cursor.moveX( -1 );
 | 
			
		||||
			case H: // Left
 | 
			
		||||
				cMoveX( -1 );
 | 
			
		||||
				break;
 | 
			
		||||
			case 74: // j
 | 
			
		||||
				cfeeder.cursor.moveY( 1 );
 | 
			
		||||
			case L: // Right
 | 
			
		||||
				cMoveX( 1 );
 | 
			
		||||
				break;
 | 
			
		||||
			case 75: // k
 | 
			
		||||
				cfeeder.cursor.moveY( -1 );
 | 
			
		||||
			case K: // Up
 | 
			
		||||
				cMoveY( -1 );
 | 
			
		||||
				break;
 | 
			
		||||
			case 76: // l
 | 
			
		||||
				cfeeder.cursor.moveX( 1 );
 | 
			
		||||
			case J: // Down
 | 
			
		||||
				cMoveY( 1 );
 | 
			
		||||
				break;
 | 
			
		||||
 | 
			
		||||
			// Insert
 | 
			
		||||
			case 65: // a
 | 
			
		||||
				cfeeder.cursor.openAction( "INSERT" );
 | 
			
		||||
			case A: // Append
 | 
			
		||||
				cMoveX( 1, true, true );
 | 
			
		||||
				ccur.openAction( "INSERT" );
 | 
			
		||||
				break;
 | 
			
		||||
			case 73: // i
 | 
			
		||||
			case I: // Insert
 | 
			
		||||
				break;
 | 
			
		||||
			case 85: // u, undo
 | 
			
		||||
				cfeeder.cursor.openRunAction( "UNDO", e );
 | 
			
		||||
			case U: // Undo
 | 
			
		||||
				ccur.openRunAction( "UNDO", e );
 | 
			
		||||
				break;
 | 
			
		||||
			case 88: // x, del
 | 
			
		||||
			case CTRL + R: // Redo
 | 
			
		||||
				ccur.openRunAction( "REDO", e );
 | 
			
		||||
				break;
 | 
			
		||||
			case 1065: // A, append at the line end
 | 
			
		||||
			case X: // Del
 | 
			
		||||
				break;
 | 
			
		||||
			case 1088: // X, delete before
 | 
			
		||||
			case SHIFT + A: // Append at the line end
 | 
			
		||||
				break;
 | 
			
		||||
			case 1085: // U, undo previous changes in oneline
 | 
			
		||||
			case SHIFT + X: // Delete before
 | 
			
		||||
				break;
 | 
			
		||||
			case 1073: // I, append before the line start, after spaces
 | 
			
		||||
			case SHIFT + U: // Undo previous changes in oneline
 | 
			
		||||
				break;
 | 
			
		||||
			case SHIFT + I: // Append before the line start, after spaces
 | 
			
		||||
				break;
 | 
			
		||||
 | 
			
		||||
			case SHIFT + G: // Goto last line
 | 
			
		||||
				ccur.moveY( Number.MAX_VALUE );
 | 
			
		||||
				ccur.moveX( Number.MAX_VALUE, true );
 | 
			
		||||
				break;
 | 
			
		||||
			// remove characters
 | 
			
		||||
			case 88: // x, remove in cursor
 | 
			
		||||
			case X: // Remove in cursor
 | 
			
		||||
				break;
 | 
			
		||||
			case 1088: // X, remove before cursor
 | 
			
		||||
			case SHIFT + X: // Remove before cursor
 | 
			
		||||
				break;
 | 
			
		||||
 | 
			
		||||
			case 1072: // H, First line buffer
 | 
			
		||||
			case SHIFT + H: // First line buffer
 | 
			
		||||
				break;
 | 
			
		||||
			case 1076: // L, Last line buffer
 | 
			
		||||
			case SHIFT + L: // Last line buffer
 | 
			
		||||
				break;
 | 
			
		||||
			case 1052: // $
 | 
			
		||||
				cfeeder.cursor.lineEnd();
 | 
			
		||||
			case SHIFT + _4: // $, End
 | 
			
		||||
				ccur.lineEnd();
 | 
			
		||||
				break;
 | 
			
		||||
			case 1053: // %
 | 
			
		||||
			case SHIFT + _5: // %, Find next item
 | 
			
		||||
				break;
 | 
			
		||||
			case 1054: // ^
 | 
			
		||||
				cfeeder.cursor.lineStart();
 | 
			
		||||
			case SHIFT + _6: // ^, Start
 | 
			
		||||
				ccur.lineStart();
 | 
			
		||||
				break;
 | 
			
		||||
			case 1074: // J, Join lines
 | 
			
		||||
			case SHIFT + J: // Join lines
 | 
			
		||||
				break;
 | 
			
		||||
			case 1075: // K, manual entry
 | 
			
		||||
			case SHIFT + K: // manual entry
 | 
			
		||||
				break;
 | 
			
		||||
			case 112: // F1, help
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	ns[ NS_EXPORT ]( EX_FUNC, "Controls", Controls );
 | 
			
		||||
	ns[ NS_EXPORT ]( EX_CLASS, "Controls", Controls );
 | 
			
		||||
})();
 | 
			
		||||
 
 | 
			
		||||
@@ -82,7 +82,7 @@
 | 
			
		||||
 | 
			
		||||
	// Can only be 1, -1
 | 
			
		||||
	// 0 will be treated as undefined
 | 
			
		||||
	Cursor.prototype.moveX = function( d )
 | 
			
		||||
	Cursor.prototype.moveX = function( d, penentrate, phantomSpace )
 | 
			
		||||
	{
 | 
			
		||||
		var x = this.pX;
 | 
			
		||||
 | 
			
		||||
@@ -93,15 +93,29 @@
 | 
			
		||||
 | 
			
		||||
		var buffs = this.feeder.lineBuffers;
 | 
			
		||||
 | 
			
		||||
		if( penentrate && x < 0 && ( 0 < this.feeder.panY || 0 < this.Y ) )
 | 
			
		||||
		{
 | 
			
		||||
			this.moveY( -1 );
 | 
			
		||||
			this.lineEnd( phantomSpace );
 | 
			
		||||
			return;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/** @type {Components.Vim.LineBuffer} */
 | 
			
		||||
		var line = GetLine( buffs, this.Y );
 | 
			
		||||
		var content = line.visualLines.join( "\n" );
 | 
			
		||||
		var cLen = content.length;
 | 
			
		||||
 | 
			
		||||
		var c = content[ x ];
 | 
			
		||||
 | 
			
		||||
		if( c == undefined )
 | 
			
		||||
		// Include empty lines befor cursor end
 | 
			
		||||
		if( ( phantomSpace && cLen - 1 <= x ) || ( cLen == 1 && c == undefined ) )
 | 
			
		||||
		{
 | 
			
		||||
			x = d > 0 ? content.length - 1 : 0;
 | 
			
		||||
			x = d > 0 ? cLen - 1 : 0;
 | 
			
		||||
		}
 | 
			
		||||
		// ( 2 < cLen ) Exclude empty lines at cursor end
 | 
			
		||||
		else if( ( 2 < cLen && x == cLen - 1 && c == " " ) || c == undefined )
 | 
			
		||||
		{
 | 
			
		||||
			x = d > 0 ? cLen - 2 : 0;
 | 
			
		||||
		}
 | 
			
		||||
		else if( c == "\n" )
 | 
			
		||||
		{
 | 
			
		||||
@@ -124,9 +138,9 @@
 | 
			
		||||
		this.updatePosition();
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	Cursor.prototype.lineEnd = function()
 | 
			
		||||
	Cursor.prototype.lineEnd = function( phantomSpace )
 | 
			
		||||
	{
 | 
			
		||||
		this.moveX( Number.MAX_VALUE );
 | 
			
		||||
		this.moveX( Number.MAX_VALUE, false, phantomSpace );
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	Cursor.prototype.updatePosition = function()
 | 
			
		||||
@@ -135,7 +149,7 @@
 | 
			
		||||
		this.feeder.dispatcher.dispatchEvent( new BotanEvent( "VisualUpdate" ) );
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	Cursor.prototype.moveY = function( d )
 | 
			
		||||
	Cursor.prototype.moveY = function( d, penentrate )
 | 
			
		||||
	{
 | 
			
		||||
		var Y = this.Y + d;
 | 
			
		||||
		var line;
 | 
			
		||||
@@ -158,7 +172,7 @@
 | 
			
		||||
			var lineShift = Y - feeder.moreAt;
 | 
			
		||||
 | 
			
		||||
			var i = 0;
 | 
			
		||||
			while( true )
 | 
			
		||||
			while( !feeder.EOF )
 | 
			
		||||
			{
 | 
			
		||||
				feeder.pan( undefined, lineShift + i );
 | 
			
		||||
 | 
			
		||||
@@ -182,7 +196,7 @@
 | 
			
		||||
				line = line.next )
 | 
			
		||||
			{
 | 
			
		||||
				if( line.br ) i ++;
 | 
			
		||||
				if( line.lineNum == Y ) break;
 | 
			
		||||
				if( line.lineNum == Y || line.next.placeholder ) break;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			this.Y = i;
 | 
			
		||||
@@ -299,6 +313,33 @@
 | 
			
		||||
		return w;
 | 
			
		||||
	} );
 | 
			
		||||
 | 
			
		||||
	// The absolute content position
 | 
			
		||||
	__readOnly( Cursor.prototype, "aPos", function()
 | 
			
		||||
	{
 | 
			
		||||
		var f = this.feeder;
 | 
			
		||||
		var line = this.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 += this.aX;
 | 
			
		||||
		return p;
 | 
			
		||||
	} );
 | 
			
		||||
 | 
			
		||||
	__readOnly( Cursor.prototype, "message", function()
 | 
			
		||||
	{
 | 
			
		||||
		if( this.__pulseMsg )
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										59
									
								
								botanjs/src/Components/Vim/DateTime/String.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										59
									
								
								botanjs/src/Components/Vim/DateTime/String.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,59 @@
 | 
			
		||||
(function(){
 | 
			
		||||
	var ns = __namespace( "Components.Vim.DateTime" );
 | 
			
		||||
 | 
			
		||||
	var messages = {
 | 
			
		||||
		  "AboutAMinuteAgo"                 : "about a minute ago"
 | 
			
		||||
		, "AboutAMonthAgo"                  : "about a month ago"
 | 
			
		||||
		, "AboutAnHourAgo"                  : "about an hour ago"
 | 
			
		||||
		, "AboutAWeekAgo"                   : "about a week ago"
 | 
			
		||||
		, "last Friday"                     : "last Friday"
 | 
			
		||||
		, "last Monday"                     : "last Monday"
 | 
			
		||||
		, "last Saturday"                   : "last Saturday"
 | 
			
		||||
		, "last Sunday"                     : "last Sunday"
 | 
			
		||||
		, "last Thursday"                   : "last Thursday"
 | 
			
		||||
		, "last Tuesday"                    : "last Tuesday"
 | 
			
		||||
		, "last Wednesday"                  : "last Wednesday"
 | 
			
		||||
		, "on Friday"                       : "on Friday"
 | 
			
		||||
		, "on Monday"                       : "on Monday"
 | 
			
		||||
		, "on Saturday"                     : "on Saturday"
 | 
			
		||||
		, "on Sunday"                       : "on Sunday"
 | 
			
		||||
		, "on Thursday"                     : "on Thursday"
 | 
			
		||||
		, "on Tuesday"                      : "on Tuesday"
 | 
			
		||||
		, "on Wednesday"                    : "on Wednesday"
 | 
			
		||||
		, "OverAYearAgo"                    : "over a year ago"
 | 
			
		||||
		, "XHoursAgo_2To4"                  : "%1 hours ago"
 | 
			
		||||
		, "XHoursAgo_EndsIn1Not11"          : "%1 hours ago"
 | 
			
		||||
		, "XHoursAgo_EndsIn2To4Not12To14"   : "%1 hours ago"
 | 
			
		||||
		, "XHoursAgo_Other"                 : "%1 hours ago"
 | 
			
		||||
		, "XMinutesAgo_2To4"                : "%1 minutes ago"
 | 
			
		||||
		, "XMinutesAgo_EndsIn1Not11"        : "%1 minutes ago"
 | 
			
		||||
		, "XMinutesAgo_EndsIn2To4Not12To14" : "%1 minutes ago"
 | 
			
		||||
		, "XMinutesAgo_Other"               : "%1 minutes ago"
 | 
			
		||||
		, "XMonthsAgo_2To4"                 : "%1 months ago"
 | 
			
		||||
		, "XMonthsAgo_5To12"                : "%1 months ago"
 | 
			
		||||
		, "XSecondsAgo_2To4"                : "%1 seconds ago"
 | 
			
		||||
		, "XSecondsAgo_EndsIn1Not11"        : "%1 seconds ago"
 | 
			
		||||
		, "XSecondsAgo_EndsIn2To4Not12To14" : "%1 seconds ago"
 | 
			
		||||
		, "XSecondsAgo_Other"               : "%1 seconds ago"
 | 
			
		||||
		, "XWeeksAgo_2To4"                  : "%1 weeks ago"
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	var GetString = function( arr, key, restArgs )
 | 
			
		||||
	{
 | 
			
		||||
		if( arr[ key ] == undefined ) return key;
 | 
			
		||||
 | 
			
		||||
		var i = 0;
 | 
			
		||||
		return arr[ key ].replace( /%\d+/g, function( e )
 | 
			
		||||
		{
 | 
			
		||||
			return restArgs[ i ++ ];
 | 
			
		||||
		} );
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	var DateTimeString = function( key )
 | 
			
		||||
	{
 | 
			
		||||
		var restArgs = Array.prototype.slice.call( arguments, 1 );
 | 
			
		||||
		return GetString( messages, key, restArgs );
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	ns[ NS_EXPORT ]( EX_FUNC, "String", DateTimeString );
 | 
			
		||||
})();
 | 
			
		||||
							
								
								
									
										213
									
								
								botanjs/src/Components/Vim/DateTime/_this.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										213
									
								
								botanjs/src/Components/Vim/DateTime/_this.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,213 @@
 | 
			
		||||
(function(){
 | 
			
		||||
	var ns = __namespace( "Components.Vim.DateTime" );
 | 
			
		||||
 | 
			
		||||
	var Minute = 60;
 | 
			
		||||
	var Hour = 60 * Minute;
 | 
			
		||||
	var Day = 24 * Hour;
 | 
			
		||||
	var Week = 7 * Day;
 | 
			
		||||
	var Month = 30.5 * Day;
 | 
			
		||||
	var Year = 365 * Day;
 | 
			
		||||
 | 
			
		||||
	var Mesg = ns[ NS_INVOKE ]( "String" );
 | 
			
		||||
 | 
			
		||||
	var PluralHourStrings = [
 | 
			
		||||
		"XHoursAgo_2To4",
 | 
			
		||||
		"XHoursAgo_EndsIn1Not11",
 | 
			
		||||
		"XHoursAgo_EndsIn2To4Not12To14",
 | 
			
		||||
		"XHoursAgo_Other"
 | 
			
		||||
	];
 | 
			
		||||
 | 
			
		||||
	var PluralMinuteStrings = [
 | 
			
		||||
		"XMinutesAgo_2To4",
 | 
			
		||||
		"XMinutesAgo_EndsIn1Not11",
 | 
			
		||||
		"XMinutesAgo_EndsIn2To4Not12To14",
 | 
			
		||||
		"XMinutesAgo_Other"
 | 
			
		||||
	];
 | 
			
		||||
 | 
			
		||||
	var PluralSecondStrings = [
 | 
			
		||||
		"XSecondsAgo_2To4",
 | 
			
		||||
		"XSecondsAgo_EndsIn1Not11",
 | 
			
		||||
		"XSecondsAgo_EndsIn2To4Not12To14",
 | 
			
		||||
		"XSecondsAgo_Other"
 | 
			
		||||
	];
 | 
			
		||||
 | 
			
		||||
	var DayOfWeek = { Sunday: 0, Monday: 1, Tuesday: 2, Wednesday: 3, Thursday: 4, Friday: 5, Saturday: 6 };
 | 
			
		||||
 | 
			
		||||
	var GetPluralMonth = function( month )
 | 
			
		||||
	{
 | 
			
		||||
		if ( month >= 2 && month <= 4 )
 | 
			
		||||
		{
 | 
			
		||||
			return Mesg( "XMonthsAgo_2To4", month );
 | 
			
		||||
		}
 | 
			
		||||
		else if ( month >= 5 && month <= 12 )
 | 
			
		||||
		{
 | 
			
		||||
			return Mesg( "XMonthsAgo_5To12", month );
 | 
			
		||||
		}
 | 
			
		||||
		else
 | 
			
		||||
		{
 | 
			
		||||
			throw new Error( "Invalid number of Months" );
 | 
			
		||||
		}
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	var GetLastDayOfWeek = function( dow )
 | 
			
		||||
	{
 | 
			
		||||
		var result;
 | 
			
		||||
		switch ( dow )
 | 
			
		||||
		{
 | 
			
		||||
			case DayOfWeek.Monday:
 | 
			
		||||
				result = Mesg( "last Monday" );
 | 
			
		||||
				break;
 | 
			
		||||
			case DayOfWeek.Tuesday:
 | 
			
		||||
				result = Mesg( "last Tuesday" );
 | 
			
		||||
				break;
 | 
			
		||||
			case DayOfWeek.Wednesday:
 | 
			
		||||
				result = Mesg( "last Wednesday" );
 | 
			
		||||
				break;
 | 
			
		||||
			case DayOfWeek.Thursday:
 | 
			
		||||
				result = Mesg( "last Thursday" );
 | 
			
		||||
				break;
 | 
			
		||||
			case DayOfWeek.Friday:
 | 
			
		||||
				result = Mesg( "last Friday" );
 | 
			
		||||
				break;
 | 
			
		||||
			case DayOfWeek.Saturday:
 | 
			
		||||
				result = Mesg( "last Saturday" );
 | 
			
		||||
				break;
 | 
			
		||||
			case DayOfWeek.Sunday:
 | 
			
		||||
				result = Mesg( "last Sunday" );
 | 
			
		||||
				break;
 | 
			
		||||
			default:
 | 
			
		||||
				result = Mesg( "last Sunday" );
 | 
			
		||||
				break;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		return result;
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	var GetOnDayOfWeek = function( dow )
 | 
			
		||||
	{
 | 
			
		||||
		var result;
 | 
			
		||||
 | 
			
		||||
		switch( dow )
 | 
			
		||||
		{
 | 
			
		||||
			case DayOfWeek.Monday:
 | 
			
		||||
				result = Mesg( "on Monday" );
 | 
			
		||||
				break;
 | 
			
		||||
			case DayOfWeek.Tuesday:
 | 
			
		||||
				result = Mesg( "on Tuesday" );
 | 
			
		||||
				break;
 | 
			
		||||
			case DayOfWeek.Wednesday:
 | 
			
		||||
				result = Mesg( "on Wednesday" );
 | 
			
		||||
				break;
 | 
			
		||||
			case DayOfWeek.Thursday:
 | 
			
		||||
				result = Mesg( "on Thursday" );
 | 
			
		||||
				break;
 | 
			
		||||
			case DayOfWeek.Friday:
 | 
			
		||||
				result = Mesg( "on Friday" );
 | 
			
		||||
				break;
 | 
			
		||||
			case DayOfWeek.Saturday:
 | 
			
		||||
				result = Mesg( "on Saturday" );
 | 
			
		||||
				break;
 | 
			
		||||
			case DayOfWeek.Sunday:
 | 
			
		||||
				result = Mesg( "on Sunday" );
 | 
			
		||||
				break;
 | 
			
		||||
			default:
 | 
			
		||||
				result = Mesg( "on Sunday" );
 | 
			
		||||
				break;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		return result;
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	var GetPluralTimeUnits = function( units, resources )
 | 
			
		||||
	{
 | 
			
		||||
		var modTen = units % 10;
 | 
			
		||||
		var modHundred = units % 100;
 | 
			
		||||
 | 
			
		||||
		if ( units <= 1 )
 | 
			
		||||
		{
 | 
			
		||||
			throw new Error( "Invalid number of Time units" );
 | 
			
		||||
		}
 | 
			
		||||
		else if ( 2 <= units && units <= 4 )
 | 
			
		||||
		{
 | 
			
		||||
			return Mesg( resources[ 0 ], units );
 | 
			
		||||
		}
 | 
			
		||||
		else if ( modTen == 1 && modHundred != 11 )
 | 
			
		||||
		{
 | 
			
		||||
			return Mesg( resources[ 1 ], units );
 | 
			
		||||
		}
 | 
			
		||||
		else if ( ( 2 <= modTen && modTen <= 4 ) && !( 12 <= modHundred && modHundred <= 14 ) )
 | 
			
		||||
		{
 | 
			
		||||
			return Mesg( resources[ 2 ], units );
 | 
			
		||||
		}
 | 
			
		||||
		else
 | 
			
		||||
		{
 | 
			
		||||
			return Mesg( resources[ 3 ], units );
 | 
			
		||||
		}
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	var RelativeTime = function( given )
 | 
			
		||||
	{
 | 
			
		||||
		var diffSecs = Math.round( 0.001 * ( new Date().getTime() - given.getTime() ) );
 | 
			
		||||
 | 
			
		||||
		if( Year < diffSecs )
 | 
			
		||||
		{
 | 
			
		||||
			result = Mesg( "OverAYearAgo" );
 | 
			
		||||
		}
 | 
			
		||||
		else if( ( 1.5 * Month ) < diffSecs )
 | 
			
		||||
		{
 | 
			
		||||
			var nMonths = Math.round( ( diffSecs + Month / 2 ) / Month );
 | 
			
		||||
			result = GetPluralMonth( nMonths );
 | 
			
		||||
		}
 | 
			
		||||
		else if( ( 3.5 * Week ) <= diffSecs )
 | 
			
		||||
		{
 | 
			
		||||
			result = Mesg( "AboutAMonthAgo" );
 | 
			
		||||
		}
 | 
			
		||||
		else if( Week <= diffSecs )
 | 
			
		||||
		{
 | 
			
		||||
			var nWeeks = Math.round( diffSecs / Week );
 | 
			
		||||
			if ( 1 < nWeeks )
 | 
			
		||||
			{
 | 
			
		||||
				result = Mesg( "XWeeksAgo_2To4", nWeeks );
 | 
			
		||||
			}
 | 
			
		||||
			else
 | 
			
		||||
			{
 | 
			
		||||
				result = Mesg( "AboutAWeekAgo" );
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		else if ( ( 5 * Day ) <= diffSecs )
 | 
			
		||||
		{
 | 
			
		||||
			result = GetLastDayOfWeek( given.getDay() );
 | 
			
		||||
		}
 | 
			
		||||
		else if ( Day <= diffSecs )
 | 
			
		||||
		{
 | 
			
		||||
			result = GetOnDayOfWeek( given.getDay() );
 | 
			
		||||
		}
 | 
			
		||||
		else if ( ( 2 * Hour ) <= diffSecs )
 | 
			
		||||
		{
 | 
			
		||||
			var nHours = Math.round( diffSecs / Hour );
 | 
			
		||||
			result = GetPluralTimeUnits( nHours, PluralHourStrings );
 | 
			
		||||
		}
 | 
			
		||||
		else if ( Hour <= diffSecs )
 | 
			
		||||
		{
 | 
			
		||||
			result = Mesg( "AboutAnHourAgo" );
 | 
			
		||||
		}
 | 
			
		||||
		else if ( ( 2 * Minute ) <= diffSecs )
 | 
			
		||||
		{
 | 
			
		||||
			var nMinutes = Math.round( diffSecs / Minute );
 | 
			
		||||
			result = GetPluralTimeUnits( nMinutes, PluralMinuteStrings );
 | 
			
		||||
		}
 | 
			
		||||
		else if ( Minute <= diffSecs )
 | 
			
		||||
		{
 | 
			
		||||
			result = Mesg( "AboutAMinuteAgo" );
 | 
			
		||||
		}
 | 
			
		||||
		else
 | 
			
		||||
		{
 | 
			
		||||
			var nSeconds =  1 < diffSecs ? diffSecs : 2;
 | 
			
		||||
			result = GetPluralTimeUnits( nSeconds, PluralSecondStrings );
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		return result;
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	ns[ NS_EXPORT ]( EX_FUNC, "RelativeTime", RelativeTime );
 | 
			
		||||
})();
 | 
			
		||||
@@ -97,6 +97,11 @@
 | 
			
		||||
 | 
			
		||||
	LineBuffer.prototype.toString = function()
 | 
			
		||||
	{
 | 
			
		||||
		if( this.content.length < this.cols )
 | 
			
		||||
		{
 | 
			
		||||
			return this.content + " ";
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		return this.content || " ";
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -144,7 +144,13 @@
 | 
			
		||||
			f = this.content.indexOf( "\n" );
 | 
			
		||||
			for( i = 1; f != -1 && i < Y; i ++ )
 | 
			
		||||
			{
 | 
			
		||||
				f = this.content.indexOf( "\n", f + 1 );
 | 
			
		||||
				var a = this.content.indexOf( "\n", f + 1 );
 | 
			
		||||
				if( a == -1 )
 | 
			
		||||
				{
 | 
			
		||||
					Y = i;
 | 
			
		||||
					break;
 | 
			
		||||
				}
 | 
			
		||||
				f = a;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
@@ -163,6 +169,10 @@
 | 
			
		||||
		this.__softRender();
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	__readOnly( Feeder.prototype, "linesTotal", function() {
 | 
			
		||||
		return this.content.match( "\n" );
 | 
			
		||||
	} );
 | 
			
		||||
 | 
			
		||||
	__readOnly( Feeder.prototype, "firstBuffer", function() {
 | 
			
		||||
		return this.lineBuffers[ 0 ];
 | 
			
		||||
	} );
 | 
			
		||||
 
 | 
			
		||||
@@ -4,7 +4,9 @@
 | 
			
		||||
	var Recorder = function()
 | 
			
		||||
	{
 | 
			
		||||
		this.__steps = [];
 | 
			
		||||
		this.__stacks = [];
 | 
			
		||||
		this.__i = 0;
 | 
			
		||||
		this.__j = 0;
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	Recorder.prototype.undo = function()
 | 
			
		||||
@@ -18,13 +20,11 @@
 | 
			
		||||
 | 
			
		||||
	Recorder.prototype.redo = function()
 | 
			
		||||
	{
 | 
			
		||||
		var i = this.__i + 1;
 | 
			
		||||
		if( i == -1 || !this.__steps.length ) return null;
 | 
			
		||||
		var State = this.__steps[ this.__i ];
 | 
			
		||||
 | 
			
		||||
		var State = this.__steps[ i ];
 | 
			
		||||
		if( State )
 | 
			
		||||
		{
 | 
			
		||||
			this.__i = i;
 | 
			
		||||
			this.__i ++;
 | 
			
		||||
			return State;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
@@ -33,8 +33,12 @@
 | 
			
		||||
 | 
			
		||||
	Recorder.prototype.record = function( StateObj )
 | 
			
		||||
	{
 | 
			
		||||
		this.__steps[ this.__i ] = StateObj;
 | 
			
		||||
		delete this.__steps[ ++ this.__i ];
 | 
			
		||||
		this.__steps[ this.__i ++ ] = StateObj;
 | 
			
		||||
		this.__stacks[ this.__j ++ ] = StateObj;
 | 
			
		||||
 | 
			
		||||
		delete this.__steps[ this.__i ];
 | 
			
		||||
 | 
			
		||||
		StateObj.id = this.__j;
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	ns[ NS_EXPORT ]( EX_CLASS, "Recorder", Recorder );
 | 
			
		||||
 
 | 
			
		||||
@@ -1,13 +1,16 @@
 | 
			
		||||
(function(){
 | 
			
		||||
	var ns = __namespace( "Components.Vim.State" );
 | 
			
		||||
 | 
			
		||||
	var Stack = function()
 | 
			
		||||
	{
 | 
			
		||||
	};
 | 
			
		||||
	/** @type {Components.Vim.DateTime} */
 | 
			
		||||
	var RelativeTime = __import( "Components.Vim.DateTime.RelativeTime" );
 | 
			
		||||
 | 
			
		||||
	var Stack = function() { };
 | 
			
		||||
 | 
			
		||||
	Stack.prototype.store = function( handler )
 | 
			
		||||
	{
 | 
			
		||||
		this.__handler = handler;
 | 
			
		||||
		this.__time = new Date();
 | 
			
		||||
		this.id = 0;
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	Stack.prototype.play = function()
 | 
			
		||||
@@ -15,5 +18,10 @@
 | 
			
		||||
		if( this.__handler ) this.__handler();
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	__readOnly( Stack.prototype, "time", function()
 | 
			
		||||
	{
 | 
			
		||||
		return RelativeTime( this.__time );
 | 
			
		||||
	} );
 | 
			
		||||
 | 
			
		||||
	ns[ NS_EXPORT ]( EX_CLASS, "Stack", Stack );
 | 
			
		||||
})();
 | 
			
		||||
 
 | 
			
		||||
@@ -53,7 +53,12 @@
 | 
			
		||||
 | 
			
		||||
		var _self = this;
 | 
			
		||||
 | 
			
		||||
		stage.addEventListener( "KeyDown", KeyHandler( this, VimControls ) );
 | 
			
		||||
		var controls = new VimControls( this );
 | 
			
		||||
		stage.addEventListener(
 | 
			
		||||
			"KeyDown"
 | 
			
		||||
			, KeyHandler( this, controls.handler.bind( controls ) )
 | 
			
		||||
		);
 | 
			
		||||
 | 
			
		||||
		stage.addEventListener( "Focus", function() { _self.__active = true; } );
 | 
			
		||||
		stage.addEventListener( "Blur", function() { _self.__active = false; } );
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -15,6 +15,7 @@
 | 
			
		||||
		, "EXIT": "Type :quit<Enter>  to exit Vim"
 | 
			
		||||
 | 
			
		||||
		, "UNDO_LIMIT": "Already at oldest change"
 | 
			
		||||
		, "REDO_LIMIT": "Already at newest change"
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	var errors = {
 | 
			
		||||
@@ -44,6 +45,178 @@
 | 
			
		||||
		return GetString( errors, key, restArgs );
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	var bAudio = new Audio(
 | 
			
		||||
		/*{{{ Audio Data */
 | 
			
		||||
		"data:audio/ogg;base64,"
 | 
			
		||||
		+ "T2dnUwACAAAAAAAAAADXYAAAAAAAADs1WuYBHgF2b3JiaXMAAAAAAkSsAAAAAAAAAHECAAAAAAC4AU9n"
 | 
			
		||||
		+ "Z1MAAAAAAAAAAAAA12AAAAEAAAB6JNs9Ejv/////////////////////kQN2b3JiaXMrAAAAWGlwaC5P"
 | 
			
		||||
		+ "cmcgbGliVm9yYmlzIEkgMjAxMjAyMDMgKE9tbmlwcmVzZW50KQAAAAABBXZvcmJpcylCQ1YBAAgAAAAx"
 | 
			
		||||
		+ "TCDFgNCQVQAAEAAAYCQpDpNmSSmllKEoeZiUSEkppZTFMImYlInFGGOMMcYYY4wxxhhjjCA0ZBUAAAQA"
 | 
			
		||||
		+ "gCgJjqPmSWrOOWcYJ45yoDlpTjinIAeKUeA5CcL1JmNuprSma27OKSUIDVkFAAACAEBIIYUUUkghhRRi"
 | 
			
		||||
		+ "iCGGGGKIIYcccsghp5xyCiqooIIKMsggg0wy6aSTTjrpqKOOOuootNBCCy200kpMMdVWY669Bl18c845"
 | 
			
		||||
		+ "55xzzjnnnHPOCUJDVgEAIAAABEIGGWQQQgghhRRSiCmmmHIKMsiA0JBVAAAgAIAAAAAAR5EUSbEUy7Ec"
 | 
			
		||||
		+ "zdEkT/IsURM10TNFU1RNVVVVVXVdV3Zl13Z113Z9WZiFW7h9WbiFW9iFXfeFYRiGYRiGYRiGYfh93/d9"
 | 
			
		||||
		+ "3/d9IDRkFQAgAQCgIzmW4ymiIhqi4jmiA4SGrAIAZAAABAAgCZIiKZKjSaZmaq5pm7Zoq7Zty7Isy7IM"
 | 
			
		||||
		+ "hIasAgAAAQAEAAAAAACgaZqmaZqmaZqmaZqmaZqmaZqmaZpmWZZlWZZlWZZlWZZlWZZlWZZlWZZlWZZl"
 | 
			
		||||
		+ "WZZlWZZlWZZlWZZlWUBoyCoAQAIAQMdxHMdxJEVSJMdyLAcIDVkFAMgAAAgAQFIsxXI0R3M0x3M8x3M8"
 | 
			
		||||
		+ "R3REyZRMzfRMDwgNWQUAAAIACAAAAAAAQDEcxXEcydEkT1It03I1V3M913NN13VdV1VVVVVVVVVVVVVV"
 | 
			
		||||
		+ "VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVWB0JBVAAAEAAAhnWaWaoAIM5BhIDRkFQCAAAAAGKEIQwwIDVkF"
 | 
			
		||||
		+ "AAAEAACIoeQgmtCa8805DprloKkUm9PBiVSbJ7mpmJtzzjnnnGzOGeOcc84pypnFoJnQmnPOSQyapaCZ"
 | 
			
		||||
		+ "0JpzznkSmwetqdKac84Z55wOxhlhnHPOadKaB6nZWJtzzlnQmuaouRSbc86JlJsntblUm3POOeecc845"
 | 
			
		||||
		+ "55xzzqlenM7BOeGcc86J2ptruQldnHPO+WSc7s0J4ZxzzjnnnHPOOeecc84JQkNWAQBAAAAEYdgYxp2C"
 | 
			
		||||
		+ "IH2OBmIUIaYhkx50jw6ToDHIKaQejY5GSqmDUFIZJ6V0gtCQVQAAIAAAhBBSSCGFFFJIIYUUUkghhhhi"
 | 
			
		||||
		+ "iCGnnHIKKqikkooqyiizzDLLLLPMMsusw84667DDEEMMMbTSSiw11VZjjbXmnnOuOUhrpbXWWiullFJK"
 | 
			
		||||
		+ "KaUgNGQVAAACAEAgZJBBBhmFFFJIIYaYcsopp6CCCggNWQUAAAIACAAAAPAkzxEd0REd0REd0REd0REd"
 | 
			
		||||
		+ "z/EcURIlURIl0TItUzM9VVRVV3ZtWZd127eFXdh139d939eNXxeGZVmWZVmWZVmWZVmWZVmWZQlCQ1YB"
 | 
			
		||||
		+ "ACAAAABCCCGEFFJIIYWUYowxx5yDTkIJgdCQVQAAIACAAAAAAEdxFMeRHMmRJEuyJE3SLM3yNE/zNNET"
 | 
			
		||||
		+ "RVE0TVMVXdEVddMWZVM2XdM1ZdNVZdV2Zdm2ZVu3fVm2fd/3fd/3fd/3fd/3fd/XdSA0ZBUAIAEAoCM5"
 | 
			
		||||
		+ "kiIpkiI5juNIkgSEhqwCAGQAAAQAoCiO4jiOI0mSJFmSJnmWZ4maqZme6amiCoSGrAIAAAEABAAAAAAA"
 | 
			
		||||
		+ "oGiKp5iKp4iK54iOKImWaYmaqrmibMqu67qu67qu67qu67qu67qu67qu67qu67qu67qu67qu67qu67pA"
 | 
			
		||||
		+ "aMgqAEACAEBHciRHciRFUiRFciQHCA1ZBQDIAAAIAMAxHENSJMeyLE3zNE/zNNETPdEzPVV0RRcIDVkF"
 | 
			
		||||
		+ "AAACAAgAAAAAAMCQDEuxHM3RJFFSLdVSNdVSLVVUPVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV"
 | 
			
		||||
		+ "VVVVVdU0TdM0gdCQlQAAGQAA5KSm1HoOEmKQOYlBaAhJxBzFXDrpnKNcjIeQI0ZJ7SFTzBAEtZjQSYUU"
 | 
			
		||||
		+ "1OJaah1zVIuNrWRIQS22xlIh5agHQkNWCAChGQAOxwEcTQMcSwMAAAAAAAAASdMATRQBzRMBAAAAAAAA"
 | 
			
		||||
		+ "wNE0QBM9QBNFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
 | 
			
		||||
		+ "AAAAAAAAAAAAAAAAAAAAAAAcTQM0UQQ0UQQAAAAAAAAATRQB0VQB0TQBAAAAAAAAQBNFwDNFQDRVAAAA"
 | 
			
		||||
		+ "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
 | 
			
		||||
		+ "AAAAAAAcTQM0UQQ0UQQAAAAAAAAATRQBUTUBTzQBAAAAAAAAQBNFQDRNQFRNAAAAAAAAAAAAAAAAAAAA"
 | 
			
		||||
		+ "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
 | 
			
		||||
		+ "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
 | 
			
		||||
		+ "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
 | 
			
		||||
		+ "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
 | 
			
		||||
		+ "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
 | 
			
		||||
		+ "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
 | 
			
		||||
		+ "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
 | 
			
		||||
		+ "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
 | 
			
		||||
		+ "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
 | 
			
		||||
		+ "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
 | 
			
		||||
		+ "AQAAAQ4AAAEWQqEhKwKAOAEAh+NAkiBJ8DSAY1nwPHgaTBPgWBY8D5oH0wQAAAAAAAAAAABA8jR4HjwP"
 | 
			
		||||
		+ "pgmQNA+eB8+DaQIAAAAAAAAAAAAgeR48D54H0wRIngfPg+fBNAEAAAAAAAAAAADwTBOmCdGEagI804Rp"
 | 
			
		||||
		+ "wjRhqgAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAACAAQcAgAATykChISsCgDgBAIejSBIAADiSZFkAAKBI"
 | 
			
		||||
		+ "kmUBAIBlWZ4HAACSZXkeAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
 | 
			
		||||
		+ "AAAAAAAAAAAAAAAAAAAAAAAAAIAAAIABBwCAABPKQKEhKwGAKAAAh6JYFnAcywKOY1lAkiwLYFkATQN4"
 | 
			
		||||
		+ "GkAUAYAAAIACBwCAABs0JRYHKDRkJQAQBQDgcBTL0jRR5DiWpWmiyHEsS9NEkWVpmqaJIjRL00QRnud5"
 | 
			
		||||
		+ "pgnP8zzThCiKomkCUTRNAQAABQ4AAAE2aEosDlBoyEoAICQAwOE4luV5oiiKpmmaqspxLMvzRFEUTVNV"
 | 
			
		||||
		+ "XZfjWJbniaIomqaqui7L0jTPE0VRNE1VdV1omueJoiiapqq6LjRNFE3TNFVVVV0XmuaJpmmaqqqqrgvP"
 | 
			
		||||
		+ "E0XTNE1VdV3XBaJomqapqq7rukAUTdM0VdV1XReIomiapqq6rusC0zRNVVVd15VlgGmqqqq6riwDVFVV"
 | 
			
		||||
		+ "XdeVZRmgqqrquq4rywDXdV3ZlWVZBuC6rivLsiwAAODAAQAgwAg6yaiyCBtNuPAAFBqyIgCIAgAAjGFK"
 | 
			
		||||
		+ "MaUMYxJCCqFhTEJIIWRSUioppQpCKiWVUkFIpaRSMkotpZZSBSGVkkqpIKRSUikFAIAdOACAHVgIhYas"
 | 
			
		||||
		+ "BADyAAAIY5RizDnnJEJKMeaccxIhpRhzzjmpFGPOOeeclJIx55xzTkrJmHPOOSelZMw555yTUjrnnHMO"
 | 
			
		||||
		+ "SimldM4556SUUkLonHNSSimdc845AQBABQ4AAAE2imxOMBJUaMhKACAVAMDgOJalaZ4niqZpSZKmeZ4n"
 | 
			
		||||
		+ "mqZpapKkaZ4niqZpmjzP80RRFE1TVXme54miKJqmqnJdURRN0zRNVSXLoiiKpqmqqgrTNE3TVFVVhWma"
 | 
			
		||||
		+ "pmmqquvCtlVVVV3XdWHbqqqqruu6wHVd13VlGbiu67quLAsAAE9wAAAqsGF1hJOiscBCQ1YCABkAAIQx"
 | 
			
		||||
		+ "CCmEEFIGIaQQQkgphZAAAIABBwCAABPKQKEhKwGAcAAAgBCMMcYYY4wxNoxhjDHGGGOMMXEKY4wxxhhj"
 | 
			
		||||
		+ "jDHGGGOMMcYYY4wxxhhjjDHGGGOMMcYYY4wxxhhjjDHGGGOMMcYYY4wxxhhjjDHGGGOMMcYYY4wxxhhj"
 | 
			
		||||
		+ "jDHGGGOMMcYYY4wxxhhjjDHGGGOMMcYYY4wxxhhjjDHGGGOMMcYYY4wxxhhjjDHG2FprrbVWABjOhQNA"
 | 
			
		||||
		+ "WYSNM6wknRWOBhcashIACAkAAIxBiDHoJJSSSkoVQow5KCWVllqKrUKIMQilpNRabDEWzzkHoaSUWoop"
 | 
			
		||||
		+ "tuI556Sk1FqMMcZaXAshpZRaiy22GJtsIaSUUmsxxlpjM0q1lFqLMcYYayxKuZRSa7HFGGuNRSibW2sx"
 | 
			
		||||
		+ "xlprrTUp5XNLsdVaY6y1JqOMkjHGWmustdYilFIyxhRTrLXWmoQwxvcYY6wx51qTEsL4HlMtsdVaa1JK"
 | 
			
		||||
		+ "KSNkjanGWnNOSglljI0t1ZRzzgUAQD04AEAlGEEnGVUWYaMJFx6AQkNWAgC5AQAIQkoxxphzzjnnnHMO"
 | 
			
		||||
		+ "UqQYc8w55yCEEEIIIaQIMcaYc85BCCGEEEJIGWPMOecghBBCCKGEklLKmHPOQQghhFJKKSWl1DnnIIQQ"
 | 
			
		||||
		+ "QiillFJKSqlzzkEIIYRSSimllJRSCCGEEEIIpZRSSikppZRCCCGEEkoppZRSUkophRBCCKWUUkoppaSU"
 | 
			
		||||
		+ "UgohhBBKKaWUUkpJKaUUQgmllFJKKaWUklJKKaUQSimllFJKKSWllFJKpZRSSimllFJKSimllEoppZRS"
 | 
			
		||||
		+ "SimllJRSSimVUkoppZRSSikppZRSSqmUUkoppZRSUkoppZRSKaWUUkoppaSUUkoppVJKKaWUUkpJKaWU"
 | 
			
		||||
		+ "UkqllFJKKaWUklJKKaWUUiqllFJKKaUAAKADBwCAACMqLcROM648AkcUMkxAhYasBADIAAAQB7G01lqr"
 | 
			
		||||
		+ "jHLKSUmtQ0Ya5qCk2EkHIbVYS2UgQcpJSp2CCCkGqYWMKqWYk5ZCy5hSDGIrMXSMMUc55VRCxxgAAACC"
 | 
			
		||||
		+ "AAADETITCBRAgYEMADhASJACAAoLDB3DRUBALiGjwKBwTDgnnTYAAEGIzBCJiMUgMaEaKCqmA4DFBYZ8"
 | 
			
		||||
		+ "AMjQ2Ei7uIAuA1zQxV0HQghCEIJYHEABCTg44YYn3vCEG5ygU1TqQAAAAAAAHgDgAQAg2QAiIqKZ4+jw"
 | 
			
		||||
		+ "+AAJERkhKTE5QREAAAAAADsA+AAASFKAiIho5jg6PD5AQkRGSEpMTlACAAABBAAAAABAAAEICAgAAAAA"
 | 
			
		||||
		+ "AAQAAAAICE9nZ1MAAMAzAAAAAAAA12AAAAIAAAAQIhJlHjJMWVr/Mv89/0r/UP9O/07/PP87/yj/Hv8s"
 | 
			
		||||
		+ "/xT/FEwdl5tJHgTj1XG5wc7FNGE8TlenIkVyBgAA4PwvppJZ1J37Xf21rorjO/aQd5/1wnEAdB3du46c"
 | 
			
		||||
		+ "lFBPW0fyAfSIhKN/gLIVBACPiwDrlx+W8frlbCXU41W/qedrwXGvi1fLGiI5ZJkJnnNY+o7fK+g4zECx"
 | 
			
		||||
		+ "JYxwKcJ3FloJAOw5/ft6QNRqFxSSM1ycCpd6xNz7TvFtp7Y7TjbzIFIxKUkBoMOP7t+hqhG8Wi4bP/OA"
 | 
			
		||||
		+ "X35zWKeYcNWiBnK/lk++PTebHOrxR6/I0sDQCum6mZkCvtdJAdAejF7tUSVU73ViaOCfuo1HDYH0rzOO"
 | 
			
		||||
		+ "pBqq/y9AI0ke2G8uDQOgBsiZNIxOCNmjhmyVwbZzMN4308KY2/LnQ/+9NeCVFMZv6saHsz/zmrRYtAI2"
 | 
			
		||||
		+ "/cESGEA0wgoAOngFeJv0bwUwdjWZQRUbtcZcGnOqvHLvFfM9SHwDoHC1P/vOcLS7ZgEAoAfgNEIC8vzG"
 | 
			
		||||
		+ "F2BpTBE6bAUI6hNAZG9P82p0EMLCwFSAcMdAAAAAMkJAjm9YLqZooHGujca3m7Jp/zGZPPpxON7m9HXr"
 | 
			
		||||
		+ "L8oCH98a0wDAhfda8F3JgdENmvQtkyvw7tBqL8/Z+WEbAEgBkOBVUkxnV1xmdIFccknb6z7bC8AuV2Tm"
 | 
			
		||||
		+ "P0e4zM5MNTdL/9adO2nItonlK1tj0aaK7lVDj7i1wcuyLGdpzZLlxXJapUqKEM3VGD63cByv3p7z2O47"
 | 
			
		||||
		+ "Of/D/9M1zU2H47G5eYU8Bx4AoK4FoBqAxAEcCMA0ABwAAKaYnr3zi2oPSQFgKMcDAACr8K04RkYGAAAA"
 | 
			
		||||
		+ "UAcAAAS3ASC+BAASIAB+WNXyprmFswoaO2J4KjxWvTtm/LMxDO5ZC5+A+YUkvwEA2sBHjx7mWGwDAGDk"
 | 
			
		||||
		+ "QgL2ldd/Hw2WojAcvqsA2BEwDwUICS4MtBMQpriDAggAYM8AlKeXg8MHmPNriXfLp6niN6+tzf34cv78"
 | 
			
		||||
		+ "633eZiCuOpzuXwEAvX6n3uNXmv79/sPk7Wq4+p0CEABCpmRfste+OZsTlwoAhNu0GxRgwPfKolpY0GVG"
 | 
			
		||||
		+ "PDMkSZ0qrnJ56yhDlU1qcPdMf2jS9ETPJvy44Kb2EueZzkp64jLxEvGurtti+i46aluXay23q5724P64"
 | 
			
		||||
		+ "P+fKL3jrd5/lAQAA8Nh57ng48Bz09vceMgCAdtYAdJwFAMC44hwDQFYzzwsAAEAYt/40Fd4rXCkAwDQ0"
 | 
			
		||||
		+ "0EO/igMAcHD2DAAAAAAo2gKAzn5yAQASAGugNAAgPuhc9OVG76gWnBkdY/MlUoiH0cOdB+6oicYzGTc/"
 | 
			
		||||
		+ "cyD9CgDw+W5rDBk9doIgSZCX///aCfyl3SkAAGtSL5j67PgLAEBIdIwDgP70EsIkHCf4AxAu7gAAADgr"
 | 
			
		||||
		+ "QLnRZuAe99md7zs+zsrpNtNo2CTydP3itF3S5Qx+bXvjeCQAXgaI784A5AKgAAiZn6aPHQDwpPHlVAQE"
 | 
			
		||||
		+ "Mw+lZAAY9L6h7zZcnJemA9vs0WL5/FM/SX0zsXDy86J7ioHZm1v/+gJOzTSQfsU0X4MuT3riVk0OVQxw"
 | 
			
		||||
		+ "4GQLGcO+O/RzW+GA2L4rNAUAAAxQ1NDv05362a42eJKVC8vPtgLTbjYb5u3lKQE83xgoFVN0q4D7RzNF"
 | 
			
		||||
		+ "V2vdBcNjA5bZuwEGDgcAAOD8CQwJfACABwAAAIA5PBQAAAAA9ACQIQBoAOATAQAAAAD1CgC+/eETAABe"
 | 
			
		||||
		+ "CF3948jyOuj7DEOHivklQ7YQuvX7UfxZbbTfwcb8Tzp/BQBYZAaE3cq/u3oE3KzOcJ9HZyu4ePvDyw4A"
 | 
			
		||||
		+ "sFMFf4Xw4gQOAMLFHQAAAAAil2hv08JOXwLmYN19gtuOfFFCaU+rvr55AGC5lzi7fDwpIPkPASADwB9A"
 | 
			
		||||
		+ "LoXtujH6Om0EIFPceQevMoLYKyI1FQBkTKq37w9cSHx4Pn96++FWow/ZfvvlA8/K9J7b58N/eGYs7r77"
 | 
			
		||||
		+ "isftxs9z/tb8EwvNIj1zsjjfFeBAfaz26a17ca1paqDAQFovAABQkJWHiuZar58/A5/+mK+7WbYRmdP+"
 | 
			
		||||
		+ "c1MjZeu8jqjsOK8sZ+37xVVMOxMYqKumwLVGlBhmKchm3iJHMP7TuSu8AwCPiYbgI1cHAAAAALLflQQA"
 | 
			
		||||
		+ "AAAAAAAcLQAAAAAAOACAagCuE98AAAAAiKcAmD6cBxQAAJ4HHen1RpdXi+aMpAwhm/ec2PYYr1WJxrs5"
 | 
			
		||||
		+ "vBiI9xsA4IKC+1ErPI8Kcgagub3/28MJHCu544BmPV8C89lQ5ysBCB87AI0RP+6N8IkL1IBwxwAAAJAH"
 | 
			
		||||
		+ "oP24kUI+GjwdDH/J6vz7rmS2ic3D6r+dvtb4fe54NFuk7RVeC2R7ungn+naZS/EKFw/b0Au5AKX79TWj"
 | 
			
		||||
		+ "JK9/bAEoAJBQQpW+MqmymwE8bTv5E9cuvWKivEFOAZATJ7z94qUjDgUX3QPNX7/PMMBb1CjZDHQei/J5"
 | 
			
		||||
		+ "RmuaPkic3J0nCwZIdvemCXoAVJlTtxcd2vUOZJaWOzPkbfWxx4H9wkxuJZ9ftZNDBx6CwMXoqamMnCQO"
 | 
			
		||||
		+ "+d1d7Ai8myL3cqGuRBdngDcOAAAApoYUARgAAAAA3A/9h30AAAAAABzrAQAAAEhA1gMAAwD6xwAAAADA"
 | 
			
		||||
		+ "YwPADgAAAL7nPMTlJrrVuDZPdCoy30WIBTqvdNdhQq+20Z5xutgU84ED/isAwKP8AYMZGlZ+GS/X1XGA"
 | 
			
		||||
		+ "u1drgflW0PlKAKIjFbyPqAhTABsIdwwAAAAA0o1Ykrn7uouD8UvH8HA7MbT5sJde+X3m/KvSmNMVPFTm"
 | 
			
		||||
		+ "9RdsFsKJ7ddoDEAA4L6plA7/szi4PjZ0/zOJw6EKgKZtxhe3/Jmp+N5/63S63urLO5zxu396eNaffW5o"
 | 
			
		||||
		+ "kCcPfZuow8tMke0uPk+Xd0X+zcV0GlrTUzdTw9ReqPNe2aWhSSj2FpsbZmsMVWWgfspagktVwdLTZRGW"
 | 
			
		||||
		+ "h3688l26tZcfS+JXXaX5OCqf4UpIKJKqM53e1SZnPV2jx4vJTj9Z/bThktx/+gEAMBsy3wUHAAAAABnl"
 | 
			
		||||
		+ "nwwAAAAAAHQLAADWAwANAFwP/fnwx2ILALweAAAAAMD+HAB4TlEAAL7n3MrbTEu7pI37ZIeK+ZCBf695"
 | 
			
		||||
		+ "kcdBPta+Be3OMszMiCzwGwDgooE7HKkAVKcC3KXhOKDJ334AnVkFhSFaEqYIBYFjAAAAAOCy2DLI5wOy"
 | 
			
		||||
		+ "svK+OMi5TUvc5C65v+v9ReujhePpfBjv8jb0ilHak1Dt/SZMlftWc6BZQm9loIwECgK0uZMuAk+m1VEK"
 | 
			
		||||
		+ "sLbh/d/llwxsnobNU+A+o28EQ0b1z5xdtoiL+pl/J4f1eyL9q/5ubnbTzMZLAgwNlTWnAUbDjCssCt9L"
 | 
			
		||||
		+ "bBJ4KfLf31SOnokabyfIl+dviK3tm9wQCoGeXH539sxN0vOLAxl5WIZ9t06/PXrFU+MBEG/5s7Vf0AAA"
 | 
			
		||||
		+ "AAcAAAAA6NP9p4hojyr9+i8/ndL7HQAAAAAA0GkBAABoLQAAAMy7+jsbAICbBADgPABv1AgDAD7HvOLz"
 | 
			
		||||
		+ "JkKqbI3duR4VM0FWao55YfstU6ttzVMxg1q4bwCA0+OJu/sTRYDCpydQVlZn+IuYD6/CIPxUgUTICVYQ"
 | 
			
		||||
		+ "7hgAAAAMgMbStlZmbwd0b2w914/tg25vDx1I9Jfl233Rfl9LSJwK5u5F6xs7gobk5MF0f629DRSytN3/"
 | 
			
		||||
		+ "fe6TkkFDj2qC17OlD/z5AGR823vx2d8un9RBhyrAuqWnk+lf7+htemef6nRUa5uAgE9pp+6oFGB3FVVR"
 | 
			
		||||
		+ "/Jl/sbHJ3UWeJBBg7GeSHc0pl3N2PqOuLrTMz0nBk75Z7dzbZcTkYqiqrRtNqSdgl5vcTOSTmbjXbPlM"
 | 
			
		||||
		+ "Np81OSuY3Kbm79jzsce8BViAZdn8//rLLhygAQAAAIBrVgAAAAAAKIwBAAAA4AAAgJp892M1AABcAAAA"
 | 
			
		||||
		+ "AIBfAYAALgAA3sY8wXZqoV3DVrt72dkMyArlLV9ymeu09mXDu5eVMluYvwEQACcwj6ZACQB23/P47Slg"
 | 
			
		||||
		+ "KmvSRkMEwjo2AdjfJ3BABkIkAAAAAGzfTGJhWXMbe7uz/gnHJyZG9i/loNn2V9V/evTRZ6bnU3IMiq81"
 | 
			
		||||
		+ "B3N/m+DSFQhd6L3EVLYH8AXpmNf9mb3XJcpC1j/oovlJqYoAJtvAZPULdQ3m+/ld2Aw6k32ylp1u93Sc"
 | 
			
		||||
		+ "dAxTsMlN0ZM4oPmv31/qEBDdZDYAMHZ225PrGdLEnbFsutYZ8846K//+N7v60OwcPVk0+aV1gh8Xs7yv"
 | 
			
		||||
		+ "gvQDruv8TR8Pe/LgZw696GkyWWCABJHYODwAHs4Oe/cXAEwDAAAAAPKDCwBAAwDAAwCAzo9vfiYALAMA"
 | 
			
		||||
		+ "8CVgAP7GvODLXFV6pWicrKRgJeOON7bMzO7t22jcK2awhW9fAQDuE8A5wNOBI0BlOMMP820IgzCXKDIQ"
 | 
			
		||||
		+ "AgAAAACoT15y0/+7txj9O/NicH0m9pWX/nZUfPbqQ7imb3KjTdj6roVCo9NhH4EHCjAadxkhbVWADEDG"
 | 
			
		||||
		+ "OIsj/LjB7dK8dbjfkZcfO56uu89Oh2rslpm/93k90EOH5hj+DIjjPX3yQ23WonIq2qcOI7LLKIjX26TI"
 | 
			
		||||
		+ "nX9K8fHtGKgg6v3r4O4fyuTpbLutXqL0Xb2iRKioLAaBk1yHykoiEqm8sOmoV2AcP+U8YPjzZHugaBp5"
 | 
			
		||||
		+ "Dh4AWAzTxw0AOAAAAABAvrMAYCY6yfQbTkEQAFgBAAAAAFgaAAAABuJRJAAsAACoAR63fNHjKJW7lqbN"
 | 
			
		||||
		+ "CwNY8XwzvsAy82nt92jel4vfmcFWuH0FADiajjgEAMC6JjbDh4HQkhDDMRASBAAAAADZfPJhLjlvbv6+"
 | 
			
		||||
		+ "3psxM3r/eRkBgGfqTRXwAI7aA2+c+bDPL2P/6FO2lXR5/fAW9m99P3vFyogYtY7IKt/zNFdi0owd/24A"
 | 
			
		||||
		+ "CiLs//iscQF4u7Kh/W73VNXh+sSS3mwj785ihoq8VK991bI/Byc5hXcHM+E9/cuh5Q3tQU/nlDAFmWif"
 | 
			
		||||
		+ "mmmCqRSO283l/CyL0uq5Xsn18FNumXv3ncooyaBSlACbjw/0DtvlaBTR0gSem6Vny32unl09StQFh6Ey"
 | 
			
		||||
		+ "i1LBlDWsN0Bg+PM+BwA4AAAwOBQAAMOj35z/6g8AAACOAhQAAPTvqAEA+KsDBAsA3nZ8EOuhl1UatfmS"
 | 
			
		||||
		+ "TVKyUTjTjC9unuFWc1C+nUKzUdw3AMAjisAjocgYAGbvK//zcARsaU1stEo4CF8YoMMICOAYCAcAAAAc"
 | 
			
		||||
		+ "QMYNzZPMofWDWp1dK28rD+5uvOFa+3r7m5zo70bfhu+ezNvea6rKcsq9jT/J5BAghJueihQPABAIgzNL"
 | 
			
		||||
		+ "Ql/MOABwYlfN0u3rbz1HHRfm7hA651N864C0cpTBHMrRCucucsmhoEn4NGmUA9O/PPMKD9YzuqB64rpa"
 | 
			
		||||
		+ "wuOkc1mYPZe0zHW5ozt8yI4WJEaH4dUBtBpc1ApA52QCWmdyfCj29GB8J3oDpjtYewS+s/uWON0JxAD/"
 | 
			
		||||
		+ "BgDaDQAAAEBFwJAAADj3eSgAAADQAgB+Z/wDx9kqq3CtjH7UTlKulbjO+C3PuR7p0i7GeJEiWPH2FQDg"
 | 
			
		||||
		+ "AJz22ToSa6sGQgsD7i4IEcAxEAIAAAAA5M5rsHNWGS1dDpjJqaV9MwBACP4w/jdCtz3POoAwZU/7UVDE"
 | 
			
		||||
		+ "MqYMa3j7ZmX3O/r8aSRD1oP6+5Wn3f3B/86L913+YfPhJJu/PxUd0LHqzWKpAuMBIMm4GRLm8CaRuKc9"
 | 
			
		||||
		+ "OfM4T/4ss48qfV45qwVNlIoizTzNH54Xi2Cq5cSYUu7a2dPTM1p7svfR9P4Oy+6JIo3eZ5qVrhyyIsPh"
 | 
			
		||||
		+ "cQNMvl2AZQE5T3Wa9lUDywqiX40A6DE+rtPs+f5we3wIAJb1fqYBgBEAAHAAAE8BANCfON8GACgLAk9n"
 | 
			
		||||
		+ "Z1MABI9FAAAAAAAA12AAAAMAAAA80+lLBfnXAQEBfmb8BONBl5bRnJ3rSCmQhVdm/CDXubilSjBLVEgp"
 | 
			
		||||
		+ "wn8DAFSOn+C9EwUA+9kJDE2soYKEQGhJQAiOgQAAAADIBIhL3Ywmd30rf4/Xqu1vZPaZx80ZzuPkVL7u"
 | 
			
		||||
		+ "LXL3N+9lFBr7NO+8byVWN5w+dyF4ArmInp4L1BqtWwAZiAesc8W5/pmJGaCryY1imGLmQLRcm7NnKZKT"
 | 
			
		||||
		+ "ve+siU6SaPnXUSsNvNOGAvBvNlBwyvnBFsbnNLvFXJrew/a77NzR4eflpJp35yTe2YZmlhFkLwCAx90B"
 | 
			
		||||
		+ "O5eQ/vI5w/jpgAcAAHAAAGw5AOCRyKs81/YAAHCAAQAAqHCtBOAAPmb8g+q8T6804p5zXyA0ZvyL2yyW"
 | 
			
		||||
		+ "dW0HR2F4axqQRbXm5KOH20MBs4/MqoIAQCgjpBAEAAAAAP/fyiDOdHoccpv5bZtvr29nXeXs8+ns3thn"
 | 
			
		||||
		+ "wTnfeTi/ky6Wi9P1hZf3jNilgm6280RqceAB+6umGRjJw/GQ9zPM8/K8dMZSLGBxvLy+HXo68sqPaPMa"
 | 
			
		||||
		+ "P6ZqNx8lq+yRkdG6WEbhYlkA01PJ1FW7s7TP/1mXWZubheZq8+rq6uq/q1cCz4EDANZmAABg5emTVX0F"
 | 
			
		||||
		+ "AADA+zAAAAAwBVztbAIODg4="
 | 
			
		||||
		/*}}}*/
 | 
			
		||||
	);
 | 
			
		||||
 | 
			
		||||
	var Beep = function()
 | 
			
		||||
	{
 | 
			
		||||
		// Beep Async
 | 
			
		||||
		setTimeout(function() {
 | 
			
		||||
			bAudio.pause();
 | 
			
		||||
			bAudio.currentTime = 0;
 | 
			
		||||
			bAudio.play();
 | 
			
		||||
		}, 0 );
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	ns[ NS_EXPORT ]( EX_FUNC, "Message", Message );
 | 
			
		||||
	ns[ NS_EXPORT ]( EX_FUNC, "Error", Error );
 | 
			
		||||
	ns[ NS_EXPORT ]( EX_FUNC, "Beep", Beep );
 | 
			
		||||
})();
 | 
			
		||||
 
 | 
			
		||||
@@ -22,7 +22,7 @@
 | 
			
		||||
	/* }}}*/
 | 
			
		||||
 | 
			
		||||
	// Reverse an array using XOR swap
 | 
			
		||||
	var Array_Reverse = function( array )
 | 
			
		||||
	var ArrayReverse = function( array )
 | 
			
		||||
	{
 | 
			
		||||
		var i = null;
 | 
			
		||||
		var l = array.length;
 | 
			
		||||
@@ -39,6 +39,26 @@
 | 
			
		||||
		}
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	// Count Occurance of a string
 | 
			
		||||
	var CountSubString = function ( str, search )
 | 
			
		||||
	{
 | 
			
		||||
		if ( search.length <= 0 )
 | 
			
		||||
		{
 | 
			
		||||
			return str.length + 1;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		var c = 0;
 | 
			
		||||
 | 
			
		||||
		for( var i = str.indexOf( search ); 0 <= i ; i = str.indexOf( search, i ) )
 | 
			
		||||
		{
 | 
			
		||||
			c ++;
 | 
			
		||||
			i ++;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		return c;
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	ns[ NS_EXPORT ]( EX_READONLY_GETTER, "uuid", UUID );
 | 
			
		||||
	ns[ NS_EXPORT ]( EX_FUNC, "ArrayReverse", Array_Reverse );
 | 
			
		||||
	ns[ NS_EXPORT ]( EX_FUNC, "CountSubstr", CountSubString );
 | 
			
		||||
	ns[ NS_EXPORT ]( EX_FUNC, "ArrayReverse", ArrayReverse );
 | 
			
		||||
})();
 | 
			
		||||
 
 | 
			
		||||
@@ -38,6 +38,8 @@ Components.Vim.Cursor.X;
 | 
			
		||||
/** @type Number */
 | 
			
		||||
Components.Vim.Cursor.Y;
 | 
			
		||||
/** @type Number */
 | 
			
		||||
Components.Vim.Cursor.aPos;
 | 
			
		||||
/** @type Number */
 | 
			
		||||
Components.Vim.Cursor.cols;
 | 
			
		||||
/** @type message */
 | 
			
		||||
Components.Vim.Cursor.string;
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										7
									
								
								botanjs/src/externs/Components.Vim.DateTime.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								botanjs/src/externs/Components.Vim.DateTime.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,7 @@
 | 
			
		||||
/** @constructor */
 | 
			
		||||
Components.Vim.DateTime = function(){};
 | 
			
		||||
 | 
			
		||||
/** @type Function */
 | 
			
		||||
Components.Vim.DateTime.RelativeTime;
 | 
			
		||||
/** @type Function */
 | 
			
		||||
Components.Vim.DateTime.String;
 | 
			
		||||
@@ -5,3 +5,5 @@ Components.Vim.State.Stack = function(){};
 | 
			
		||||
Components.Vim.State.Stack.play;
 | 
			
		||||
/** @type Function */
 | 
			
		||||
Components.Vim.State.Stack.store;
 | 
			
		||||
/** @type Function */
 | 
			
		||||
Components.Vim.State.Stack.time;
 | 
			
		||||
 
 | 
			
		||||
@@ -6,3 +6,5 @@ System.utils.Perf.uuid;
 | 
			
		||||
 | 
			
		||||
/** @type {Function} */
 | 
			
		||||
System.utils.Perf.ArrayReverse;
 | 
			
		||||
/** @type {Function} */
 | 
			
		||||
System.utils.Perf.CountSubstr;
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user