commit 553cab97763cde3b3c54a324772d17aab3f42ca2
| author | 斟酌 鵬兄 <tgckpg@gmail.com> |
| date | 2016-03-30T18:25:39Z |
| subject | Visual viw, viw{bracket}, Ctrl+f, Ctcl+b |
commit 553cab97763cde3b3c54a324772d17aab3f42ca2
Author: 斟酌 鵬兄 <tgckpg@gmail.com>
Date: 2016-03-30T18:25:39Z
Visual viw, viw{bracket}, Ctrl+f, Ctcl+b
---
botanjs/src/Components/Vim/Actions/DELETE.js | 21 +++---
botanjs/src/Components/Vim/Actions/VISUAL.js | 12 ++-
botanjs/src/Components/Vim/Controls.js | 65 +++++++++++-----
botanjs/src/Components/Vim/Cursor.js | 4 +-
botanjs/src/Components/Vim/LineFeeder.js | 4 +-
botanjs/src/Components/Vim/Syntax/Analyzer.js | 86 ++++++++++++++++------
.../src/externs/Components.Vim.Syntax.Analyzer.js | 2 +
7 files changed, 136 insertions(+), 58 deletions(-)
diff --git a/botanjs/src/Components/Vim/Actions/DELETE.js b/botanjs/src/Components/Vim/Actions/DELETE.js
index 922f703..b509fb5 100644
--- a/botanjs/src/Components/Vim/Actions/DELETE.js
+++ b/botanjs/src/Components/Vim/Actions/DELETE.js
@@ -41,19 +41,22 @@
var feeder = cur.feeder;
var Triggered = false;
- if( sp == undefined && this.__startX != cur.aPos )
- {
- Triggered = true;
- if( e.kMap( "l" ) )
+ if( sp == undefined )
+ {
+ if( this.__startX != cur.aPos )
{
- cur.moveX( -1 );
- }
+ Triggered = true;
- sp = this.__startX;
- }
- else if( sp == undefined ) return;
+ if( e.kMap( "l" ) )
+ {
+ cur.moveX( -1 );
+ }
+ sp = this.__startX;
+ }
+ else return;
+ }
var c = feeder.content;
diff --git a/botanjs/src/Components/Vim/Actions/VISUAL.js b/botanjs/src/Components/Vim/Actions/VISUAL.js
index 1574d95..7cac789 100644
--- a/botanjs/src/Components/Vim/Actions/VISUAL.js
+++ b/botanjs/src/Components/Vim/Actions/VISUAL.js
@@ -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;
diff --git a/botanjs/src/Components/Vim/Controls.js b/botanjs/src/Components/Vim/Controls.js
index f318060..950ddbc 100644
--- a/botanjs/src/Components/Vim/Controls.js
+++ b/botanjs/src/Components/Vim/Controls.js
@@ -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
diff --git a/botanjs/src/Components/Vim/Cursor.js b/botanjs/src/Components/Vim/Cursor.js
index c39080f..47b10ad 100644
--- a/botanjs/src/Components/Vim/Cursor.js
+++ b/botanjs/src/Components/Vim/Cursor.js
@@ -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 );
};
diff --git a/botanjs/src/Components/Vim/LineFeeder.js b/botanjs/src/Components/Vim/LineFeeder.js
index e50f4ac..b27779f 100644
--- a/botanjs/src/Components/Vim/LineFeeder.js
+++ b/botanjs/src/Components/Vim/LineFeeder.js
@@ -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;
diff --git a/botanjs/src/Components/Vim/Syntax/Analyzer.js b/botanjs/src/Components/Vim/Syntax/Analyzer.js
index cb816cf..131ec75 100644
--- a/botanjs/src/Components/Vim/Syntax/Analyzer.js
+++ b/botanjs/src/Components/Vim/Syntax/Analyzer.js
@@ -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 rPair = BracketPairs.find( p, tokState );
+ var tMatch = SetParent( BracketPairs, rPair )
+ tMatch.__selected = p;
+
+ return tMatch;
+ };
+
+ 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 tMatch = new TokenMatch();
- tMatch.__level = pair[ TOK_LEVEL ];
- tMatch.__open = pair[ TOK_OPEN ];
- tMatch.__close = pair[ TOK_CLOSED ];
+ var highest = null;
- if( -1 < pair[ TOK_PARENT ] )
+ // 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 ] )
{
- var rPair = BracketPairs.find( pair[ TOK_PARENT ] );
- tMatch.__parent = SetParent( rPair );
+ if( ( highest && highest[ TOK_LEVEL ] < pair[ TOK_LEVEL ] ) || !highest )
+ {
+ highest = pair;
+ }
}
- return tMatch;
- };
+ }
- var rPair = BracketPairs.find( p, tokState );
- var tMatch = SetParent( rPair )
- tMatch.__selected = p;
+ var tMatch = SetParent( tokPairs, highest );
+ var oMatch = tMatch;
- return tMatch;
+ do {
+ oMatch.__open ++;
+ oMatch.__close --;
+ } while( oMatch = oMatch.parent )
+
+ if( highest ) return tMatch;
+
+ return new TokenMatch();
};
- Analyzer.prototype.GetPairs = function( def, reload )
+ Analyzer.prototype.__getPairs = function( def, reload )
{
if( !reload && this.__tokpairs[ def ] )
{
diff --git a/botanjs/src/externs/Components.Vim.Syntax.Analyzer.js b/botanjs/src/externs/Components.Vim.Syntax.Analyzer.js
index 6be9e80..47a3b3b 100644
--- a/botanjs/src/externs/Components.Vim.Syntax.Analyzer.js
+++ b/botanjs/src/externs/Components.Vim.Syntax.Analyzer.js
@@ -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;