From 2fda27b7be019c21c8c17887f01d1c0dc4e586c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=96=9F=E9=85=8C=20=E9=B5=AC=E5=85=84?= Date: Mon, 30 Jan 2017 20:13:15 +0800 Subject: [PATCH] c-d, c-u, HTML, gj, gk & bug fixes --- botanjs/src/Components/Vim/Controls.js | 67 +++++++++++++++++++++++++- botanjs/src/Components/Vim/Cursor.js | 43 +++++++++++++++-- 2 files changed, 103 insertions(+), 7 deletions(-) diff --git a/botanjs/src/Components/Vim/Controls.js b/botanjs/src/Components/Vim/Controls.js index 82877da..bb22ce4 100644 --- a/botanjs/src/Components/Vim/Controls.js +++ b/botanjs/src/Components/Vim/Controls.js @@ -215,9 +215,10 @@ Controls.prototype.__composite = function( e, handler ) { + if( !this.__compositeReg ) this.__compositeReg = []; + if( handler ) { - if( !this.__compositeReg ) this.__compositeReg = []; this.__compositeReg.push({ keys: Array.prototype.slice.call( arguments, 2 ) , handler: handler @@ -528,7 +529,7 @@ cfeeder.pan( undefined, 1 ); cfeeder.softReset(); - ccur.moveY( 0 < ccur.Y ? -1 : 0 ); + ccur.moveY( 0 < ccur.Y ? -1 : 0 ); ccur.moveX(); break; case CTRL + Y: // Pan Y, Scroll Up @@ -544,10 +545,33 @@ ccur.moveY( ccur.Y == cfeeder.moreAt ? 0 : 1 ); ccur.moveX(); break; + case CTRL + D: // Page Down, keep cursor.Y + cfeeder.pan( undefined, cfeeder.moreAt ); + cfeeder.softReset(); + ccur.moveY( 0 ); + break; + case CTRL + U: // Page Up, keep cursor.Y + if( cfeeder.panY == 0 ) + { + beep(); + break; + } + cfeeder.pan( undefined, -cfeeder.moreAt ); + cfeeder.softReset(); + ccur.moveY( 0 ); + break; case SHIFT + H: // First line buffer + ccur.moveY( -ccur.Y ); + ccur.lineStart( true ); + break; + case SHIFT + M: // Middle line buffer + ccur.moveY( Math.floor( 0.5 * cfeeder.moreAt ) - ccur.Y ); + ccur.lineStart( true ); break; case SHIFT + L: // Last line buffer + ccur.moveY( cfeeder.moreAt - ccur.Y ); + ccur.lineStart( true ); break; case _0: // Really line Start @@ -685,6 +709,45 @@ ccur.moveX( -Number.MAX_VALUE, true ); }, G ); + // Wordwrap next display line + this.__composite( e, function() { + var dispLine = ccur.getLine( true ); + ccur.moveX( dispLine.content.length + 1 ); + }, J ); + + // Wordwrap prev display line + this.__composite( e, function() { + var dispLine = ccur.getLine( true ).prev; + var thisLine = ccur.getLine().lineNum; + + if( !dispLine ) + { + ccur.lineStart(); + beep(); + return; + } + + if( dispLine.content != "" && dispLine.lineNum == thisLine ) + { + ccur.moveX( -( dispLine.content.length + 1 ) ); + } + else + { + ccur.moveY( -1 ); + var lines = ccur.getLine().visualLines; + if( 1 < lines.length ) + { + var l = lines.length - 1; + var j = 0; + for( var i = 0; i < l; i ++ ) + { + j += lines[i].content.length; + } + ccur.moveX( j ); + } + } + }, K ); + // Print Hex this.__composite( e, function() { ccur.openRunAction( "PRINT_HEX", e ); diff --git a/botanjs/src/Components/Vim/Cursor.js b/botanjs/src/Components/Vim/Cursor.js index ad3a5ed..2bf2eb4 100644 --- a/botanjs/src/Components/Vim/Cursor.js +++ b/botanjs/src/Components/Vim/Cursor.js @@ -132,7 +132,14 @@ var jumpY = expLineNum - lastLineNum; var jumpX = aPos < lineStart ? lineStart - aPos : aPos - lineStart; - jumpX += Math.ceil( jumpX / pline.cols ) - 1; + var kX = jumpX - pline.content.length; + while( 0 < kX ) + { + jumpX ++; + pline = pline.next + if(!( pline && pline.lineNum == expLineNum )) break; + kX -= pline.content.length; + } if( jumpY ) this.moveY( jumpY ); @@ -256,7 +263,7 @@ if( s == 0 ) { - x = 1; + x = d; if ( rline[ 0 ] == "\t" ) { x += tabStep; @@ -266,14 +273,19 @@ e += d; var ntabs = occurence( rline.substring( s + 1, e + 1 ), "\t" ); + if( 1 < ntabs && rline[ e ] == "\t" ) ntabs --; x += ntabs * tabStep + isLF; - if( 1 < d ) x += d - 1; + x += Math.max( 0, Math.floor( d / line.cols ) - 1 ); + + // Reset the distance to 1 as x is now calculated + d = 1; } else // jk, non-X navigation. i.e., pX does not change { // s = 0, which is unused here e = x + d; x += ( occurence( rline.substring( 0, e ), "\t" ) ) * tabStep; + x += Math.floor( x / line.cols ); if( 1 < d ) x += d - 1; } } @@ -286,6 +298,13 @@ if( boundary ) { x = 0 < x ? lineEnd : 0; + + // This happens on backspacing max filled lines on INSERT mode + if( d < 0 && 0 < x ) + { + boundary = false; + x += d; + } } else if( c == "\n" ) { @@ -505,7 +524,7 @@ Cursor.prototype.suppressEvent = function() { ++ this.__suppEvt; }; Cursor.prototype.unsuppressEvent = function() { -- this.__suppEvt; }; - Cursor.prototype.getLine = function( raw ) + Cursor.prototype.getLine = function( display ) { var feeder = this.feeder; var line = feeder.firstBuffer; @@ -513,7 +532,21 @@ for( var i = 0; line != eBuffer; line = line.next ) { if( line.br ) i ++; - if( this.Y == i ) return line; + if( this.Y == i ) + { + // Return the display line + if( display ) + { + var x = this.aX + 1; + while( 0 < ( x -= line.content.length ) ) + { + if( !line.next ) return line; + line = line.next; + } + } + + return line; + } } return null;