commit a6ccf7e4dbd85b12e792f74ef7aa88564fc7d6ef
| author | 斟酌 鵬兄 <tgckpg@gmail.com> |
| date | 2017-01-06T10:05:07Z |
| subject | Quote in between & PUT impl |
commit a6ccf7e4dbd85b12e792f74ef7aa88564fc7d6ef
Author: 斟酌 鵬兄 <tgckpg@gmail.com>
Date: 2017-01-06T10:05:07Z
Quote in between & PUT impl
---
README.md | 2 +-
botanjs/src/Components/Vim/Actions/PUT.js | 28 ++++++---
botanjs/src/Components/Vim/Actions/TO.js | 4 +-
botanjs/src/Components/Vim/Actions/VISUAL.js | 11 +++-
botanjs/src/Components/Vim/Controls.js | 16 ++++-
botanjs/src/Components/Vim/Syntax/Analyzer.js | 69 ++++++++++++++++++++++
.../src/externs/Components.Vim.Syntax.Analyzer.js | 2 +
7 files changed, 117 insertions(+), 15 deletions(-)
diff --git a/README.md b/README.md
index 02e8606..30265e8 100644
--- a/README.md
+++ b/README.md
@@ -8,7 +8,7 @@ Visit the demo over [here](https://tgckpg.github.io/VimArea)
Common commands are now supported. I am now going to list the commands that yet to be made.
```
Commands that are going to implement soon:
-auto indent ( new line from bracket ), [action]i[quote]
+auto indent ( new line from bracket )
:'<,'>
Commands that are planning to implement in near future:
diff --git a/botanjs/src/Components/Vim/Actions/PUT.js b/botanjs/src/Components/Vim/Actions/PUT.js
index 52a6891..6dacc15 100644
--- a/botanjs/src/Components/Vim/Actions/PUT.js
+++ b/botanjs/src/Components/Vim/Actions/PUT.js
@@ -25,7 +25,7 @@
this.__cursor.unsuppressEvent();
};
- PUT.prototype.handler = function( e )
+ PUT.prototype.handler = function( e, sp, newLine )
{
e.preventDefault();
@@ -63,20 +63,32 @@
var stator = new Stator( cur );
var aP = cur.aPos;
+ var contentUndo = "";
- feeder.content = feeder.content.substring( 0, aP )
- + cput
- + feeder.content.substring( aP );
+ if( sp == undefined )
+ {
+ feeder.content = feeder.content.substring( 0, aP )
+ + cput + feeder.content.substring( aP );
- feeder.pan();
+ feeder.pan();
+ cur.moveTo( 0 < nLines ? aP : aP + clen, true );
+ }
+ else
+ {
+ sp ++;
+ contentUndo = feeder.content.substring( aP, sp );
+ feeder.content = feeder.content.substring( 0, aP )
+ + cput + feeder.content.substring( sp );
- cur.moveTo( 0 < nLines ? aP : aP + clen, true );
+ feeder.pan();
+ cur.moveTo( aP + clen, true );
+ }
var stack = new Stack();
if( newLine )
{
- var f = stator.save( clen, "" );
+ var f = stator.save( clen, contentUndo );
stack.store( function()
{
f();
@@ -85,7 +97,7 @@
}
else
{
- stack.store( stator.save( clen, "" ) );
+ stack.store( stator.save( clen, contentUndo ) );
}
cur.rec.record( stack );
diff --git a/botanjs/src/Components/Vim/Actions/TO.js b/botanjs/src/Components/Vim/Actions/TO.js
index eb1e00e..83daa03 100644
--- a/botanjs/src/Components/Vim/Actions/TO.js
+++ b/botanjs/src/Components/Vim/Actions/TO.js
@@ -38,7 +38,7 @@
if( 0 < n ) p ++;
- var lowerLimmit = p;
+ var lowerLimit = p;
var Char = et.key;
if( et.kMap( "Tab" ) )
@@ -64,7 +64,7 @@
tX = f.content.lastIndexOf( Char, cur.aPos - 1 );
}
- if( lowerLimmit <= tX && tX < upperLimit )
+ if( lowerLimit <= tX && tX < upperLimit )
{
cur.moveTo( tX );
}
diff --git a/botanjs/src/Components/Vim/Actions/VISUAL.js b/botanjs/src/Components/Vim/Actions/VISUAL.js
index 5e0cbea..55aa192 100644
--- a/botanjs/src/Components/Vim/Actions/VISUAL.js
+++ b/botanjs/src/Components/Vim/Actions/VISUAL.js
@@ -12,6 +12,8 @@
var DELETE = ns[ NS_INVOKE ]( "DELETE" );
/** @type {Components.Vim.IAction} */
var SHIFT_LINES = ns[ NS_INVOKE ]( "SHIFT_LINES" );
+ /** @type {Components.Vim.IAction} */
+ var PUT = ns[ NS_INVOKE ]( "PUT" );
var MODE_NULL = -1;
var MODE_VISUAL = 0;
@@ -121,6 +123,10 @@
{
Action = new DELETE( cur );
}
+ else if( e.kMap( "p" ) )
+ {
+ Action = new PUT( cur );
+ }
else if( e.kMap( "V" ) )
{
if( this.__mode == MODE_LINE ) return true;
@@ -180,7 +186,8 @@
// this swap the cursor direction from LTR to RTL
// i.e. treat all delete as "e<----s" flow
// to keep the cursor position as the top on UNDO / REDO
- if( Action.constructor == DELETE && startLine.aPos < cur.aPos )
+ var IsContMod = ~[ DELETE, PUT ].indexOf( Action.constructor );
+ if( IsContMod && startLine.aPos < cur.aPos )
{
var o = cur.aPos;
cur.moveTo( startLine.aPos, true );
@@ -189,7 +196,7 @@
Action.handler( e, startLine.aPos, lineMode );
- if( Action.constructor != DELETE )
+ if( !IsContMod )
{
cur.moveTo( startLine.aPos );
}
diff --git a/botanjs/src/Components/Vim/Controls.js b/botanjs/src/Components/Vim/Controls.js
index 36d0e04..cdb320c 100644
--- a/botanjs/src/Components/Vim/Controls.js
+++ b/botanjs/src/Components/Vim/Controls.js
@@ -616,14 +616,26 @@
var BracketMatch = analyzer.bracketIn( "[", ccur.aPos );
e2.__range = BracketMatch;
};
+ var singleQuote = function( e2 ) {
+ var BracketMatch = analyzer.quoteIn( "'", ccur.aPos );
+ e2.__range = BracketMatch;
+ };
+ var doubleQuote = function( e2 ) {
+ var BracketMatch = analyzer.quoteIn( "\"", ccur.aPos );
+ e2.__range = BracketMatch;
+ };
// Bracket boundaries
- this.__composite( e, bracket , SHIFT + _0 );
+ this.__composite( e, bracket, SHIFT + _0 );
this.__composite( e, bracket, SHIFT + _9 );
this.__composite( e, squareBracket, S_BRACKET_L );
this.__composite( e, squareBracket, S_BRACKET_R );
this.__composite( e, curlyBracket, SHIFT + S_BRACKET_L );
this.__composite( e, curlyBracket, SHIFT + S_BRACKET_R );
+
+ // Quote boundaries
+ this.__composite( e, singleQuote, QUOTE );
+ this.__composite( e, doubleQuote, SHIFT + QUOTE );
break;
case G:
@@ -725,7 +737,7 @@
var cfeeder = this.__cfeeder;
var ccur = this.__ccur;
- if( !ccur.action || ccur.action.allowMovement )
+ if( !this.__cMovement && ( !ccur.action || ccur.action.allowMovement ) )
{
this.__modCommand( e );
if( e.canceled ) return;
diff --git a/botanjs/src/Components/Vim/Syntax/Analyzer.js b/botanjs/src/Components/Vim/Syntax/Analyzer.js
index c10e441..de66e22 100644
--- a/botanjs/src/Components/Vim/Syntax/Analyzer.js
+++ b/botanjs/src/Components/Vim/Syntax/Analyzer.js
@@ -4,6 +4,8 @@
/** @type {System.Debug} */
var debug = __import( "System.Debug" );
+ var beep = __import( "Components.Vim.Beep" );
+
/** @type {Components.Vim.Syntax.Word} */
var Word = ns[ NS_INVOKE ]( "Word" );
@@ -265,6 +267,73 @@
return new TokenMatch();
};
+ Analyzer.prototype.quoteIn = function( Char )
+ {
+ var f = this.__feeder;
+ var cur = f.cursor;
+ var n = cur.getLine().lineNum;
+
+ var p = 0;
+ for( var i = 0; p != -1 && i < n; i ++ ) p = f.content.indexOf( "\n", p + 1 );
+
+ var upperLimit = f.content.indexOf( "\n", p + 1 );
+
+ if( 0 < n ) p ++;
+
+ var lowerLimit = p;
+
+ // Cursor is at the quote character
+ // Move cursor inside the matching quote
+ if( f.content[ cur.aPos ] == Char )
+ {
+ // Mark all quotes on current line
+ var quotePos = [];
+ var l = 0;
+
+ for( var i = lowerLimit; i < upperLimit; i ++ )
+ {
+ if( f.content[ i ] == Char )
+ quotePos[ l ++ ] = i;
+ }
+
+ var indexQuote = quotePos.indexOf( cur.aPos );
+ var indexEnd = ( indexQuote == ( l - 1 ) );
+
+ // Length is even: Quotes are matched
+ // OR
+ // Length is odd and cursor is not at the last quote
+ if( l % 2 == 0 || !indexEnd )
+ {
+ cur.moveX( indexQuote % 2 == 0 ? 1 : -1 );
+ }
+ // Cursor is at the last quote
+ else
+ {
+ // Beep because last quote of odd length is an unmatch quote
+ beep();
+ return new TokenMatch();
+ }
+
+ }
+
+ // Forward
+ var fX = f.content.indexOf( Char, cur.aPos + 1 );
+ // backward
+ var bX = f.content.lastIndexOf( Char, cur.aPos - 1 );
+
+ if( lowerLimit <= bX && fX < upperLimit )
+ {
+ var tMatch = new TokenMatch();
+ tMatch.__open = bX + 1;
+ tMatch.__close = fX - 1;
+ tMatch.__selected = Char;
+ return tMatch;
+ }
+ else beep();
+
+ return new TokenMatch();
+ };
+
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 24f603c..ae4b31f 100644
--- a/botanjs/src/externs/Components.Vim.Syntax.Analyzer.js
+++ b/botanjs/src/externs/Components.Vim.Syntax.Analyzer.js
@@ -6,6 +6,8 @@ Components.Vim.Syntax.Analyzer.bracketAt;
/** @type Function */
Components.Vim.Syntax.Analyzer.bracketIn;
/** @type Function */
+Components.Vim.Syntax.Analyzer.quoteIn;
+/** @type Function */
Components.Vim.Syntax.Analyzer.wordAt;
/** @type Function */
Components.Vim.Syntax.Analyzer.quoteAt;