diff --git a/botanjs/src/Components/Vim/Actions/INSERT.js b/botanjs/src/Components/Vim/Actions/INSERT.js index d97d34c..e6d4615 100644 --- a/botanjs/src/Components/Vim/Actions/INSERT.js +++ b/botanjs/src/Components/Vim/Actions/INSERT.js @@ -36,13 +36,21 @@ INSERT.prototype.__saveCur = function() { var c = this.__cursor; - return { + var obj = { p: c.P , x: c.X , y: c.Y , px: c.feeder.panX , py: c.feeder.panY }; + + if( 0 < obj.x ) + { + obj.p -= 1; + obj.x -= 1; + } + + return obj; } INSERT.prototype.dispose = function() @@ -186,20 +194,23 @@ + inputChar + feeder.content.substring( f ); - feeder.pan(); - feeder.dispatcher.dispatchEvent( new BotanEvent( "VisualUpdate" ) ); - - this.__rec( inputChar ); - if( inputChar == "\n" ) { + feeder.softReset(); + feeder.pan(); cur.moveY( 1 ); cur.lineStart(); } else { - cur.moveX( 1 ); + feeder.pan(); + cur.moveX( 1, false, true ); } + + feeder.dispatcher.dispatchEvent( new BotanEvent( "VisualUpdate" ) ); + + this.__rec( inputChar ); + }; INSERT.prototype.getMessage = function() diff --git a/botanjs/src/Components/Vim/Controls.js b/botanjs/src/Components/Vim/Controls.js index 5e4d892..7f37de7 100644 --- a/botanjs/src/Components/Vim/Controls.js +++ b/botanjs/src/Components/Vim/Controls.js @@ -19,6 +19,12 @@ var U = 85; var V = 86; var W = 87; var X = 88; var Y = 89; var Z = 90; + var ESC = 27; + + var F1 = 112; var F2 = 113; var F3 = 114; var F4 = 115; var F5 = 116; + var F6 = 117; var F7 = 118; var F8 = 119; var F9 = 120; var F10 = 121; + var F11 = 122; var F12 = 123; + var Controls = function( vimArea ) { /** @type {Components.Vim.VimArea} */ @@ -77,7 +83,7 @@ // Neve capture these keys if( e.altKey // F2 - F12 - || ( 112 < e.keyCode && e.keyCode < 124 ) + || ( F1 < e.keyCode && e.keyCode < 124 ) ) return; var vArea = this.__vimArea; @@ -85,7 +91,7 @@ var cfeeder = vArea.contentFeeder; // Esc OR Ctrl + c - var Escape = e.keyCode == 27 || ( e.ctrlKey && e.keyCode == 67 ); + var Escape = e.keyCode == ESC || ( e.ctrlKey && e.keyCode == C ); // Clear the keychains in combo commands if( Escape && this.__keyChains.length ) @@ -141,26 +147,10 @@ } }; + var ActionHandled = true; + // Action Commands switch( kCode ) { - // Cursor movements - case BACKSPACE: // Backspace, go back 1 char, regardless of line - cMoveX( -1, true ); - break; - case H: // Left - cMoveX( -1 ); - break; - case L: // Right - cMoveX( 1 ); - break; - case K: // Up - cMoveY( -1 ); - break; - case J: // Down - cMoveY( 1 ); - break; - - // Insert case SHIFT + A: // Append at the line end ccur.lineEnd(); case A: // Append @@ -182,34 +172,57 @@ break; case SHIFT + I: // Append before the line start, after spaces break; + case SHIFT + J: // Join lines + break; + case SHIFT + K: // Find the manual entry + break; - case SHIFT + G: // Goto last line - ccur.moveY( Number.MAX_VALUE ); - ccur.moveX( Number.MAX_VALUE, true ); - break; - // remove characters - case X: // Remove in cursor - break; - case SHIFT + X: // Remove before cursor + case F1: // F1, help break; + default: + ActionHandled = false; + } + + if( ActionHandled ) return; + + // Cursor Commands + switch( kCode ) + { + case BACKSPACE: cMoveX( -1, true ); break; // Backspace, go back 1 char, regardless of line + case H: cMoveX( -1 ); break; // Left + case L: cMoveX( 1 ); break; // Right + case K: cMoveY( -1 ); break; // Up + case J: cMoveY( 1 ); break; // Down case SHIFT + H: // First line buffer break; case SHIFT + L: // Last line buffer break; - case SHIFT + _4: // $, End - ccur.lineEnd(); - break; - case SHIFT + _5: // %, Find next item - break; case SHIFT + _6: // ^, Start ccur.lineStart(); break; - case SHIFT + J: // Join lines + case SHIFT + _4: // $, End + ccur.lineEnd(); break; - case SHIFT + K: // manual entry + case SHIFT + G: // Goto last line + ccur.moveY( Number.MAX_VALUE ); + ccur.moveX( Number.MAX_VALUE, true ); + break; + + case SHIFT + _5: // %, Find next item + break; + } + + + // Integrated commands + switch( kCode ) + { + case V: // Visual + ccur.openAction( "VISUAL" ); + break; + case SHIFT + V: // Visual line + ccur.openAction( "VISUAL_LINE" ); break; - case 112: // F1, help } }; diff --git a/botanjs/src/Components/Vim/Cursor.js b/botanjs/src/Components/Vim/Cursor.js index b57650f..f4b6d9b 100644 --- a/botanjs/src/Components/Vim/Cursor.js +++ b/botanjs/src/Components/Vim/Cursor.js @@ -9,26 +9,6 @@ var Actions = __import( "Components.Vim.Actions.*" ); - var GetLine = function( buffs, l ) - { - /** @type {Components.Vim.LineBuffer} */ - var LineHead = buffs[0]; - l ++; - - for( var i = 0, line = LineHead; - line && i < l; i ++ ) - { - LineHead = line; - while( line ) - { - line = line.next; - if( line.br ) break; - } - } - - return LineHead; - }; - var LineOffset = function( buffs, l ) { /** @type {Components.Vim.LineBuffer} */ @@ -123,7 +103,7 @@ } /** @type {Components.Vim.LineBuffer} */ - var line = GetLine( buffs, this.Y ); + var line = this.getLine(); var content = line.visualLines.join( "\n" ); var cLen = content.length; @@ -211,35 +191,40 @@ { var lastLine = feeder.lastBuffer.lineNum; var lineShift = Y - feeder.moreAt; + var thisLine = this.getLine().lineNum; - i = lineShift; - while( !feeder.EOF ) + if( !feeder.EOF ) + feeder.pan( undefined, lineShift ); + + // if it turns out to be the same line + // before after panning + // we keep scrolling it ( panning ) + // until the entire line cosumes the screen + while( !feeder.EOF && feeder.lastBuffer.lineNum == lastLine ) { - feeder.pan( undefined, i ); - - // if it turns out to be the same line - // before after panning - // we keep scrolling it ( panning ) - // until the entire line cosumes the screen - if( feeder.lastBuffer.lineNum == lastLine ) - { - i ++; - } - else break; + feeder.pan( undefined, 1 ); } // The line number cursor need to be in - Y = lastLine + lineShift; + Y = thisLine + d; + i = this.Y; + this.Y = 0; // Calculate the visual line position "i" - for( i = 0, line = feeder.firstBuffer; - line != feeder.lastBuffer; - line = line.next ) + for( var line = this.getLine(); + line && line.lineNum != Y && !line.placeholder; + this.Y ++, line = this.getLine() ) { - if( line.br ) i ++; - if( line.lineNum == Y || line.next.placeholder ) break; } + i = this.Y; + + // Check if this line is collapsed + if( !feeder.EOF && feeder.lastBuffer.next.lineNum == line.lineNum ) + { + // If yes, step back to last visible line + i --; + } } this.Y = i; @@ -301,15 +286,16 @@ { var feeder = this.feeder; var line = feeder.firstBuffer; + var eBuffer = feeder.lastBuffer.next; for( var i = 0; - line != feeder.lastBuffer; + line != eBuffer; line = line.next ) { if( line.br ) i ++; - if( this.Y == i ) break; + if( this.Y == i ) return line; } - return line; + return null; }; // The absX for current Line diff --git a/botanjs/src/Components/Vim/LineFeeder.js b/botanjs/src/Components/Vim/LineFeeder.js index 7bedae0..e50f4ac 100644 --- a/botanjs/src/Components/Vim/LineFeeder.js +++ b/botanjs/src/Components/Vim/LineFeeder.js @@ -94,7 +94,7 @@ this.__softRender = function() { var line = _self.lineBuffers[ _self.__rStart ]; - var steps = _self.__rLength; + var steps = _self.__rLength + 1; for( var i = 0; line && i < steps && ( line = line.next ) && placeholdCond( line ); diff --git a/botanjs/src/Components/Vim/VimArea.js b/botanjs/src/Components/Vim/VimArea.js index b9a76e4..8452fab 100644 --- a/botanjs/src/Components/Vim/VimArea.js +++ b/botanjs/src/Components/Vim/VimArea.js @@ -92,7 +92,9 @@ // Content feeder var cfeeder = new LineFeeder( cRange, c ); - cfeeder.init( content ); + // This "\n" fixes the last line "\n" not displaying + // it will be trimmed after saving + cfeeder.init( content + "\n" ); // Status can consumes up to full screen, I think sfeeder = new LineFeeder( r, c ); @@ -147,7 +149,7 @@ }; __readOnly( VimArea.prototype, "content", function() { - return this.contentFeeder.content; + return this.contentFeeder.content.slice( 0, -1 ); } ); ns[ NS_EXPORT ]( EX_CLASS, "VimArea", VimArea ); diff --git a/botanjs/src/Components/Vim/_this.js b/botanjs/src/Components/Vim/_this.js index 5b263b9..04060da 100644 --- a/botanjs/src/Components/Vim/_this.js +++ b/botanjs/src/Components/Vim/_this.js @@ -5,6 +5,7 @@ "INSERT": "-- INSERT --" , "REPLACE": "-- REPLACE --" , "MORE": "-- MORE --" + , "VISUAL": "-- VISUAL --" , "VISLINE": "-- VISUAL LINE --" , "WRITE": "\"%1\" %2L, %3C written" , "CONTINUE": "Press ENTER or type command to continue"