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 = {