commit ce669c2cb625e2cd969157a38dc391460d7d7f4a
| author | 斟酌 鵬兄 <tgckpg@gmail.com> |
| date | 2016-04-15T20:00:15Z |
| subject | Line shifting support |
commit ce669c2cb625e2cd969157a38dc391460d7d7f4a
Author: 斟酌 鵬兄 <tgckpg@gmail.com>
Date: 2016-04-15T20:00:15Z
Line shifting support
---
botanjs/src/Components/Vim/Actions/SHIFT_LINES.js | 108 ++++++++++++++++++----
botanjs/src/Components/Vim/Actions/VISUAL.js | 6 ++
botanjs/src/Components/Vim/Controls.js | 26 +++++-
botanjs/src/Components/Vim/_this.js | 2 +
4 files changed, 118 insertions(+), 24 deletions(-)
diff --git a/botanjs/src/Components/Vim/Actions/SHIFT_LINES.js b/botanjs/src/Components/Vim/Actions/SHIFT_LINES.js
index 650c68e..1202b6c 100644
--- a/botanjs/src/Components/Vim/Actions/SHIFT_LINES.js
+++ b/botanjs/src/Components/Vim/Actions/SHIFT_LINES.js
@@ -62,12 +62,14 @@
var start = this.__slineNum;
var nline = this.__lines;
+ var indentMult = 1;
if( 1 < e.count )
{
nline += e.count;
}
+ // default: >>, <<, >l, <h
var end = start;
var shiftCount = 1;
@@ -81,30 +83,86 @@
if( this.__startX != currAp )
{
- if( e.kMap( "h" ) || e.kMap( "l" ) ){}
- else if( e.kMap( "j" ) )
+ if( currAp < sp )
{
- end = start + nline;
+ sp = sp + currAp;
+ currAp = sp - currAp;
+ sp = sp - currAp;
}
- else if( e.kMap( "k" ) )
- {
- start -= nline;
- }
- else // TODO: Dectect movement line count
+
+ start = end = 0;
+ for( var i = 0; i < currAp; i ++ )
{
+ if( feeder.content[ i ] == "\n" )
+ {
+ end ++;
+ if( i < sp )
+ {
+ start ++;
+ }
+ }
}
}
else
{
- if( !( ( 0 < dir && ( e.kMap( ">" ) || e.kMap( "l" ) ) )
- || ( dir < 0 && ( e.kMap( "<" ) || e.kMap( "h" ) ) )
- ) )
+ if( e.range )
+ {
+ sp = e.range.close;
+
+ start = 1; end = -1;
+ for( var i = 0; i < sp; i ++ )
+ {
+ if( feeder.content[ i ] == "\n" )
+ {
+ end ++;
+ if( i < e.range.open )
+ {
+ start ++;
+ }
+ }
+ }
+
+ if( end == -1 )
+ {
+ start = end = 0;
+ }
+
+ if( end < start )
+ {
+ end = -- start;
+ }
+
+ indentMult = e.count;
+ }
+ else if( 0 < dir && ( e.kMap( ">" ) || e.kMap( "l" ) ) );
+ else if( dir < 0 && ( e.kMap( "<" ) || e.kMap( "h" ) ) );
+ else
{
beep();
return true;
}
}
}
+ // VISUAL Mode
+ else
+ {
+ start = 0;
+ for( var i = 0; i < sp; i ++ )
+ {
+ if( feeder.content[ i ] == "\n" ) start ++;
+ }
+
+ end = this.__slineNum;
+
+ indentMult = e.count;
+ }
+
+ if( end < start )
+ {
+ start = start + end;
+ end = start - end;
+ start = start - end;
+ }
// last "\n" padding
var c = feeder.content.slice( 0, -1 );
@@ -124,7 +182,7 @@
var spOccr = 0;
// Guess indent
- var tabStat = {};
+ var tabStat = [];
for( var i = 0; i < l; i ++ )
{
@@ -146,6 +204,7 @@
var indentCLen = 0;
for( var i in tabStat )
{
+ i = Number( i );
var p = tabStat[ i ];
if( upperDiff < p )
{
@@ -179,13 +238,15 @@
var nLen = 0;
var started = false;
- var indentTimes = 1;
var recStart = 0;
feeder.content = "";
nline = 0;
+ var indented = "";
+ for( var i = 0; i < indentMult; i ++ ) indented += indentChar;
+
for( var i = 0, j = 0; 0 <= i; i = c.indexOf( "\n", i ), j ++ )
{
i ++;
@@ -216,24 +277,24 @@
var indentedLine;
if( 0 < dir )
{
- indentedLine = indentChar + line;
+ indentedLine = indented + line;
}
else
{
- for( var si = 0, sj = 1; si < indentTimes; si ++ )
+ for( var si = 0, sj = 0; si < indentMult; si ++ )
{
- var startC = line[ si ];
+ var startC = line[ sj ];
if( startC == " " )
{
- for( ; sj < tabwidth; sj ++ )
+ for( var swidth = tabwidth + ( sj ++ ); sj < swidth; sj ++ )
{
- if( !~"\t ".indexOf( line[ si + sj ] ) ) break;
+ if( !~"\t ".indexOf( line[ sj ] ) ) break;
}
}
else if( startC != "\t" ) break;
}
- indentedLine = line.substring( si + sj - 1 );
+ indentedLine = line.substring( sj );
}
feeder.content += indentedLine;
@@ -267,7 +328,14 @@
cur.rec.record( stack );
- this.__msg = Mesg( "LINES_SHIFTED", nline, dir < 0 ? "<" : ">", 1 );
+ if( nline )
+ {
+ this.__msg = Mesg( "LINES_SHIFTED", nline, dir < 0 ? "<" : ">", indentMult );
+ }
+ else
+ {
+ this.__msg = Mesg( "NO_SHIFT", dir < 0 ? "<" : ">" );
+ }
return Triggered;
};
diff --git a/botanjs/src/Components/Vim/Actions/VISUAL.js b/botanjs/src/Components/Vim/Actions/VISUAL.js
index 1d4071d..5e0cbea 100644
--- a/botanjs/src/Components/Vim/Actions/VISUAL.js
+++ b/botanjs/src/Components/Vim/Actions/VISUAL.js
@@ -10,6 +10,8 @@
var YANK = ns[ NS_INVOKE ]( "YANK" );
/** @type {Components.Vim.IAction} */
var DELETE = ns[ NS_INVOKE ]( "DELETE" );
+ /** @type {Components.Vim.IAction} */
+ var SHIFT_LINES = ns[ NS_INVOKE ]( "SHIFT_LINES" );
var MODE_NULL = -1;
var MODE_VISUAL = 0;
@@ -129,6 +131,10 @@
this.__msg = Mesg( "VISLINE" );
}
}
+ else if( e.kMap( "<" ) || e.kMap( ">" ) )
+ {
+ Action = new SHIFT_LINES( cur, e );
+ }
else if( e.kMap( "v" ) )
{
if( this.__mode == MODE_VISUAL ) return true;
diff --git a/botanjs/src/Components/Vim/Controls.js b/botanjs/src/Components/Vim/Controls.js
index c34a4d9..1173343 100644
--- a/botanjs/src/Components/Vim/Controls.js
+++ b/botanjs/src/Components/Vim/Controls.js
@@ -300,8 +300,9 @@
var ccur = this.__ccur;
var x = ccur.X;
+ var y = ccur.Y;
ccur.moveX( a, b, c || ccur.pSpace );
- if( ccur.X == x )
+ if( ccur.X == x && ccur.Y == y )
{
beep();
return false;
@@ -559,15 +560,32 @@
this.__composite( e, curlyBracket, SHIFT + S_BRACKET_R );
break;
- case G: // Go to top
+ case G:
+
this.__cMovement = true;
- this.__composite( e, function(){
+
+ // Go to top
+ this.__composite( e, function() {
ccur.moveY( -Number.MAX_VALUE );
ccur.moveX( -Number.MAX_VALUE, true );
}, G );
- this.__composite( e, function(){
+
+ // Print Hex
+ this.__composite( e, function() {
ccur.openRunAction( "PRINT_HEX", e );
}, _8 );
+
+ // to lowercase
+ this.__composite( e, function( e2 ) {
+ if( ccur.action ) { beep(); return; }
+ // TODO
+ }, U );
+
+ // to uppercase
+ this.__composite( e, function( e2 ) {
+ if( ccur.action ) { beep(); return; }
+ // TODO
+ }, SHIFT + U );
break;
case SHIFT + N: // Next Search
diff --git a/botanjs/src/Components/Vim/_this.js b/botanjs/src/Components/Vim/_this.js
index dedf3f4..bfa1b4b 100644
--- a/botanjs/src/Components/Vim/_this.js
+++ b/botanjs/src/Components/Vim/_this.js
@@ -26,6 +26,8 @@ VIMRE_VERSION = "1.0.0b";
, "LINES_YANKED": "%1 line(s) yanked"
, "LINES_SHIFTED": "%1 line(s) %2ed %3 time(s)"
+ , "NO_SHIFT": "No line to %1"
+
, "SEARCH_HIT_BOTTOM": "search hit BOTTOM, continuing at TOP"
, "SEARCH_HIT_TOP": "search hit TOP, continuing at BOTTOM"
, "REPLACE": "%1 substitution(s) on %2 line(s)"