penguin/AstroJS

Javascript framework for my blog

commit 062e9d8bb94cbf431296e0584b72cda96a381c96

author斟酌 鵬兄 <tgckpg@gmail.com>
date2016-04-02T12:00:23Z
subjectFIND command
commit 062e9d8bb94cbf431296e0584b72cda96a381c96
Author: 斟酌 鵬兄 <tgckpg@gmail.com>
Date:   2016-04-02T12:00:23Z

    FIND command
---
 botanjs/src/Components/Vim/Actions/FIND.js      | 127 ++++++++++++++++++++++++
 botanjs/src/Components/Vim/Actions/PRINT_HEX.js |   2 -
 botanjs/src/Components/Vim/Controls.js          |   5 +
 botanjs/src/Components/Vim/Ex/Command.js        |  19 +++-
 botanjs/src/Components/Vim/_this.js             |   3 +
 5 files changed, 151 insertions(+), 5 deletions(-)

diff --git a/botanjs/src/Components/Vim/Actions/FIND.js b/botanjs/src/Components/Vim/Actions/FIND.js
new file mode 100644
index 0000000..c94f4f0
--- /dev/null
+++ b/botanjs/src/Components/Vim/Actions/FIND.js
@@ -0,0 +1,127 @@
+(function(){
+	var ns = __namespace( "Components.Vim.Actions" );
+
+	/** @type {System.Debug} */
+	var debug                                 = __import( "System.Debug" );
+
+	var Mesg = __import( "Components.Vim.Message" );
+
+	// Private static
+	var PATTERN = "";
+
+	var ParsePattern = function( pattern )
+	{
+		var parsed = "";
+		var l = pattern.length;
+
+		for( var i = 1; i < l; i ++ )
+		{
+			switch( pattern[ i ] )
+			{
+				case "^I":
+					parsed += "\t";
+					break;
+				case "\\":
+					var tok = pattern[ ++ i ];
+					debug.Error( "Unknown escaped token: " + tok );
+					++ i;
+				default:
+					parsed += pattern[ i ];
+			}
+		}
+
+		var RegEx = null;
+
+		try
+		{
+			var RegEx = new RegExp( parsed, "gm" );
+		}
+		catch( ex )
+		{
+			debug.Error( ex );
+		}
+
+		return RegEx;
+	};
+
+	/** @type {Components.Vim.Cursor.IAction} */
+	var FIND = function( Cursor )
+	{
+		/** @type {Components.Vim.Cursor} */
+		this.__cursor = Cursor;
+		this.__msg = "";
+		Cursor.suppressEvent();
+	};
+
+	FIND.prototype.dispose = function()
+	{
+		this.__cursor.unsuppressEvent();
+	};
+
+	FIND.prototype.handler = function( e, p )
+	{
+		e.preventDefault();
+
+		if( p ) PATTERN = p;
+
+		var search = ParsePattern( PATTERN );
+
+		var content = this.__cursor.feeder.content;
+
+		var cur = this.__cursor;
+		var p = cur.aPos;
+
+		var r;
+		var Hit;
+		var FirstHit;
+		var PrevStack = [];
+
+		while( ( r = search.exec( content ) ) !== null )
+		{
+			if( !FirstHit ) FirstHit = r.index;
+			if( p < r.index )
+			{
+				Hit = r.index;
+				break;
+			}
+
+			PrevStack.push( r.index );
+		}
+
+		if( e.kMap( "N" ) )
+		{
+			Hit = PrevStack[ PrevStack.length - 2 ];
+			if( Hit == undefined )
+			{
+				this.__msg = Mesg( "SEARCH_HIT_TOP" );
+
+				while( ( r = search.exec( content ) ) !== null ) Hit = r.index;
+			}
+		}
+		else if( FirstHit != undefined && Hit == undefined )
+		{
+			// Search Hit Bottom
+			Hit = FirstHit;
+			this.__msg = Mesg( "SEARCH_HIT_BOTTOM" );
+		}
+		else
+		{
+			this.__msg = PATTERN.join( "" )
+		}
+
+		if( Hit == undefined )
+		{
+		}
+		else
+		{
+			cur.moveTo( Hit );
+		}
+	};
+
+	FIND.prototype.getMessage = function()
+	{
+		return this.__msg;
+	};
+
+	ns[ NS_EXPORT ]( EX_CLASS, "FIND", FIND );
+})();
diff --git a/botanjs/src/Components/Vim/Actions/PRINT_HEX.js b/botanjs/src/Components/Vim/Actions/PRINT_HEX.js
index c3efbbb..185bb28 100644
--- a/botanjs/src/Components/Vim/Actions/PRINT_HEX.js
+++ b/botanjs/src/Components/Vim/Actions/PRINT_HEX.js
@@ -1,8 +1,6 @@
 (function(){
 	var ns = __namespace( "Components.Vim.Actions" );
 
-	/** @type {Components.Vim.State.Stack} */
-	var Stack                                 = __import( "Components.Vim.State.Stack" );
 	/** @type {System.Debug} */
 	var debug                                 = __import( "System.Debug" );
 
diff --git a/botanjs/src/Components/Vim/Controls.js b/botanjs/src/Components/Vim/Controls.js
index 631d736..19c76bd 100644
--- a/botanjs/src/Components/Vim/Controls.js
+++ b/botanjs/src/Components/Vim/Controls.js
@@ -441,6 +441,11 @@
 				}, _8 );
 				break;
 
+			case SHIFT + N: // Next Search
+			case N: // Next Search
+				ccur.openRunAction( "FIND", e );
+				break;
+
 			case SLASH: // "/" Search movement
 				this.__cMovement = true;
 
diff --git a/botanjs/src/Components/Vim/Ex/Command.js b/botanjs/src/Components/Vim/Ex/Command.js
index cd8600b..d3bfe05 100644
--- a/botanjs/src/Components/Vim/Ex/Command.js
+++ b/botanjs/src/Components/Vim/Ex/Command.js
@@ -8,7 +8,7 @@
 	/** @type {System.utils.Perf} */
 	var Perf                         = __import( "System.utils.Perf" );
 
-	/**j@type {Components.Vim.State.History} */
+	/** @type {Components.Vim.State.History} */
 	var History                                 = __import( "Components.Vim.State.History" );
 	var Mesg                                    = __import( "Components.Vim.Message" );
 	var beep                                    = __import( "Components.Vim.Beep" );
@@ -134,7 +134,7 @@
 		}
 		else if( e.kMap( "Enter" ) )
 		{
-			this.__process();
+			this.__process( e );
 			return true;
 		}
 		else if( e.kMap( "Left" ) )
@@ -206,9 +206,22 @@
 		feeder.dispatcher.dispatchEvent( new BotanEvent( "VisualUpdate" ) );
 	};
 
-	Command.prototype.__process = function()
+	Command.prototype.__process = function( e )
 	{
 		this.__hist.push( this.__command );
+
+		var action = "";
+		switch( this.__mode )
+		{
+			case "/":
+				action = "FIND";
+				break;
+		}
+
+		var cur = this.__cursor;
+		cur.suppressEvent();
+		this.__cursor.openRunAction( action, e, this.__command.slice() );
+		cur.unsuppressEvent();
 	};
 
 	ns[ NS_EXPORT ]( EX_CLASS, "Command", Command );
diff --git a/botanjs/src/Components/Vim/_this.js b/botanjs/src/Components/Vim/_this.js
index e387304..345a882 100644
--- a/botanjs/src/Components/Vim/_this.js
+++ b/botanjs/src/Components/Vim/_this.js
@@ -21,6 +21,9 @@
 		, "LINES_FEWER": "%1 fewer line(s)"
 		, "LINES_MORE": "%1 more line(s)"
 		, "LINES_YANKED": "%1 line(s) yanked"
+
+		, "SEARCH_HIT_BOTTOM": "search hit BOTTOM, continuing at TOP"
+		, "SEARCH_HIT_TOP": "search hit TOP, continuing at BOTTOM"
 	};
 
 	var errors = {