diff --git a/botanjs/src/Components/Vim/Actions/DELETE.js b/botanjs/src/Components/Vim/Actions/DELETE.js index c42b2ef..922f703 100644 --- a/botanjs/src/Components/Vim/Actions/DELETE.js +++ b/botanjs/src/Components/Vim/Actions/DELETE.js @@ -19,6 +19,7 @@ /** @type {Components.Vim.Cursor} */ this.__cursor = Cursor; this.__nline = 0; + this.__startX = Cursor.aPos; }; DELETE.prototype.allowMovement = true; @@ -32,12 +33,28 @@ { e.preventDefault(); + /** @type {Components.Vim.State.Registers} */ var reg = e.target.registers; var cur = this.__cursor; var feeder = cur.feeder; + var Triggered = false; + if( sp == undefined && this.__startX != cur.aPos ) + { + Triggered = true; + + if( e.kMap( "l" ) ) + { + cur.moveX( -1 ); + } + + sp = this.__startX; + } + else if( sp == undefined ) return; + + var c = feeder.content; var s = sp; @@ -77,6 +94,8 @@ cur.rec.record( stack ); feeder.pan(); + + return Triggered; }; DELETE.prototype.getMessage = function() diff --git a/botanjs/src/Components/Vim/Actions/VISUAL.js b/botanjs/src/Components/Vim/Actions/VISUAL.js index 659b058..8072e6b 100644 --- a/botanjs/src/Components/Vim/Actions/VISUAL.js +++ b/botanjs/src/Components/Vim/Actions/VISUAL.js @@ -17,6 +17,7 @@ /** @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; this.__msg = Mesg( "VISUAL" ); @@ -45,46 +46,63 @@ var cur = this.__cursor; var Action = null; - switch( true ) - { - case e.kMap( "y" ): - Action = new YANK( cur ); - break; - case e.kMap( "d" ): - Action = new DELETE( cur ); - break; - } - var prevPos = this.__start; - var newPos = cur.PStart; - - var posDiff = newPos - prevPos; - if( 0 <= posDiff ) + if( e.kMap( "y" ) ) { - this.__selStart = newPos; - newPos = newPos + 1; + Action = new YANK( cur ); } - else if( posDiff < 0 ) + else if( e.kMap( "d" ) ) { - prevPos += posDiff; - newPos = this.__start + 1; - this.__selStart = prevPos; + Action = new DELETE( cur ); } if( Action ) { cur.suppressEvent(); + + // Low-level cursor position adjustment + // 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 && this.__startaP < cur.aPos ) + { + this.__startaP = cur.aPos; + cur.X = this.__startP.x; + cur.Y = this.__startP.y; + cur.P = this.__startP.p; + } + Action.handler( e, this.__startaP ); this.__leaveMesg = Action.getMessage(); + Action.dispose(); cur.unsuppressEvent(); this.__selStart = cur.PStart; + return true; } + else + { + var prevPos = this.__start; + var newPos = cur.PStart; - cur.PStart = prevPos; - cur.PEnd = newPos; + var posDiff = newPos - prevPos; + if( 0 <= posDiff ) + { + this.__selStart = newPos; + newPos = newPos + 1; + } + else if( posDiff < 0 ) + { + prevPos += posDiff; + newPos = this.__start + 1; + this.__selStart = prevPos; + } + + cur.PStart = prevPos; + cur.PEnd = newPos; + } }; VISUAL.prototype.getMessage = function() diff --git a/botanjs/src/Components/Vim/Controls.js b/botanjs/src/Components/Vim/Controls.js index 7bcc195..8dba252 100644 --- a/botanjs/src/Components/Vim/Controls.js +++ b/botanjs/src/Components/Vim/Controls.js @@ -26,6 +26,8 @@ var U = 85; var V = 86; var W = 87; var X = 88; var Y = 89; var Z = 90; + var S_BRACKET_L = 219; var S_BRACKET_R = 221; + var ESC = 27; var F1 = 112; var F2 = 113; var F3 = 114; var F4 = 115; var F5 = 116; @@ -184,6 +186,9 @@ case CTRL + R: // Redo ccur.openRunAction( "REDO", e ); break; + case D: // Del with motion + ccur.openAction( "DELETE" ); + break; case X: // Del break; case SHIFT + X: // Delete before @@ -277,6 +282,33 @@ case SHIFT + _5: // %, Find next item break; + case T: // To + break; + case I: // In between boundary + if( !ccur.action ) + { + cursorHandled = false; + break; + } + + this.__cMovement = true; + // Word boundary + this.__comp( kCode, function(){ + debug.Info( "Word boundary" ); + }, W ); + this.__comp( kCode, function(){ + debug.Info( "Bracket boundary [" ); + }, S_BRACKET_L ); + this.__comp( kCode, function(){ + debug.Info( "Bracket boundary ]" ); + }, S_BRACKET_R ); + this.__comp( kCode, function(){ + debug.Info( "Bracket boundary {" ); + }, SHIFT + S_BRACKET_L ); + this.__comp( kCode, function(){ + debug.Info( "Bracket boundary }" ); + }, SHIFT + S_BRACKET_R ); + break; case G: // Go to top this.__cMovement = true;