forked from Botanical/BotanJS
		
	Visual viw, viw{bracket}, Ctrl+f, Ctcl+b
This commit is contained in:
		@@ -41,19 +41,22 @@
 | 
			
		||||
		var feeder = cur.feeder;
 | 
			
		||||
 | 
			
		||||
		var Triggered = false;
 | 
			
		||||
		if( sp == undefined && this.__startX != cur.aPos )
 | 
			
		||||
 | 
			
		||||
		if( sp == undefined )
 | 
			
		||||
		{
 | 
			
		||||
			Triggered = true;
 | 
			
		||||
 | 
			
		||||
			if( e.kMap( "l" ) )
 | 
			
		||||
			if( this.__startX != cur.aPos )
 | 
			
		||||
			{
 | 
			
		||||
				cur.moveX( -1 );
 | 
			
		||||
				Triggered = true;
 | 
			
		||||
 | 
			
		||||
				if( e.kMap( "l" ) )
 | 
			
		||||
				{
 | 
			
		||||
					cur.moveX( -1 );
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				sp = this.__startX;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			sp = this.__startX;
 | 
			
		||||
			else return;
 | 
			
		||||
		}
 | 
			
		||||
		else if( sp == undefined ) return;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		var c = feeder.content;
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -27,7 +27,6 @@
 | 
			
		||||
		/** @type {Components.Vim.Cursor} */
 | 
			
		||||
		this.__cursor = Cursor;
 | 
			
		||||
		this.__startaP = Cursor.aPos;
 | 
			
		||||
		this.__startP = { x: Cursor.X, y: Cursor.Y, p: Cursor.P };
 | 
			
		||||
		this.__start = Cursor.PStart;
 | 
			
		||||
		this.__selStart = Cursor.PStart;
 | 
			
		||||
	};
 | 
			
		||||
@@ -71,10 +70,9 @@
 | 
			
		||||
			// to keep the cursor position as the top on UNDO / REDO
 | 
			
		||||
			if( Action.constructor == DELETE && this.__startaP < cur.aPos )
 | 
			
		||||
			{
 | 
			
		||||
				this.__startaP = cur.aPos;
 | 
			
		||||
				cur.X = this.__startP.x;
 | 
			
		||||
				cur.Y = this.__startP.y;
 | 
			
		||||
				cur.P = this.__startP.p;
 | 
			
		||||
				var o = cur.aPos;
 | 
			
		||||
				cur.moveTo( this.__startaP, true );
 | 
			
		||||
				this.__startaP = o;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			Action.handler( e, this.__startaP );
 | 
			
		||||
@@ -97,12 +95,12 @@
 | 
			
		||||
 | 
			
		||||
				if( cur.aPos == this.__startaP )
 | 
			
		||||
				{
 | 
			
		||||
					cur.moveX( r.open - this.__startaP );
 | 
			
		||||
					cur.moveTo( r.open, true );
 | 
			
		||||
					this.__reset( cur );
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				cur.unsuppressEvent();
 | 
			
		||||
				cur.moveX( r.close - cur.aPos );
 | 
			
		||||
				cur.moveTo( r.close, true );
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			var prevPos = this.__start;
 | 
			
		||||
 
 | 
			
		||||
@@ -257,6 +257,8 @@
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		var ccur = this.__ccur;
 | 
			
		||||
		var vima = this.__vimArea;
 | 
			
		||||
		var cfeeder = ccur.feeder;
 | 
			
		||||
 | 
			
		||||
		var cursorHandled = true;
 | 
			
		||||
		switch( kCode )
 | 
			
		||||
@@ -267,6 +269,29 @@
 | 
			
		||||
			case K: this.__cMoveY( -1 ); break; // Up
 | 
			
		||||
			case J: this.__cMoveY( 1 ); break; // Down
 | 
			
		||||
 | 
			
		||||
			case CTRL + F: // Page Down
 | 
			
		||||
				if( cfeeder.firstBuffer.next.placeholder )
 | 
			
		||||
				{
 | 
			
		||||
					beep();
 | 
			
		||||
					break;
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				var oPan = cfeeder.panY;
 | 
			
		||||
				cfeeder.pan( undefined, vima.rows - 1 );
 | 
			
		||||
				ccur.moveY( -ccur.Y );
 | 
			
		||||
 | 
			
		||||
				break;
 | 
			
		||||
			case CTRL + B: // Page Up
 | 
			
		||||
				if( cfeeder.panY == 0 )
 | 
			
		||||
				{
 | 
			
		||||
					beep();
 | 
			
		||||
					break;
 | 
			
		||||
				}
 | 
			
		||||
				cfeeder.pan( undefined, -vima.rows + 1 );
 | 
			
		||||
				ccur.moveY( -ccur.Y );
 | 
			
		||||
				if( !cfeeder.EOF ) ccur.moveY( cfeeder.moreAt );
 | 
			
		||||
				break;
 | 
			
		||||
 | 
			
		||||
			case SHIFT + H: // First line buffer
 | 
			
		||||
				break;
 | 
			
		||||
			case SHIFT + L: // Last line buffer
 | 
			
		||||
@@ -313,29 +338,33 @@
 | 
			
		||||
				var analyzer = this.__vimArea.contentAnalyzer;
 | 
			
		||||
 | 
			
		||||
				this.__cMovement = true;
 | 
			
		||||
 | 
			
		||||
				// Word boundary
 | 
			
		||||
				this.__comp( e, function( e2 ) {
 | 
			
		||||
					var WordMatch = analyzer.wordAt( ccur.aPos );
 | 
			
		||||
 | 
			
		||||
					debug.Info( "Word: "
 | 
			
		||||
						+ ccur.feeder.content.substring( WordMatch.open, WordMatch.close + 1 )
 | 
			
		||||
					);
 | 
			
		||||
 | 
			
		||||
					e2.__range = WordMatch;
 | 
			
		||||
				}, W );
 | 
			
		||||
				this.__comp( e, function(){
 | 
			
		||||
					debug.Info( "Bracket boundary [" );
 | 
			
		||||
				}, S_BRACKET_L );
 | 
			
		||||
				this.__comp( e, function(){
 | 
			
		||||
					debug.Info( "Bracket boundary ]" );
 | 
			
		||||
				}, S_BRACKET_R );
 | 
			
		||||
				this.__comp( e, function(){
 | 
			
		||||
					debug.Info( "Bracket boundary {" );
 | 
			
		||||
				}, SHIFT + S_BRACKET_L );
 | 
			
		||||
				this.__comp( e, function(){
 | 
			
		||||
					debug.Info( "Bracket boundary }" );
 | 
			
		||||
					analyzer.bracketAt( ccur.aPos );
 | 
			
		||||
				}, SHIFT + S_BRACKET_R );
 | 
			
		||||
 | 
			
		||||
				var bracket = function( e2 ) {
 | 
			
		||||
					var BracketMatch = analyzer.bracketIn( "(", ccur.aPos );
 | 
			
		||||
					e2.__range = BracketMatch;
 | 
			
		||||
				};
 | 
			
		||||
				var curlyBracket = function( e2 ) {
 | 
			
		||||
					var BracketMatch = analyzer.bracketIn( "{", ccur.aPos );
 | 
			
		||||
					e2.__range = BracketMatch;
 | 
			
		||||
				};
 | 
			
		||||
				var squareBracket = function( e2 ) {
 | 
			
		||||
					var BracketMatch = analyzer.bracketIn( "[", ccur.aPos );
 | 
			
		||||
					e2.__range = BracketMatch;
 | 
			
		||||
				};
 | 
			
		||||
 | 
			
		||||
				// Bracket boundaries
 | 
			
		||||
				this.__comp( e, bracket , SHIFT + _0 );
 | 
			
		||||
				this.__comp( e, bracket, SHIFT + _9 );
 | 
			
		||||
				this.__comp( e, squareBracket, S_BRACKET_L );
 | 
			
		||||
				this.__comp( e, squareBracket, S_BRACKET_R );
 | 
			
		||||
				this.__comp( e, curlyBracket, SHIFT + S_BRACKET_L );
 | 
			
		||||
				this.__comp( e, curlyBracket, SHIFT + S_BRACKET_R );
 | 
			
		||||
				break;
 | 
			
		||||
 | 
			
		||||
			case G: // Go to top
 | 
			
		||||
 
 | 
			
		||||
@@ -89,7 +89,7 @@
 | 
			
		||||
	Cursor.prototype.Vim;
 | 
			
		||||
 | 
			
		||||
	// Move to an absolute position
 | 
			
		||||
	Cursor.prototype.moveTo = function( aPos )
 | 
			
		||||
	Cursor.prototype.moveTo = function( aPos, phantomSpace )
 | 
			
		||||
	{
 | 
			
		||||
		var content = this.feeder.content;
 | 
			
		||||
		var lastLineNum = this.getLine().lineNum;
 | 
			
		||||
@@ -115,7 +115,7 @@
 | 
			
		||||
		if( 0 < this.getLine().lineNum && lineStart <= aPos ) jumpX --;
 | 
			
		||||
 | 
			
		||||
		this.moveX( - Number.MAX_VALUE );
 | 
			
		||||
		this.moveX( jumpX );
 | 
			
		||||
		this.moveX( jumpX, false, phantomSpace );
 | 
			
		||||
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -149,7 +149,9 @@
 | 
			
		||||
				var a = this.content.indexOf( "\n", f + 1 );
 | 
			
		||||
				if( a == -1 )
 | 
			
		||||
				{
 | 
			
		||||
					Y = i;
 | 
			
		||||
					Y = i - 1;
 | 
			
		||||
					// -2 to compensate the last "\n" content placeholder
 | 
			
		||||
					f -= 2;
 | 
			
		||||
					break;
 | 
			
		||||
				}
 | 
			
		||||
				f = a;
 | 
			
		||||
 
 | 
			
		||||
@@ -117,6 +117,24 @@
 | 
			
		||||
	};
 | 
			
		||||
	/* End Private Class }}}*/
 | 
			
		||||
 | 
			
		||||
	var SetParent = function( BracketPairs, pair )
 | 
			
		||||
	{
 | 
			
		||||
		if( !pair ) throw new Error( "Parent not found" );
 | 
			
		||||
 | 
			
		||||
		var tMatch = new TokenMatch();
 | 
			
		||||
		tMatch.__level = pair[ TOK_LEVEL ];
 | 
			
		||||
		tMatch.__open = pair[ TOK_OPEN ];
 | 
			
		||||
		tMatch.__close = pair[ TOK_CLOSED ];
 | 
			
		||||
 | 
			
		||||
		if( -1 < pair[ TOK_PARENT ] )
 | 
			
		||||
		{
 | 
			
		||||
			var rPair = BracketPairs.find( pair[ TOK_PARENT ] );
 | 
			
		||||
			tMatch.__parent = SetParent( BracketPairs, rPair );
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		return tMatch;
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	var Analyzer = function( feeder )
 | 
			
		||||
	{
 | 
			
		||||
		/* @type {Components.Vim.LineFeeder} */
 | 
			
		||||
@@ -136,17 +154,17 @@
 | 
			
		||||
		{
 | 
			
		||||
			case "{": tokState = TOK_OPEN;
 | 
			
		||||
			case "}":
 | 
			
		||||
					  BracketPairs = this.GetPairs( TOK_JOIN( "{", "}" ) );
 | 
			
		||||
					  BracketPairs = this.__getPairs( TOK_JOIN( "{", "}" ) );
 | 
			
		||||
				break;
 | 
			
		||||
 | 
			
		||||
			case "[": tokState = TOK_OPEN;
 | 
			
		||||
			case "]":
 | 
			
		||||
				BracketPairs = this.GetPairs( TOK_JOIN( "[", "]" ) );
 | 
			
		||||
				BracketPairs = this.__getPairs( TOK_JOIN( "[", "]" ) );
 | 
			
		||||
				break;
 | 
			
		||||
 | 
			
		||||
			case "(": tokState = TOK_OPEN;
 | 
			
		||||
			case ")":
 | 
			
		||||
				BracketPairs = this.GetPairs( TOK_JOIN( "(", ")" ) );
 | 
			
		||||
				BracketPairs = this.__getPairs( TOK_JOIN( "(", ")" ) );
 | 
			
		||||
				break;
 | 
			
		||||
 | 
			
		||||
			case "/":
 | 
			
		||||
@@ -186,39 +204,65 @@
 | 
			
		||||
		{
 | 
			
		||||
			case "/*": tokState = TOK_OPEN;
 | 
			
		||||
			case "*/":
 | 
			
		||||
				BracketPairs = this.GetPairs( TOK_JOIN( "/*", "*/" ) );
 | 
			
		||||
				BracketPairs = this.__getPairs( TOK_JOIN( "/*", "*/" ) );
 | 
			
		||||
				break;
 | 
			
		||||
 | 
			
		||||
			default:
 | 
			
		||||
				return new TokenMatch();
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		var SetParent = function( pair )
 | 
			
		||||
		{
 | 
			
		||||
			if( !pair ) throw new Error( "Parent not found" );
 | 
			
		||||
 | 
			
		||||
			var tMatch = new TokenMatch();
 | 
			
		||||
			tMatch.__level = pair[ TOK_LEVEL ];
 | 
			
		||||
			tMatch.__open = pair[ TOK_OPEN ];
 | 
			
		||||
			tMatch.__close = pair[ TOK_CLOSED ];
 | 
			
		||||
 | 
			
		||||
			if( -1 < pair[ TOK_PARENT ] )
 | 
			
		||||
			{
 | 
			
		||||
				var rPair = BracketPairs.find( pair[ TOK_PARENT ] );
 | 
			
		||||
				tMatch.__parent = SetParent( rPair );
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			return tMatch;
 | 
			
		||||
		};
 | 
			
		||||
 | 
			
		||||
		var rPair = BracketPairs.find( p, tokState );
 | 
			
		||||
		var tMatch = SetParent( rPair )
 | 
			
		||||
		var tMatch = SetParent( BracketPairs, rPair )
 | 
			
		||||
		tMatch.__selected = p;
 | 
			
		||||
 | 
			
		||||
		return tMatch;
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	Analyzer.prototype.GetPairs = function( def, reload )
 | 
			
		||||
	Analyzer.prototype.bracketIn = function( b, p )
 | 
			
		||||
	{
 | 
			
		||||
		var bro = "{[(";
 | 
			
		||||
		var brc = "}])";
 | 
			
		||||
 | 
			
		||||
		var i = bro.indexOf( b );
 | 
			
		||||
		if( i < 0 ) i = brc.indexOf( b );
 | 
			
		||||
		if( i < 0 ) throw new Error( "Unsupported bracket: " + b );
 | 
			
		||||
 | 
			
		||||
		var tokPairs = this.__getPairs( TOK_JOIN( bro[i], brc[i] ) );
 | 
			
		||||
		var pairs = tokPairs.__pairs;
 | 
			
		||||
 | 
			
		||||
		var l = pairs.length;
 | 
			
		||||
 | 
			
		||||
		var highest = null;
 | 
			
		||||
 | 
			
		||||
		// Find the range of highest level
 | 
			
		||||
		for( var i = 0; i < l; i ++ )
 | 
			
		||||
		{
 | 
			
		||||
			var pair = pairs[ i ];
 | 
			
		||||
 | 
			
		||||
			if( pair[ TOK_OPEN ] <= p && p <= pair[ TOK_CLOSED ] )
 | 
			
		||||
			{
 | 
			
		||||
				if( ( highest && highest[ TOK_LEVEL ] < pair[ TOK_LEVEL ] ) || !highest )
 | 
			
		||||
				{
 | 
			
		||||
					highest = pair;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		var tMatch = SetParent( tokPairs, highest );
 | 
			
		||||
		var oMatch = tMatch;
 | 
			
		||||
 | 
			
		||||
		do {
 | 
			
		||||
			oMatch.__open ++;
 | 
			
		||||
			oMatch.__close --;
 | 
			
		||||
		} while( oMatch = oMatch.parent )
 | 
			
		||||
 | 
			
		||||
		if( highest ) return tMatch;
 | 
			
		||||
 | 
			
		||||
		return new TokenMatch();
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	Analyzer.prototype.__getPairs = function( def, reload )
 | 
			
		||||
	{
 | 
			
		||||
		if( !reload && this.__tokpairs[ def ] )
 | 
			
		||||
		{
 | 
			
		||||
 
 | 
			
		||||
@@ -4,6 +4,8 @@ Components.Vim.Syntax.Analyzer = function(){};
 | 
			
		||||
/** @type Function */
 | 
			
		||||
Components.Vim.Syntax.Analyzer.bracketAt;
 | 
			
		||||
/** @type Function */
 | 
			
		||||
Components.Vim.Syntax.Analyzer.bracketIn;
 | 
			
		||||
/** @type Function */
 | 
			
		||||
Components.Vim.Syntax.Analyzer.wordAt;
 | 
			
		||||
/** @type Function */
 | 
			
		||||
Components.Vim.Syntax.Analyzer.quoteAt;
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user