commit d6bbf245c682048aa723a38257b11c647600681f
| author | 斟酌 鵬兄 <tgckpg@gmail.com> |
| date | 2016-03-12T19:30:33Z |
| subject | Some drafts |
commit d6bbf245c682048aa723a38257b11c647600681f
Author: 斟酌 鵬兄 <tgckpg@gmail.com>
Date: 2016-03-12T19:30:33Z
Some drafts
---
botanjs/src/Components/Vim/LineFeeder.js | 195 +++++++++++++++++++++++++++++++
botanjs/src/Components/Vim/StatusBar.js | 50 ++++++++
botanjs/src/Components/Vim/VimArea.js | 163 ++++++++++++++++++++++++++
botanjs/src/Components/Vim/_this.css | 4 +
botanjs/src/Components/Vim/_this.js | 42 +++++++
5 files changed, 454 insertions(+)
diff --git a/botanjs/src/Components/Vim/LineFeeder.js b/botanjs/src/Components/Vim/LineFeeder.js
new file mode 100644
index 0000000..ae8af80
--- /dev/null
+++ b/botanjs/src/Components/Vim/LineFeeder.js
@@ -0,0 +1,195 @@
+(function(){
+ var ns = __namespace( "Components.Vim" );
+
+ /** @type {Dandelion} */
+ var Dand = __import( "Dandelion" );
+ /** @type {Dandelion.IDOMElement} */
+ var IDOMElement = __import( "Dandelion.IDOMElement" );
+ /** @type {Dandelion.IDOMObject} */
+ var IDOMObject = __import( "Dandelion.IDOMObject" );
+ /** @type {System.Cycle} */
+ var Cycle = __import( "System.Cycle" );
+ /** @type {System.Debug} */
+ var debug = __import( "System.Debug" );
+
+ var Line = function( cols, nextLine )
+ {
+ this.cols = cols;
+ this.next = nextLine;
+ this.br = false;
+ this.placeholder = true;
+ };
+
+ Line.prototype.Push = function( content, wrap )
+ {
+ if( content == undefined || content === "" )
+ {
+ this.content = "~";
+ this.placeholder = true;
+ if( this.next ) this.next.Push( content, wrap );
+ return;
+ }
+
+ this.placeholder = false;
+
+ var line = "";
+ var br = false;
+
+ if( wrap )
+ {
+ for( var i = 0; i < this.cols; i ++ )
+ {
+ var c = content[i];
+ if( c === undefined ) break;
+
+ if( c == "\n" )
+ {
+ br = true;
+ i ++;
+ break;
+ }
+
+ line += c;
+ }
+ }
+ else
+ {
+ br = true;
+ for( var i = 0; true; i ++ )
+ {
+ var c = content[i];
+ if( c === undefined ) break;
+
+ if( c == "\n" )
+ {
+ i ++;
+ break;
+ }
+
+ if( i < this.cols )
+ {
+ line += c;
+ }
+ }
+ }
+
+ if( this.next )
+ {
+ this.next.br = br;
+ this.next.Push( content.substr( i ), wrap );
+ }
+
+ this.content = line;
+ };
+
+ Line.prototype.toString = function()
+ {
+ return this.content;
+ };
+
+ var Feeder = function( rows, cols )
+ {
+ var lines = [];
+
+ // Last line
+ lines[ rows - 1 ] = new Line( cols );
+
+ for( var i = rows - 2; 0 <= i; i -- )
+ {
+ lines[i] = new Line( cols, lines[ i + 1 ] );
+ }
+
+ this.lines = lines;
+ this.setRender();
+ };
+
+ Feeder.prototype.init = function( content, wrap )
+ {
+ if( wrap == undefined ) wrap = true;
+ if( this.lines.length )
+ {
+ this.lines[0].Push( content, wrap );
+ }
+ };
+
+ // Advance the text to number of lines
+ Feeder.prototype.feed = function( num )
+ {
+ };
+
+ Feeder.prototype.wrap = function( setwrap )
+ {
+ };
+
+ Feeder.prototype.setRender = function( placeholder )
+ {
+ if( placeholder == undefined ) placeholder = true;
+
+ if( placeholder )
+ {
+ this.__render = function( line, steps )
+ {
+ var display = ( line == undefined ? "" : line ) + "";
+
+ for( var i = 0;
+ line && i < steps && ( line = line.next );
+ i ++ )
+ {
+ display += "\n" + line;
+ }
+
+ return display;
+ };
+ }
+ else
+ {
+ this.__render = function( line, steps )
+ {
+ var display = ( line == undefined ? "" : line ) + "";
+
+ for( var i = 0;
+ line && i < steps && ( line = line.next ) && !line.placeholder;
+ i ++ )
+ {
+ display += "\n" + line;
+ }
+
+ return display;
+ };
+ }
+ }
+
+ Feeder.prototype.cursor = function( direction )
+ {
+ switch( direction )
+ {
+ case 0:
+ return { start: 0, end: 1 };
+ }
+ };
+
+ Feeder.prototype.render = function( start, length )
+ {
+ if( start == undefined ) start = 0;
+ else if( this.lines.length < start ) return "";
+
+ if( length == undefined || ( this.lines.length - start ) < length )
+ length = this.lines.length - start;
+
+ if( length == 0 ) return "";
+
+ return this.__render( this.lines[ start ], length - 1 );
+ };
+
+ __readOnly( Feeder.prototype, "linesOccupied", function() {
+ var line = this.lines[0];
+ if( line.placeholder ) return 0;
+
+ var i = 0;
+ do i ++;
+ while( ( line = line.next ) && !line.placeholder );
+ return i;
+ } );
+
+ ns[ NS_EXPORT ]( EX_CLASS, "LineFeeder", Feeder );
+})();
diff --git a/botanjs/src/Components/Vim/StatusBar.js b/botanjs/src/Components/Vim/StatusBar.js
new file mode 100644
index 0000000..9aa4535
--- /dev/null
+++ b/botanjs/src/Components/Vim/StatusBar.js
@@ -0,0 +1,50 @@
+(function(){ var ns = __namespace( "Components.Vim" );
+
+ /** @type {Dandelion} */
+ var Dand = __import( "Dandelion" );
+ /** @type {Dandelion.IDOMElement} */
+ var IDOMElement = __import( "Dandelion.IDOMElement" );
+ /** @type {Dandelion.IDOMObject} */
+ var IDOMObject = __import( "Dandelion.IDOMObject" );
+ /** @type {System.Cycle} */
+ var Cycle = __import( "System.Cycle" );
+ /** @type {System.Debug} */
+ var debug = __import( "System.Debug" );
+
+ /** @type {Components.VimArea.LineFeeder} */
+ var LineFeeder = ns[ NS_INVOKE ]( "LineFeeder" );
+
+ var StatusBar = function( cols )
+ {
+ this.cols = cols;
+ this.statStamp = {};
+ };
+
+ StatusBar.prototype.stamp = function( pos, func )
+ {
+ this.statStamp[ pos ] = func;
+ };
+
+ __readOnly( StatusBar.prototype, "statusText", function()
+ {
+ var display = "";
+ var l = this.cols;
+
+ for( var i = 0; i < l; i ++ )
+ {
+ var avail = l - i;
+ var text = this.statStamp[ i ] || this.statStamp[ - avail ];
+ if( text )
+ {
+ text = text();
+ display += text.substr( 0, avail );
+ i = display.length - 1;
+ }
+ else display += " ";
+ }
+
+ return display;
+ } );
+
+ ns[ NS_EXPORT ]( EX_CLASS, "StatusBar", StatusBar );
+})();
diff --git a/botanjs/src/Components/Vim/VimArea.js b/botanjs/src/Components/Vim/VimArea.js
new file mode 100644
index 0000000..791f511
--- /dev/null
+++ b/botanjs/src/Components/Vim/VimArea.js
@@ -0,0 +1,163 @@
+(function(){
+ var ns = __namespace( "Components.Vim" );
+
+ /** @type {Dandelion} */
+ var Dand = __import( "Dandelion" );
+ /** @type {Dandelion.IDOMElement} */
+ var IDOMElement = __import( "Dandelion.IDOMElement" );
+ /** @type {Dandelion.IDOMObject} */
+ var IDOMObject = __import( "Dandelion.IDOMObject" );
+ /** @type {System.utils.DataKey} */
+ var DataKey = __import( "System.utils.DataKey" );
+ /** @type {System.Cycle} */
+ var Cycle = __import( "System.Cycle" );
+ /** @type {System.Debug} */
+ var debug = __import( "System.Debug" );
+
+ /** @type {Components.VimArea.LineFeeder} */
+ var LineFeeder = ns[ NS_INVOKE ]( "LineFeeder" );
+ var StatusBar = ns[ NS_INVOKE ]( "StatusBar" );
+
+ var KeyHandler = function( sender, handler )
+ {
+ return function( e )
+ {
+ e = e || window.event;
+ if ( e.keyCode ) code = e.keyCode;
+ else if ( e.which ) code = e.which;
+
+ handler( sender, e );
+ };
+ };
+
+ var VimControls = function( sender, e )
+ {
+ e.preventDefault();
+ if( e.ctrlKey )
+ {
+ VimComboFunc( sender, e );
+ return;
+ }
+
+ var kCode = e.KeyCode + ( e.shiftKey ? 1000 : 0 );
+ switch( e.KeyCode )
+ {
+ case 65: // a
+ case 1065: // A
+ break;
+ case 72: // h
+ case 1072: // H
+ break;
+ case 74: // j
+ case 1074: // J
+ break;
+ case 75: // k
+ case 1075: // K
+ break;
+ case 76: // l
+ case 1076: // L
+ break;
+ case 1053: // %
+ case 1054: // ^
+ break;
+ }
+ };
+
+ /* stage @param {Dandelion.IDOMElement} */
+ var VimArea = function( stage )
+ {
+ if( !stage ) return;
+
+ var element = stage.element;
+
+ if( element.nodeName != "TEXTAREA" )
+ {
+ debug.Error( "Element is not compatible for VimArea" );
+ return;
+ }
+
+ stage.setAttribute( new DataKey( "vimarea", 1 ) );
+
+ this.stage = stage;
+ this.rows = element.rows;
+ this.cols = element.cols;
+
+ this.PosX = 1;
+ this.PosY = 1;
+
+ stage.addEventListener( "KeyDown", KeyHandler( this, VimControls ) );
+
+ // Init
+ this.content = element.value;
+ this.VisualizeVimFrame();
+ };
+
+ VimArea.prototype.startInput = function( mode )
+ {
+
+ };
+
+ VimArea.prototype.cursor = function( x, y )
+ {
+ return this.__cursor();
+ };
+
+ VimArea.prototype.flashCursor = function()
+ {
+ var _self = this;
+ var textarea = this.stage.element;
+ Cycle.perma( "VimCursorFlashCycle", function()
+ {
+ var cursor = _self.cursor();
+ if( cursor )
+ {
+ textarea.selectionStart = cursor.start;
+ textarea.selectionEnd = cursor.end;
+ }
+ }, 600 );
+ };
+
+ VimArea.prototype.VisualizeVimFrame = function()
+ {
+ var element = this.stage.element;
+ var r = this.rows;
+ var c = this.cols;
+
+ // Content feeder
+ var cfeeder = new LineFeeder( r, c );
+
+ cfeeder.init( this.content );
+
+ // Status feeder
+ sfeeder = new LineFeeder( r, c );
+ sfeeder.setRender( false );
+
+ var statusBar = new StatusBar( c );
+ statusBar.stamp( -18, function(){
+ return "1,1-1";
+ });
+
+ statusBar.stamp( -3, function(){
+ return "All";
+ });
+
+ sfeeder.init( statusBar.statusText );
+
+ element.value = cfeeder.render( 0, r - sfeeder.linesOccupied ) + "\n" + sfeeder.render();
+
+ this.contentFeeder = cfeeder;
+ this.statusFeeder = sfeeder;
+
+ var f = true;
+ this.__cursor = function()
+ {
+ if( f = !f )
+ return this.contentFeeder.cursor( 0 );
+ else return { start: 0, end: 0 };
+ }
+
+ this.flashCursor();
+ };
+
+ ns[ NS_EXPORT ]( EX_CLASS, "VimArea", VimArea );
+})();
diff --git a/botanjs/src/Components/Vim/_this.css b/botanjs/src/Components/Vim/_this.css
new file mode 100644
index 0000000..1716ca4
--- /dev/null
+++ b/botanjs/src/Components/Vim/_this.css
@@ -0,0 +1,4 @@
+textarea[data-vimarea="1"] {
+ color: transparent;
+ text-shadow: 0 0 0 #000;
+}
diff --git a/botanjs/src/Components/Vim/_this.js b/botanjs/src/Components/Vim/_this.js
new file mode 100644
index 0000000..706cf48
--- /dev/null
+++ b/botanjs/src/Components/Vim/_this.js
@@ -0,0 +1,42 @@
+(function(){
+ var ns = __namespace( "Components.Vim" );
+
+ /** @type {Dandelion} */
+ var Dand = __import( "Dandelion" );
+ /** @type {Dandelion.IDOMElement} */
+ var IDOMElement = __import( "Dandelion.IDOMElement" );
+ /** @type {Dandelion.IDOMObject} */
+ var IDOMObject = __import( "Dandelion.IDOMObject" );
+ /** @type {System.Cycle} */
+ var Cycle = __import( "System.Cycle" );
+ /** @type {System.Debug} */
+ var debug = __import( "System.Debug" );
+
+ var messages = {
+ "INSERT": "-- INSERT --"
+ , "MORE": "-- MORE --"
+ , "WRITE": "\"%1\" %2L, %3C written"
+ , "CONTINUE": "Press ENTER or type command to continue"
+ , "SEARCH_HIT_BOTTOM": "Seach hit BOTTOM, contining at TOP"
+ , "TOP": "Top"
+ , "BOTTOM": "Bot"
+ , "ALL": "All"
+ , "EXIT": "Type :quit<Enter> to exit Vim"
+ };
+
+ var errors = {
+ "E486": "E486: Pattern not found: %1"
+ };
+
+ var Message = function( key )
+ {
+ var restArgs = Array.prototype.slice.apply( arguments, 1 );
+ var i = 0;
+ return messages[ key ].replace( /%\d+/g, function( e )
+ {
+ return restArgs[ i ++ ];
+ } );
+ };
+
+ ns[ NS_EXPORT ]( EX_FUNC, "Message", Message );
+})();